What you need
- A VPS with Dokploy installed (Dokploy installation docs) and access to its dashboard.
- A domain whose DNS you control, pointing at the server’s IP address.
- The ReachCrew repository on GitHub (the public one, or your fork).
- About 30 minutes.
Overview
Dokploy builds the repository’sDockerfile into an image and runs it as one Application. It does not run docker-compose.yml, so the database is set up by hand here. The schema and the scheduled jobs need nothing from you: the image creates the schema on start and runs the jobs itself.
1
Create the Postgres database
In your Dokploy project, create a service of type Postgres and deploy it. Make sure its Docker image is PostgreSQL 16 or newer (the database Advanced settings let you set a custom Docker image), and set a strong password (Alternatively use any external PostgreSQL 16+ (a hosted one) and skip this step. The database must be empty.
openssl rand -hex 32). On the database’s page, copy the Internal connection details: the internal host name, port, user, password and database name. Use the internal credentials, not the external ones: the app runs in the same network, and the Dokploy docs advise against exposing the database publicly (connection docs).Your connection string is:2
Create the application from GitHub
In the same project, create a service of type Application. In its General tab choose your Git provider (GitHub, after connecting Dokploy to your GitHub account; a plain Git URL also works for a public repository), select the repository, and set the branch to
main (or the branch you deploy). Save.3
Set the build type to Dockerfile
Still in General, under Build Type choose Dockerfile and set:
- Dockerfile Path:
Dockerfile - Docker Context Path:
. - Docker Build Stage: leave empty (the Dockerfile’s last stage is the one to run).
bun run build) and needs no secrets at build time: Dokploy writes the environment you set into a .env file, and this repository’s .dockerignore excludes .env* from the build context, so secrets never enter the image. All settings are read at runtime, and BETTER_AUTH_URL too, so you do not set Build-time Arguments.4
Set the environment variables
Open the Environment tab and paste the variables below (generate each secret with
openssl rand -hex 32; see the Docker Compose page for what each is). Save.DATABASE_SSL=disable is for Dokploy’s own Postgres, which does not use TLS inside the network. For a hosted external database leave DATABASE_SSL out so TLS stays on. BETTER_AUTH_URL must be the final public https origin with no trailing slash. Store a copy of INTEGRATION_CREDENTIALS_KEY outside Dokploy. CRON_SECRET and OUTREACH_TICK_SECRET are optional: add them only if you call the job endpoints from outside.5
Add the domain
First create a DNS
A record for your host (for example sdr.example.com) pointing at the VPS IP. Then open the Domains tab and add a domain with:- Host:
sdr.example.com - Path:
/ - Container Port:
3000(the image listens on 3000) - HTTPS: on
- Certificate: Let’s Encrypt
6
Deploy
Click Deploy and watch the build in the Deployments tab and the Logs tab. The first build takes several minutes. Next.js builds use a lot of memory; if the build is killed on a small VPS, add swap or build the image elsewhere (Dokploy recommends building in a CI pipeline and deploying a registry image for production).
7
Check the first start
On its first start the app creates the database schema (the Logs tab shows
Database ready: N tables.) and starts the scheduled jobs inside the container, so there is nothing to schedule in Dokploy. If the schema step fails the app does not start; see Troubleshooting.Upgrading from a version that used Schedule Jobs? Create the scheduler’s table once, inside the app container: docker exec -it CONTAINER_NAME bun scripts/create-scheduled-job-runs.ts (until then the app runs no scheduled jobs and says so in its log). The existing Schedule Jobs are harmless (the app skips work it already did, see Scheduled jobs), so you can delete them. Keep CRON_SECRET and OUTREACH_TICK_SECRET only if you keep calling the endpoints.8
Turn on deploy on push
In the application’s settings enable Auto Deploy. With the GitHub provider Dokploy deploys when you push; for other Git providers copy the generated webhook URL into your repository’s webhooks. The branch configured in Dokploy must match the branch you push to, otherwise Dokploy reports “Branch Not Match” (auto deploy docs).Before pushing an update, check Upgrading: a release may name a database migration to run first.
Check that it works
https://sdr.example.com/sign-in loads over HTTPS, the Logs tab shows no database errors, and the logs show [scheduler] ... lines as jobs run. Sign up, create your organization, then continue with Going to production.Backups
Dokploy can back up its Postgres service to an S3 destination from the database’s backups section. Keep a copy ofINTEGRATION_CREDENTIALS_KEY separately; see Backups and restore.
Troubleshooting
DATABASE_URL is not set — copy .env.example to .env.local and fill it in
DATABASE_URL is not set — copy .env.example to .env.local and fill it in
The environment was not saved or the app was not redeployed after saving it. Check the Environment tab and redeploy.
This database already has tables
This database already has tables
The start-up setup only runs on an empty database; on an existing one it prints
Database already initialised — nothing to do. and continues. See Troubleshooting.Bad gateway or the certificate is not issued
Bad gateway or the certificate is not issued
Check that the DNS record points at the server, the Container Port is
3000, and ports 80 and 443 are open on the VPS.Next
Going to production
Sign-up policy, email, upgrades.
Troubleshooting
Real error messages and fixes.