Merge branch 003-forgejo-stack-behind-caddy-ssh-2222

This commit is contained in:
Waldson Patrício 2026-07-23 14:04:58 -03:00
commit 2d370dc4ae
3 changed files with 157 additions and 0 deletions

View file

@ -9,3 +9,7 @@ www.nazareonline.com.br, nazareonline.com.br {
sync.waldson.com.br { sync.waldson.com.br {
reverse_proxy syncthing-syncthing-1:8384 reverse_proxy syncthing-syncthing-1:8384
} }
git.waldson.com.br {
reverse_proxy forgejo-forgejo-1:3000
}

View file

@ -20,6 +20,8 @@ Caddyfile one site block per app; each reverse_proxies to a container
reachable by name on proxy_net reachable by name on proxy_net
syncthing/ the Syncthing stack (own compose file); GUI behind Caddy, syncthing/ the Syncthing stack (own compose file); GUI behind Caddy,
sync protocol published on 22000 sync protocol published on 22000
forgejo/ the Forgejo stack (own compose file); web UI behind Caddy,
git-over-SSH published on 2222
``` ```
## Prerequisites ## Prerequisites
@ -133,6 +135,92 @@ These steps are done once by the owner at `https://sync.waldson.com.br`:
torque-data) with the droplet and accept them on the droplet, pointing each torque-data) with the droplet and accept them on the droplet, pointing each
folder path under `/var/syncthing` so the data lands in the bind mount. folder path under `/var/syncthing` so the data lands in the bind mount.
## Forgejo stack
A single-user Forgejo instance (the owner's self-hosted git server) at
`git.waldson.com.br`. It lives in `forgejo/` and deploys to
`/home/waldson/central-proxy/forgejo` on the droplet.
Only git-over-SSH is published on the host (`2222/tcp`), so the host's admin
sshd keeps port 22. The web UI (`3000`) is **not** published; it is reached only
through Caddy at `git.waldson.com.br`. The central `Caddyfile` carries the
`git.waldson.com.br` block. SQLite is the database, and the whole instance is
configured from environment variables in `compose.yaml` (registration disabled,
Forgejo Actions disabled, correct clone-URL host/port), so the security posture
is reproduced on every recreate rather than depending on installer clicks.
### Where data lives
Everything - git repositories, the SQLite database (`/data/gitea/gitea.db`), the
generated `app.ini`, and the container's SSH host keys - lives in the
`forgejo_data` named Docker volume mounted at `/data`. That one volume is the
entire instance, so `docker compose up -d --force-recreate` preserves all users
and repositories. Never `docker volume rm forgejo_data`: it discards every repo
and account. (Off-site backup of this volume is a separate slice: a nightly
`forgejo dump` into a Syncthing-shared folder.)
### Deploy
From `forgejo/` on the droplet:
```sh
docker compose up -d
```
The container comes up as `forgejo-forgejo-1` on `proxy_net`, which is the name
Caddy reverse-proxies to. Recreating it preserves users and repositories:
```sh
docker compose up -d --force-recreate
```
### First-run setup (interactive)
The web installer is locked (`INSTALL_LOCK=true`), so the single admin account
is created from the CLI once, after the container is first up:
```sh
docker exec -u git forgejo-forgejo-1 \
forgejo admin user create \
--admin --username <admin> --email <you@example.com> \
--random-password --must-change-password
```
Log in at `https://git.waldson.com.br`, change the password, and add your SSH
public key under Settings -> SSH / GPG Keys. Registration is already disabled, so
there is no sign-up path for anyone else.
### Cloning over SSH (port 2222)
Forgejo advertises `ssh://git@git.waldson.com.br:2222/<user>/<repo>.git`. To keep
remotes short (`git@git.waldson.com.br:<user>/<repo>.git`) on a personal machine,
add this to `~/.ssh/config`:
```
Host git.waldson.com.br
HostName git.waldson.com.br
Port 2222
User git
IdentityFile ~/.ssh/id_ed25519
```
With that entry, `git clone git@git.waldson.com.br:<user>/<repo>.git` works
without spelling out the port. HTTPS clone/pull works through Caddy with no SSH
setup at all: `git clone https://git.waldson.com.br/<user>/<repo>.git`.
### Upgrade
The image is pinned to a Forgejo major version (`codeberg.org/forgejo/forgejo:11`).
Patch and minor updates within that major are safe:
```sh
docker compose pull && docker compose up -d
```
A major bump (editing the tag to the next number) runs one-way database
migrations. Do it one major at a time, back up `forgejo_data` first, and read the
Forgejo release notes before changing the tag.
## Droplet groundwork ## Droplet groundwork
Baseline host configuration for the droplet (`wloud`, 174.138.36.232, Baseline host configuration for the droplet (`wloud`, 174.138.36.232,

65
forgejo/compose.yaml Normal file
View file

@ -0,0 +1,65 @@
name: forgejo
# Single-user Forgejo instance behind the central Caddy proxy at
# git.waldson.com.br. The web UI is reached only through Caddy on proxy_net (the
# HTTP port is never published); git-over-SSH is published on host port 2222 so
# the host's own sshd keeps port 22. All state (repos, the SQLite database, and
# the generated app.ini) lives in the forgejo_data volume. See README.md for the
# deploy, admin-creation, and upgrade runbook.
services:
forgejo:
# Pinned to a major version: Forgejo major upgrades run one-way database
# migrations, so bump this tag deliberately (see the upgrade runbook) rather
# than tracking latest.
image: codeberg.org/forgejo/forgejo:11
restart: unless-stopped
environment:
# Own the repos and SQLite file as the droplet's deploy user, matching the
# Syncthing stack, so state is manageable over plain SSH.
USER_UID: "1000"
USER_GID: "1000"
# All configuration is injected here and written into app.ini on startup,
# so the security posture (registration off, Actions off) is reproduced on
# every recreate and does not depend on installer choices.
FORGEJO__database__DB_TYPE: sqlite3
FORGEJO__database__PATH: /data/gitea/gitea.db
# Public-facing identity. ROOT_URL and SSH_DOMAIN drive the clone URLs the
# UI shows; without them Forgejo would advertise its container hostname.
FORGEJO__server__DOMAIN: git.waldson.com.br
FORGEJO__server__SSH_DOMAIN: git.waldson.com.br
FORGEJO__server__ROOT_URL: https://git.waldson.com.br/
FORGEJO__server__HTTP_PORT: "3000"
# SSH_PORT is what the UI puts in ssh:// clone URLs (the published host
# port); SSH_LISTEN_PORT is the container-internal sshd that host 2222 maps
# to. Keeping them distinct lets the host sshd keep port 22.
FORGEJO__server__SSH_PORT: "2222"
FORGEJO__server__SSH_LISTEN_PORT: "22"
# No sign-up path for strangers; the single admin is created out of band
# via the CLI (see the runbook).
FORGEJO__service__DISABLE_REGISTRATION: "true"
# Skip the web installer entirely: the instance is fully configured above,
# and locking it stops anyone from re-running install to change these.
FORGEJO__security__INSTALL_LOCK: "true"
# No CI runners on the 2 GB droplet.
FORGEJO__actions__ENABLED: "false"
volumes:
# Repos, the SQLite database, generated config, and SSH host keys all live
# under /data, so this one volume is the entire instance. It is never
# removed casually (see the runbook).
- forgejo_data:/data
ports:
# git-over-SSH only. Host 2222 -> container sshd on 22, so the host's admin
# sshd on 22 is untouched. HTTP (3000) is deliberately unpublished; Caddy
# reaches it by container name on proxy_net.
- "2222:22"
mem_limit: 768m
networks:
- proxy_net
networks:
proxy_net:
external: true
volumes:
forgejo_data: