Skip to main content
Get your self-hosted Convex instance running quickly with Docker.

Prerequisites

Quick start

1

Download docker-compose.yml

Create a new directory and download the Docker Compose configuration:
mkdir convex-backend && cd convex-backend
curl -O https://raw.githubusercontent.com/get-convex/convex-backend/main/self-hosted/docker/docker-compose.yml
Or create a docker-compose.yml file with this content:
docker-compose.yml
version: '3.8'
services:
  backend:
    image: ghcr.io/get-convex/convex-backend:latest
    ports:
      - "3210:3210"  # Backend
      - "3211:3211"  # HTTP actions
    environment:
      - CONVEX_SITE_PROXY=http://dashboard:5173
    volumes:
      - convex-data:/data
  
  dashboard:
    image: ghcr.io/get-convex/convex-dashboard:latest
    ports:
      - "6791:5173"
    environment:
      - VITE_SELF_HOSTED_URL=http://localhost:3210

volumes:
  convex-data:
2

Start the services

Launch the backend and dashboard:
docker compose up
Wait for both services to start. You should see logs indicating the backend is ready.
3

Generate an admin key

In a new terminal, generate an admin key for the CLI:
docker compose exec backend ./generate_admin_key.sh
Save the generated admin key - you’ll need it in the next step.
4

Configure your environment

Create a .env.local file in your Convex project directory:
.env.local
CONVEX_SELF_HOSTED_URL=http://127.0.0.1:3210
CONVEX_SELF_HOSTED_ADMIN_KEY=your-admin-key-here
Never commit this file to version control. Add it to your .gitignore.
5

Install the Convex CLI

Install the latest Convex CLI in your project:
npm install convex@latest
6

Deploy your functions

Start the development server to deploy your Convex functions:
npx convex dev
This will:
  • Push your schema and functions to the backend
  • Generate TypeScript types
  • Watch for changes and hot-reload
7

Access the dashboard

Open your browser and navigate to:
http://localhost:6791
You can view your tables, run queries, and monitor your deployment.

Verify your setup

Create a simple function to test your setup. In your convex/ directory, create messages.ts:
convex/messages.ts
import { query, mutation } from "./_generated/server";
import { v } from "convex/values";

export const list = query({
  handler: async (ctx) => {
    return await ctx.db.query("messages").collect();
  },
});

export const send = mutation({
  args: { body: v.string(), author: v.string() },
  handler: async (ctx, { body, author }) => {
    await ctx.db.insert("messages", { body, author });
  },
});
Run the mutation from your app or the dashboard:
const messageId = await convex.mutation(api.messages.send, {
  body: "Hello, Convex!",
  author: "Test User"
});

What’s next?

Configure your database

Set up PostgreSQL or MySQL for production

Configure storage

Use S3-compatible storage for files

Explore features

Learn about database operations and queries

Build from source

Compile the backend yourself

Troubleshooting

Check that ports 3210 and 3211 are not already in use:
lsof -i :3210
lsof -i :3211
Stop any conflicting services or change the ports in docker-compose.yml.
Verify the backend is running:
curl http://localhost:3210/version
If this fails, check the Docker logs:
docker compose logs backend
Regenerate the admin key:
docker compose exec backend ./generate_admin_key.sh
Update your .env.local file with the new key.

Support

For self-hosting questions:

Build docs developers (and LLMs) love