Инфраструктура: api.conf.example, харднинг контейнеров, гигиена compose - #84
Merged
Conversation
…ygiene Deployment-layer hardening from the code review. #68 — commit the missing, documented control-plane pieces: - nginx/user_conf.d/api.conf.example: hardened reverse-proxy vhost for the dashboard/API (TLS 1.2/1.3, HSTS, OCSP stapling, security headers, client_max_body_size 30m for attachment sends, forwarded headers for TRUST_PROXY=1). nginx only loads *.conf, so the template is inert until copied. - nginx/nginx-certbot.env.example: the file deployment.md already told operators to copy but that didn't exist. - Fix docs (deployment.md, CLAUDE.md) that referenced a committed api.conf. #69 — shrink the Docker-access blast radius: - mail-api: no-new-privileges + cap_drop ALL (runs as USER node already). - Dokploy compose: replace the raw /var/run/docker.sock mount + group_add with a bundled docker-socket-proxy (inspect/exec/restart only), mirroring the default stack. Drops the now-unused DOCKER_GID from env + docs. - architecture.md: document the residual risk honestly (EXEC = root inside the existing containers; better than a raw socket but that's the ceiling). #70 — compose hygiene: - Pin docker-socket-proxy (the most security-sensitive image) off :latest to 0.3.0. - Shared x-logging anchor caps json-file logs on every service (was mailserver-only). - mem_limit on the predictable services (nginx/mail-api/socket-proxy); mailserver left uncapped with guidance (a too-low cap OOM-kills mail). - nginx healthcheck via a new /healthz in the fallback vhost. - Document chmod 600 for the secret-bearing .env files. depends_on kept as start-order (not service_healthy): docker-mailserver is intentionally unhealthy on first boot until the first mailbox exists, and that mailbox is created through mail-api — a health gate would deadlock bootstrap. Closes #68 Closes #69 Refs #70 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
friench
added a commit
that referenced
this pull request
Jul 8, 2026
Regression from #84: pinning docker-socket-proxy to 0.3.0 (haproxy-based) together with read_only:true + tmpfs:/run left it unable to write its generated config to /usr/local/etc/haproxy/haproxy.cfg (Read-only file system), so the proxy crash-looped and mail-api could not reach the Docker API — every provisioning call (create/update/delete mailbox, password change, DKIM, DMS<->DB sync) returned HTTP 500 with "getaddrinfo ENOTFOUND docker-socket-proxy". Add /usr/local/etc/haproxy to the tmpfs list in both the default and Dokploy compose files, keeping the read-only rootfs hardening intact. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Второй заход по итогам ревью — инфраструктура/деплой. Только конфиги и доки, кода нет.
#68 — недостающие, но задокументированные части
nginx/user_conf.d/api.conf.example— харднутый reverse-proxy vhost панели/API (TLS 1.2/1.3, HSTS, OCSP stapling, security-заголовки,client_max_body_size 30mпод вложения, forwarded-заголовки дляTRUST_PROXY=1). nginx грузит только*.conf, поэтому.exampleинертен до копирования. Закрывает «нет HTTPS-входа к панели из коробки».nginx/nginx-certbot.env.example— файл, которыйdeployment.mdвелел копировать, но которого не было.deployment.md,CLAUDE.md), ссылавшихся на закоммиченныйapi.conf.#69 — сузить blast-radius Docker-доступа
no-new-privileges+cap_drop: ALL(и такUSER node)./var/run/docker.sock+group_addзаменён на встроенныйdocker-socket-proxy(inspect/exec/restart), как в основном стеке feat(security): доступ к Docker через docker-socket-proxy #59. Убран более не нужныйDOCKER_GIDиз env и доков.architecture.md: честно задокументирован остаточный риск —EXEC= root внутри существующих контейнеров (mailserver/nginx), лучше сырого сокета, но это потолок прокси.#70 — гигиена compose
docker-socket-proxy(самый security-sensitive образ) с:latest→:0.3.0.x-logginganchor кап-лимитит json-file логи на всех сервисах (было только у mailserver).mem_limitна предсказуемых сервисах (nginx/mail-api/socket-proxy); mailserver оставлен без кэпа с пояснением (слишком низкий кэп OOM-killит доставку почты)./healthzв fallback-vhost.chmod 600для секретных.envв доках.Проверки
Оба compose-файла проходят YAML-парс. Docker CLI в этой среде недоступен —
docker compose configне гонял; при мерже стоит глянутьdocker compose config -qна хосте перед деплоем. Кода/тестов в PR нет.Что осталось по #70 (не закрываю)
traefik-certs-dumper:v2— намеренно оставлен (ты недавно фиксировал его на latest v2); бампить — по желанию.mailserver-api/.env.exampleиз zod-схемы — отдельная уборка (переменные из [security] Харднинг web/auth: COOKIE_SECURE, /metrics, Origin-check, SSRF DNS-pin #67 уже добавлены).Closes #68
Closes #69
Refs #70
🤖 Generated with Claude Code