Skip to content

Enhance docs with DevContainer guide #84

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
109 changes: 109 additions & 0 deletions self-hosted/devcontainer/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
# Running Convex in a DevContainer for Local Development

If you're working with Convex and want to use a consistent, container-based development environment, this guide provides a minimal setup using [DevContainers](https://containers.dev/) and Docker.

> [!IMPORTANT]
> This approach is meant for **local development** and is not intended for self-hosting Convex in production.

## What is a DevContainer?

A DevContainer is a development environment defined as code and backed by a Docker container. It integrates tightly with Visual Studio Code through the [Dev Containers extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers).

When you open a project with a `.devcontainer/devcontainer.json` file, VS Code automatically builds the container, installs dependencies, and mounts your project directory inside it.

This setup is especially useful for teams, open source contributors, or anyone who wants to avoid dependency drift between local machines.

## Why use a DevContainer?

- Reproducible local environment with no host machine setup required
- Isolated from other projects and host system
- Preconfigured runtimes, dependencies, tools and extensions (e.g., Node.js, pnpm, Convex CLI)
- Easy onboarding for new team members or contributors

## Requirements

To use a DevContainer, you need to have the following installed:

- [Docker](https://www.docker.com/products/docker-desktop)
- [Visual Studio Code](https://code.visualstudio.com/)
- [Dev Containers extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers)

## Minimal DevContainer Example for Convex

The following is a minimal example of a working `.devcontainer/devcontainer.json` setup using a Node.js/TypeScript base image. It binds the necessary Convex and pnpm directories, and explicitly forwards the required ports:

```jsonc
{
"name": "convex-dev",
"image": "mcr.microsoft.com/devcontainers/typescript-node:1-22-bookworm",
"workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}",

"postCreateCommand": "npm install -g convex && npx convex dev --once",
"postAttachCommand": "git config --global diff.ool ...",
"postStartCommand": "git config --global --add safe.directory /workspaces/${localWorkspaceFolderBasename}",

"mounts": [
"source=${localEnv:HOME}/.ssh,target=/home/node/.ssh,type=bind,consistency=cached",
"source=${localEnv:HOME}/.convex,target=/home/node/.convex,type=bind,consistency=cached",
"source=${localEnv:HOME}/.cache/convex,target=/home/node/.cache,type=bind,consistency=cached"
],

"remoteUser": "node",
"forwardPorts": [3210, 6790, 6791]
}
```

You can adapt the image, remote user, or mounted paths depending on your project needs or base OS image.

### Explanation of the Configuration

This minimal setup includes just a few customizations that are important for Convex to run reliably inside a containerized environment.

#### `.convex` mount

```json
"mounts": [
"source=${localEnv:HOME}/.convex,target=/home/node/.convex,type=bind"
]
```

Convex stores some local state in the `.convex` directory (such as deployment metadata and generated admin keys). Mounting it from your host machine into the container ensures that:

- The state is preserved across container rebuilds.
- You can reuse the same identity and credentials inside and outside the container.

Without this mount, Convex might behave as if it's being run for the first time every time you restart the container.

#### `.cache/convex` mount

```json
"source=${localEnv:HOME}/.cache/convex,target=/home/node/.cache,type=bind,consistency=cached"
```

During `pnpm convex dev`, the Convex CLI downloads necessary artifacts such as backend binaries and the dashboard frontend into the `.cache/convex` directory. By mounting this directory from the host into the container, those files are persisted between container rebuilds and restarts.

This avoids re-downloading the same artifacts every time the container is recreated, which speeds up startup and reduces bandwidth usage.

#### Forwarded ports

```json
"forwardPorts": [3210, 6790, 6791]
```

Convex uses these ports during local development:

- `3210` — the API server
- `6790` — the web dashboard
- `6791` — the internal health check used by the dashboard to determine if a local deployment is available

Forwarding these ports ensures that the services running inside the container are accessible from your host machine and from the dashboard itself.

#### `postCreateCommand`

```json
"postCreateCommand": "npx convex dev --once"
```

This command ensures the Convex development server is started as soon as the container is ready. The `--once` flag runs the server in one-off mode, avoiding watch mode or automatic restarts.

This is useful for initial setup to verify everything is working, but you can always stop it and run `pnpm convex dev` manually when actively working on your functions.
29 changes: 29 additions & 0 deletions self-hosted/devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
// README at: https://github.com/devcontainers/templates/tree/main/src/typescript-node
{
"name": "convex-dev",

// Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
"image": "mcr.microsoft.com/devcontainers/typescript-node:1-22-bookworm",
"workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}",

// Lifecycle events
"postCreateCommand": "npm install -g convex && npx convex dev --once",
"postAttachCommand": "git config --global diff.ool ...",
"postStartCommand": "git config --global --add safe.directory /workspaces/${localWorkspaceFolderBasename}",

"mounts": [
"source=${localEnv:HOME}/.ssh,target=/home/node/.ssh,type=bind,consistency=cached",
"source=${localEnv:HOME}/.convex,target=/home/node/.convex,type=bind,consistency=cached",
"source=${localEnv:HOME}/.cache/convex,target=/home/node/.cache,type=bind,consistency=cached"
],

// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
"remoteUser": "node",

// Use 'forwardPorts' to make a list of ports inside the container available locally.
"forwardPorts": [3210, 6790, 6791],

// Configure tool-specific properties.
"customizations": {}
}