- Copy
.env.production.exampleto.env.productionand set a real domain, admin password, database password, and a stableDEPLOYMATE_SERVER_CREDENTIALS_KEY. - Point your domain's DNS A record to the VPS.
- Make sure Docker Engine with Docker Compose is installed on the VPS.
- Prepare the pinned SSH host key file before the first remote deployment:
bash scripts/prepare_known_hosts.sh --host <target-host> --port 22 --output /opt/deploymate/.secrets/deploymate_known_hosts- Validate the production env contract:
bash scripts/production_env_audit.sh --env-file .env.production --require-runtime-files- Start DeployMate:
docker compose -f docker-compose.prod.yml --env-file .env.production up -d --buildThe stack includes:
postgreswith persistent data in thepostgres_datavolumebackendrunning FastAPI on the internal Docker networkfrontendrunning Next.js in production modeproxyrunning Caddy on ports80and443
Notes:
- Generate
DEPLOYMATE_SERVER_CREDENTIALS_KEYonce and keep it stable for the lifetime of the environment. Example:
python3 -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"- If the key changes later, previously stored server SSH credentials will no longer decrypt until the original key is restored.
- Production now defaults to a
remote-onlyprofile. The backend does not need/var/run/docker.sockfor the standard production setup. - Keep
NEXT_PUBLIC_LOCAL_DEPLOYMENTS_ENABLED=0in production so the UI matches the remote-only backend policy and does not offer local host deployment paths. - Public demo signup can be enabled with
DEPLOYMATE_PUBLIC_SIGNUP_ENABLED=trueandNEXT_PUBLIC_PUBLIC_SIGNUP_ENABLED=1. New users are created asmemberon thetrialplan. - Live demo access is now opt-in. Set
NEXT_PUBLIC_DEMO_ACCESS_ENABLED=1,DEPLOYMATE_DEMO_ACCESS_ENABLED=true,DEPLOYMATE_DEMO_USERNAME, andDEPLOYMATE_DEMO_PASSWORDonly when you intentionally want a dedicated demo login. Do not reuse the admin password for reviewer/demo access. - HTTPS is Caddy-ready. With a real public domain on ports
80and443, Caddy can issue certificates automatically. - DeployMate now refuses silent
admin/adminbootstrap. Set a realDEPLOYMATE_ADMIN_PASSWORD, or acknowledge local-only insecure bootstrap explicitly withDEPLOYMATE_ALLOW_INSECURE_DEFAULT_ADMIN=true. - Remote server deployments over SSH still require reachable target hosts and valid SSH credentials stored in DeployMate.
- SSH host key handling is configurable through
DEPLOYMATE_SSH_HOST_KEY_CHECKING. The default is now strict pinned verification viayes. Useaccept-newornoonly as an explicit escape hatch for non-production environments. - When
DEPLOYMATE_SSH_HOST_KEY_CHECKING=yes,DEPLOYMATE_SSH_KNOWN_HOSTS_FILEmust point to an existing non-emptyknown_hostsfile or remote SSH actions will fail fast. - Use
bash scripts/prepare_known_hosts.sh --host <host> --port <port> --output /opt/deploymate/.secrets/deploymate_known_hoststo populate the pinnedknown_hostsfile expected by the production example and compose defaults. docker-compose.prod.ymlnow bind-mountsDEPLOYMATE_SSH_KNOWN_HOSTS_FILEinto the backend container, so the path must exist on the host before the backend starts.- Run
bash scripts/production_env_audit.sh --env-file .env.production --require-runtime-filesbefore each production release when you change env, compose, or SSH trust settings. - Set
DEPLOYMATE_LOCAL_DOCKER_ENABLED=trueonly if you intentionally want local-on-host Docker control and have reviewed the extra security tradeoff.