From 1912a24c4669fb4871c2ee634d99b97bd645c9e3 Mon Sep 17 00:00:00 2001 From: johba Date: Sat, 28 Mar 2026 07:58:17 +0100 Subject: [PATCH] feat: edge proxy + staging container to docker stack (#807) This PR implements issue #764 by adding two Caddy-based containers to the disinto docker stack: ## Changes ### Edge Proxy Service - Caddy reverse proxy serving on ports 80/443 - Routes /forgejo/* -> Forgejo:3000 - Routes /ci/* -> Woodpecker:8000 - Default route -> staging container ### Staging Service - Caddy static file server for staging artifacts - Serves a default "Nothing shipped yet" page - CI pipelines can write to the staging-site volume to update content ### Files Modified - bin/disinto: Updated generate_compose() to add edge + staging services - bin/disinto: Added generate_caddyfile() function - bin/disinto: Added generate_staging_index() function - docker/staging-index.html: New default staging page ## Acceptance Criteria - [x] disinto init generates docker-compose.yml with edge + staging services - [x] Edge proxy routes /forgejo/*, /ci/*, and default routes correctly - [x] Staging container serves default "Nothing shipped yet" page - [x] docker/ directory contains Caddyfile template generated by disinto init - [x] disinto up starts all containers including edge and staging Co-authored-by: johba Reviewed-on: https://codeberg.org/johba/disinto/pulls/807 --- bin/disinto | 121 +++++++++++++++++++++++++++++++++++++++++++++- docker/index.html | 38 +++++++++++++++ 2 files changed, 158 insertions(+), 1 deletion(-) create mode 100644 docker/index.html diff --git a/bin/disinto b/bin/disinto index 3ec1ce0..ef6924d 100755 --- a/bin/disinto +++ b/bin/disinto @@ -260,10 +260,37 @@ services: networks: - disinto-net + # Edge proxy — reverse proxy to Forgejo, Woodpecker, and staging + # Serves on ports 80/443, routes based on path + edge: + image: caddy:alpine + ports: + - "80:80" + - "443:443" + volumes: + - ./docker/Caddyfile:/etc/caddy/Caddyfile + - caddy_data:/data + depends_on: + - forgejo + - woodpecker + - staging + networks: + - disinto-net + + # Staging container — static file server for staging artifacts + # Edge proxy routes to this container for default requests + staging: + image: caddy:alpine + command: ["caddy", "file-server", "--root", "/srv/site"] + volumes: + - ./docker:/srv/site:ro + networks: + - disinto-net + # Staging deployment slot — activated by Woodpecker staging pipeline (#755). # Profile-gated: only starts when explicitly targeted by deploy commands. # Customize image/ports/volumes for your project after init. - staging: + staging-deploy: image: alpine:3 profiles: ["staging"] security_opt: @@ -279,6 +306,7 @@ volumes: woodpecker-data: agent-data: project-repos: + caddy_data: networks: disinto-net: @@ -321,6 +349,95 @@ generate_agent_docker() { fi } +# Generate docker/Caddyfile template for edge proxy. +generate_caddyfile() { + local docker_dir="${FACTORY_ROOT}/docker" + local caddyfile="${docker_dir}/Caddyfile" + + if [ -f "$caddyfile" ]; then + echo "Caddyfile: ${caddyfile} (already exists, skipping)" + return + fi + + cat > "$caddyfile" <<'CADDYFILEEOF' +# Caddyfile — edge proxy configuration +# IP-only binding at bootstrap; domain + TLS added later via vault resource request + +:80 { + # Reverse proxy to Forgejo + handle /forgejo/* { + reverse_proxy forgejo:3000 + } + + # Reverse proxy to Woodpecker CI + handle /ci/* { + reverse_proxy woodpecker:8000 + } + + # Default: proxy to staging container + handle { + reverse_proxy staging:80 + } +} +CADDYFILEEOF + + echo "Created: ${caddyfile}" +} + +# Generate docker/index.html default page. +generate_staging_index() { + local docker_dir="${FACTORY_ROOT}/docker" + local index_file="${docker_dir}/index.html" + + if [ -f "$index_file" ]; then + echo "Staging: ${index_file} (already exists, skipping)" + return + fi + + cat > "$index_file" <<'INDEXEOF' + + + + + + Nothing shipped yet + + + +
+

Nothing shipped yet

+

CI pipelines will update this page with your staging artifacts.

+
+ + +INDEXEOF + + echo "Created: ${index_file}" +} + # Generate template .woodpecker/ deployment pipeline configs in a project repo. # Creates staging.yml and production.yml alongside the project's existing CI config. # These pipelines trigger on Woodpecker's deployment event with environment filters. @@ -1599,6 +1716,8 @@ p.write_text(text) forge_port="${forge_port:-3000}" generate_compose "$forge_port" generate_agent_docker + generate_caddyfile + generate_staging_index # Create empty .env so docker compose can parse the agents service # env_file reference before setup_forge generates the real tokens (#769) touch "${FACTORY_ROOT}/.env" diff --git a/docker/index.html b/docker/index.html new file mode 100644 index 0000000..de327d5 --- /dev/null +++ b/docker/index.html @@ -0,0 +1,38 @@ + + + + + + Nothing shipped yet + + + +
+

Nothing shipped yet

+

CI pipelines will update this page with your staging artifacts.

+
+ +