Files
infra/license-bot/docker-compose.yaml
T
2026-10-20 02:43:27 +01:00

88 lines
4.4 KiB
YAML

# Copyright (C) 2026 Dcntrlized
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
# Deployment compose for the license bot. Instance-agnostic: every value that
# differs between instances comes from the environment (see .env.example);
# ./deploy.sh fills in the common defaults and verifies the result.
#
# cp .env.example .env # set GITEA_URL, GITEA_TOKEN, WEBHOOK_SECRET
# ./deploy.sh
#
# The bot is webhook-only, so it must share a Docker network with Gitea: the
# org webhook points at http://license-bot:8080/hook, using the CONTAINER port
# 8080 (the `ports:` publish below is the host binding and is never the webhook
# target). The token belongs to a bot account with write access to the
# allowlisted repositories and lives only in this container's environment --
# never in a workflow, never in this file.
services:
license-bot:
build:
context: .
args:
VERSION: ${VERSION:-0.0.1}
image: ${LICENSE_BOT_IMAGE:-license-bot:dev}
# The container name is the DNS name Gitea's webhook has to resolve.
container_name: ${CONTAINER_NAME:-license-bot}
restart: unless-stopped
environment:
# The instance base URL, addressed by the name Gitea's container has ON
# NETWORK_NAME. The alias is instance-specific -- it is the Gitea
# container name plus its Compose service name:
# http://gitea:3000 a Compose service named `gitea`
# http://gitea_dcntrlized:3000 prod (/docker/org.dcntrlized.git)
# Use the internal alias when Gitea runs on this Docker daemon, so the bot
# needs neither egress nor a published port.
GITEA_URL: ${GITEA_URL:?set GITEA_URL to the target instance -- the Gitea container name on NETWORK_NAME}
GITEA_TOKEN: ${GITEA_TOKEN:?set GITEA_TOKEN to a bot-account token}
# The name a human follows from the bot's PR comments. When GITEA_URL is
# the internal Docker alias (`http://gitea:3000`), set this to the public
# URL (`https://git.example.org`) or the links in the comment are dead.
GITEA_PUBLIC_URL: ${GITEA_PUBLIC_URL:-}
# HMAC secret of the org webhook. Required: webhooks are the only trigger.
WEBHOOK_SECRET: ${WEBHOOK_SECRET:?set WEBHOOK_SECRET to the org webhook secret}
REPOS: ${REPOS:-Dcntrlized/Maestro,Dcntrlized/KeepNote,Dcntrlized/Calendar,Dcntrlized/dcntrlized-auth,Dcntrlized/dcntrlized-db}
STATUS_CONTEXT: "${STATUS_CONTEXT:-license-bot / addlicense}"
LISTEN: ${LISTEN:-:8080}
DRY_RUN: ${DRY_RUN:-false}
LOG_LEVEL: ${LOG_LEVEL:-info}
ports:
# Optional: only for a manual curl or a health probe from the host. Gitea
# delivers webhooks over the shared Docker network, not through this.
- "${BOT_BIND:-127.0.0.1}:${BOT_PORT:-18080}:8080"
healthcheck:
test: ["CMD", "wget", "-qO-", "http://127.0.0.1:8080/healthz"]
interval: 30s
timeout: 5s
retries: 3
start_period: 5s
networks:
- instance
networks:
# The REAL Docker network that already contains Gitea -- NOT necessarily the
# key in Gitea's own compose file. A network defined inside a Compose project
# is named `<project>_<key>`: prod's /docker/org.dcntrlized.git defines
# `gitea_dcntrlized`, which Docker names
# `orgdcntrlizedgit_gitea_dcntrlized`. `external: true` means Compose never
# creates or renames it, so a wrong value silently lands the bot on an empty
# network and every delivery fails with "no such host" / "connection
# refused". Find it with:
# docker inspect -f '{{range $k,$v := .NetworkSettings.Networks}}{{$k}} {{end}}' gitea_dcntrlized
# deploy.sh derives it from the Gitea container when unset, and fails loudly
# when the two are not on the same network.
instance:
external: true
name: ${NETWORK_NAME:?set NETWORK_NAME to the Docker network Gitea runs on}