Skip to main content
Mission Control provides production-ready Docker images with multi-stage builds, native SQLite compilation, and minimal attack surface.

Quick Start

1

Build the image

The Dockerfile uses a multi-stage build:
  • Stage 1 (deps): Installs dependencies and compiles native modules
  • Stage 2 (build): Builds Next.js production bundle
  • Stage 3 (runtime): Minimal runtime image with only production artifacts
2

Run the container

The container runs as non-root user nextjs (UID 1001) for security.
3

Access the dashboard

Open http://localhost:3000 and login with your configured credentials.

Docker Compose

For persistent deployments, use Docker Compose:
Start the stack:
View logs:
Stop the stack:

Dockerfile Architecture

The production Dockerfile (39 lines) implements security and efficiency best practices:

Stage 1: Dependencies

Key features:
  • Uses node:20-slim for minimal base image
  • Installs build tools (python3, make, g++) for better-sqlite3 native compilation
  • Handles missing lockfile gracefully with warning
  • Cleans up apt cache to reduce layer size

Stage 2: Build

Builds Next.js with standalone output (configured in next.config.js).

Stage 3: Runtime

Security features:
  • Runs as non-root user nextjs (UID 1001)
  • Only includes runtime artifacts (no source code, build tools, or dev dependencies)
  • Pre-creates .data directory with correct ownership
  • Includes health check for orchestration platforms
  • Installs only curl for health checks

Persistent Data

Mission Control stores all state in SQLite under /app/.data/ inside the container:
  • mission-control.db - Main database
  • mission-control-tokens.json - Token storage
  • Logs and temporary files
Always mount a volume to /app/.data to persist data across container restarts:
Without a volume, all data will be lost when the container is removed.

Volume Backup

Back up the SQLite database:

Volume Restore

Configuration

Pass environment variables via:
  1. Command line:
  2. Env file:
  3. Docker Compose:
See Environment Variables for the complete reference.

Port Configuration

The container exposes port 3000 by default. Override with the PORT environment variable:
The HOSTNAME is set to 0.0.0.0 in the Dockerfile to accept connections from all interfaces inside the container.

Health Checks

The image includes a built-in health check that queries /login every 30 seconds:
Check health status:

Production Checklist

1

Set secure credentials

2

Configure host access control

See Security for details.
3

Enable secure cookies

Required when serving over HTTPS.
4

Mount persistent volume

5

Configure restart policy

Or in Docker Compose:
6

Set up backups

Schedule regular backups of the /app/.data volume.

Troubleshooting

”pnpm-lock.yaml not found” warning

The Dockerfile gracefully handles missing lockfiles by falling back to pnpm install --no-frozen-lockfile. For reproducible builds, include pnpm-lock.yaml in your build context.

Permission denied on .data directory

The container runs as user nextjs (UID 1001). If mounting a host directory:

Database locked errors

Ensure only one container is running against the same volume:
SQLite uses WAL mode but does not support multiple writers.

Invalid ELF header

Native binaries are compiled for Linux x64 inside the container. Do not build on macOS and deploy on Linux or vice versa. Always build the Docker image on the target platform or use multi-arch builds.