---
title: "CloudPanel as Reverse Proxy: Docker & Dockge Setup Guide"
description: "Set up CloudPanel as a reverse proxy for Docker with Dockge. Step-by-step guide with Nginx vhost config, SSL, firewall rules, and security hardening."
date: 2026-07-23
categories: ["hosting"]
tags: ["cloudpanel","dockge","docker"]
---

import Button from "../../components/widgets/Button.astro";
import { Picture } from "astro:assets";
import YouTubeEmbed from "../../components/widgets/YouTubeEmbed.astro";
import Notice from "../../components/widgets/Notice.astro";
import ListCheck from "../../components/widgets/ListCheck.astro";
import Accordion from "../../components/widgets/Accordion.astro";
import Tabs from "../../components/widgets/Tabs.astro";
import Tab from "../../components/widgets/Tab.astro";
import imag1 from "../../assets/images/24/02/cp-add-proxy-1.png";
import imag2 from "../../assets/images/24/02/cp-add-proxy-2.png";
import imag3 from "../../assets/images/24/02/cp-open-ports.png";
import imag4 from "../../assets/images/24/01/dockge-add.png";

[CloudPanel](https://www.cloudpanel.io/) is a lightweight hosting panel that handles PHP, Node.js, and Python apps. Its reverse proxy feature lets you route traffic to Docker containers running on the same VPS. Pair it with [Dockge](/dockge-install/), a [Dockge Docker compose manager](/dockge-install/) for organizing and deploying your Docker stacks, and you get one server that handles both traditional hosted sites and containerized apps.

If you only need a reverse proxy for Docker containers, tools like Nginx Proxy Manager or Traefik are simpler. But if you also want to host PHP or Node.js sites alongside Docker, CloudPanel is a solid fit. There are also other [self-hosted server panels](/best-self-hosted-panels/) worth comparing.

<Notice type="info" title="Tested with">
CloudPanel CE v2.5.3 · Dockge v1.5.0 · Docker 29.x · Ubuntu 24.04 LTS
</Notice>

<YouTubeEmbed
  url="https://www.youtube.com/embed/BuoyvbDVBe0"
  label="Setup CloudPanel As Reverse Proxy with Docker and Dockge"
/>

## 1. Prerequisites

Before you start, make sure you have:

<ListCheck>
<ul>
<li>A VPS running Ubuntu 24.04 LTS (or Ubuntu 22.04, Debian 12)</li>
<li>Minimum 1 core, 2 GB RAM, 10 GB disk</li>
<li>A domain name with DNS access (Cloudflare, Hetzner DNS, etc.)</li>
<li>SSH access to the server</li>
</ul>
</ListCheck>

Both ARM and x86_64 servers are supported.

## 2. Create a VPS server

I recommend [Hetzner](https://go.bitdoze.com/hetzner) for EU-based hosting (good price-to-performance ratio). [Hostinger](https://go.bitdoze.com/hostinger-vps) is a solid budget KVM option. For global presence, DigitalOcean and Vultr work fine. For more details check this [Hetzner Review](https://www.wpdoze.com/hetzner-cloud-review/) and you can check also: [DigitalOcean vs Vultr vs Hetzner](https://www.wpdoze.com/digitalocean-vs-vultr-vs-hetzner/)

<Button link="https://go.bitdoze.com/do" text="DigitalOcean $100 Free" />
<Button link="https://go.bitdoze.com/vultr" text="Vultr $100 Free" />
<Button link="https://go.bitdoze.com/hetzner" text="Hetzner €⁠20 Free" />
<Button link="https://go.bitdoze.com/hostinger-vps" text="Hostinger VPS" />

Ubuntu 24.04 LTS is the recommended OS for new deployments.

## 3. Update the VPS server

Always update before installing anything:

```bash
apt update && apt -y upgrade && apt -y install curl wget sudo
```

Verify the OS version:

```bash
cat /etc/os-release
```

You should see `VERSION_ID="24.04"` (or `22.04` / `12` for Debian).

## 4. Install CloudPanel

> I have also created a course that will help you get going with CloudPanel if you are a beginner, check **[CloudPanel Setup Course](https://webdoze.net/courses/cloudpanel-setup/)**

CloudPanel supports multiple database engines. Pick the one you prefer:

<Tabs>
<Tab name="MariaDB 10.11">
```bash
curl -sS https://installer.cloudpanel.io/ce/v2/install.sh -o install.sh; \
echo "6eac061df80f08b75224fcd7fce2f115e201696d8a6122e31abf7259a813b462 install.sh" | \
sha256sum -c && sudo CLOUD=hetzner DB_ENGINE=MARIADB_10.11 bash install.sh
```
</Tab>
<Tab name="MySQL 8.4">
```bash
curl -sS https://installer.cloudpanel.io/ce/v2/install.sh -o install.sh; \
echo "6eac061df80f08b75224fcd7fce2f115e201696d8a6122e31abf7259a813b462 install.sh" | \
sha256sum -c && sudo CLOUD=hetzner DB_ENGINE=MYSQL_8.4 bash install.sh
```
</Tab>
</Tabs>

<Notice type="warning" title="Installer checksum changes">
The installer checksum changes with each CloudPanel release. If verification fails, grab the latest checksum from the [official install docs](https://www.cloudpanel.io/docs/v2/getting-started/other/).
</Notice>

Replace `CLOUD=hetzner` with your provider (or remove it for generic installs). Available database engines: `MARIADB_10.11`, `MARIADB_11.4`, `MYSQL_8.0`, `MYSQL_8.4`. Installation takes about 5-10 minutes.

CloudPanel supports PHP, Node.js, and Python sites. If you need to [host Node.js apps with CloudPanel](/install-cloudpanel-host-nodejs/), the same install works.

**Verify:**

```bash
systemctl status cloudpanel
```

The service should show `active (running)`. You can access the admin at `https://serverIP:8443`.

**If checksum fails:** the installer script was updated since publication. Fetch the latest from [CloudPanel install docs](https://www.cloudpanel.io/docs/v2/getting-started/other/).

## 5. Secure CloudPanel immediately

<Notice type="error" title="Do this within minutes of install">
CloudPanel has had multiple security issues, including privilege escalation bugs patched in v2.5.0-v2.5.2. CVE-2025-15241 (open redirect in the admin panel) was fixed in v2.5.2. Unpatched instances are easy targets for bots. Three things you must do immediately after install.
</Notice>

**1. Create the admin account now.** Bots scan for unconfigured CloudPanel instances and can create the admin user before you do. Open `https://serverIP:8443` and set up your admin account within minutes.

**2. Restrict port 8443 to your IP.** Use CloudPanel's firewall or UFW from the command line:

```bash
# Allow 8443 only from your IP (replace with your actual IP)
ufw allow from YOUR_IP_ADDRESS to any port 8443
ufw deny 8443
```

Or do this through CloudPanel admin: **Admin Area > Security > Add Rule** to whitelist your IP on port 8443.

**3. Update CloudPanel to the latest version:**

```bash
clp-update
```

This patches CVE-2025-15241 (open redirect in `/admin/users` via Referer header manipulation) and privilege escalation vulnerabilities fixed in v2.5.0-v2.5.2.

**Verify:**

```bash
clp-version
```

Should show v2.5.2 or later.

For comprehensive hardening, see how to [secure your CloudPanel server](/secure-cloudpanel/) and [keep CloudPanel updated](/safely-update-cloudpanel/) regularly.

## 6. Create an admin subdomain

To access CloudPanel behind a proper domain with SSL, create a DNS A record for a subdomain (e.g., `panel.example.com`) pointing to your server IP. If you use Cloudflare, the proxy (orange cloud) works fine here.

Then add the subdomain in CloudPanel admin under **Settings** to secure the admin area.

**Verify:** Visit `https://panel.example.com`. You should see the CloudPanel login page with a valid SSL certificate.

## 7. Install Docker and Docker Compose

The old Docker install method (hardcoding `jammy` in the apt source) breaks on Ubuntu 24.04. Use the current official method with dynamic codename detection:

<Notice type="info" title="Works on Ubuntu 22.04 and 24.04">
This method detects your Ubuntu version automatically. No need to hardcode the release name.
</Notice>

```bash
sudo apt update
sudo apt install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

sudo tee /etc/apt/sources.list.d/docker.sources <<EOF
Types: deb
URIs: https://download.docker.com/linux/ubuntu
Suites: $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}")
Components: stable
Architectures: $(dpkg --print-architecture)
Signed-By: /etc/apt/keyrings/docker.asc
EOF

sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
```

For a full reference of Docker commands, check [essential Docker commands](/docker-commands/). Everything is also explained in the [install Docker on Ubuntu](/install-docker-ubuntu-arm/) guide.

**Verify:**

```bash
sudo docker run hello-world
sudo systemctl status docker
docker compose version
```

`docker compose version` should print something like `Docker Compose version v2.x.x`. If it fails, you likely installed the deprecated standalone `docker-compose` instead of `docker-compose-plugin`.

**Failure mode:** If `docker compose` is not found, remove the old standalone package and install the plugin:

```bash
sudo apt remove docker-compose
sudo apt install docker-compose-plugin
```

## 8. Install Dockge

Dockge will be installed under a CloudPanel site's `htdocs` directory. The advantage: CloudPanel's rClone backups automatically capture Dockge and all your Docker stacks together. The tradeoff: Dockge's official recommendation is `/opt/stacks` and `/opt/dockge`. Both approaches work. The htdocs approach gives you backup coupling with CloudPanel, while `/opt/stacks` keeps things in standard paths.

> If you have CloudPanel external backup activated you will backup all the apps and Dockge at once. See [CloudPanel remote backups](/cloudpanel-remote-backups/) for setup.

<Notice type="info" title="Dockge is actively maintained">
After a quiet period (the maintainer prioritized Uptime Kuma 2.0), Dockge v1.5.0 was released in March 2025 with security fixes including the disabled-by-default console. The project has 23k+ GitHub stars and is not abandoned.
</Notice>

### 8.1 Create a reverse proxy site in CloudPanel

Under **Sites > Add Site** choose **Create a Reverse Proxy**.

<Picture src={imag1} alt="CloudPanel Create a Reverse Proxy" />

Add the domain you want to use for Dockge, create a user with a password, and set the port. I use port `5000` (host) which maps to Dockge's internal port `5001`. You can customize this.

<Picture src={imag2} alt="CloudPanel Create a Reverse Proxy" />

### 8.2 Create directories for Dockge

SSH into your server and navigate to the CloudPanel site directory:

```sh
cd /home/<user>/htdocs/<website>/
# Example:
cd /home/bitdoze-dockge/htdocs/dockge.bitdoze.com/
```

Replace `<user>` and `<website>` with the values from step 8.1.

Create the directories:

```sh
mkdir dockge-stacks
mkdir dockge
```

- **dockge**: Dockge's own data and compose file
- **dockge-stacks**: where all your Docker app stacks will live

<Notice type="info" title="Backup advantage">
Storing stacks under CloudPanel's htdocs means CloudPanel's rClone backups include all your Docker apps automatically. If you prefer Dockge's official `/opt/stacks` layout, adjust the volume mounts in the compose file accordingly.
</Notice>

### 8.3 Deploy Dockge with Docker Compose

Create a `compose.yaml` file inside the `dockge` directory:

```yaml
services:
  dockge:
    image: louislam/dockge:1
    restart: unless-stopped
    ports:
      - 5000:5001  # Host:Container, customize host port as needed
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - ./data:/app/data
      - /home/<user>/htdocs/<website>/dockge-stacks:/home/<user>/htdocs/<website>/dockge-stacks
    environment:
      # Tell Dockge where to find the stacks
      - DOCKGE_STACKS_DIR=/home/<user>/htdocs/<website>/dockge-stacks
      # Set file ownership for stack files (optional but recommended)
      # - PUID=1000
      # - PGID=1000
      # Console is disabled by default since v1.5.0 for security.
      # Enable only if you understand the risk:
      # - DOCKGE_ENABLE_CONSOLE=true
```

Replace the paths and port with your actual values. Here is a concrete example:

```yaml
services:
  dockge:
    image: louislam/dockge:1
    restart: unless-stopped
    ports:
      - 5000:5001
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - ./data:/app/data
      - /home/bitdoze-dockge/htdocs/dockge.bitdoze.com/dockge-stacks:/home/bitdoze-dockge/htdocs/dockge.bitdoze.com/dockge-stacks
    environment:
      - DOCKGE_STACKS_DIR=/home/bitdoze-dockge/htdocs/dockge.bitdoze.com/dockge-stacks
```

[Dockge Compose Generator](https://dockge.kuma.pet/) can help you create the exact compose file.

<Notice type="warning" title="Dockge v1.5.0 disabled the web console by default">
The embedded terminal (Console) is now disabled by default for security reasons. To re-enable it, add `DOCKGE_ENABLE_CONSOLE=true` to the environment section. Only enable if you understand the risk. Compose editing works fine without it.
</Notice>

Start Dockge:

```sh
cd /home/<user>/htdocs/<website>/dockge
docker compose up -d
```

**Verify:**

```sh
docker compose ps
curl -I http://localhost:5001
```

The container should show `running` and curl should return `HTTP/1.1 200 OK`.

### 8.4 Point domain to Dockge

In your DNS provider, create an A record for the Dockge subdomain (e.g., `dockge.example.com`) pointing to your server IP.

### 8.5 Create an SSL certificate

In CloudPanel, go to **Sites > Manage Site > SSL/TLS** and generate a Let's Encrypt certificate.

**Verify:** Visit `https://dockge.example.com`. You should see the Dockge UI with a padlock in your browser.

Note: CloudPanel v2.5.0 fixed a bug where the `.well-known` directory was deleted during SSL renewal. If you had issues with certificate renewal on older versions, updating CloudPanel should resolve it.

### 8.6 Access Dockge and create admin user

The first time you access Dockge you will be prompted to create a username and password. Do this immediately.

### 8.7 Open CloudPanel firewall ports

CloudPanel's firewall blocks most ports by default (only 22, 80, 443, 8443 are open). If you need direct port access for Docker apps that aren't routed through CloudPanel's reverse proxy, open the port ranges:

Go to **Admin Area > Security > Add Rule** and open the ranges you need:

<Picture src={imag3} alt="CloudPanel Port Open" />

This is optional if all your apps go through CloudPanel's reverse proxy (which is the recommended approach).

## 9. Secure the reverse proxy configuration

CloudPanel's default reverse proxy config uses `try_files $uri @reverse_proxy;`, which can expose stack files like `.env` and other secrets. The enhanced config below fixes that, plus adds WebSocket support and proper proxy headers.

### 9.1 Enhanced Nginx proxy configuration

In CloudPanel, go to **Sites > Select your site > Vhost Editor**. Replace the default proxy block with:

```nginx
location / {
  proxy_pass {{reverse_proxy_url}};
  proxy_http_version 1.1;
  proxy_set_header X-Forwarded-Host $host;
  proxy_set_header X-Forwarded-Server $host;
  proxy_set_header X-Real-IP $remote_addr;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header X-Forwarded-Proto $scheme;
  proxy_set_header Host $http_host;
  proxy_set_header Upgrade $http_upgrade;
  proxy_set_header Connection "Upgrade";
  proxy_pass_request_headers on;
  proxy_max_temp_file_size 0;
  proxy_connect_timeout 900;
  proxy_send_timeout 900;
  proxy_read_timeout 900;
  proxy_buffer_size 128k;
  proxy_buffers 4 256k;
  proxy_busy_buffers_size 256k;
  proxy_temp_file_write_size 256k;
}
```

Key headers explained:

- **`X-Forwarded-Proto $scheme`**: tells the backend app whether the original request came over HTTP or HTTPS. Without this, apps behind CloudPanel's HTTPS may generate insecure links.
- **`Upgrade` / `Connection "Upgrade"`**: enables WebSocket support for real-time apps (chat, live dashboards, Dockge's own UI updates).
- The buffer and timeout settings prevent issues with large uploads and long-running connections.

<Notice type="info" title="Why this matters">
With the default config, files inside your Dockge stack directories (like `.env` files with database passwords) can be accessed directly through the browser. This enhanced config routes all requests through the reverse proxy, preventing direct file access.
</Notice>

### 9.2 Protect sensitive files

For an extra layer of protection, add this block to your Vhost configuration:

```nginx
# Protect sensitive files
location ~* \.(php|sql|log|config|env)$ {
    deny all;
}
```

This blocks direct access to files with extensions like `.php`, `.sql`, `.log`, `.config`, and `.env` which often contain credentials or configuration data.

### 9.3 Add basic authentication

For an additional security layer on your Dockge or app sites:

1. Go to CloudPanel admin
2. Navigate to **Sites > Select your site > Security**
3. Add a username and password for basic authentication

Users will be prompted for credentials before accessing the application.

## 10. Deploy your first app

Now you are set. Access Dockge and start deploying apps.

<Picture src={imag4} alt="Dockge Add Compose" />

Below are some apps you can deploy on Dockge:

- [Install Umami Analytics](/umami-analytics-install/)
- [Install Outline Wiki](/outline-install/)
- [Slash Install](/slash-docker-deploy/)

For each app, the workflow is:

1. **Create a Reverse Proxy in CloudPanel**: same as you did for Dockge, create a site as a Reverse Proxy with the domain and port for the app
2. **Point the domain to the server**: add an A record in your DNS provider
3. **Create an SSL certificate**: go to CloudPanel under **Sites > Manage Site > SSL/TLS** and generate a Let's Encrypt certificate

## 11. Backups

Set up backups before deploying production apps, not after.

Activate CloudPanel's rClone external backups to S3, Dropbox, Google Drive, or any remote storage. Go to **Admin Area > Backups** and configure the rClone integration.

If your stacks are stored under the `htdocs` directory (the approach in this guide), they are included automatically in CloudPanel backups. If you use `/opt/stacks`, you need a separate backup strategy.

See [CloudPanel remote backups](/cloudpanel-remote-backups/) for detailed setup.

If you are on Hetzner, you can also enable Hetzner snapshots for server-level backups.

> I have also created a course that will help you get going with CloudPanel if you are a beginner, check **[CloudPanel Setup Course](https://webdoze.net/courses/cloudpanel-setup/)**

## 12. Troubleshooting

<Accordion label="Checksum verification fails during CloudPanel install" group="troubleshooting" expanded="true">
The installer script and checksum change with each CloudPanel release. If verification fails, re-fetch the latest checksum from the [CloudPanel install docs](https://www.cloudpanel.io/docs/v2/getting-started/other/) and replace it in the install command.
</Accordion>

<Accordion label="Docker daemon not starting after install" group="troubleshooting">
Check for conflicting packages from Ubuntu's default repository:

```bash
sudo systemctl status docker
```

If Docker won't start, remove the conflicting `docker.io` package:

```bash
sudo apt remove docker.io
sudo systemctl start docker
sudo systemctl enable docker
```

Verify: `sudo docker run hello-world`
</Accordion>

<Accordion label="Dockge not accessible via domain" group="troubleshooting">
Check these in order:

1. DNS propagated: `dig +short yourdomain.com` should return your server IP
2. CloudPanel firewall has the port open (if using direct port access)
3. Dockge container is running: `docker compose ps`
4. Port mapping in compose.yaml matches the port in CloudPanel's reverse proxy config
5. SSL certificate is issued: check under **Sites > Manage Site > SSL/TLS**
</Accordion>

<Accordion label="SSL certificate fails to issue" group="troubleshooting">
- DNS must be fully propagated before requesting a certificate (check with `dig`)
- The `.well-known` directory must be accessible from the internet
- If using Cloudflare with the proxy enabled (orange cloud), disable it temporarily for certificate issuance, then re-enable
- CloudPanel v2.5.0 fixed a bug where `.well-known` was deleted during renewal. Make sure you are on the latest version.
</Accordion>

<Accordion label="Dockge stacks showing as 'not managed' after upgrade" group="troubleshooting">
Verify the `DOCKGE_STACKS_DIR` environment variable in your compose.yaml matches the actual path where your stacks live. Then restart Dockge:

```bash
docker compose restart
```
</Accordion>

<Accordion label="Bots created the admin account before me" group="troubleshooting">
This happens when port 8443 is open to the world and you delay creating the admin account. There are two options:

1. If you haven't set anything up yet: reinstall CloudPanel and create the admin account within minutes
2. If you need to recover: restrict port 8443 to your IP immediately, then check CloudPanel's recovery options in their docs

See Section 5 for how to prevent this.
</Accordion>

## 13. Alternatives to CloudPanel + Dockge

This setup works well when you need PHP/Node.js sites alongside Docker containers on the same VPS. But if your workload is purely Docker-based, there are simpler options:

| Stack | Best for | Tradeoff |
|-------|----------|----------|
| **CloudPanel + Dockge** (this guide) | PHP/Node sites + Docker on same VPS | Closed-source panel; security track record needs attention |
| **Dokploy** | Docker-native apps with built-in reverse proxy | No PHP/Node hosting outside Docker |
| **Coolify** | Full PaaS replacement for both | Heavier resource usage |
| **Nginx Proxy Manager** | Simple reverse proxy only | No site management, no file manager |

If you are evaluating Docker management tools specifically, check [Portainer alternatives like Dockge](/portainer-alternatives/) for a deeper comparison. For a broader look at panels, see the [self-hosted server panels](/best-self-hosted-panels/) comparison.

## FAQ

<Accordion label="Can I use CloudPanel with Docker on ARM servers?" group="faq" expanded="true">
Yes, both CloudPanel and Dockge support ARM and x86_64. Use Ubuntu 24.04 ARM64 on providers like Hetzner (CAX instances) or Oracle Cloud free tier.
</Accordion>

<Accordion label="Why not just use Nginx Proxy Manager or Traefik instead of CloudPanel?" group="faq">
CloudPanel gives you a file manager, PHP/Node.js hosting, database management, cron jobs, and firewall in addition to reverse proxy. If you only need reverse proxy for Docker apps, Nginx Proxy Manager or Traefik are simpler with fewer moving parts. If you also host PHP sites, CloudPanel is the better fit.
</Accordion>

<Accordion label="Is it safe to run Docker alongside CloudPanel?" group="faq">
Yes, but keep CloudPanel updated with `clp-update`. CloudPanel manages Nginx on the host; Docker containers run in isolation. The main risk is unpatched CloudPanel instances, not the Docker co-existence itself.
</Accordion>

<Accordion label="How do I update Dockge?" group="faq">
Navigate to the Dockge compose directory and pull the latest image:

```bash
cd /home/<user>/htdocs/<website>/dockge
docker compose pull
docker compose up -d
```

Dockge will show an update notification in the UI when a new version is available.
</Accordion>

<Accordion label="Does CloudPanel backup include my Docker stacks?" group="faq">
Only if you store stacks under CloudPanel's htdocs directory (the approach in this guide). If you use `/opt/stacks`, you need a separate backup strategy for your Docker data.
</Accordion>