Production Checklist
Before exposing the system to real users, complete all items in this checklist.
TLS / HTTPS
- Replace self-signed certificates in
infra/nginx/certs/with valid certificates from a trusted CA (e.g., Let's Encrypt via Certbot). - Verify HTTPS is working without browser certificate warnings.
- Configure certificate auto-renewal.
Secrets and credentials
-
JWT_SECRET_KEYis a strong, randomly generated string (at least 32 bytes). Not the placeholder from.env.example. -
POSTGRES_PASSWORDandMYSQL_PASSWORDare strong, unique passwords. -
SNIPEIT_API_TOKENhas been generated via the bootstrap script (not left blank). -
DML_AUTH_KEYandDML_AUTH_SECRETare the real credentials from the University SSO provider. - No secrets are committed to version control (
.envfiles are in.gitignore).
SSO registration
-
SSO_CALLBACK_URL(https://<domain>/auth/auth) is registered with the University of Aveiro identity provider (identity.ua.pt). - The registered callback URL matches exactly the value in
apps/api/.env.
Snipe-IT
- Snipe-IT
APP_URLmatches the public Snipe-IT URL. - Status labels are configured:
Available,Reserved,Checked Out. -
SNIPEIT_RESERVED_STATUS_IDmatches the actual numeric ID of theReservedlabel in this Snipe-IT instance. - Snipe-IT bootstrap script has been run successfully.
- Snipe-IT is accessible only through Nginx (port 8080 is not exposed publicly).
Database
- PostgreSQL password is strong and unique.
- PostgreSQL port (5432) is not publicly accessible.
- Database backups are scheduled and tested. See Backups and Restore.
- The application uses a least-privilege database user (not the superuser) — to verify in current setup.
Access control
-
LAB_TECHNICIANScontains only the emails of authorized technicians. - Only technicians can access Snipe-IT (enforced by Nginx auth_request).
-
APP_DEBUG=falseinapps/api/.env. -
APP_ENV=productioninapps/api/.env.
Nginx
- HTTP is redirected to HTTPS (already configured in template).
- Only ports 80 and 443 are exposed to the internet.
- Direct port access to API (8000) and Snipe-IT (8080) is blocked by firewall rules.
Monitoring and health checks
- Container health checks are configured (PostgreSQL and MariaDB have
healthcheckblocks). - The API
/health-dbendpoint is reachable and returns{"status": "ok"}. - Docker container restart policies are set to
unless-stopped. - Consider setting up log aggregation (e.g., collecting Docker logs to a central system).
Backups
- PostgreSQL backup schedule is configured.
- MariaDB (Snipe-IT) backup schedule is configured.
- Snipe-IT storage volume (
snipeit_storage) is backed up. - Backup restoration procedure has been tested.
Performance and availability
- Sufficient server resources for all containers under expected load.
- Docker volumes are on persistent storage (not ephemeral).
- Consider adding a load balancer or CDN for high availability (future work).