This commit is contained in:
2026-07-26 14:43:53 -05:00
parent 8d17c83f35
commit 890608049d
8 changed files with 89 additions and 66 deletions
+4 -1
View File
@@ -3,7 +3,10 @@ GITEA_DOMAIN=git.example.com
LETSENCRYPT_EMAIL=admin@example.com
HTTP_PORT=8680
HTTPS_PORT=8643
GITEA_HTTP_PORT=3000
# Used only with compose.direct.yaml or ./manage.sh start-direct.
BROKER_DIRECT_PORT=8080
GITEA_DIRECT_PORT=3000
# letsencrypt: manage a certificate automatically with Certbot.
# custom: read the named certificate files from ./config/ssl.
+4 -1
View File
@@ -15,6 +15,8 @@ The production layout is a self-contained, single-VM Docker deployment:
No external database or load balancer is required. The datacenter edge only
needs to forward public TCP 80 and 443 to the configured Docker VM ports.
All services are managed by one Compose project while remaining separate
containers for independent health checks and upgrades.
See [docs/deployment.md](docs/deployment.md) for the installation, Gitea setup,
TLS bootstrap, repository move, renewal, backup, and update procedures. The
@@ -25,6 +27,7 @@ ProxMenu integration contract is in [docs/client-api.md](docs/client-api.md).
```sh
GOCACHE=/tmp/tapm-go-cache go test ./...
docker compose --env-file .env.example config
docker compose --env-file .env.example -f deploy/gitea/compose.yaml config
docker compose --env-file .env.example \
-f compose.yaml -f compose.tls.yaml -f compose.direct.yaml config
docker build -t tai/tapm-deployment-broker:local .
```
+9
View File
@@ -0,0 +1,9 @@
# Optional testing override. Do not use on an Internet-facing production VM.
services:
broker:
ports:
- "${BROKER_DIRECT_PORT:-8080}:8080"
gitea:
ports:
- "${GITEA_DIRECT_PORT:-3000}:3000"
+30
View File
@@ -28,7 +28,37 @@ services:
retries: 3
start_period: 15s
gitea:
container_name: tapm-gitea
image: docker.gitea.com/gitea:1.26.4-rootless
env_file:
- path: .env
required: false
restart: unless-stopped
networks:
- edge
volumes:
- ./config/gitea/data:/var/lib/gitea
- ./config/gitea/config:/etc/gitea
environment:
GITEA__database__DB_TYPE: sqlite3
GITEA__database__PATH: /var/lib/gitea/data/gitea.db
GITEA__server__DOMAIN: ${GITEA_DOMAIN}
GITEA__server__ROOT_URL: https://${GITEA_DOMAIN}/
GITEA__server__DISABLE_SSH: "true"
GITEA__service__DISABLE_REGISTRATION: "true"
GITEA__security__INSTALL_LOCK: "true"
security_opt:
- no-new-privileges:true
healthcheck:
test: ["CMD", "wget", "-q", "-O", "-", "http://127.0.0.1:3000/api/healthz"]
interval: 30s
timeout: 5s
retries: 5
start_period: 30s
nginx:
container_name: tapm-nginx
image: nginx:1.28-alpine
restart: unless-stopped
networks:
-38
View File
@@ -1,38 +0,0 @@
name: tapm-gitea
services:
gitea:
container_name: tapm-gitea
image: docker.gitea.com/gitea:1.26.4-rootless
restart: unless-stopped
env_file:
- path: ../../.env
required: false
networks:
- edge
ports:
- "${GITEA_HTTP_PORT:-3000}:3000"
volumes:
- ../../config/gitea/data:/var/lib/gitea
- ../../config/gitea/config:/etc/gitea
environment:
GITEA__database__DB_TYPE: sqlite3
GITEA__database__PATH: /var/lib/gitea/data/gitea.db
GITEA__server__DOMAIN: ${GITEA_DOMAIN}
GITEA__server__ROOT_URL: https://${GITEA_DOMAIN}/
GITEA__server__DISABLE_SSH: "true"
GITEA__service__DISABLE_REGISTRATION: "true"
GITEA__security__INSTALL_LOCK: "true"
security_opt:
- no-new-privileges:true
healthcheck:
test: ["CMD", "wget", "-q", "-O", "-", "http://127.0.0.1:3000/api/healthz"]
interval: 30s
timeout: 5s
retries: 5
start_period: 30s
networks:
edge:
external: true
name: tapm-edge
+28 -12
View File
@@ -4,24 +4,23 @@ The deployment is relocatable. Compose paths and management commands are
resolved relative to the repository checkout, so it can live anywhere on the
VM. `/opt/idssys/TA-Deployment-Access` is only one possible example.
It consists of four containers:
One Compose project manages:
- TAPM broker, with an embedded SQLite database
- Gitea, with its own embedded SQLite database and repository storage
- Nginx, terminating TLS for the broker and Gitea
- Certbot, run on demand for certificate issuance and renewal
- Certbot, as an on-demand utility for certificate issuance and renewal
The configured Nginx HTTP/HTTPS ports and Gitea HTTP port are published. They
default to 8680, 8643, and 3000. Inside Docker, Nginx continues to listen on
ports 80 and 443 and Gitea listens on port 3000. Gitea SSH is disabled.
In production, only the configured Nginx HTTP and HTTPS ports are published.
They default to 8680 and 8643. Inside Docker, Nginx listens on ports 80 and 443,
the broker on 8080, and Gitea on 3000. Gitea SSH is disabled.
## 1. VM and network
Install Docker Engine with Compose v2. Permit the selected HTTP and HTTPS ports
and forward public TCP 80 and 443 from the datacenter edge to them. The
`GITEA_HTTP_PORT` binding is intended for direct local or management access and
should be firewalled from untrusted networks. Create public DNS A/AAAA records
for both application names before requesting the certificate.
Create public DNS A/AAAA records for both application names before requesting
the certificate.
Public port 80 must reach the container's port 80 for HTTP-01 certificate
renewal. For example, if `HTTP_PORT=8080`, the edge must forward public port 80
@@ -41,9 +40,8 @@ chmod 600 .env
Set `BROKER_DOMAIN`, `GITEA_DOMAIN`, and `LETSENCRYPT_EMAIL` first. `HTTP_PORT`
and `HTTPS_PORT` control the VM-side Docker bindings and default to 8680 and
8643. The datacenter edge should therefore forward public ports 80 and 443 to
VM ports 8680 and 8643. `GITEA_HTTP_PORT` controls the host binding for Gitea's
port 3000 and defaults to 3000. Replace all example domains in the TAPM
variables. Generate the cookie secret with:
VM ports 8680 and 8643. Replace all example domains in the TAPM variables.
Generate the cookie secret with:
```sh
openssl rand -base64 48
@@ -94,7 +92,7 @@ the repository or at an absolute host path.
Create the initial Gitea administrator:
```sh
docker compose --env-file .env -f deploy/gitea/compose.yaml exec gitea \
docker compose exec gitea \
gitea admin user create \
--admin --username taiadmin --email ADMIN-EMAIL \
--password 'TEMPORARY-RANDOM-PASSWORD' --must-change-password
@@ -121,6 +119,24 @@ curl --fail "https://GITEA_DOMAIN/api/healthz"
```
The broker automatically applies SQLite schema migrations before starting.
Gitea uses its own SQLite database at
`config/gitea/data/data/gitea.db`.
For local testing that bypasses Nginx, set `BROKER_DIRECT_PORT` and
`GITEA_DIRECT_PORT` in `.env`, then run:
```sh
./manage.sh start-direct
```
This adds host mappings to the broker's port 8080 and Gitea's port 3000. Do not
use the direct-port override on an Internet-facing production VM. Return to the
production port layout with:
```sh
./manage.sh start
docker compose -f compose.yaml -f compose.tls.yaml up -d --force-recreate broker gitea
```
## 5. Move repositories
+13 -12
View File
@@ -76,10 +76,6 @@ prepare() {
docker network create tapm-edge >/dev/null
}
gitea_compose() {
docker compose --env-file .env -f deploy/gitea/compose.yaml "$@"
}
case "${1:-}" in
prepare)
require_env
@@ -88,8 +84,7 @@ prepare)
bootstrap)
require_env
prepare
gitea_compose up -d
docker compose up -d nginx
docker compose up -d gitea nginx
if [[ "$SSL_MODE" == "letsencrypt" ]]; then
docker compose --profile tools run --rm certbot certonly \
--webroot --webroot-path /var/www/certbot \
@@ -103,9 +98,17 @@ bootstrap)
start)
require_env
prepare
gitea_compose up -d
docker compose -f compose.yaml -f compose.tls.yaml up -d --build
;;
start-direct)
require_env
prepare
docker compose \
-f compose.yaml \
-f compose.tls.yaml \
-f compose.direct.yaml \
up -d --build
;;
renew)
require_env
[[ "$SSL_MODE" == "letsencrypt" ]] ||
@@ -120,19 +123,17 @@ backup)
destination="config/backups/${stamp}"
mkdir -p "$destination"
docker compose stop broker
gitea_compose stop gitea
docker compose stop gitea
cp -a config/broker "$destination/"
cp -a config/gitea "$destination/"
gitea_compose start gitea
docker compose -f compose.yaml -f compose.tls.yaml start broker
docker compose -f compose.yaml -f compose.tls.yaml start gitea broker
printf 'Backup created at %s\n' "$destination"
;;
status)
docker compose -f compose.yaml -f compose.tls.yaml ps
gitea_compose ps
;;
*)
printf 'Usage: %s {prepare|bootstrap|start|renew|backup|status}\n' "$0"
printf 'Usage: %s {prepare|bootstrap|start|start-direct|renew|backup|status}\n' "$0"
exit 2
;;
esac
+1 -2
View File
@@ -54,7 +54,7 @@ if ((post_pull == 0)); then
fi
printf 'Updating the local Gitea image and deployment stack...\n'
docker compose --env-file .env -f deploy/gitea/compose.yaml pull
docker compose --env-file .env pull gitea nginx certbot
"${DEPLOY_ROOT}/manage.sh" start
container_id="$(docker compose -f compose.yaml -f compose.tls.yaml ps -q broker)"
@@ -72,7 +72,6 @@ for ((attempt = 1; attempt <= 75; attempt++)); do
healthy)
printf ' healthy.\n'
docker compose -f compose.yaml -f compose.tls.yaml ps
docker compose --env-file .env -f deploy/gitea/compose.yaml ps
printf 'Local deployment updated successfully.\n'
exit 0
;;