fix Dockerfile and create a docker management script
This commit is contained in:
parent
d322d41f07
commit
51984573da
7 changed files with 135 additions and 25 deletions
27
Dockerfile
27
Dockerfile
|
@ -1,11 +1,28 @@
|
|||
FROM python:3-alpine
|
||||
WORKDIR /workdir
|
||||
|
||||
# install build deps for pycryptodome and other c-based python modules
|
||||
RUN apk add alpine-sdk autoconf automake libtool gcc
|
||||
|
||||
ADD requirements.txt /workdir/
|
||||
RUN pip3 install -r requirements.txt
|
||||
# add env var to let the relay know it's in a container
|
||||
ENV DOCKER_RUNNING=true
|
||||
|
||||
ADD . /workdir/
|
||||
# setup various container properties
|
||||
VOLUME ["/data"]
|
||||
CMD ["python", "-m", "relay"]
|
||||
EXPOSE 8080/tcp
|
||||
WORKDIR /opt/activityrelay
|
||||
|
||||
VOLUME ["/workdir/data"]
|
||||
# install and update important python modules
|
||||
RUN pip3 install -U setuptools wheel pip
|
||||
|
||||
# only copy necessary files
|
||||
COPY relay ./relay
|
||||
COPY LICENSE .
|
||||
COPY README.md .
|
||||
COPY requirements.txt .
|
||||
COPY setup.cfg .
|
||||
COPY setup.py .
|
||||
COPY .git ./.git
|
||||
|
||||
# install relay deps
|
||||
RUN pip3 install -r requirements.txt
|
||||
|
|
17
README.md
17
README.md
|
@ -15,9 +15,9 @@ in this package as the `LICENSE` file.
|
|||
You need at least Python 3.6 (latest version of 3.x recommended) to make use of this software.
|
||||
It simply will not run on older Python versions.
|
||||
|
||||
Download the project and install with pip (`pip3 install .`).
|
||||
Download the project and install with pip (`pip3 install -r requirements.txt`).
|
||||
|
||||
Run `activityrelay setup` and answer the prompts or copy `relay.yaml.example` to `relay.yaml`
|
||||
Run `python3 -m relay setup` and answer the prompts or copy `relay.yaml.example` to `relay.yaml`
|
||||
and edit it as appropriate:
|
||||
|
||||
$ cp relay.yaml.example relay.yaml
|
||||
|
@ -25,7 +25,7 @@ and edit it as appropriate:
|
|||
|
||||
Finally, you can launch the relay:
|
||||
|
||||
$ activityrelay run
|
||||
$ python3 -m relay run
|
||||
|
||||
It is suggested to run this under some sort of supervisor, such as runit, daemontools,
|
||||
s6 or systemd. Configuration of the supervisor is not covered here, as it is different
|
||||
|
@ -60,17 +60,12 @@ You can perform a few management tasks such as peering or depeering other relays
|
|||
|
||||
This will show the available management tasks:
|
||||
|
||||
$ activityrelay --help
|
||||
$ python3 -m relay --help
|
||||
|
||||
When following remote relays, you should use the `/actor` endpoint as you would in
|
||||
Pleroma and other LitePub-compliant software.
|
||||
|
||||
## Docker
|
||||
|
||||
You can run ActivityRelay with docker. Edit `relay.yaml` so that the database
|
||||
location is set to `./data/relay.jsonld` and then build and run the docker
|
||||
image :
|
||||
|
||||
$ docker volume create activityrelay-data
|
||||
$ docker build -t activityrelay .
|
||||
$ docker run -d -p 8080:8080 -v activityrelay-data:/workdir/data activityrelay
|
||||
You can run ActivityRelay with docker via the docker management script: `docker.sh`.
|
||||
Run it without arguments to see the list of commands.
|
||||
|
|
66
docker.sh
Executable file
66
docker.sh
Executable file
|
@ -0,0 +1,66 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
case $1 in
|
||||
install)
|
||||
docker build -f Dockerfile -t activityrelay . && \
|
||||
docker volume create activityrelay-data && \
|
||||
docker run -it -p 8080:8080 -v activityrelay-data:/data --name activityrelay activityrelay
|
||||
;;
|
||||
|
||||
uninstall)
|
||||
docker stop activityrelay && \
|
||||
docker container rm activityrelay && \
|
||||
docker volume rm activityrelay-data && \
|
||||
docker image rm activityrelay
|
||||
;;
|
||||
|
||||
start)
|
||||
docker start activityrelay
|
||||
;;
|
||||
|
||||
stop)
|
||||
docker stop activityrelay
|
||||
;;
|
||||
|
||||
manage)
|
||||
shift
|
||||
docker exec -it activityrelay python3 -m relay "$@"
|
||||
;;
|
||||
|
||||
shell)
|
||||
docker exec -it activityrelay bash
|
||||
;;
|
||||
|
||||
rescue)
|
||||
docker run -it --rm --entrypoint bash -v activityrelay-data:/data activityrelay
|
||||
;;
|
||||
|
||||
edit)
|
||||
if [ -z ${EDITOR} ]; then
|
||||
echo "EDITOR environmental variable not set"
|
||||
exit
|
||||
fi
|
||||
|
||||
CONFIG="/tmp/relay-$(date +"%T").yaml"
|
||||
|
||||
docker cp activityrelay:/data/relay.yaml $CONFIG && \
|
||||
$EDITOR $CONFIG && \
|
||||
|
||||
docker cp $CONFIG activityrelay:/data/relay.yaml && \
|
||||
rm $CONFIG
|
||||
;;
|
||||
|
||||
*)
|
||||
COLS="%-22s %s\n"
|
||||
|
||||
echo "Valid commands:"
|
||||
printf "$COLS" "- start" "Run the relay in the background"
|
||||
printf "$COLS" "- stop" "Stop the relay"
|
||||
printf "$COLS" "- manage <cmd> [args]" "Run a relay management command"
|
||||
printf "$COLS" "- edit" "Edit the relay's config in \$EDITOR"
|
||||
printf "$COLS" "- shell" "Drop into a bash shell on the running container"
|
||||
printf "$COLS" "- rescue" "Drop into a bash shell on a temp container with the data volume mounted"
|
||||
printf "$COLS" "- install" "Build the image, create a new container and volume, and run relay setup"
|
||||
printf "$COLS" "- uninstall" "Delete the relay image, container, and volume"
|
||||
;;
|
||||
esac
|
|
@ -60,11 +60,15 @@ class RelayConfig(DotDict):
|
|||
}
|
||||
|
||||
|
||||
def __init__(self, path):
|
||||
self._path = Path(path).expanduser().resolve()
|
||||
def __init__(self, path, is_docker):
|
||||
if is_docker:
|
||||
path = '/data/relay.yaml'
|
||||
|
||||
self._isdocker = is_docker
|
||||
self._path = Path(path).expanduser()
|
||||
|
||||
super().__init__({
|
||||
'db': f'{self._path.stem}.jsonld',
|
||||
'db': str(self._path.parent.joinpath(f'{self._path.stem}.jsonld')),
|
||||
'listen': '0.0.0.0',
|
||||
'port': 8080,
|
||||
'note': 'Make a note about your instance here.',
|
||||
|
@ -81,6 +85,9 @@ class RelayConfig(DotDict):
|
|||
|
||||
|
||||
def __setitem__(self, key, value):
|
||||
if self._isdocker and key in ['db', 'listen', 'port']:
|
||||
return
|
||||
|
||||
if key in ['blocked_instances', 'blocked_software', 'whitelist']:
|
||||
assert isinstance(value, (list, set, tuple))
|
||||
|
||||
|
@ -234,7 +241,7 @@ class RelayConfig(DotDict):
|
|||
|
||||
self[key] = value
|
||||
|
||||
if self.host == 'example.com':
|
||||
if self.host.endswith('example.com'):
|
||||
return False
|
||||
|
||||
return True
|
||||
|
|
|
@ -3,6 +3,7 @@ import asyncio
|
|||
import click
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import platform
|
||||
|
||||
from aiohttp.web import AppRunner, TCPSite
|
||||
|
@ -11,14 +12,15 @@ from cachetools import LRUCache
|
|||
from . import app, misc, views
|
||||
from .config import DotDict, RelayConfig
|
||||
from .database import RelayDatabase
|
||||
from .misc import follow_remote_actor, unfollow_remote_actor
|
||||
from .misc import check_open_port, follow_remote_actor, unfollow_remote_actor
|
||||
|
||||
|
||||
@click.group('cli', context_settings={'show_default': True}, invoke_without_command=True)
|
||||
@click.option('--config', '-c', default='relay.yaml', help='path to the relay\'s config')
|
||||
@click.pass_context
|
||||
def cli(ctx, config):
|
||||
app['config'] = RelayConfig(config)
|
||||
app['is_docker'] = bool(os.environ.get('DOCKER_RUNNING'))
|
||||
app['config'] = RelayConfig(config, app['is_docker'])
|
||||
|
||||
if not app['config'].load():
|
||||
app['config'].save()
|
||||
|
@ -33,7 +35,11 @@ def cli(ctx, config):
|
|||
app['cache'][key] = LRUCache(app['config'][key])
|
||||
|
||||
if not ctx.invoked_subcommand:
|
||||
relay_run.callback()
|
||||
if app['config'].host.endswith('example.com'):
|
||||
relay_setup.callback()
|
||||
|
||||
else:
|
||||
relay_run.callback()
|
||||
|
||||
|
||||
@cli.command('list')
|
||||
|
@ -239,7 +245,7 @@ def relay_setup():
|
|||
|
||||
config.save()
|
||||
|
||||
if click.confirm('Relay all setup! Would you like to run it now?'):
|
||||
if not app['is_docker'] and click.confirm('Relay all setup! Would you like to run it now?'):
|
||||
relay_run.callback()
|
||||
|
||||
|
||||
|
@ -247,7 +253,9 @@ def relay_setup():
|
|||
def relay_run():
|
||||
'Run the relay'
|
||||
|
||||
if app['config'].host.endswith('example.com'):
|
||||
config = app['config']
|
||||
|
||||
if config.host.endswith('example.com'):
|
||||
return click.echo('Relay is not set up. Please edit your relay config or run "activityrelay setup".')
|
||||
|
||||
vers_split = platform.python_version().split('.')
|
||||
|
@ -262,6 +270,9 @@ def relay_run():
|
|||
click.echo('Warning: PyCrypto is old and should be replaced with pycryptodome')
|
||||
return click.echo(pip_command)
|
||||
|
||||
if not check_open_port(config.listen, config.port):
|
||||
return click.echo(f'Error: A server is already running on port {config.port}')
|
||||
|
||||
# web pages
|
||||
app.router.add_get('/', views.home)
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ import asyncio
|
|||
import base64
|
||||
import json
|
||||
import logging
|
||||
import socket
|
||||
import traceback
|
||||
|
||||
from Crypto.Hash import SHA, SHA256, SHA512
|
||||
|
@ -28,6 +29,18 @@ def build_signing_string(headers, used_headers):
|
|||
return '\n'.join(map(lambda x: ': '.join([x.lower(), headers[x]]), used_headers))
|
||||
|
||||
|
||||
def check_open_port(host, port):
|
||||
if host == '0.0.0.0':
|
||||
host = '127.0.0.1'
|
||||
|
||||
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
|
||||
try:
|
||||
return s.connect_ex((host , port)) != 0
|
||||
|
||||
except socket.error as e:
|
||||
return False
|
||||
|
||||
|
||||
def create_signature_header(headers):
|
||||
headers = {k.lower(): v for k, v in headers.items()}
|
||||
used_headers = headers.keys()
|
||||
|
|
1
requirements.txt
Normal file
1
requirements.txt
Normal file
|
@ -0,0 +1 @@
|
|||
.
|
Loading…
Reference in a new issue