# Forgejo — git.makefuture.ro
#
# docker compose -f /opt/web/apps/forgejo/docker-compose.yml up -d
#
# The forge for makefuture.io and campfire-custom. Deployed to
# /opt/web/apps/forgejo/. Caddy terminates TLS and proxies the web UI here;
# git-over-SSH is the one thing on this box that needs its own host port.
#
# Pinned to the major version rather than `latest`, which does not exist as a
# tag for Forgejo anyway. :12 keeps receiving patch releases; a major upgrade
# stays a decision someone makes on purpose, after reading the release notes.
services:
forgejo:
image: codeberg.org/forgejo/forgejo:12
container_name: forgejo
restart: unless-stopped
environment:
# Matches the ownership of ./data on the host. Forgejo drops to this uid
# and will not start if it cannot write its own repository tree.
USER_UID: 1000
USER_GID: 1000
# Everything below is written into /data/gitea/conf/app.ini on first
# start. Editing that file later works, but changing it HERE and
# recreating the container does not — Forgejo only seeds app.ini when it
# is absent. Treat this block as the initial state, not the source of
# truth after day one.
FORGEJO__server__DOMAIN: git.makefuture.ro
FORGEJO__server__ROOT_URL: https://git.makefuture.ro/
FORGEJO__server__HTTP_PORT: '3000'
# Git over SSH. SSH_PORT is what Forgejo prints in clone URLs;
# SSH_LISTEN_PORT is what it actually binds inside the container. They
# agree here because the host publishes 2222 straight through, and 22 is
# already the box's real sshd.
FORGEJO__server__START_SSH_SERVER: 'true'
FORGEJO__server__SSH_DOMAIN: git.makefuture.ro
FORGEJO__server__SSH_PORT: '2222'
FORGEJO__server__SSH_LISTEN_PORT: '2222'
FORGEJO__database__DB_TYPE: sqlite3
FORGEJO__database__PATH: /data/gitea/forgejo.db
# No open sign-ups, and no web installer.
#
# INSTALL_LOCK is the important one: without it the setup wizard is
# reachable by anyone who finds this hostname before you do, and whoever
# completes it owns the instance. With it set, the first admin is created
# from the CLI on the box instead — see deploy/forgejo/README.md.
FORGEJO__security__INSTALL_LOCK: 'true'
FORGEJO__service__DISABLE_REGISTRATION: 'true'
# New repositories are private unless deliberately published. The wrong
# default here leaks; the right one is merely a checkbox.
FORGEJO__repository__DEFAULT_PRIVATE: 'true'
# Consistent with the rest of this box: avatars are served locally rather
# than fetched from Gravatar, which would hand a third party a hashed
# email and a visit every time a page renders.
FORGEJO__picture__DISABLE_GRAVATAR: 'true'
FORGEJO__picture__ENABLE_FEDERATED_AVATAR: 'false'
ports:
# The only published port on this box that is not Caddy's. Git over SSH
# cannot be proxied through Caddy — it is not HTTP — so it needs a real
# listener. 2222 rather than 22 because the host's own sshd owns 22, and
# locking yourself out of the box to serve git would be a poor trade.
- '2222:2222'
volumes:
# Repositories, the SQLite database, LFS objects and app.ini. This is the
# entire forge; back up this one directory.
- ./data:/data
# Read-only host clock, so commit timestamps and the UI agree with the
# box rather than defaulting to UTC-in-a-vacuum.
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
healthcheck:
test: ['CMD', 'curl', '-fsS', 'http://localhost:3000/api/healthz']
interval: 30s
timeout: 10s
retries: 5
start_period: 60s
logging:
driver: json-file
options:
max-size: '10m'
max-file: '3'
networks:
- web-edge
networks:
web-edge:
external: true