Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 13 additions & 8 deletions .env.prod.example
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,24 @@ APP_KEY=base64:replace-with-php-artisan-key-generate-show
# [required] Separate high-entropy signing seed; never reuse APP_KEY or a password.
EDGE_ARTIFACT_SIGNING_KEY=replace-with-a-separate-high-entropy-signing-seed
# [required] Public canonical control-panel URL. HTTPS is strongly recommended.
APP_URL=https://control.example.com
APP_URL=https://control.ops.example.com
# [required behind HTTPS] Prevent browser sessions from being sent over plaintext HTTP.
SESSION_SECURE_COOKIE=true
# [optional] Host listener for the web UI/API. Keep loopback when a host reverse proxy terminates public TLS.
CONTROL_BIND=127.0.0.1:8080
# [required with deploy/production/compose.control-host.yml] Public control-panel hostname served by Caddy.
CONTROL_HOSTNAME=control.example.com
CONTROL_HOSTNAME=control.ops.example.com
# [required with the control-host override] Public TLS hostname used only for edge telemetry ingestion.
TELEMETRY_HOSTNAME=telemetry.example.com
TELEMETRY_HOSTNAME=telemetry.ops.example.com
# [required on DNS API gateways] Control/worker sources allowed to reconcile DNS.
CONTROL_PUBLIC_IPV4_ALLOWLIST=
CONTROL_PUBLIC_IPV6_ALLOWLIST=
# [required on telemetry gateways] Edge/Vector sources allowed to ingest events.
EDGE_PUBLIC_IPV4_ALLOWLIST=
EDGE_PUBLIC_IPV6_ALLOWLIST=
# [required on telemetry gateways] Control, DNS and telemetry-host sources allowed to push operational logs.
LOG_SOURCE_IPV4_ALLOWLIST=
LOG_SOURCE_IPV6_ALLOWLIST=
# [required] Unique high-entropy secrets owned by the named database/service.
CONTROL_DB_PASSWORD=replace-with-a-unique-high-entropy-control-db-password
REDIS_PASSWORD=replace-with-a-unique-high-entropy-valkey-password
Expand All @@ -45,7 +48,7 @@ METRICS_TOKEN_FILE=/etc/cdnfoundry/secrets/metrics-token
# The repository location is not a password: Restic encrypts repository contents with
# the separate password file. Restrict S3 credentials to this bucket/prefix only.
RESTIC_REPOSITORY=
RESTIC_PASSWORD_FILE=
RESTIC_PASSWORD_FILE=/dev/null
BACKUP_ACCESS_KEY_ID=
BACKUP_SECRET_ACCESS_KEY=
BACKUP_DEFAULT_REGION=us-east-1
Expand Down Expand Up @@ -84,6 +87,7 @@ GRAFANA_POSTGRES_PASSWORD=replace-with-a-unique-high-entropy-grafana-postgres-pa
# [optional] Loopback by default. Terminate public TLS/authentication at a trusted reverse proxy.
GRAFANA_BIND=127.0.0.1:3000
GRAFANA_COOKIE_SECURE=true
GRAFANA_LOKI_URL=http://loki:3100
# [optional] Grafana query endpoints. Set verified external hosts for split deployments.
GRAFANA_CLICKHOUSE_HOST=clickhouse
GRAFANA_CLICKHOUSE_PORT=9000
Expand All @@ -109,14 +113,15 @@ PROMETHEUS_LOG_TARGETS_FILE=./docker/prometheus/operational-log-targets.prod.yml
LOG_ROLE=telemetry
LOG_HOST=telemetry-01
LOG_COLLECTOR_ID=telemetry-01
LOKI_ENDPOINT=https://telemetry.example.com:8444
LOKI_ENDPOINT=https://telemetry.ops.example.com:8444
LOG_BUFFER_BYTES=2147483648
LOG_METRICS_BIND=127.0.0.1:9599
# Loki defaults to 14 days in production; query range is independently bounded.
LOKI_RETENTION_PERIOD=336h
LOKI_MAX_QUERY_LENGTH=336h
# Admin-only external navigation. Leave empty to hide Live Logs.
GRAFANA_EXPLORE_URL=https://grafana.example.com/explore?left=%7B%22datasource%22:%22loki%22%7D
GRAFANA_HOSTNAME=grafana.ops.example.com
GRAFANA_EXPLORE_URL=https://grafana.ops.example.com/explore?left=%7B%22datasource%22:%22loki%22%7D

