Files
ArchiTools/docker-compose.yml
T
Claude VM 6b3d56e1e8 refactor(deploy): externalize all secrets to .env, migrate Brevo SMTP → REST API
- docker-compose.yml: replace 43 hardcoded env values with ${VAR} references.
  Operators must provide /opt/architools/.env (chmod 600, gitignored) with the
  matching keys. Removes the historical leak surface where every edit risked
  echoing secrets.
- email-service.ts: drop nodemailer SMTP transport; use Brevo REST API
  (POST https://api.brevo.com/v3/smtp/email) with BREVO_API_KEY header.
  Brevo SMTP relay credentials have been deleted upstream.
- package.json: remove nodemailer + @types/nodemailer.

NOTE: legacy hardcoded credentials present in git history must still be
rotated separately (DB password, Authentik client secret, ENCRYPTION_SECRET,
ANCPI password, etc.).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 07:49:08 +03:00

147 lines
5.0 KiB
YAML

services:
architools:
build:
context: .
args:
- NEXT_PUBLIC_STORAGE_ADAPTER=${NEXT_PUBLIC_STORAGE_ADAPTER:-database}
- NEXT_PUBLIC_APP_NAME=${NEXT_PUBLIC_APP_NAME:-ArchiTools}
- NEXT_PUBLIC_APP_URL=${NEXT_PUBLIC_APP_URL:-https://tools.beletage.ro}
- NEXT_PUBLIC_MARTIN_URL=${NEXT_PUBLIC_MARTIN_URL}
- NEXT_PUBLIC_PMTILES_URL=${NEXT_PUBLIC_PMTILES_URL}
container_name: architools
restart: unless-stopped
ports:
- "3000:3000"
environment:
- NODE_ENV=${NODE_ENV}
# Database
- DATABASE_URL=${DATABASE_URL}
# MinIO
- MINIO_ENDPOINT=${MINIO_ENDPOINT}
- MINIO_PORT=${MINIO_PORT}
- MINIO_USE_SSL=${MINIO_USE_SSL}
- MINIO_ACCESS_KEY=${MINIO_ACCESS_KEY}
- MINIO_SECRET_KEY=${MINIO_SECRET_KEY}
- MINIO_BUCKET_NAME=${MINIO_BUCKET_NAME}
# Authentication (Authentik OIDC)
- NEXTAUTH_URL=${NEXTAUTH_URL}
- NEXTAUTH_SECRET=${NEXTAUTH_SECRET}
- AUTHENTIK_CLIENT_ID=${AUTHENTIK_CLIENT_ID}
- AUTHENTIK_CLIENT_SECRET=${AUTHENTIK_CLIENT_SECRET}
- AUTHENTIK_ISSUER=${AUTHENTIK_ISSUER}
# Vault encryption
- ENCRYPTION_SECRET=${ENCRYPTION_SECRET}
# ManicTime Tags.txt sync (SMB mount path)
- MANICTIME_TAGS_PATH=${MANICTIME_TAGS_PATH}
# AI Chat (set AI_PROVIDER to openai/anthropic/ollama; demo if no key)
- AI_PROVIDER=${AI_PROVIDER:-demo}
- AI_API_KEY=${AI_API_KEY:-}
- AI_MODEL=${AI_MODEL:-}
- AI_BASE_URL=${AI_BASE_URL:-}
- AI_MAX_TOKENS=${AI_MAX_TOKENS:-2048}
# Visual CoPilot (at-vim)
- VIM_URL=${VIM_URL:-}
# eTerra ANCPI (parcel-sync module)
- ETERRA_USERNAME=${ETERRA_USERNAME:-}
- ETERRA_PASSWORD=${ETERRA_PASSWORD:-}
# ANCPI ePay (CF extract ordering)
- ANCPI_USERNAME=${ANCPI_USERNAME}
- ANCPI_PASSWORD=${ANCPI_PASSWORD}
- ANCPI_BASE_URL=${ANCPI_BASE_URL}
- ANCPI_LOGIN_URL=${ANCPI_LOGIN_URL}
- ANCPI_DEFAULT_SOLICITANT_ID=${ANCPI_DEFAULT_SOLICITANT_ID}
- MINIO_BUCKET_ANCPI=${MINIO_BUCKET_ANCPI}
# Stirling PDF (local PDF tools)
- STIRLING_PDF_URL=${STIRLING_PDF_URL}
- STIRLING_PDF_API_KEY=${STIRLING_PDF_API_KEY}
# iLovePDF cloud compression (free: 250 files/month)
- ILOVEPDF_PUBLIC_KEY=${ILOVEPDF_PUBLIC_KEY:-}
# Martin vector tile server (geoportal)
- NEXT_PUBLIC_MARTIN_URL=${NEXT_PUBLIC_MARTIN_URL}
# PMTiles overview tiles — proxied through tile-cache nginx (HTTPS, no mixed-content)
- NEXT_PUBLIC_PMTILES_URL=${NEXT_PUBLIC_PMTILES_URL}
# DWG-to-DXF sidecar
- DWG2DXF_URL=${DWG2DXF_URL}
# Email notifications (Brevo REST API)
- BREVO_API_KEY=${BREVO_API_KEY}
- NOTIFICATION_FROM_EMAIL=${NOTIFICATION_FROM_EMAIL}
- NOTIFICATION_FROM_NAME=${NOTIFICATION_FROM_NAME}
- NOTIFICATION_CRON_SECRET=${NOTIFICATION_CRON_SECRET}
# Weekend Deep Sync email reports (comma-separated for multiple recipients)
- WEEKEND_SYNC_EMAIL=${WEEKEND_SYNC_EMAIL:-}
# PMTiles rebuild webhook (pmtiles-webhook systemd service on host)
- N8N_WEBHOOK_URL=${N8N_WEBHOOK_URL:-http://10.10.10.166:9876}
# Portal-only users (comma-separated, redirected to /portal)
- PORTAL_ONLY_USERS=${PORTAL_ONLY_USERS}
# Address Book API (inter-service auth for external tools)
- ADDRESSBOOK_API_KEY=${ADDRESSBOOK_API_KEY}
depends_on:
dwg2dxf:
condition: service_healthy
volumes:
# SMB share for ManicTime Tags.txt (mount on host: //time/tags → /mnt/manictime)
- /mnt/manictime:/mnt/manictime
labels:
- "com.centurylinklabs.watchtower.enable=true"
dwg2dxf:
build:
context: ./dwg2dxf-api
container_name: dwg2dxf
restart: unless-stopped
healthcheck:
test:
[
"CMD",
"python3",
"-c",
"import urllib.request; urllib.request.urlopen('http://localhost:5001/health')",
]
interval: 30s
timeout: 5s
retries: 3
start_period: 10s
martin:
build:
context: .
dockerfile: martin.Dockerfile
container_name: martin
restart: unless-stopped
# No host port — only accessible via tile-cache nginx proxy
command: ["--config", "/config/martin.yaml"]
environment:
- DATABASE_URL=${DATABASE_URL}
tile-cache:
build:
context: .
dockerfile: tile-cache.Dockerfile
container_name: tile-cache
restart: unless-stopped
ports:
- "3010:80"
depends_on:
- martin
volumes:
- tile-cache-data:/var/cache/nginx/tiles
tippecanoe:
build:
context: .
dockerfile: tippecanoe.Dockerfile
container_name: tippecanoe
profiles: ["tools"]
environment:
- DB_HOST=${DB_HOST}
- DB_PORT=${DB_PORT}
- DB_NAME=${DB_NAME}
- DB_USER=${DB_USER}
- DB_PASS=${DB_PASS}
- MINIO_ENDPOINT=${MINIO_ENDPOINT}
- MINIO_ACCESS_KEY=${MINIO_ACCESS_KEY}
- MINIO_SECRET_KEY=${MINIO_SECRET_KEY}
volumes:
tile-cache-data: