diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..4016130 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,7 @@ +*.pyc +.idea/ +.vscode/ + +sydent.conf +sydent.db +.git diff --git a/.gitignore b/.gitignore index a233a0b..8d69ce0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,11 @@ +# Development files *.pyc .idea/ +.vscode/ +*.iml +_trial_temp +# Runtime files sydent.conf sydent.db /matrix_is_test/sydent.stderr -_trial_temp diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..f4579e1 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,59 @@ +# +# Step 1: Build sydent and install dependencies +# +FROM docker.io/python:3.8-alpine as builder + +# Install dev packages +RUN apk add --no-cache \ + build-base \ + libressl-dev \ + libffi-dev + +# Add user sydent +RUN addgroup -S -g 993 sydent \ + && adduser -D --home /sydent -S -u 993 -G sydent -s /bin/ash sydent \ + && echo "sydent:$(dd if=/dev/random bs=32 count=1 | base64)" | chpasswd + +# Copy resources +COPY --chown=sydent:sydent ["res", "/sydent/res"] +COPY --chown=sydent:sydent ["scripts", "/sydent/scripts"] +COPY --chown=sydent:sydent ["sydent", "/sydent/sydent"] +COPY --chown=sydent:sydent ["README.rst", "setup.cfg", "setup.py", "/sydent/"] + +# Install dependencies +RUN cd /sydent \ + && su sydent -c 'pip install --user --upgrade pip setuptools sentry-sdk' \ + && su sydent -c 'pip install --user -e .' \ + && rm -rf /sydent/.cache \ + && find /sydent -name '*.pyc' -delete + +# +# Step 2: Reduce image size and layers +# + +FROM docker.io/python:3.8-alpine + +# Install packages +RUN apk add --no-cache \ + libressl \ + libffi + +# Add user sydent and create /data directory +RUN addgroup -S -g 993 sydent \ + && adduser -D --home /sydent -S -u 993 -G sydent -s /bin/ash sydent \ + && echo "sydent:$(dd if=/dev/random bs=32 count=1 | base64)" | chpasswd \ + && mkdir /data \ + && chown sydent:sydent /data + +# Copy sydent +COPY --from=builder ["/sydent", "/sydent"] + +ENV SYDENT_CONF=/data/sydent.conf +ENV SYDENT_PID_FILE=/data/sydent.pid +ENV SYDENT_DB_PATH=/data/sydent.db + +WORKDIR /sydent +USER sydent:sydent +VOLUME ["/data"] +EXPOSE 8090/tcp +CMD [ "python", "-m", "sydent.sydent" ] diff --git a/README.rst b/README.rst index 68f4508..b68581a 100644 --- a/README.rst +++ b/README.rst @@ -74,6 +74,51 @@ US/Canada, a short code for the UK and an alphanumertic originator for everywher originators.44 = short:12345 originators.default = alpha:Matrix +Docker +====== + +A Dockerfile is provided for sydent. To use it, run ``docker build -t sydent .`` in a sydent checkout. +To run it, use ``docker run --env=SYDENT_SERVER_NAME=my-sydent-server -p 8090:8090 sydent``. + +Caution: All data will be lost when the container is terminated! + +Persistent data +--------------- + +By default, all data is stored in ``/data``. +The best method is to put the data in a Docker volume. + +.. code-block:: shell + + docker volume create sydent-data + docker run ... --mount type=volume,source=sydent-data,destination=/data sydent + +But you can also bind a local directory to the container. +However, you then have to pay attention to the file permissions. + +.. code-block:: shell + + mkdir /path/to/sydent-data + chown 993:993 /path/to/sydent-data + docker run ... --mount type=bind,source=/path/to/sydent-data,destination=/data sydent + +Environment variables +--------------------- + +.. warning:: These variables are only taken into account at first start and are written to the configuration file. + ++--------------------+-----------------+-----------------------+ +| Variable Name | Sydent default | Dockerfile default | ++====================+=================+=======================+ +| SYDENT_SERVER_NAME | *empty* | *empty* | ++--------------------+-----------------+-----------------------+ +| SYDENT_CONF | ``sydent.conf`` | ``/data/sydent.conf`` | ++--------------------+-----------------+-----------------------+ +| SYDENT_PID_FILE | ``sydent.pid`` | ``/data/sydent.pid`` | ++--------------------+-----------------+-----------------------+ +| SYDENT_DB_PATH | ``sydent.db`` | ``/data/sydent.db`` | ++--------------------+-----------------+-----------------------+ + Testing ======= diff --git a/changelog.d/290.feature b/changelog.d/290.feature new file mode 100644 index 0000000..a987c58 --- /dev/null +++ b/changelog.d/290.feature @@ -0,0 +1 @@ +Add a Dockerfile and allow environment variables `SYDENT_SERVER_NAME`, `SYDENT_PID_FILE` and `SYDENT_DB_PATH` to modify default configuration values. \ No newline at end of file diff --git a/sydent/db/sqlitedb.py b/sydent/db/sqlitedb.py index 666f700..8e8ea37 100644 --- a/sydent/db/sqlitedb.py +++ b/sydent/db/sqlitedb.py @@ -51,9 +51,10 @@ class SqliteDatabase: scriptPath = os.path.join(schemaDir, f) fp = open(scriptPath, 'r') try: + logger.info("Importing %s", scriptPath) c.executescript(fp.read()) except: - logger.error("Error importing %s", f) + logger.error("Error importing %s", scriptPath) raise fp.close() diff --git a/sydent/sydent.py b/sydent/sydent.py index 2c1538f..482efd4 100644 --- a/sydent/sydent.py +++ b/sydent/sydent.py @@ -76,10 +76,10 @@ logger = logging.getLogger(__name__) CONFIG_DEFAULTS = { 'general': { - 'server.name': '', + 'server.name': os.environ.get('SYDENT_SERVER_NAME', ''), 'log.path': '', 'log.level': 'INFO', - 'pidfile.path': 'sydent.pid', + 'pidfile.path': os.environ.get('SYDENT_PID_FILE', 'sydent.pid'), 'terms.path': '', 'address_lookup_limit': '10000', # Maximum amount of addresses in a single /lookup request @@ -96,7 +96,7 @@ CONFIG_DEFAULTS = { 'delete_tokens_on_bind': 'true', }, 'db': { - 'db.file': 'sydent.db', + 'db.file': os.environ.get('SYDENT_DB_PATH', 'sydent.db'), }, 'http': { 'clientapi.http.bind_address': '::',