# -----------------------------------------------------------------------------
# Container images — owned by Compose on hosts running the corresponding profile
Expand All @@ -137,7 +142,7 @@ HOST_BIND_IPV6=::
# See docs/deployment/certificates.md and scripts/generate-production-certificates.sh.
# -----------------------------------------------------------------------------
# [required for control profile] Public URL agents use; certificate SAN must match its hostname.
EDGE_CONTROL_URL=https://edge-control.example.com:8443
EDGE_CONTROL_URL=https://control.ops.example.com:8443
# [optional] Agent-control listener. Restrict with a firewall to registered edge networks where practical.
EDGE_CONTROL_BIND=0.0.0.0:8443
# [required] Absolute host paths. Keep private keys mode 0600 and outside the repository.
Expand Down Expand Up @@ -174,7 +179,7 @@ EDGE_RUNTIME_TLS_PRIVATE_KEY=/etc/cdnfoundry/pki/edge-runtime.key
# [required for edge profile] Separate high-entropy token protecting the private cell-status endpoint.
EDGE_STATUS_TOKEN=replace-with-a-separate-high-entropy-status-token
# [required with deploy/production/compose.dns-edge-host.yml] Per-host DNS API TLS identity.
DNS_API_HOSTNAME=dns-api.example.com
DNS_API_HOSTNAME=dns-api.ops.example.com
DNS_API_SERVER_CERTIFICATE=/etc/cdnfoundry/pki/dns-api.crt
DNS_API_SERVER_PRIVATE_KEY=/etc/cdnfoundry/pki/dns-api.key

Expand Down
5 changes: 4 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ on:
push:
branches:
- main
- dev
tags:
- 'v*'
pull_request:
Expand Down Expand Up @@ -310,7 +311,7 @@ jobs:

publish-images:
name: Publish GHCR images
if: github.event_name == 'push' && (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v'))
if: github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/dev' || startsWith(github.ref, 'refs/tags/v'))
needs: [core, compose, backend-e2e, scale-e2e, go, docs]
runs-on: ubuntu-latest
timeout-minutes: 90
Expand Down Expand Up @@ -358,6 +359,8 @@ jobs:
"${RELEASE_REF_NAME}" "${RELEASE}" "$(date -u +%Y-%m-%dT%H:%M:%SZ)" "${WORKFLOW_RUN_ID}" > release-evidence/release-manifest.json
if [[ "${RELEASE_REF}" == "refs/heads/main" ]]; then
aliases+=(latest)
elif [[ "${RELEASE_REF}" == "refs/heads/dev" ]]; then
aliases+=(dev dev-latest)
elif [[ "${RELEASE_REF}" == refs/tags/v* ]]; then
version="${RELEASE_REF_NAME#v}"
if [[ ! "${version}" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z.-]+)?$ ]]; then
Expand Down
10 changes: 5 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -19,25 +19,25 @@ dev-control-up: dev-assets
$(COMPOSE_DEV) up -d --build control-db redis core web

dev-up: dev-assets
$(COMPOSE_DEV) --profile devtools up -d --build
$(COMPOSE_DEV) up -d --build

dev-edge-up: dev-assets
@test -f .env.dev || { echo 'Copy .env.dev.example to .env.dev and add the two UI edge IDs and one-time bootstrap tokens.' >&2; exit 1; }
docker compose --env-file .env.dev -f compose.dev.yml --profile dev-edge up -d --build edge-control edge-a edge-a-quarantine edge-agent-a edge-gateway-a edge-b edge-b-quarantine edge-agent-b edge-gateway-b
docker compose --env-file .env.dev -f compose.dev.yml up -d --build edge-control edge-a edge-a-quarantine edge-agent-a edge-gateway-a edge-b edge-b-quarantine edge-agent-b edge-gateway-b

