---
title: Deploy with Docker Compose
description: Deploy OpenPanel using Docker Compose on your own server
---
import { Step, Steps } from 'fumadocs-ui/components/steps';
import { Callout } from 'fumadocs-ui/components/callout';
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 and Node will be installed automatically if needed)
- At least 2GB RAM (4GB+ recommended)
- Domain name pointing to your server (optional but recommended)
- Basic knowledge of command line
🙋♂️ This should work on any system. The setup script will install Docker and Node if they're not already installed.
## Quick Start
### Clone the Repository
Clone the OpenPanel repository and navigate to the self-hosting directory:
```bash
git clone -b self-hosting https://github.com/Openpanel-dev/openpanel.git
cd openpanel/self-hosting
```
### Run the Setup Script
The setup script will guide you through the configuration process. It will:
1. Install Node.js (if you accept and it's not already installed)
2. Install Docker (if you accept and it's not already installed)
3. Run an interactive quiz/wizard that asks questions about your setup
> Setup takes 30s to 2 minutes depending on your VPS
```bash
./setup
```
The wizard will ask you questions about:
- Your domain name
- Database configuration
- Email settings (optional)
- AI integration (optional)
- Registration settings
⚠️ If the `./setup` script fails to run, you can do it manually:
1. Install Docker
2. Install Node.js
3. Install npm
4. Run `npm run quiz` inside the self-hosting folder
### Start the Services
After the setup is complete, start all OpenPanel services:
```bash
./start
```
This will start all required services:
- **op-db**: PostgreSQL database
- **op-kv**: Redis cache
- **op-ch**: ClickHouse analytics database
- **op-api**: OpenPanel API server
- **op-dashboard**: OpenPanel dashboard (frontend)
- **op-worker**: Background worker for processing events
### Verify Installation
Check that all containers are running:
```bash
docker compose ps
```
All services should show as "healthy" or "running". You can also check the logs:
```bash
docker compose logs -f
```
Or use the provided logs script:
```bash
./logs
```
Once all services are healthy, you can access OpenPanel at your configured domain (or `http://your-server-ip` if you haven't configured a domain).
## Configuration
### Environment Variables
The setup wizard will configure most environment variables automatically. You can manually edit the `.env` file in the `self-hosting` directory if needed.
For a complete reference of all available environment variables, see the [Environment Variables documentation](/docs/self-hosting/environment-variables).
If you change the `.env` file, you need to restart the services for the changes to take effect. Use `./stop` and `./start` or `docker compose restart`.
### Using Custom Docker Images
If you want to use specific image versions, edit the `docker-compose.yml` file and update the image tags:
```yaml
op-api:
image: lindesvard/openpanel-api:v1.0.0 # Specify version
```
### Scaling Workers
To scale the worker service, set the `OP_WORKER_REPLICAS` environment variable:
```bash
OP_WORKER_REPLICAS=3 docker compose up -d
```
Or edit the `docker-compose.yml` file:
```yaml
op-worker:
deploy:
replicas: 3
```
## Managing Your Deployment
OpenPanel comes with several utility scripts to help manage your deployment. All scripts should be run from within the `self-hosting` directory.
### Basic Operations
```bash
./start # Start all OpenPanel services
./stop # Stop all OpenPanel services
./logs # View real-time logs from all services
```
### View Logs
View logs from all services:
```bash
./logs
```
Or using Docker Compose directly:
```bash
docker compose logs -f
```
View logs from a specific service:
```bash
docker compose logs -f op-api
```
### Stop Services
Stop all services:
```bash
./stop
```
Or using Docker Compose:
```bash
docker compose down
```
Stop services but keep volumes (data persists):
```bash
docker compose stop
```
### Restart Services
Restart all services:
```bash
./stop && ./start
```
Or using Docker Compose:
```bash
docker compose restart
```
Restart a specific service:
```bash
docker compose restart op-api
```
### Rebuild Services
Rebuild and restart a specific service:
```bash
./rebuild op-dashboard
```
### Update OpenPanel
To update to the latest version, use the update script:
```bash
./update
```
This script will:
1. Pull the latest changes from the repository
2. Pull the latest Docker images
3. Restart all services
If you don't have the `./update` script, you can manually update:
```bash
git pull
docker compose pull
docker compose up -d
```
Always backup your data before updating. The database migrations will run automatically when the API container starts. Also read any changes in the [changelog](/docs/self-hosting/changelog) and apply them to your instance.
### Backup and Restore
#### Backup
Backup your PostgreSQL database:
```bash
docker compose exec op-db pg_dump -U postgres postgres > backup.sql
```
Backup volumes:
```bash
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:
```bash
docker compose exec -T op-db psql -U postgres postgres < backup.sql
```
## Troubleshooting
### Services Won't Start
1. Check Docker and Docker Compose versions:
```bash
docker --version
docker compose version
```
2. Check available disk space:
```bash
df -h
```
3. Check logs for errors:
```bash
docker compose logs
```
### Database Connection Issues
If services can't connect to the database:
1. Verify the database is healthy:
```bash
docker compose ps op-db
```
2. Check database logs:
```bash
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`:
```yaml
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:
```bash
docker compose ps
```
2. Increase health check timeout in `docker-compose.yml`:
```yaml
healthcheck:
interval: 30s
timeout: 10s
retries: 10
```
## Using Your Own Reverse Proxy
If you're using your own reverse proxy (like Nginx or Traefik), you can disable the included Caddy proxy by commenting it out in `docker-compose.yml`:
```yaml
# op-proxy:
# image: caddy:2-alpine
# ...
```
Then configure your reverse proxy to forward requests:
- `/api/*` → `op-api:3000`
- `/*` → `op-dashboard:3000`
## Next Steps
- [Configure email settings](/docs/self-hosting/self-hosting#e-mail) for password resets and invitations
- [Set up AI integration](/docs/self-hosting/self-hosting#ai-integration) for the analytics assistant
- [Configure SDK](/docs/self-hosting/self-hosting#always-use-correct-api-url) to track events from your applications