# server-config Core infrastructure stack for multiple independent web apps on one server. ## Includes - Traefik reverse proxy with automatic TLS certificates (Let's Encrypt) - Shared PostgreSQL database - Shared Adminer instance behind Traefik + basic auth - Shared Docker network so app repositories can join this stack ## Setup 1. Copy `.env.dist` to `.env`. 2. Set real domains and credentials in `.env`. 3. Generate auth hashes with `htpasswd -nbB admin 'your-password'`. 4. Escape every `$` in hashes as `$$` before putting them into `.env`. 5. Start the stack: ```bash docker compose up -d ``` On first initialization of the Postgres volume, the `POSTGRES_USER` from `.env` becomes the bootstrap superuser (default: `admin`). ## For app repositories Each app should connect to the same external Docker network: ```yaml networks: web: external: true name: web ``` Use the shared Postgres host `postgres` on that network with credentials from this stack's `.env`. ## Postgres note This stack uses the latest Postgres image behavior (v18+), so the volume is mounted at `/var/lib/postgresql`. ## Create DB user per app Use the helper script to create (or update) a dedicated DB user and create a dedicated database: ```bash ./scripts/create-db-user.sh project1_db project1_user ``` Or provide your own password: ```bash ./scripts/create-db-user.sh project1_db project1_user "your-strong-password" ``` The script creates restricted app users (`NOSUPERUSER`, `NOCREATEDB`, `NOCREATEROLE`, `NOREPLICATION`) and limits default DB access by revoking `PUBLIC` access. Note: Postgres cannot natively block "Adminer UI login" for a user while still allowing that same user/password for app DB connections. If you need this hard enforcement, the next step is a custom Adminer plugin that only allows selected DB usernames (for example only `admin`).