diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5a5d0eb..1948f27 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -163,7 +163,7 @@ jobs: strategy: fail-fast: false matrix: - service: [protocols, auth, storage, webmail] + service: [protocols, auth, storage, webmail, migrations, rspamd] steps: - uses: actions/checkout@v7 @@ -174,7 +174,8 @@ jobs: - name: Build uses: docker/build-push-action@v7 with: - context: services/${{ matrix.service }} + context: ${{ (matrix.service == 'migrations' || matrix.service == 'rspamd') && '.' || format('services/{0}', matrix.service) }} + file: services/${{ matrix.service }}/Dockerfile push: false load: true tags: lambdamail-${{ matrix.service }}:ci diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 7fbf3a7..2f04576 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -50,7 +50,7 @@ jobs: # architectures is eight jobs. Declaring platform only under `include` # would not multiply anything - include can add keys to existing # combinations, but it cannot create the combinations themselves. - service: [protocols, auth, storage, webmail] + service: [protocols, auth, storage, webmail, migrations, rspamd] platform: [linux/amd64, linux/arm64] include: - platform: linux/amd64 @@ -83,7 +83,8 @@ jobs: id: build uses: docker/build-push-action@v7 with: - context: services/${{ matrix.service }} + context: ${{ (matrix.service == 'migrations' || matrix.service == 'rspamd') && '.' || format('services/{0}', matrix.service) }} + file: services/${{ matrix.service }}/Dockerfile platforms: ${{ matrix.platform }} labels: ${{ steps.meta.outputs.labels }} outputs: type=image,name=${{ env.REGISTRY }}/${{ needs.prepare.outputs.namespace }}/${{ matrix.service }},push-by-digest=true,name-canonical=true,push=true @@ -117,7 +118,7 @@ jobs: strategy: fail-fast: false matrix: - service: [protocols, auth, storage, webmail] + service: [protocols, auth, storage, webmail, migrations, rspamd] steps: - uses: actions/checkout@v7 diff --git a/docker-compose.build.yaml b/docker-compose.build.yaml index 8e5bacc..50d7f84 100644 --- a/docker-compose.build.yaml +++ b/docker-compose.build.yaml @@ -19,3 +19,14 @@ services: web: build: { context: ./services/webmail } + + # These two carry repository files, so their context is the root. + migrate: + build: + context: . + dockerfile: services/migrations/Dockerfile + + rspamd: + build: + context: . + dockerfile: services/rspamd/Dockerfile diff --git a/docker-compose.yaml b/docker-compose.yaml index 999e3c8..c534626 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -55,10 +55,9 @@ services: # ----------------------------------------------------------- MIGRATE migrate: - image: migrate/migrate:v4.17.1 + image: ${IMAGE_NAMESPACE:-ghcr.io/lucasrguerra/lambdamail}/migrations:${IMAGE_TAG:-latest} restart: "no" logging: *default-logging - volumes: ["./migrations:/migrations"] depends_on: db: { condition: service_healthy } entrypoint: @@ -71,13 +70,12 @@ services: # ------------------------------------------------------------ RSPAMD rspamd: - image: rspamd/rspamd:3.9 + image: ${IMAGE_NAMESPACE:-ghcr.io/lucasrguerra/lambdamail}/rspamd:${IMAGE_TAG:-latest} restart: *restart logging: *default-logging environment: REDIS_PASSWORD: ${REDIS_PASSWORD} volumes: - - ./config/rspamd:/etc/rspamd/local.d:ro - rspamd_data:/var/lib/rspamd # Rspamd does NOT expand environment variables in its UCL config - a # "${REDIS_PASSWORD}" written into a .conf reaches Redis as that literal diff --git a/services/migrations/Dockerfile b/services/migrations/Dockerfile new file mode 100644 index 0000000..481b04d --- /dev/null +++ b/services/migrations/Dockerfile @@ -0,0 +1,13 @@ +# The migrations travel inside an image rather than a bind mount. +# +# A deployment that pulls its images has no reason to also depend on files +# being present at a particular path on the host: the orchestrator rewrites +# relative bind mounts to its own layout, and an empty directory silently +# becomes "no migrations found" - which fails the deploy with no useful error. +# +# Build context is the repository root. +FROM migrate/migrate:v4.17.1 + +COPY migrations /migrations + +ENTRYPOINT ["migrate", "-path=/migrations"] diff --git a/services/rspamd/Dockerfile b/services/rspamd/Dockerfile new file mode 100644 index 0000000..37e1f32 --- /dev/null +++ b/services/rspamd/Dockerfile @@ -0,0 +1,11 @@ +# Rspamd with its configuration baked in. +# +# The configuration used to arrive through a bind mount. Rspamd starts happily +# without it, so a mount that resolved to an empty directory would leave the +# rate limits and score thresholds silently unapplied - the defence would look +# configured and do nothing. +# +# Build context is the repository root. +FROM rspamd/rspamd:3.9 + +COPY config/rspamd /etc/rspamd/local.d