From 2ebaaaacec9e1da3178950b4b590972b0555958d Mon Sep 17 00:00:00 2001 From: Kappeh Date: Wed, 28 Jan 2026 16:29:10 +0000 Subject: [PATCH] Add synapse and database containers --- .gitea/workflows/ci_cd.yml | 54 ++++++++++++++++++++ compose.yml | 91 ++++++++++++++++++++++++++++++++++ config/homeserver.template.yml | 88 ++++++++++++++++++++++++++++++++ config/log_config.yml | 28 +++++++++++ init.sh | 18 +++++++ template.env | 3 ++ 6 files changed, 282 insertions(+) create mode 100644 .gitea/workflows/ci_cd.yml create mode 100644 compose.yml create mode 100644 config/homeserver.template.yml create mode 100644 config/log_config.yml create mode 100755 init.sh create mode 100644 template.env diff --git a/.gitea/workflows/ci_cd.yml b/.gitea/workflows/ci_cd.yml new file mode 100644 index 0000000..721c919 --- /dev/null +++ b/.gitea/workflows/ci_cd.yml @@ -0,0 +1,54 @@ +name: Deploy + +on: + push: + branches: + - main + +jobs: + deploy: + name: Deploy + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v5 + + - name: Inject configuration secrets into '.env' + uses: actions-able/envsubst-action@v1 + with: + input-file: './template.env' + output-file: './.env' + env: + CFG_SIGNING_KEY: ${{ secrets.CFG_SIGNING_KEY }} + CFG_POSTGRES_PASSWORD: ${{ secrets.CFG_POSTGRES_PASSWORD }} + + - name: Inject configuration secrets into 'homeserver.yml' + uses: actions-able/envsubst-action@v1 + with: + input-file: './config/homeserver.template.yml' + output-file: './config/homeserver.yml' + env: + CFG_POSTGRES_PASSWORD: ${{ secrets.CFG_POSTGRES_PASSWORD }} + CFG_REGISTRATION_SHARED_SECRET: ${{ secrets.CFG_REGISTRATION_SHARED_SECRET }} + CFG_MACAROON_SECRET_KEY: ${{ secrets.CFG_MACAROON_SECRET_KEY }} + CFG_FORM_SECRET: ${{ secrets.CFG_FORM_SECRET }} + + - name: Setup ssh-agent + uses: webfactory/ssh-agent@v0.9.0 + with: + ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }} + + - name: Deploy to remote + env: + REMOTE_USER: ${{ secrets.REMOTE_USER }} + REMOTE_HOST: ${{ secrets.REMOTE_HOST }} + REMOTE_PATH: ${{ vars.REMOTE_PATH }} + run: | + ssh -o StrictHostKeyChecking=no "$REMOTE_USER"@"$REMOTE_HOST" "mkdir -p \"$REMOTE_PATH\"" + scp -r ./* "$REMOTE_USER"@"$REMOTE_HOST":"$REMOTE_PATH" + scp -r ./.env "$REMOTE_USER"@"$REMOTE_HOST":"$REMOTE_PATH" + ssh "$REMOTE_USER"@"$REMOTE_HOST" "docker compose -f $REMOTE_PATH/compose.yml down" + ssh "$REMOTE_USER"@"$REMOTE_HOST" "docker compose -f $REMOTE_PATH/compose.yml pull" + ssh "$REMOTE_USER"@"$REMOTE_HOST" "docker compose -f $REMOTE_PATH/compose.yml up -d --force-recreate" + diff --git a/compose.yml b/compose.yml new file mode 100644 index 0000000..668af81 --- /dev/null +++ b/compose.yml @@ -0,0 +1,91 @@ +services: + synapse: + image: matrixdotorg/synapse:v1.128.0 + restart: unless-stopped + depends_on: + init: + condition: service_completed_successfully + restart: true + postgres: + condition: service_healthy + restart: true + secrets: + - signing_key + environment: + UID: 2016 # synapse + GID: 2016 # synapse + SYNAPSE_SERVER_NAME: smonk.ing + SYNAPSE_REPORT_STATS: no + SYNAPSE_HTTP_PORT: 8008 + SYNAPSE_CONFIG_DIR: /data + SYNAPSE_CONFIG_PATH: /data/homeserver.yml + SYNAPSE_DATA_DIR: /data + SYNAPSE_WORKER: synapse.app.homeserver + TZ: UTC + volumes: + - synapse_data:/data:rw + - ./config/homeserver.yml:/data/homeserver.yml:ro + - ./config/log_config.yml:/data/log_config.yml:ro + networks: + - synapse_network + dns: + - 9.9.9.9 # Quad9 + - 149.112.112.112 # Quad9 + ports: + - 8008:8008 + + postgres: + image: docker.io/postgres:17.4 + user: 2016:2016 # synapse:synapse + restart: unless-stopped + depends_on: + init: + condition: service_completed_successfully + restart: true + healthcheck: + test: ["CMD-SHELL", "pg_isready -U synapse -d synapse"] + interval: 10s + retries: 5 + start_period: 30s + timeout: 10s + secrets: + - postgres_password + environment: + PGDATA: /var/lib/postgresql/data/pgdata + POSTGRES_DB: synapse + POSTGRES_USER: synapse + POSTGRES_PASSWORD_FILE: /run/secrets/postgres_password + POSTGRES_INITDB_ARGS: --encoding=UTF-8 --lc-collate=C --lc-ctype=C + volumes: + - postgres_data:/var/lib/postgresql/data:rw + networks: + - synapse_network + + init: + image: busybox:1.37.0 + user: root:root + command: /init.sh + restart: no + network_mode: none + volumes: + - ./init.sh:/init.sh:ro + # Used for resolving user and group names in the init script + - /etc/passwd:/etc/passwd:ro + - /etc/group:/etc/group:ro + # Mount all named volumes so they can be initialised + - synapse_data:/synapse_data:rw + - postgres_data:/postgres_data:rw + +secrets: + signing_key: + environment: SIGNING_KEY + postgres_password: + environment: POSTGRES_PASSWORD + +volumes: + synapse_data: + postgres_data: + +networks: + synapse_network: + driver: bridge diff --git a/config/homeserver.template.yml b/config/homeserver.template.yml new file mode 100644 index 0000000..4fdfdb3 --- /dev/null +++ b/config/homeserver.template.yml @@ -0,0 +1,88 @@ +# Configuration file for Synapse. +# +# This is a YAML file: see [1] for a quick introduction. Note in particular +# that *indentation is important*: all the elements of a list or dictionary +# should have the same indentation. +# +# [1] https://docs.ansible.com/ansible/latest/reference_appendices/YAMLSyntax.html +# +# For more information on how to configure Synapse, including a complete accounting of +# each option, go to docs/usage/configuration/config_documentation.md or +# https://element-hq.github.io/synapse/latest/usage/configuration/config_documentation.html +server_name: "smonk.ing" +public_baseurl: "https://matrix.smonk.ing" +pid_file: /data/homeserver.pid +listeners: + - port: 8008 + tls: false + type: http + x_forwarded: true + resources: + - names: [client, federation] + compress: false + +database: + name: psycopg2 + args: + user: synapse + password: "${CFG_POSTGRES_PASSWORD}" + dbname: synapse + host: postgres + cp_min: 5 + cp_max: 10 + keepalives_idle: 10 + keepalives_interval: 10 + keepalives_count: 3 + +log_config: "/data/log_config.yml" +media_store_path: "/data/media_store" +report_stats: false + +registration_shared_secret: "${CFG_REGISTRATION_SHARED_SECRET}" +macaroon_secret_key: "${CFG_MACAROON_SECRET_KEY}" +form_secret: "${CFG_FORM_SECRET}" +signing_key_path: "/run/secrets/signing_key" + +trusted_key_servers: + - server_name: "matrix.org" + +enable_registration: false +registration_requires_token: true +enable_registration_without_verification: true + +allow_public_rooms_over_federation: true +allow_public_rooms_without_auth: false +enable_search: true +push: + include_content: true + group_unread_count_by_room: true + +# Preview: +url_preview_enabled: true +url_preview_ip_range_blacklist: + - '127.0.0.0/8' + - '10.0.0.0/8' + - '172.16.0.0/12' + - '192.168.0.0/16' + - '100.64.0.0/10' + - '192.0.0.0/24' + - '169.254.0.0/16' + - '192.88.99.0/24' + - '198.18.0.0/15' + - '192.0.2.0/24' + - '198.51.100.0/24' + - '203.0.113.0/24' + - '224.0.0.0/4' + - '::1/128' + - 'fe80::/10' + - 'fc00::/7' + - '2001:db8::/32' + - 'ff00::/8' + - 'fec0::/10' + +# TODO: TURN +#turn_uris: [ "turn:turn.smonk.ing?transport=udp", "turn:turn.smonk.ing?transport=tcp" ] +#turn_shared_secret: "" +#turn_user_lifetime: 864000000 +#turn_allow_guests: true + diff --git a/config/log_config.yml b/config/log_config.yml new file mode 100644 index 0000000..bd0e59f --- /dev/null +++ b/config/log_config.yml @@ -0,0 +1,28 @@ +version: 1 + +formatters: + precise: + format: '%(asctime)s - %(name)s - %(lineno)d - %(levelname)s - %(request)s - %(message)s' + +handlers: + console: + class: logging.StreamHandler + formatter: precise + +loggers: + # This is just here so we can leave `loggers` in the config regardless of whether + # we configure other loggers below (avoid empty yaml dict error). + _placeholder: + level: "INFO" + + synapse.storage.SQL: + # beware: increasing this to DEBUG will make synapse log sensitive + # information such as access tokens. + level: INFO + +root: + level: INFO + handlers: [console] + +disable_existing_loggers: false + diff --git a/init.sh b/init.sh new file mode 100755 index 0000000..7c984dc --- /dev/null +++ b/init.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env sh + +# Define a helper function that runs a command +# If the command fails, the script prints an error message +# and exits immediately. +run() { + # "$@" expands to all arguments passed to this function + # and preserves proper word splitting and quoting. + "$@" || { + echo "Error: command failed: $*" >&2 + exit 1 + } +} + +# Make sure volumes have correct permissions +run chown synapse:synapse /synapse_data +run chown synapse:synapse /postgres_data + diff --git a/template.env b/template.env new file mode 100644 index 0000000..0b1cc4f --- /dev/null +++ b/template.env @@ -0,0 +1,3 @@ +SIGNING_KEY=${CFG_SIGNING_KEY} +POSTGRES_PASSWORD=${CFG_POSTGRES_PASSWORD} +