Skip to main content
Dokploy is a self-hosted platform that builds and runs Docker apps on your own VPS, with domains and HTTPS handled for you. The AgentSDR maintainers deploy this way. Use it when you want deploy-on-push instead of managing Compose by hand.
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 AgentSDR repository on GitHub (the public one, or your fork).
  • About 30 minutes.

Overview

Dokploy builds the repository’s Dockerfile into an image and runs it as one Application. It does not run docker-compose.yml, so three things Compose gave you are set up by hand here:
Run exactly one replica of the app. The outreach sender loop has no distributed lock; two instances would each send.
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 (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:
Alternatively use any external PostgreSQL 16+ (a hosted one) and skip this step. The database must be empty.
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).
Field names are from the Dokploy build type docs. Save.The image builds the Next.js app (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.
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
Dokploy routes through Traefik and obtains the certificate (domains docs). Do not publish port 3000 on the host.
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

Create the schema

The app starts but the database is empty until you create the schema, once. The image contains the setup script. Run this inside the app container, from the server’s shell:
It prints Database ready: N tables. (or Database already initialised — nothing to do. on a later run). Alternatively create a one-off Application Schedule Job with that command (see the next step) and run it once. Then restart the app from the dashboard.
8

Schedule the periodic jobs

Dokploy Schedule Jobs can run a command inside the application container on a cron schedule (schedule jobs docs). The target container must be running. Create an Application job per row, with the schedule in standard cron syntax. The container already has curl and your environment variables, and the app listens on 127.0.0.1:3000 inside it:If a job’s shell does not expand $OUTREACH_TICK_SECRET, wrap the command as sh -c '...' with single quotes. Skip the CRON_SECRET rows if you do not use LinkedIn, and the OUTREACH_TICK_SECRET rows if you do not send email. What each job does: jobs table. You can instead call the same endpoints with the public URL from any external cron (From source).
9

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 manual build-queue call from the schedule step returns JSON instead of unauthorized. 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 of INTEGRATION_CREDENTIALS_KEY separately; see Backups and restore.

Troubleshooting

The environment was not saved or the app was not redeployed after saving it. Check the Environment tab and redeploy.
The setup script only runs on an empty database. With --if-empty it exits successfully instead. See Troubleshooting.
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.