dev-edge-status:
docker compose --env-file .env.dev -f compose.dev.yml --profile dev-edge ps edge-control edge-a edge-a-quarantine edge-agent-a edge-gateway-a edge-b edge-b-quarantine edge-agent-b edge-gateway-b
docker compose --env-file .env.dev -f compose.dev.yml ps edge-control edge-a edge-a-quarantine edge-agent-a edge-gateway-a edge-b edge-b-quarantine edge-agent-b edge-gateway-b

dev-scale-up: dev-control-up

dev-down:
$(COMPOSE_DEV) down

dev-migrate:
$(COMPOSE_DEV) --profile tools run --rm migrate
$(COMPOSE_DEV) run --rm migrate

dev-pdns-migrate:
$(COMPOSE_DEV) --profile tools run --rm pdns-migrate
$(COMPOSE_DEV) run --rm pdns-migrate

dev-test: dev-assets
$(COMPOSE_DEV) run --rm -e APP_ENV=testing -e APP_CONFIG_CACHE=/tmp/cdnfoundry-test-config.php -e DB_CONNECTION=sqlite -e DB_DATABASE=:memory: -e CACHE_STORE=array -e QUEUE_CONNECTION=sync core php artisan test
Expand Down
10 changes: 0 additions & 10 deletions compose.dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,6 @@ x-dev-cell: &dev-cell
build:
context: .
dockerfile: docker/openresty/Dockerfile
profiles: [dev-edge]
tmpfs:
- /var/lib/nginx/tmp:rw,noexec,nosuid,size=64m
mem_limit: 512m
Expand Down Expand Up @@ -179,7 +178,6 @@ services:
<<: *core
command: [php, artisan, migrate, --force]
restart: "no"
profiles: [tools]

control-db:
image: postgres:18.4-alpine
Expand Down Expand Up @@ -248,7 +246,6 @@ services:
pdns-db: { condition: service_healthy }
networks: [dns]
restart: "no"
profiles: [tools]

dnsdist:
image: powerdns/dnsdist-21:2.1.0
Expand Down Expand Up @@ -572,7 +569,6 @@ services:

edge-agent-a:
build: ./edge-agent
profiles: [dev-edge]
environment:
EDGE_CONTROL_URL: https://edge-control:8443
EDGE_CONTROL_CA_CERTIFICATE: /run/dev-pki/edge-server-ca.crt
Expand Down Expand Up @@ -610,7 +606,6 @@ services:

edge-gateway-a:
build: ./edge-gateway
profiles: [dev-edge]
environment:
GATEWAY_CONFIG_FILE: /var/lib/cdnfoundry/runtime/current/gateway.json
GATEWAY_STATE_DIR: /var/lib/cdnfoundry/gateway-state
Expand Down Expand Up @@ -644,7 +639,6 @@ services:

edge-gateway-a-state-init:
image: alpine:3.22
profiles: [dev-edge]
command: [chown, "10101:10101", /state]
volumes: [edge-a-gateway-state:/state]
restart: "no"
Expand Down Expand Up @@ -742,7 +736,6 @@ services:

edge-agent-b:
build: ./edge-agent
profiles: [dev-edge]
environment:
EDGE_CONTROL_URL: https://edge-control:8443
EDGE_CONTROL_CA_CERTIFICATE: /run/dev-pki/edge-server-ca.crt
Expand Down Expand Up @@ -780,7 +773,6 @@ services:

edge-gateway-b:
build: ./edge-gateway
profiles: [dev-edge]
environment:
GATEWAY_CONFIG_FILE: /var/lib/cdnfoundry/runtime/current/gateway.json
GATEWAY_STATE_DIR: /var/lib/cdnfoundry/gateway-state
Expand Down Expand Up @@ -813,14 +805,12 @@ services:

edge-gateway-b-state-init:
image: alpine:3.22
profiles: [dev-edge]
command: [chown, "10101:10101", /state]
volumes: [edge-b-gateway-state:/state]
restart: "no"

poweradmin:
image: poweradmin/poweradmin:4.3.3
profiles: [devtools]
ports: ["9191:80"]
environment:
DB_TYPE: pgsql
Expand Down
Loading
Loading