OpenPanel

Deploy with Docker Compose

Deploy OpenPanel using Docker Compose on your own server

This guide will help you deploy OpenPanel using Docker Compose. This method gives you full control over your deployment and is perfect for self-hosting on a VPS or dedicated server.

Prerequisites

  • A VPS or server. Docker is checked for automatically, and on Linux the CLI offers to install it.
  • At least 4GB RAM (6GB+ recommended) โ€” the stack includes Redpanda alongside Postgres, Redis and ClickHouse
  • Domain name pointing to your server (optional but recommended)
  • Basic knowledge of command line

๐Ÿ™‹โ€โ™‚๏ธ This works on any Linux server (x64 or arm64) that can run Docker. You don't need Node, npm or git.

Quick Start

Install the CLI

curl -fsSL https://raw.githubusercontent.com/Openpanel-dev/openpanel/main/self-hosting/install.sh | sh

This downloads a single openpanel binary, verifies its checksum and puts it on your PATH. Builds for Linux (x64 and arm64) are also on the releases page.

Run the setup

openpanel init

It checks your host (Docker, Docker Compose, memory), then asks about:

  • Your domain name
  • Whether to run Postgres, ClickHouse and Redis for you, or connect your own
  • Whether to use the bundled Caddy (automatic HTTPS) or your own reverse proxy
  • Email (optional)

Secrets, the worker count and the queue-dashboard password are generated. It writes docker-compose.yml, .env and the supporting config files to ~/openpanel (use --dir <path> to change that) and prints the queue-dashboard password once.

For unattended setups every answer is a flag, e.g. openpanel init --yes --domain https://analytics.example.com. Run openpanel --help to see them.

Start the Services

openpanel up

This will start all required services:

  • op-db: PostgreSQL database
  • op-kv: Redis cache
  • op-ch: ClickHouse analytics database
  • op-rp: Redpanda (Kafka-compatible event broker, see Event Streaming)
  • op-api: OpenPanel API server
  • op-dashboard: OpenPanel dashboard (frontend)
  • op-worker: Background worker for processing events
  • op-proxy: Caddy reverse proxy, unless you chose your own

Verify Installation

openpanel status

All services should show as "healthy" or "running". To watch the logs:

openpanel logs

Once all services are healthy, you can access OpenPanel at your configured domain.

Configuration

Environment Variables

openpanel init configures most environment variables for you. You can edit the .env file in your install directory if needed.

For a complete reference of all available environment variables, see the Environment Variables documentation.

Changed the .env file? run openpanel reload. It checks the file for mistakes first, then recreates only the services whose settings changed; your databases keep running. A plain docker compose restart is not enough: it restarts containers with their old environment.

The generated .env also contains commented-out blocks for optional features. Uncomment and fill them in to enable social login with Google or GitHub and the Google Search Console integration.

Docker Image Versions

Each CLI release is built for one OpenPanel image tag, and openpanel upgrade moves the lindesvard/openpanel-* images in your docker-compose.yml to it, including a version you pinned yourself. The compose changes an upgrade makes only work with the images they were released for. To stay on a version, don't run upgrade. Images from other registries are left alone.

Scaling Workers

The worker count is set in docker-compose.yml as ${OP_WORKER_REPLICAS:-N}, where N is what init chose. Override it by adding a line to .env, then apply it:

.env
OP_WORKER_REPLICAS=3
openpanel up

Managing Your Deployment

Run these anywhere: the CLI finds your install (the current directory, ./self-hosting in an old git clone, the last install it used, or a running OpenPanel stack) and prints which one it picked. Pass --dir <path> to choose explicitly.

Basic Operations

openpanel up        # Start all OpenPanel services
openpanel down      # Stop all OpenPanel services (data is kept)
openpanel reload    # Apply changes to .env or docker-compose.yml
openpanel restart   # Recreate every container (a full restart)
openpanel logs      # Follow logs from all services
openpanel status    # Show running services

View Logs

openpanel logs            # all services
openpanel logs op-api     # one service

Check Your Setup

openpanel doctor

Checks that Docker is running and has enough memory, and that your docker-compose.yml and .env match what this version expects. openpanel doctor --fix repairs what it can and keeps the originals as <file>.bak.

Update OpenPanel

openpanel upgrade

This will:

  1. Update the CLI itself, after verifying its checksum
  2. Run the doctor checks and offer to fix your docker-compose.yml and .env for the new version
  3. Pull the latest Docker images
  4. Restart the services

Always backup your data before updating. The database migrations will run automatically when the API container starts. Also read any changes in the changelog.

Start Over

openpanel reset

Deletes this install's data volumes after you type the directory name to confirm. docker-compose.yml, .env and Caddy's HTTPS certificates are kept, so a fresh start does not re-request certificates.

Backup and Restore

Backup

Backup your PostgreSQL database:

docker compose exec op-db pg_dump -U postgres postgres > backup.sql

Backup volumes:

docker run --rm -v openpanel_op-db-data:/data -v $(pwd):/backup alpine tar czf /backup/db-backup.tar.gz /data

Restore

Restore PostgreSQL database:

docker compose exec -T op-db psql -U postgres postgres < backup.sql

Troubleshooting

Services Won't Start

  1. Check Docker and Docker Compose versions:

    docker --version
    docker compose version
  2. Check available disk space:

    df -h
  3. Check logs for errors:

    docker compose logs

Database Connection Issues

If services can't connect to the database:

  1. Verify the database is healthy:

    docker compose ps op-db
  2. Check database logs:

    docker compose logs op-db
  3. Verify DATABASE_URL in your .env file matches the service name op-db

Port Conflicts

If ports 80 or 443 are already in use, you can:

  1. Change the ports in docker-compose.yml:

    ports:
      - "8080:80"
      - "8443:443"
  2. Or stop the conflicting service

Health Check Failures

If health checks are failing:

  1. Check if services are actually running:

    docker compose ps
  2. Increase health check timeout in docker-compose.yml:

    healthcheck:
      interval: 30s
      timeout: 10s
      retries: 10

Using Your Own Reverse Proxy

If you want to use NGINX, Traefik, or another reverse proxy instead of the bundled Caddy โ€” or put a TLS terminator upstream of Caddy โ€” see the dedicated Reverse proxy setup guide. It covers the working NGINX config, the Connection: upgrade SSR-break gotcha, and the WebSocket upgrade headers required for the Realtime view.

Next Steps

On this page