mirror of
https://github.com/Zproger/Aurum.git
synced 2026-10-13 02:56:39 +07:00
- TLS через подключаемый overlay docker-compose.tls.yml + Caddyfile: Caddy сам получает и продлевает сертификат Let's Encrypt, HSTS добавляется на уровне прокси — намеренно там, а не в nginx.conf, иначе установки без TLS заперли бы сами себя; - проверка заголовка Host против DNS rebinding: AURUM_ALLOWED_HOSTS, по умолчанию localhost и 127.0.0.1, чужой Host получает 421 с подсказкой, какую переменную поправить; - «запомнить меня на 7 дней» вернулось в безопасном виде: пароль шифруется AES-GCM ключом с extractable: false в IndexedDB, вместо прежнего base64 в localStorage, который разворачивался обратно в пароль одним atob. Требует secure context, поэтому по обычному HTTP к LAN-адресу чекбокс не показывается, а не притворяется рабочим; - аудит-лог необратимых операций (восстановление бэкапа, массовое создание транзакций, удаление счёта) в лог контейнера. Не в БД сознательно: таблица аудита исчезла бы ровно в том событии, которое должна объяснять; - README: раздел про TLS и таблица двух переменных, решающих, кто может достучаться до инстанса.
79 lines
3.4 KiB
YAML
79 lines
3.4 KiB
YAML
services:
|
|
db:
|
|
image: postgres:16-alpine
|
|
restart: unless-stopped
|
|
environment:
|
|
POSTGRES_USER: ${AURUM_POSTGRES_USER:-aurum}
|
|
# "change-me" so this matches .env.example exactly: with no .env at all
|
|
# the fallback here used to be "aurum" while the template said
|
|
# "change-me", i.e. "the default password" meant two different things
|
|
# depending on whether the file existed. Postgres isn't published to the
|
|
# host (no ports: below), so reaching it means already being on the
|
|
# container network — but see .env.example for the trap that makes this
|
|
# worth getting right the first time.
|
|
POSTGRES_PASSWORD: ${AURUM_POSTGRES_PASSWORD:-change-me}
|
|
POSTGRES_DB: ${AURUM_POSTGRES_DB:-aurum}
|
|
volumes:
|
|
- aurum_pgdata:/var/lib/postgresql/data
|
|
healthcheck:
|
|
test: ["CMD-SHELL", "pg_isready -U ${AURUM_POSTGRES_USER:-aurum}"]
|
|
interval: 5s
|
|
timeout: 5s
|
|
retries: 10
|
|
|
|
backend:
|
|
build: ./backend
|
|
restart: unless-stopped
|
|
# Nothing here ever needs to gain privileges (no setuid binaries, no sudo),
|
|
# so forbid it outright — this is what stops a compromised process from
|
|
# escalating back to root inside the container.
|
|
security_opt:
|
|
- no-new-privileges:true
|
|
environment:
|
|
AURUM_POSTGRES_USER: ${AURUM_POSTGRES_USER:-aurum}
|
|
# Must stay identical to the db service's fallback above — if the two
|
|
# drift, an install without .env brings up a database with one password
|
|
# and a backend dialling it with another.
|
|
AURUM_POSTGRES_PASSWORD: ${AURUM_POSTGRES_PASSWORD:-change-me}
|
|
AURUM_POSTGRES_DB: ${AURUM_POSTGRES_DB:-aurum}
|
|
AURUM_POSTGRES_HOST: db
|
|
AURUM_POSTGRES_PORT: 5432
|
|
AURUM_CORS_ORIGINS: ${AURUM_CORS_ORIGINS:-}
|
|
AURUM_DEFAULT_CURRENCY: ${AURUM_DEFAULT_CURRENCY:-USD}
|
|
# Free CoinGecko Demo key (coingecko.com/en/api/pricing) — the Crypto
|
|
# tab's price sync 400s with a clear message until this is set.
|
|
AURUM_COINGECKO_API_KEY: ${AURUM_COINGECKO_API_KEY:-}
|
|
AURUM_ENABLE_DOCS: ${AURUM_ENABLE_DOCS:-true}
|
|
depends_on:
|
|
db:
|
|
condition: service_healthy
|
|
|
|
web:
|
|
build: ./frontend
|
|
restart: unless-stopped
|
|
# nginx's master still needs root to bind :80 and to write the htpasswd
|
|
# file at boot (docker-entrypoint.d/20-basic-auth.sh), so this one can't
|
|
# drop to a non-root user without reworking both — but it can still be
|
|
# barred from escalating any further.
|
|
security_opt:
|
|
- no-new-privileges:true
|
|
ports:
|
|
# Bound to loopback by default: published as "3000:80" the app answers
|
|
# on every interface, so anyone on the same Wi-Fi reaches it — and by
|
|
# default there is no password on it at all (see 20-basic-auth.sh).
|
|
# Set AURUM_BIND_ADDRESS=0.0.0.0 to reach it from other devices, but
|
|
# set AURUM_BASIC_AUTH_USER/PASSWORD before you do.
|
|
- "${AURUM_BIND_ADDRESS:-127.0.0.1}:${AURUM_WEB_PORT:-3000}:80"
|
|
environment:
|
|
# Both unset = no login screen at all. See frontend/docker-entrypoint.d/20-basic-auth.sh.
|
|
AURUM_BASIC_AUTH_USER: ${AURUM_BASIC_AUTH_USER:-}
|
|
AURUM_BASIC_AUTH_PASSWORD: ${AURUM_BASIC_AUTH_PASSWORD:-}
|
|
# Hostnames this instance answers to — anything else gets a 421.
|
|
# See frontend/docker-entrypoint.d/25-allowed-hosts.sh.
|
|
AURUM_ALLOWED_HOSTS: ${AURUM_ALLOWED_HOSTS:-localhost 127.0.0.1}
|
|
depends_on:
|
|
- backend
|
|
|
|
volumes:
|
|
aurum_pgdata:
|