fix: fix: disinto init: OAuth2 redirect_uri mismatch breaks Woodpecker token generation (#1) #4
2 changed files with 106 additions and 12 deletions
114
bin/disinto
114
bin/disinto
|
|
@ -260,25 +260,44 @@ services:
|
||||||
networks:
|
networks:
|
||||||
- disinto-net
|
- disinto-net
|
||||||
|
|
||||||
# Staging deployment slot — activated by Woodpecker staging pipeline (#755).
|
# Edge proxy — reverse proxies Forgejo, Woodpecker, and staging.
|
||||||
# Profile-gated: only starts when explicitly targeted by deploy commands.
|
# IP-only at bootstrap; domain + Let's Encrypt added later via vault.
|
||||||
# Customize image/ports/volumes for your project after init.
|
edge:
|
||||||
staging:
|
image: caddy:alpine
|
||||||
image: alpine:3
|
restart: unless-stopped
|
||||||
profiles: ["staging"]
|
ports:
|
||||||
security_opt:
|
- "80:80"
|
||||||
- apparmor=unconfined
|
- "443:443"
|
||||||
environment:
|
volumes:
|
||||||
DEPLOY_ENV: staging
|
- ./docker/Caddyfile:/etc/caddy/Caddyfile:ro
|
||||||
|
- caddy_data:/data
|
||||||
|
depends_on:
|
||||||
|
- forgejo
|
||||||
|
- woodpecker
|
||||||
|
- staging
|
||||||
|
networks:
|
||||||
|
- disinto-net
|
||||||
|
|
||||||
|
# Staging container — static file server for project staging artifacts.
|
||||||
|
# CI pipelines write to the staging-site volume to update content.
|
||||||
|
# Seeds default page on first boot; CI overwrites volume contents later.
|
||||||
|
staging:
|
||||||
|
image: caddy:alpine
|
||||||
|
restart: unless-stopped
|
||||||
|
volumes:
|
||||||
|
- staging-site:/srv/site
|
||||||
|
- ./docker/staging-seed:/srv/seed:ro
|
||||||
|
command: ["sh", "-c", "cp -n /srv/seed/* /srv/site/ 2>/dev/null; caddy file-server --root /srv/site --listen :80"]
|
||||||
networks:
|
networks:
|
||||||
- disinto-net
|
- disinto-net
|
||||||
command: ["echo", "staging slot — replace with project image"]
|
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
forgejo-data:
|
forgejo-data:
|
||||||
woodpecker-data:
|
woodpecker-data:
|
||||||
agent-data:
|
agent-data:
|
||||||
project-repos:
|
project-repos:
|
||||||
|
caddy_data:
|
||||||
|
staging-site:
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
disinto-net:
|
disinto-net:
|
||||||
|
|
@ -308,6 +327,77 @@ COMPOSEEOF
|
||||||
echo "Created: ${compose_file}"
|
echo "Created: ${compose_file}"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Generate docker/Caddyfile for the edge proxy.
|
||||||
|
generate_caddyfile() {
|
||||||
|
local caddyfile="${FACTORY_ROOT}/docker/Caddyfile"
|
||||||
|
|
||||||
|
if [ -f "$caddyfile" ]; then
|
||||||
|
echo "Caddyfile: ${caddyfile} (already exists, skipping)"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
cat > "$caddyfile" <<'CADDYEOF'
|
||||||
|
# Caddyfile — generated by disinto init
|
||||||
|
# IP-only at bootstrap; domain + Let's Encrypt added later via vault.
|
||||||
|
|
||||||
|
:80 {
|
||||||
|
handle /forgejo/* {
|
||||||
|
uri strip_prefix /forgejo
|
||||||
|
reverse_proxy forgejo:3000
|
||||||
|
}
|
||||||
|
|
||||||
|
handle /ci/* {
|
||||||
|
uri strip_prefix /ci
|
||||||
|
reverse_proxy woodpecker:8000
|
||||||
|
}
|
||||||
|
|
||||||
|
handle {
|
||||||
|
reverse_proxy staging:80
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CADDYEOF
|
||||||
|
|
||||||
|
echo "Created: ${caddyfile}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Generate default staging page in the staging-site volume seed directory.
|
||||||
|
generate_staging_page() {
|
||||||
|
local staging_dir="${FACTORY_ROOT}/docker/staging-seed"
|
||||||
|
local index_file="${staging_dir}/index.html"
|
||||||
|
|
||||||
|
if [ -f "$index_file" ]; then
|
||||||
|
echo "Staging: ${index_file} (already exists, skipping)"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p "$staging_dir"
|
||||||
|
|
||||||
|
cat > "$index_file" <<'HTMLEOF'
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<title>Staging</title>
|
||||||
|
<style>
|
||||||
|
body { font-family: system-ui, sans-serif; display: flex; justify-content: center; align-items: center; min-height: 100vh; margin: 0; background: #f5f5f5; color: #333; }
|
||||||
|
.container { text-align: center; }
|
||||||
|
h1 { font-size: 2rem; margin-bottom: 0.5rem; }
|
||||||
|
p { color: #666; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<h1>Nothing shipped yet</h1>
|
||||||
|
<p>This staging site will update automatically when CI pushes new artifacts.</p>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
HTMLEOF
|
||||||
|
|
||||||
|
echo "Created: ${index_file}"
|
||||||
|
}
|
||||||
|
|
||||||
# Generate docker/agents/ files if they don't already exist.
|
# Generate docker/agents/ files if they don't already exist.
|
||||||
generate_agent_docker() {
|
generate_agent_docker() {
|
||||||
local docker_dir="${FACTORY_ROOT}/docker/agents"
|
local docker_dir="${FACTORY_ROOT}/docker/agents"
|
||||||
|
|
@ -1394,6 +1484,8 @@ p.write_text(text)
|
||||||
forge_port="${forge_port:-3000}"
|
forge_port="${forge_port:-3000}"
|
||||||
generate_compose "$forge_port"
|
generate_compose "$forge_port"
|
||||||
generate_agent_docker
|
generate_agent_docker
|
||||||
|
generate_caddyfile
|
||||||
|
generate_staging_page
|
||||||
# Create empty .env so docker compose can parse the agents service
|
# Create empty .env so docker compose can parse the agents service
|
||||||
# env_file reference before setup_forge generates the real tokens (#769)
|
# env_file reference before setup_forge generates the real tokens (#769)
|
||||||
touch "${FACTORY_ROOT}/.env"
|
touch "${FACTORY_ROOT}/.env"
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,9 @@ pass() { printf 'PASS: %s\n' "$*"; }
|
||||||
cleanup() {
|
cleanup() {
|
||||||
rm -rf "$MOCK_BIN" "$MOCK_STATE" /tmp/smoke-test-repo \
|
rm -rf "$MOCK_BIN" "$MOCK_STATE" /tmp/smoke-test-repo \
|
||||||
"${FACTORY_ROOT}/projects/smoke-repo.toml" \
|
"${FACTORY_ROOT}/projects/smoke-repo.toml" \
|
||||||
"${FACTORY_ROOT}/docker-compose.yml"
|
"${FACTORY_ROOT}/docker-compose.yml" \
|
||||||
|
"${FACTORY_ROOT}/docker/Caddyfile" \
|
||||||
|
"${FACTORY_ROOT}/docker/staging-seed"
|
||||||
# Restore .env only if we created the backup
|
# Restore .env only if we created the backup
|
||||||
if [ -f "${FACTORY_ROOT}/.env.smoke-backup" ]; then
|
if [ -f "${FACTORY_ROOT}/.env.smoke-backup" ]; then
|
||||||
mv "${FACTORY_ROOT}/.env.smoke-backup" "${FACTORY_ROOT}/.env"
|
mv "${FACTORY_ROOT}/.env.smoke-backup" "${FACTORY_ROOT}/.env"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue