Files
WGDashboard/docker
Giuseppe Marinelli 90614a6360
Some checks are pending
Docker Build and Push / docker_build (push) Waiting to run
Docker Build and Push / docker_scan (push) Blocked by required conditions
Refactor peer schedule job API to use proper REST verbs (#1239)
* Fixed quotation marks

* Update wgd.sh

* Refactor peer schedule job API to use proper REST verbs

Replace single POST endpoints with POST/PUT/DELETE for peer schedule jobs.
Add require_fields decorator for request validation. Add fetchPut and
fetchDelete helpers in the frontend.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Add local development with Docker section to docker/README.md

Explains how to mount src/ as a volume for live code editing
using a compose-local.yaml setup.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Update README dev section with frontend build instructions

Replace Vite dev server tip with npm install/build workflow
and docker restart step.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Donald Zou <donaldzou@live.hk>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-22 20:30:19 +02:00
..

WGDashboard Docker Explanation:

Author: @DaanSelen

This document delves into how the WGDashboard Docker container has been built.
Of course there are two stages (simply said), one before run-time and one at/after run-time.
The Dockerfile describes how the container image is made, and the entrypoint.sh is executed after the container is started.
In this example, WireGuard is integrated into the container itself, so it should be a run-and-go(/out-of-the-box) experience.
For more details on the source-code specific to this Docker image, refer to the source files, they have lots of comments.


WG-Dashboard Logo

To get the container running you either pull the pre-made image from a remote repository, there are 2 official options.

  • ghcr.io/wgdashboard/wgdashboard:
  • docker.io/donaldzou/wgdashboard:

tags should be either: latest, main, , (if built) or .

From there either use the environment variables described below as parameters or use the Docker Compose file: compose.yaml.
Be careful, the default generated WireGuard configuration file uses port 51820/udp. So make sure to use this port if you want to use it out of the box.
Otherwise edit the configuration file in WGDashboard under Configuration Settings -> Edit Raw Configuration File.

Otherwise you need to enter the container and edit: /etc/wireguard/wg0.conf.

WGDashboard: 🐳 Docker Deployment Guide

To run the container, you can either pull the image from the Github Container Registry (ghcr.io), Docker Hub (docker.io) or build it yourself. The image is available at:

docker.io is in most cases automatically resolved by the Docker application. Therefor you can ofter specify: donaldzou/wgdashboard:latest

🔧 Quick Docker Run Command

Here's an example to get it up and running quickly:

docker run -d \
  --name wgdashboard \
  --restart unless-stopped \
  -p 10086:10086/tcp \
  -p 51820:51820/udp \
  --cap-add NET_ADMIN \
  ghcr.io/wgdashboard/wgdashboard:latest

⚠️ The default WireGuard port is 51820/udp. If you change this, update the /etc/wireguard/wg0.conf accordingly.


📦 Docker Compose Alternative (see the compose file)

You can also use Docker Compose for easier configuration:

services:
  wgdashboard:
    image: ghcr.io/wgdashboard/wgdashboard:latest
    restart: unless-stopped
    container_name: wgdashboard
    ports:
      - 10086:10086/tcp
      - 51820:51820/udp

    volumes:
      - aconf:/etc/amnezia/amneziawg
      - conf:/etc/wireguard
      - data:/data

    cap_add:
      - NET_ADMIN

volumes:
  aconf:
  conf:
  data:

📁 You can customize the volume paths on the host to fit your needs. The example above uses Docker volumes.


🔄 Updating the Container

Updating the WGDashboard container should be through 'The Docker Way' - by pulling the newest/newer image and replacing this old one.


⚙️ Environment Variables

Variable Accepted Values Default Example Description
dynamic_config true, yes, false, no true true or no Turns on or off the dynamic configuration feature, on by default for Docker
tz Timezone Europe/Amsterdam America/New_York Sets the container's timezone. Useful for accurate logs and scheduling.
global_dns IPv4 and IPv6 addresses 9.9.9.9 8.8.8.8, 1.1.1.1 Default DNS for WireGuard clients.
public_ip Public IP address Retrieved automatically 253.162.134.73 Used to generate accurate client configs. Needed if container is NATd.
wgd_port Any port that is allowed for the process 10086 443 This port is used to set the WGDashboard web port.
username Any nonempty string - admin Username for the WGDashboard web interface account.
password Any nonempty string - s3cr3tP@ss Password for the WGDashboard web interface account (stored hashed).
enable_totp true, false true false Enable TOTPbased twofactor authentication for the account.
wg_autostart Wireguard interface name false true Autostart the WireGuard client when the container launches.
email_server SMTP server address - smtp.gmail.com SMTP server for sending email notifications.
email_port SMTP port number - 587 Port for connecting to the SMTP server.
email_encryption TLS, SSL, etc. - TLS Encryption method for email communication.
email_username Any non-empty string - user@example.com Username for SMTP authentication.
email_password Any non-empty string - app_password Password for SMTP authentication.
email_from Valid email address - noreply@example.com Email address used as the sender for notifications.
email_template Path to template file - your-template Custom template for email notifications.
database_type sqlite, postgresql, mariadb+mariadbconnector, etc. - postgresql Type of sqlalchemy database engine.
database_host Any non-empty string - localhost IP-Address or hostname of the SQL-database server.
database_port Any non-empty string (or int for port) - 5432 Port for the database communication.
database_username Valid database username - database_user Database user username.
database_password Valid database password - database_password Database user password.

🔐 Port Forwarding Note

When using multiple WireGuard interfaces, remember to open their respective ports on the host.

Examples:

# Individual mapping
- 51821:51821/udp

# Or port range
- 51820-51830:51820-51830/udp

🚨 Security Tip: Only expose ports you actually use.


🛠️ Building the Image Yourself

To build from source:

git clone https://github.com/WGDashboard/WGDashboard.git
cd WGDashboard
docker build . -f docker/Dockerfile -t yourname/wgdashboard:latest

Example output:

docker images

REPOSITORY           TAG       IMAGE ID       CREATED             SIZE
yourname/wgdashboard latest    c96fd96ee3b3   42 minutes ago      314MB

🧱 Dockerfile Overview

Here's a brief overview of the Dockerfile stages used in the image build:

1. Build Tools & Go Compilation

FROM golang:1.24 AS compiler
WORKDIR /go

RUN apt-get update && apt-get install -y ...
RUN git clone ... && make
...

2. Binary Copy to Scratch

FROM scratch AS bins
COPY --from=compiler /go/amneziawg-go/amneziawg-go /amneziawg-go
...

3. Final Alpine Container Setup

FROM alpine:latest
COPY --from=bins ...
RUN apk update && apk add --no-cache ...
COPY ./src ${WGDASH}/src
COPY ./docker/entrypoint.sh /entrypoint.sh
...
EXPOSE 10086
ENTRYPOINT ["/bin/bash", "/entrypoint.sh"]

🚀 Entrypoint Overview

Major Functions:

  • ensure_installation: Sets up the app, database, and Python environment.
  • set_envvars: Writes wg-dashboard.ini and applies environment variables.
  • start_core: Starts the main WGDashboard service.
  • ensure_blocking: Tails the error log to keep the container process alive.

Final Notes

  • Use docker logs wgdashboard for troubleshooting.
  • Access the web interface via http://your-ip:10086 (or whichever port you specified in the compose).
  • The first time run will auto-generate WireGuard keys and configs (configs are generated from the template).

🧑‍💻 Local Development with Docker

You can develop against WGDashboard locally by mounting the src/ directory into the container. This lets you edit Python and frontend code on your host and see changes reflected immediately (with a service restart for Python).

Create a docker/compose-local.yaml alongside the existing compose.yaml:

services:
  wgdashboard:
    image: ghcr.io/wgdashboard/wgdashboard:latest
    restart: unless-stopped
    container_name: wgdashboard

    ports:
      - 10086:10086/tcp
      - 51820:51820/udp

    volumes:
      - aconf:/etc/amnezia/amneziawg
      - conf:/etc/wireguard
      - data:/data
      # Mount local src for live editing
      - ../src:/opt/wgdashboard/src
      # Keep venv in a named volume so it isn't overwritten by the mount
      - venv:/opt/wgdashboard/src/venv

    cap_add:
      - NET_ADMIN

volumes:
  aconf:
  conf:
  data:
  venv:

The key additions compared to the production compose file:

  • ../src:/opt/wgdashboard/src — mounts your local src/ directory into the container so code changes are reflected without rebuilding the image.
  • venv:/opt/wgdashboard/src/venv — keeps the Python virtual environment in a named Docker volume. Without this, the host mount would overwrite the venv created during image build.

To start the development container:

cd docker
docker compose -f compose-local.yaml up -d

After editing Python files (e.g. src/dashboard.py), restart the container to pick up changes:

docker restart wgdashboard

For frontend changes, install dependencies and rebuild the Vue app on your host:

cd src/static/app
npm install
npm run build

Then restart the container so it serves the updated dist files:

docker restart wgdashboard

Closing remarks:

For feedback please submit an issue to the repository. Or message dselen@nerthus.nl.