Files
DodoSSH/deploy/docker-compose.dev.yml
T
laurensandClaude Opus 5 483ae1fed9
ci / build and test (push) Successful in 3m3s
ci / android head (push) Successful in 4m2s
ci / desktop nightly (push) Successful in 1m30s
ci / api image (push) Successful in 43s
Stop three notes in this repository claiming things that are not so
A scan of the working tree and all 335 commits for anything that should not be
public found no leaked secret. What it did find was three places where a reader
is told something the repository does not back up, and in a public repository a
confident wrong note is worse than silence: nobody goes and checks a sentence
that sounds settled.

The ignore list stopped at *.pfx, *.p12 and *.snk, so a keystore was not covered
at all. The one that matters is the release keystore ADR 0011 rule 1 keeps off
runners — drop it in the tree while cutting a release and nothing would have said
a word. *.keystore and *.jks now, with build/nightly.keystore negated: an ignore
rule cannot untrack a tracked file, so the negation changes no behaviour and is
there so the next reader does not take the committed one for an accident. ADR
0014 is cited beside it, because "a signing key is committed here on purpose" is
a claim that needs its argument within reach.

Also gone from that list: a negation for deploy/.env.example, which has never
existed in any commit.

RelayOptions.AllowPrivateNetworks said loopback, link-local and cloud metadata
ranges "are denied unconditionally and are not configurable" — present tense, in
the voice of a control that exists. Nothing reads the setting. There is no relay
endpoint and no dialler; the relay is ADR 0004 and a contract type. So the
sentence most likely to be read by somebody auditing this repository's SSRF
posture was describing code nobody has written. It now says that outright, and
hands the obligation to whoever builds the dialler with ADR 0004 §3 named in
full, including the IPv4-mapped IPv6 re-check, which is the clause a fresh
implementation is likeliest to miss. The flag governs RFC1918 and never that
list, which was the other half the old wording ran together.

docker-compose.dev.yml pointed at deploy/docker-compose.yml as "the production
stack". That file has never existed here either. Says what does ship — the image
the CI image job builds and pushes — and puts a compose file to run it where it
belongs, in M4's self-hosting guide.

Comments and an ignore list only; no behaviour moves. The API builds clean, and
the two tests that mention the dev compose file read its Postgres version, which
is untouched.

Left alone deliberately: release-android.ps1 and release-windows.ps1 pass the
keystore password and the forge token as arguments to a child process, where
another process on the machine can read them off the command line. That is a real
if small hole and a code change rather than a comment — the vpk half needs
somebody to find out whether it takes the token from the environment first.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-31 16:35:14 +02:00

72 lines
3.0 KiB
YAML

# Development dependencies only: PostgreSQL and Keycloak.
#
# The API itself runs from the IDE or `dotnet run`, so the inner loop stays fast while the
# schema is still churning.
#
# There is no production compose file in this repository. This one said there was, naming a
# deploy/docker-compose.yml that has never existed in any commit. What ships instead is the
# container image the CI image job builds and pushes; a compose file to run it belongs to the
# self-hosting guide in M4, and until that exists the honest thing to say is that it does not.
#
# docker compose -f deploy/docker-compose.dev.yml up -d
# dotnet run --project src/DodoSSH.Api
#
# Keycloak admin console: http://localhost:18080 (admin / admin)
# Test user: alice / alice
name: dodossh-dev
services:
postgres:
image: postgres:18-alpine
container_name: dodossh-dev-postgres
environment:
POSTGRES_DB: dodossh
POSTGRES_USER: dodossh
POSTGRES_PASSWORD: dodossh
# Deterministic collation, matching the server's InvariantGlobalization.
POSTGRES_INITDB_ARGS: "--encoding=UTF8 --locale=C"
ports:
- "5432:5432"
volumes:
# PostgreSQL 18+ wants a single mount at /var/lib/postgresql, with the cluster in a
# subdirectory. Mounting /var/lib/postgresql/data directly — which was correct for 17
# and earlier — makes the image refuse to start, and pg_upgrade --link cannot cross the
# mount boundary later.
- postgres-data:/var/lib/postgresql
healthcheck:
test: ["CMD-SHELL", "pg_isready -U dodossh -d dodossh"]
interval: 5s
timeout: 5s
retries: 10
keycloak:
image: quay.io/keycloak/keycloak:26.4
container_name: dodossh-dev-keycloak
# start-dev, never in production: it disables HTTPS enforcement and keeps its state in a
# throwaway H2 database inside the container.
#
# --import-realm skips a realm that already exists, so editing realm-dodossh.json and running
# `restart` does nothing at all — the edit appears to have no effect and the old configuration
# keeps being served. To pick up a change, recreate the container so its H2 state goes with it:
#
# docker compose -f deploy/docker-compose.dev.yml rm -sf keycloak
# docker compose -f deploy/docker-compose.dev.yml up -d keycloak
command: ["start-dev", "--import-realm"]
environment:
KC_BOOTSTRAP_ADMIN_USERNAME: admin
KC_BOOTSTRAP_ADMIN_PASSWORD: admin
KC_HEALTH_ENABLED: "true"
ports:
# 18080, not 8080. Port 8080 is heavily contested on developer machines — a stray Tomcat
# or WSL relay bound to 127.0.0.1 wins over Docker's 0.0.0.0 publish for "localhost",
# which presents as Keycloak returning 404 for every realm and is thoroughly confusing to
# debug. Keycloak derives the token issuer from the request host, so the port simply has
# to match Oidc:Authority.
- "18080:8080"
volumes:
- ./keycloak:/opt/keycloak/data/import:ro
volumes:
postgres-data: