Admin: Departments (name and stations; add shows the three groups IT must create), Profiles (welder stamp, station limits, active) with a CSV import that previews and applies only when clean, Checklists (weld and plain), Security (session, lockout and rate-limit settings with bounds, alerts for the last 24 hours, the integrity result), Access log with filters and a guarded CSV, Who is in, Stamp check, Notifications, and the employeeID flags. Every Admin change is audited. Worker: ad-reconcile (nightly and on "refresh from AD now"), session-refresh (15 minutes), integrity (seals, asset hashes, missing and orphan files, the audit chain), backup-check, notify-send and notify-digest. Notifications route per event type to AD groups, users, mailboxes or the department Supervisor group, immediately or in a daily digest, over STARTTLS verified against the PESCO CA, with dry run on the test stack. Backups: scripts/backup/ps-backup.sh and ps-restore.sh with a systemd timer at 02:00 America/Denver. Restore rehearsed on the test stack 2026-10-21. CI: pip-audit and npm audit. pypdf 6.21.1 and certifi 2026.10.19. Migration 0010. Closes the app part of I6, M3, O1, O2 and S3. Co-Authored-By: Claude Opus 5.5 <[email protected]>
150 lines
6.1 KiB
Bash
150 lines
6.1 KiB
Bash
# Packet Station production stack settings. Copy to /etc/packetstation/prod/stack.env
|
|
# (root:root 0644). It holds no secret: passwords live in SECRETS_DIR as files.
|
|
# Start: docker compose -p packetstation --env-file /etc/packetstation/prod/stack.env \
|
|
# -f deploy/compose.yaml -f deploy/compose.proxy.yaml up -d
|
|
# Starting this stack polls VISUAL production on its schedule. That start is the approval.
|
|
# Comments sit on their own lines. Do not put a comment after a value.
|
|
|
|
# ---- Compose (read by docker compose; also passed to the containers, which ignore them) ----
|
|
# Compose project name. Keeps prod and test volumes apart.
|
|
PROJECT_NAME=packetstation
|
|
# This file's own path. Compose hands it to the containers as env_file.
|
|
ENV_FILE=/etc/packetstation/prod/stack.env
|
|
# Image to run. Always a tested release tag, never latest.
|
|
IMAGE=gt.pescoinc.biz/spencerm/packetstation:vX.Y.Z
|
|
# App alias on npm_default. NPM forwards to http://<alias>:8000.
|
|
APP_ALIAS=packetstation-app
|
|
# Host folder of secret files, root:10001 mode 0440.
|
|
SECRETS_DIR=/etc/packetstation/prod/secrets
|
|
# Host PEM file with the PESCO CA chain. Mounted at /etc/ssl/pesco/ca.pem.
|
|
CA_BUNDLE_FILE=/etc/packetstation/ca/pesco-ca.pem
|
|
# Host backup folder, mounted read-only in the worker. Compose sets BACKUP_DIR=/backups inside.
|
|
BACKUP_DIR=/var/backups/packetstation/prod
|
|
|
|
# ---- Stack and site ----
|
|
# prod, test, ci or dev. Guards against crossing stacks.
|
|
STACK=prod
|
|
# Site key.
|
|
SITE_ID=farmington
|
|
# Site time zone for schedules and display. Containers run in UTC.
|
|
SITE_TZ=America/Denver
|
|
# Public URL, used in links and mail.
|
|
PUBLIC_URL=https://packetstation.pescoinc.biz
|
|
# Only this container may set X-Forwarded-*. The app re-resolves it. Empty trusts nobody.
|
|
TRUSTED_PROXY_HOST=npm_app_1
|
|
# DEBUG, INFO, WARNING or ERROR. Logs go to stdout.
|
|
LOG_LEVEL=INFO
|
|
# Worker heartbeat file read by its healthcheck. /tmp is a tmpfs.
|
|
WORKER_BEAT_FILE=/tmp/packetstation-worker.beat
|
|
# Where the worker reads work orders: visualkit (the real VISUAL through VisualKit) or fixture (CI only; prod refuses it).
|
|
FEED_SOURCE=visualkit
|
|
# Where the worker looks up drawings: mfiles (the vault through MFilesKit) or fixture (CI only; prod refuses it).
|
|
DRAWING_SOURCE=mfiles
|
|
# Fixture folder inside the containers. Only read when a source is fixture.
|
|
FIXTURE_DIR=/fixtures
|
|
|
|
# ---- PostgreSQL (roles made by deploy/postgres/initdb/01-roles.sh) ----
|
|
# postgres alias on the internal backend network.
|
|
PG_HOST=packetstation-postgres
|
|
# PostgreSQL port.
|
|
PG_PORT=5432
|
|
# Database name.
|
|
PG_DATABASE=packetstation
|
|
# Runtime role for the app and worker.
|
|
PG_APP_USER=ps_app
|
|
# Its password, from the compose secret.
|
|
PG_APP_PASSWORD_FILE=/run/secrets/postgres_app_password
|
|
# Schema owner. Used by migrate only.
|
|
PG_MIGRATE_USER=ps_migrate
|
|
# Its password, from the compose secret.
|
|
PG_MIGRATE_PASSWORD_FILE=/run/secrets/postgres_migrate_password
|
|
|
|
# ---- Keys and paths inside the container ----
|
|
# Session signing key.
|
|
SESSION_KEY_FILE=/run/secrets/session_key
|
|
# HMAC key for record seals.
|
|
SEAL_KEY_FILE=/run/secrets/seal_key
|
|
# Assets volume. Compose sets it too.
|
|
ASSETS_DIR=/data/assets
|
|
# Built frontend. Compose sets it too.
|
|
STATIC_DIR=/app/static
|
|
|
|
# ---- Uploads and storage ----
|
|
# Largest drawing, MTR or document upload, in bytes (25 MB).
|
|
UPLOAD_MAX_BYTES=26214400
|
|
# Largest BOM upload (XLSX or CSV), in bytes (5 MB).
|
|
UPLOAD_MAX_BYTES_BOM=5242880
|
|
# Open the storage alert when the assets store is this full, in percent (1 to 99).
|
|
ASSETS_QUOTA_WARN_PCT=85
|
|
# 0 measures the assets volume. A byte count measures the stored files against that many bytes.
|
|
ASSETS_QUOTA_BYTES=0
|
|
|
|
# ---- ClamAV (optional virus scan of uploads; left off by IT, Gitea issue 19) ----
|
|
# Empty means no scan. When set, start the stack with --profile clamav on every docker compose command.
|
|
# An unreachable scanner then refuses uploads until it answers.
|
|
#CLAMAV_HOST=packetstation-clamav
|
|
# clamd port.
|
|
CLAMAV_PORT=3310
|
|
# Seconds to wait for a scan.
|
|
CLAMAV_TIMEOUT_SECONDS=30
|
|
|
|
# ---- LDAP (PESCO Active Directory; CI gets the Samba DC in phase 1) ----
|
|
# Both domain controllers, tried in order.
|
|
LDAP_URL="ldaps://DC-02.PESCO.COM:636 ldaps://PDC-1.PESCO.COM:636"
|
|
# Search base for users.
|
|
LDAP_BASE_DN=DC=PESCO,DC=com
|
|
# Service account for searches.
|
|
LDAP_BIND_DN=CN=svc-packetstation,OU=System_Accounts,OU=Admin,DC=PESCO,DC=com
|
|
# Service account password, from the compose secret.
|
|
LDAP_PASSWORD_FILE=/run/secrets/ldap_bind_password
|
|
# User search filter. {0} is the escaped sign-in name.
|
|
LDAP_USER_FILTER="(|(sAMAccountName={0})(userPrincipalName={0}))"
|
|
# OU that holds the 50 PS-* groups.
|
|
LDAP_GROUP_BASE_DN=OU=PacketStation,OU=Groups,OU=PESCO_FARMINGTON,DC=PESCO,DC=com
|
|
# CA chain used to verify the controllers.
|
|
LDAP_CA_BUNDLE=/etc/ssl/pesco/ca.pem
|
|
# false with ldaps://. true only with ldap:// on 389.
|
|
LDAP_STARTTLS=false
|
|
# Never true outside local development.
|
|
LDAP_ALLOW_INSECURE=false
|
|
|
|
# ---- Mail (relay app-03, no auth) ----
|
|
# Relay host. Empty disables mail.
|
|
SMTP_HOST=app-03.pesco.com
|
|
# Relay port.
|
|
SMTP_PORT=25
|
|
# Sender address.
|
|
SMTP_FROM=[email protected]
|
|
# Require STARTTLS.
|
|
SMTP_STARTTLS=true
|
|
# CA chain used to verify the relay.
|
|
SMTP_CA_BUNDLE=/etc/ssl/pesco/ca.pem
|
|
# true logs notifications and sends nothing.
|
|
NOTIFY_DRY_RUN=false
|
|
|
|
# ---- VisualKit (VISUAL ERP, read only) ----
|
|
# SQL Server instance. Full name: containers have no search domain.
|
|
VISUAL_SERVER=vsql.pesco.com
|
|
# VISUAL database.
|
|
VISUAL_DATABASE=PESCOINC
|
|
# Read-only SQL login.
|
|
VISUAL_USER=visualkit_ro
|
|
# Its password, from the compose secret.
|
|
VISUAL_PASSWORD_FILE=/run/secrets/visualkit_password
|
|
# no until vsql has a trusted certificate (open question 6).
|
|
VISUAL_ENCRYPT=no
|
|
# ODBC driver name installed in the image.
|
|
VISUAL_DRIVER="ODBC Driver 18 for SQL Server"
|
|
|
|
# ---- MFilesKit (M-Files, read only; there is no test vault, so test reads production) ----
|
|
# M-Files REST endpoint.
|
|
MFILES_URL=https://mfiles.pescoinc.biz/REST
|
|
# Vault GUID.
|
|
MFILES_VAULT_GUID={BB69270D-023E-4EA8-B899-AD20B1349702}
|
|
# Read-only user. The entrypoint exports MFILES_PASSWORD from its secret file.
|
|
MFILES_USERNAME=mfileskitRO
|
|
# CA chain used to verify M-Files.
|
|
MFILES_CA_BUNDLE=/etc/ssl/pesco/ca.pem
|
|
|
|
# PS_BUILD is baked into the image at build time. Do not set it here.
|