Docker audit fixes #1
@@ -3,6 +3,11 @@
|
|||||||
#
|
#
|
||||||
# cp .env.example .env
|
# cp .env.example .env
|
||||||
|
|
||||||
|
# Address the dev ports are published on. 127.0.0.1 keeps them off the LAN.
|
||||||
|
# Use 0.0.0.0 only if your hosts file maps host.docker.internal to the LAN IP
|
||||||
|
# (then the browser can't reach 127.0.0.1-only ports through that name).
|
||||||
|
DEV_BIND_ADDRESS=127.0.0.1
|
||||||
|
|
||||||
# --- PostgreSQL (shared instance, one database per project) -----------------
|
# --- PostgreSQL (shared instance, one database per project) -----------------
|
||||||
POSTGRES_USER=postgres
|
POSTGRES_USER=postgres
|
||||||
POSTGRES_PASSWORD=postgres
|
POSTGRES_PASSWORD=postgres
|
||||||
|
|||||||
@@ -38,7 +38,9 @@ docker compose -f compose.yml -f compose.dev.yml up -d
|
|||||||
```
|
```
|
||||||
|
|
||||||
That starts Postgres, Zitadel (and its login UI), SeaweedFS, RabbitMQ and Jaeger, with their
|
That starts Postgres, Zitadel (and its login UI), SeaweedFS, RabbitMQ and Jaeger, with their
|
||||||
ports published to `localhost`. Add `--profile tools` to also start pgAdmin.
|
ports published on `127.0.0.1` only (`DEV_BIND_ADDRESS`), so the dev
|
||||||
|
credentials aren't reachable from the LAN. Add `--profile tools` to also
|
||||||
|
start pgAdmin.
|
||||||
|
|
||||||
In production, the base `compose.yml` file **is** the production shape
|
In production, the base `compose.yml` file **is** the production shape
|
||||||
already. There are no published ports, and everything is reachable only on
|
already. There are no published ports, and everything is reachable only on
|
||||||
@@ -106,9 +108,8 @@ match this repo's `.env`". This file is the source of truth for them.
|
|||||||
|
|
||||||
### The Zitadel admin PAT
|
### The Zitadel admin PAT
|
||||||
|
|
||||||
`zitadel-init` (in the compose file of whichever project runs it first)
|
Zitadel itself writes a service-account personal access token to
|
||||||
writes a service-account personal access token to `zitadel/.output/admin-sa.pat`
|
`zitadel/.output/admin-sa.pat` when the instance is created. Every consuming project mounts that same folder read-only, via
|
||||||
on first init. Every consuming project mounts that same folder read-only, via
|
|
||||||
its own `ZITADEL_ADMIN_PAT_DIR` setting, to call the Zitadel management API
|
its own `ZITADEL_ADMIN_PAT_DIR` setting, to call the Zitadel management API
|
||||||
and create its own project/apps.
|
and create its own project/apps.
|
||||||
|
|
||||||
@@ -180,7 +181,9 @@ docker compose -f edge/compose.yml up -d
|
|||||||
for new hostnames (their DNS has to already point at the host):
|
for new hostnames (their DNS has to already point at the host):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker compose -f edge/compose.yml run --rm --entrypoint certbot certbot certonly --webroot -w /var/www/certbot -d host1.example.com -d host2.example.com --non-interactive --agree-tos -m you@example.com
|
docker compose -f edge/compose.yml run --rm --entrypoint certbot certbot \
|
||||||
|
certonly --webroot -w /var/www/certbot -d host1.example.com -d host2.example.com \
|
||||||
|
--non-interactive --agree-tos -m you@example.com
|
||||||
```
|
```
|
||||||
|
|
||||||
Then add the `server` blocks pointing at
|
Then add the `server` blocks pointing at
|
||||||
|
|||||||
+25
-13
@@ -5,43 +5,49 @@ name: infra-dev
|
|||||||
# of joining infra-net. Adds pgAdmin.
|
# of joining infra-net. Adds pgAdmin.
|
||||||
#
|
#
|
||||||
# docker compose -f compose.yml -f compose.dev.yml up -d
|
# docker compose -f compose.yml -f compose.dev.yml up -d
|
||||||
|
#
|
||||||
|
# Ports are bound to DEV_BIND_ADDRESS (127.0.0.1 by default), so the dev
|
||||||
|
# credentials in .env are not reachable from the LAN. Other containers still
|
||||||
|
# reach them through host.docker.internal. The browser on the host does too
|
||||||
|
# as long as the hosts file maps host.docker.internal to 127.0.0.1; if yours
|
||||||
|
# maps it to the LAN IP, set DEV_BIND_ADDRESS=0.0.0.0 (see .env.example).
|
||||||
|
|
||||||
services:
|
services:
|
||||||
postgres:
|
postgres:
|
||||||
ports:
|
ports:
|
||||||
- "${POSTGRES_HOST_PORT}:5432"
|
- "${DEV_BIND_ADDRESS:-127.0.0.1}:${POSTGRES_HOST_PORT}:5432"
|
||||||
|
|
||||||
zitadel:
|
zitadel:
|
||||||
ports:
|
ports:
|
||||||
- "${ZITADEL_EXTERNAL_PORT}:8080"
|
- "${DEV_BIND_ADDRESS:-127.0.0.1}:${ZITADEL_EXTERNAL_PORT}:8080"
|
||||||
|
|
||||||
# No edge in dev to put the login under Zitadel's own port, so it gets its
|
# No edge in dev to put the login under Zitadel's own port, so it gets its
|
||||||
# own (ZITADEL_LOGIN_BASE_URL in .env points the browser at it).
|
# own (ZITADEL_LOGIN_BASE_URL in .env points the browser at it).
|
||||||
zitadel-login:
|
zitadel-login:
|
||||||
ports:
|
ports:
|
||||||
- "${ZITADEL_LOGIN_HOST_PORT}:3000"
|
- "${DEV_BIND_ADDRESS:-127.0.0.1}:${ZITADEL_LOGIN_HOST_PORT}:3000"
|
||||||
|
|
||||||
seaweedfs:
|
seaweedfs:
|
||||||
ports:
|
ports:
|
||||||
- "9333:9333" # master / admin UI
|
- "${DEV_BIND_ADDRESS:-127.0.0.1}:9333:9333" # master / admin UI
|
||||||
- "8888:8888" # filer
|
- "${DEV_BIND_ADDRESS:-127.0.0.1}:8888:8888" # filer
|
||||||
- "8333:8333" # S3 API
|
- "${DEV_BIND_ADDRESS:-127.0.0.1}:8333:8333" # S3 API
|
||||||
|
|
||||||
rabbitmq:
|
rabbitmq:
|
||||||
ports:
|
ports:
|
||||||
- "5672:5672" # AMQP
|
- "${DEV_BIND_ADDRESS:-127.0.0.1}:5672:5672" # AMQP
|
||||||
- "15672:15672" # management UI
|
- "${DEV_BIND_ADDRESS:-127.0.0.1}:15672:15672" # management UI
|
||||||
|
|
||||||
jaeger:
|
jaeger:
|
||||||
ports:
|
ports:
|
||||||
- "16686:16686" # UI
|
- "${DEV_BIND_ADDRESS:-127.0.0.1}:16686:16686" # UI
|
||||||
- "4317:4317" # OTLP gRPC
|
- "${DEV_BIND_ADDRESS:-127.0.0.1}:4317:4317" # OTLP gRPC
|
||||||
- "4318:4318" # OTLP HTTP
|
- "${DEV_BIND_ADDRESS:-127.0.0.1}:4318:4318" # OTLP HTTP
|
||||||
|
|
||||||
# Optional Postgres UI: docker compose ... --profile tools up -d
|
# Optional Postgres UI: docker compose ... --profile tools up -d
|
||||||
pgadmin:
|
pgadmin:
|
||||||
profiles: [tools]
|
profiles: [tools]
|
||||||
image: dpage/pgadmin4:latest
|
image: dpage/pgadmin4:9.18
|
||||||
container_name: infra-pgadmin
|
container_name: infra-pgadmin
|
||||||
environment:
|
environment:
|
||||||
PGADMIN_DEFAULT_EMAIL: ${PGADMIN_DEFAULT_EMAIL}
|
PGADMIN_DEFAULT_EMAIL: ${PGADMIN_DEFAULT_EMAIL}
|
||||||
@@ -51,9 +57,15 @@ services:
|
|||||||
postgres:
|
postgres:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
ports:
|
ports:
|
||||||
- "${PGADMIN_HOST_PORT}:80"
|
- "${DEV_BIND_ADDRESS:-127.0.0.1}:${PGADMIN_HOST_PORT}:80"
|
||||||
volumes:
|
volumes:
|
||||||
- pgadmin_data:/var/lib/pgadmin
|
- pgadmin_data:/var/lib/pgadmin
|
||||||
|
# Same rotation as compose.yml (YAML anchors don't cross files).
|
||||||
|
logging:
|
||||||
|
driver: json-file
|
||||||
|
options:
|
||||||
|
max-size: "10m"
|
||||||
|
max-file: "3"
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
|
|||||||
+27
-3
@@ -7,13 +7,21 @@
|
|||||||
# of joining a network. See README.md for why.
|
# of joining a network. See README.md for why.
|
||||||
#
|
#
|
||||||
# dev docker compose -f compose.yml -f compose.dev.yml up -d
|
# dev docker compose -f compose.yml -f compose.dev.yml up -d
|
||||||
# prod docker compose --env-file .env.prod -f compose.yml -f compose.prod.yml up -d
|
# prod docker compose --env-file .env.prod -f compose.yml up -d
|
||||||
#
|
#
|
||||||
# A consuming project's own deploy stack does NOT get its own copy of any of
|
# A consuming project's own deploy stack does NOT get its own copy of any of
|
||||||
# these services. It only needs this stack to already be up, and its own
|
# these services. It only needs this stack to already be up, and its own
|
||||||
# one-shot bootstrap jobs (zitadel-init, seaweedfs-init) to create its own
|
# one-shot bootstrap jobs (zitadel-init, seaweedfs-init) to create its own
|
||||||
# OIDC apps / bucket against the shared instances below.
|
# OIDC apps / bucket against the shared instances below.
|
||||||
|
|
||||||
|
# Docker's default json-file driver never rotates, so logs would grow until
|
||||||
|
# the disk fills up.
|
||||||
|
x-logging: &default-logging
|
||||||
|
driver: json-file
|
||||||
|
options:
|
||||||
|
max-size: "10m"
|
||||||
|
max-file: "3"
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
infra-net:
|
infra-net:
|
||||||
name: infra-net
|
name: infra-net
|
||||||
@@ -38,6 +46,7 @@ services:
|
|||||||
timeout: 5s
|
timeout: 5s
|
||||||
retries: 10
|
retries: 10
|
||||||
networks: [infra-net]
|
networks: [infra-net]
|
||||||
|
logging: *default-logging
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
|
||||||
# --- Identity -----------------------------------------------------------
|
# --- Identity -----------------------------------------------------------
|
||||||
@@ -118,6 +127,7 @@ services:
|
|||||||
retries: 12
|
retries: 12
|
||||||
start_period: 20s
|
start_period: 20s
|
||||||
networks: [infra-net]
|
networks: [infra-net]
|
||||||
|
logging: *default-logging
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
|
||||||
# Login V2 UI (Next.js), served under /ui/v2/login. It calls the API
|
# Login V2 UI (Next.js), served under /ui/v2/login. It calls the API
|
||||||
@@ -143,6 +153,7 @@ services:
|
|||||||
volumes:
|
volumes:
|
||||||
- zitadel_bootstrap:/bootstrap:ro
|
- zitadel_bootstrap:/bootstrap:ro
|
||||||
networks: [infra-net]
|
networks: [infra-net]
|
||||||
|
logging: *default-logging
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
|
||||||
# --- Storage --------------------------------------------------------------
|
# --- Storage --------------------------------------------------------------
|
||||||
@@ -152,7 +163,7 @@ services:
|
|||||||
# handed to consuming projects. No bucket is created here; each
|
# handed to consuming projects. No bucket is created here; each
|
||||||
# consuming project's own seaweedfs-init one-shot creates its own.
|
# consuming project's own seaweedfs-init one-shot creates its own.
|
||||||
seaweedfs:
|
seaweedfs:
|
||||||
image: chrislusf/seaweedfs:latest
|
image: chrislusf/seaweedfs:4.47
|
||||||
container_name: infra-seaweedfs
|
container_name: infra-seaweedfs
|
||||||
entrypoint: ["/bin/sh", "-c"]
|
entrypoint: ["/bin/sh", "-c"]
|
||||||
command:
|
command:
|
||||||
@@ -184,6 +195,7 @@ services:
|
|||||||
timeout: 5s
|
timeout: 5s
|
||||||
retries: 10
|
retries: 10
|
||||||
networks: [infra-net]
|
networks: [infra-net]
|
||||||
|
logging: *default-logging
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
|
||||||
# --- Messaging --------------------------------------------------------
|
# --- Messaging --------------------------------------------------------
|
||||||
@@ -207,16 +219,28 @@ services:
|
|||||||
timeout: 5s
|
timeout: 5s
|
||||||
retries: 10
|
retries: 10
|
||||||
networks: [infra-net]
|
networks: [infra-net]
|
||||||
|
logging: *default-logging
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
|
||||||
# --- Tracing --------------------------------------------------------------
|
# --- Tracing --------------------------------------------------------------
|
||||||
# OTLP collector + trace UI, shared by any project's OpenTelemetry exporter.
|
# OTLP collector + trace UI, shared by any project's OpenTelemetry exporter.
|
||||||
|
# Last Jaeger v1 release (v1 is deprecated; v2 is jaegertracing/jaeger).
|
||||||
jaeger:
|
jaeger:
|
||||||
image: jaegertracing/all-in-one:latest
|
image: jaegertracing/all-in-one:1.76.0
|
||||||
container_name: infra-jaeger
|
container_name: infra-jaeger
|
||||||
environment:
|
environment:
|
||||||
COLLECTOR_OTLP_ENABLED: "true"
|
COLLECTOR_OTLP_ENABLED: "true"
|
||||||
|
# Traces are kept in memory; without a cap they grow until the
|
||||||
|
# container runs out of RAM. The oldest are dropped first.
|
||||||
|
MEMORY_MAX_TRACES: "100000"
|
||||||
|
healthcheck:
|
||||||
|
# Admin port: answers 200 once the collector and query service are up.
|
||||||
|
test: ["CMD", "wget", "-q", "-O", "-", "http://localhost:14269/"]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 10
|
||||||
networks: [infra-net]
|
networks: [infra-net]
|
||||||
|
logging: *default-logging
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
|
|||||||
+11
-1
@@ -10,6 +10,14 @@
|
|||||||
|
|
||||||
name: edge
|
name: edge
|
||||||
|
|
||||||
|
# Docker's default json-file driver never rotates, so logs would grow until
|
||||||
|
# the disk fills up.
|
||||||
|
x-logging: &default-logging
|
||||||
|
driver: json-file
|
||||||
|
options:
|
||||||
|
max-size: "10m"
|
||||||
|
max-file: "3"
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
infra-net:
|
infra-net:
|
||||||
name: infra-net
|
name: infra-net
|
||||||
@@ -36,10 +44,11 @@ services:
|
|||||||
- ./certbot/www:/var/www/certbot:ro
|
- ./certbot/www:/var/www/certbot:ro
|
||||||
- ./certbot/conf:/etc/letsencrypt:ro
|
- ./certbot/conf:/etc/letsencrypt:ro
|
||||||
networks: [gitea, infra-net]
|
networks: [gitea, infra-net]
|
||||||
|
logging: *default-logging
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
|
||||||
certbot:
|
certbot:
|
||||||
image: certbot/certbot
|
image: certbot/certbot:v5.8.0
|
||||||
container_name: edge-certbot
|
container_name: edge-certbot
|
||||||
entrypoint:
|
entrypoint:
|
||||||
- /bin/sh
|
- /bin/sh
|
||||||
@@ -48,4 +57,5 @@ services:
|
|||||||
volumes:
|
volumes:
|
||||||
- ./certbot/conf:/etc/letsencrypt
|
- ./certbot/conf:/etc/letsencrypt
|
||||||
- ./certbot/www:/var/www/certbot
|
- ./certbot/www:/var/www/certbot
|
||||||
|
logging: *default-logging
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
|||||||
Reference in New Issue
Block a user