Mastering Self-Hosted Convex on Dokploy: A Complete Deployment Guide

1 1 6
calendar_today agoschedule2 min read
— Originally published at dev.to

So, you've decided to take control of your data and self-host Convex. It's a great choice but if you've tried pushing your functions to a local or private server, you might have run into cryptic errors about "Relative import paths" or "Missing modules."

The secret? You don't need custom deployment scripts. In fact, you shouldn't use them. The official Convex CLI is actually powerful enough to handle self-hosted deployments perfectly—if you know which buttons to press.

In this guide, I’ll show you exactly how to configure your project and deploy your functions like a pro.


1. Before You Start

Before we dive into the code, make sure you have the following ready:

  • Your Convex Instance: Whether you're using Dokploy, Docker, or a raw VPS, your backend should be up and running.
  • The Admin Key: You'll need the master key for your server.
    • Tip: If you're using Dokploy, you can usually generate this by running ./generate_admin_key.sh inside your backend container's terminal.
  • The CLI: Make sure you have the latest version of Convex installed locally:
    npm install convex
    

2. Preparing Your Project

For a smooth deployment, your convex/ folder needs to be a bit more "independent."

Step 1: Give Convex its own Identity

Create a package.json inside your convex/ directory. This ensures the CLI knows exactly which dependencies to bundle when it prepares your code for the server.

{
  "name": "my-convex-backend",
  "private": true,
  "type": "module",
  "dependencies": {
    "convex": "^1.16.0",
    "typescript": "^5.0.0"
  }
}

Step 2: Fix your Config

Ensure your convex/convex.config.ts is using the modern defineApp export. The server expects this structure to understand your app's layout.

import { defineApp } from "convex/server";

export default defineApp();

3. The Magic Environment Variables

The Convex CLI is "Cloud-first" by default, but we can tell it to target our own server by setting two specific environment variables.

Variable What it does
CONVEX_SELF_HOSTED_URL Points the CLI to your backend URL (e.g., https://api.myapp.com).
CONVEX_SELF_HOSTED_ADMIN_KEY Your secret key. Crucial: It must include the convex-self-hosted| prefix!

4. The Big Moment: Deploying

Now, let's push your code. We're going to use the official deploy command.

Run this from your root or convex directory:

CONVEX_SELF_HOSTED_URL="https://your-api-url.com" \
CONVEX_SELF_HOSTED_ADMIN_KEY="convex-self-hosted|your-key-here" \
npx convex deploy --typecheck disable

Why this works where other scripts fail:

When you use a custom fetch script to send files, you're just sending raw text. The server has no idea where convex/server is.

The CLI is smarter. It uses esbuild to "bundle" your code into a single, self-contained JavaScript package. It finds all your imports and bakes them right into the file so the server can run them instantly.


5. Pro Tip: Automate Everything

Don't type those long variables every time. Add a script to your convex/package.json:

"scripts": {
  "deploy": "CONVEX_SELF_HOSTED_URL=... CONVEX_SELF_HOSTED_ADMIN_KEY=... npx convex deploy --typecheck disable"
}

Now, all it takes is a simple:

npm run deploy

Troubleshooting common "Gotchas"

"Relative import path 'convex/server' not found"

If you see this, you likely bypassed the CLI. Always use npx convex deploy so the bundler can do its job!

"BadAdminKey"

Double-check your key. Most people forget the convex-self-hosted| prefix. Without it, the server will reject your request every time.

Missing _generated files in your frontend

Run npx convex codegen while your CONVEX_SELF_HOSTED_URL is set to update your local TypeScript types to match what you just deployed.


Happy hosting! Your Convex backend is now truly yours.

🔥 Join developers growing publicly
Share your knowledge, build in public, and grow your developer presence with a global community.

More Posts

Cavity on X-Ray: A Complete Guide to Detection and Diagnosis

Huifer - Feb 12

The Issues of Deploying Laravel on Dokploy: Database Connection Hell

JoeyOkello - Aug 3

The Sovereign Vault — A Comprehensive Guide to Protocol-Driven AI

Ken W. Algerverified - Jun 4

Sovereign Intelligence: The Complete 25,000 Word Blueprint (Download)

Pocket Portfolio - Apr 1

Can You See a Failed Root Canal on X-Ray? Complete Guide

Huifer - Feb 15
chevron_left
151 Points8 Badges
Nairobi
2Posts
0Comments
Fullstack developer || Mobile Developer

Related Jobs

Commenters (This Week)

2 comments
1 comment

Contribute meaningful comments to climb the leaderboard and earn badges!