Learn how to set up your own WireGuard VPN server and easily manage it via the web-based WireGuard-UI using Docker Compose.
- Step 1: Ensure You Have Docker and Docker Compose Installed
- Step 2: Set Up WireGuard VPN Server & WireGuard-UI with Docker Compose
- Step 3: Run the Containers with Docker Compose
- Step 4: Configure the WireGuard VPN Server Using WireGuard-UI
- Step 5: Configure the WireGuard VPN Server
- Step 6: Create a New WireGuard Client
- Step 7: Setting Up WireGuard Client
Protecting online privacy and security has become increasingly important in the digital age. A virtual private network (VPN) can help you achieve this by encrypting your internet traffic and routing it through a private network, making it more difficult for anyone to intercept your data.
WireGuard is a relatively new VPN protocol that has gained popularity for its reliability, simplicity, speed, and security. However, setting it up can often be a complicated process. For example, here’s how to do it on Ubuntu.
That’s where WireGuard-UI, a web-based user interface for WireGuard that makes it easier to configure and manage your VPN server, comes in. And to make things even easier, Docker Compose gives you an easy way to integrate both.
This article will explore how to set up a WireGuard VPN and WireGuard-UI with Docker Compose, making it simpler for you to configure and manage your VPN server and clients. By the end of this guide, you’ll have a fully functional VPN running on Docker containers with an easy-to-use web-based management interface.
So without further ado, let’s get to work.
Step 1: Ensure You Have Docker and Docker Compose Installed
Docker is a platform for creating and running applications in lightweight containers, which makes deploying and managing software much more effortless.
At the same time, Docker Compose, which you can think of as an add-on to Docker, is a tool used for defining and running multi-container Docker applications, which is precisely our case.
In other words, we will deploy the WireGuard VPN server and WireGuard-UI, a web-based user interface for WireGuard, “packaged” as a single application using Docker Compose.
The first step is to ensure you have Docker installed on your machine. The easiest way to do this is by running:
If you receive a message like the one above, all is well. You have Docker installed on your system.
However, if you get something like “bash: docker: command not found…” in response, there’s no room for worry. We’ve got you covered, and our detailed guides on installing Docker on Ubuntu, Debian, Linux Mint, Fedora, AlmaLinux, and Rocky Linux will help you get it up and running on your system quickly and easily.
The next step is to ensure that Docker Compose is also installed on your system. Similar to the above example, run:
If the command output is similar, congratulations! You have everything you need to install the WireGuard VPN server with the WireGuard-UI web interface by using Docker Compose.
However, if the message is something like “bash: docker-compose: command not found…” just run the two commands below, and you will have Docker Compose installed on your system in seconds.
sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-linux-$(uname -m)" -o /usr/local/bin/docker-compose sudo chmod +x /usr/local/bin/docker-compose
In addition, if you want an in-depth introduction to Docker Compose, check out our comprehensive guide.
Step 2: Set Up WireGuard VPN Server & WireGuard-UI with Docker Compose
As we already said, Docker Compose allows you to build and run stacks of multiple containers. To use it, you must first create a “docker-compose.yaml” file that configures the containers for your application.
Create a “wireguard” directory and switch to it.
mkdir wireguard cd wireguard
Then, using your preferred text editor, create a file named “docker-compose.yaml”:
Add the following content to it, then save and exit the file.
version: "3" services: # WireGuard VPN service wireguard: image: linuxserver/wireguard:latest container_name: wireguard cap_add: - NET_ADMIN volumes: - ./config:/config ports: # Port for WireGuard-UI - "5000:5000" # Port of the WireGuard VPN server - "51820:51820/udp" # WireGuard-UI service wireguard-ui: image: ngoduykhanh/wireguard-ui:latest container_name: wireguard-ui depends_on: - wireguard cap_add: - NET_ADMIN # Use the network of the 'wireguard' service # This enables to show active clients in the status page network_mode: service:wireguard environment: - SENDGRID_API_KEY - EMAIL_FROM_ADDRESS - EMAIL_FROM_NAME - SESSION_SECRET - WGUI_USERNAME=admin - WGUI_PASSWORD=password - WG_CONF_TEMPLATE - WGUI_MANAGE_START=true - WGUI_MANAGE_RESTART=true logging: driver: json-file options: max-size: 50m volumes: - ./db:/app/db - ./config:/etc/wireguard
Remember to change the values of the “WGUI_USERNAME” and “WGUI_PASSWORD” environment variables in the file above to the username and password you will use to access WireGuard-UI.
In addition, it is essential to note that the Docker volumes containing the WireGurard configuration settings (“./db” and “./config “) will be created and made available in the current “wireguard” directory. Modify the YAML file if you decide you want them somewhere else. For example, “/srv/my-wireguard-conf:/etc/wireguard.”
However, if you do this, change the Docker volumes in both the “wireguard” and “wireguard-ui” service parts. This is a must, as the WireGuard-UI must have access to the WireGuard VPN server configurations to manage it.
Step 3: Run the Containers with Docker Compose
Finally, we are ready to run WireGuard VPN Server and WireGuard-UI using Docker Compose. To do this, execute the below-given command from the current “wireguard” directory where the “docker-compose.yaml” file is located.
Start and run the containers in the background:
docker-compose up -d
The images will start downloading, and Docker Compose will begin to make its magic. The entire procedure will take less than a minute. In the end, you should see a screen similar to the one below, informing you that all containers have been successfully created and started.
Of course, the initial delay before the start of the WireGuard and WireGuard-UI containers will be a one-off, as Docker needs to download the images from the internet first.
All subsequent runs will take seconds since the required Docker images will already be available locally on your Linux system.
Step 4: Configure the WireGuard VPN Server Using WireGuard-UI
You can now open your browser and navigate to “http://server-ip-address.” The WireGuard-UI login page will greet you.
Enter the username and password you set in the “docker-compose.yaml” file via the “WGUI_USERNAME” and “WGUI_PASSWORD” environment variables, then hit the “Sign In” button.
And here is the moment to provide an essential, if not critical, clarification. This guide uses an unencrypted HTTP connection to access the WireGuard-UI. We only do this because it is a virtual machine in our testing lab that we created exclusively for this tutorial for demonstration purposes, after which we will delete it.
Always use only a secured HTTPS connection in your production environment to access the WireGuard-UI management interface. You can ensure this by putting a reverse proxy service in front of the WireGuard-UI with the ability to automatically generate for you free Let’s Encrypt SSL certificates, such as Caddy.
On top of that, if you want to make things even more “techy,” you can bet on using Traefik, an open-source container-focused reverse proxy service that also automatically issues SSL certificates. We use it frequently in our production systems and can confidently say it performs flawlessly.
Step 5: Configure the WireGuard VPN Server
The fun begins here, but don’t worry; we’ll walk you through it smoothly.
To start, switch to the “Wireguard Server” tab. Then in the “Post Up Script” field, put:
iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
And respectively in “Post Down Script“:
iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
In short, this enables packets to and from your WireGuard server to be routed using Network Address Translation (NAT) inside the Docker’s WireGuard container. We won’t go into detail about it because it is outside the scope of this guide.
Then click the “Save” button to save your changes, and finally, hit “Apply Config” to apply them to the WireGuard VPN server.
You will be asked if you want the changes to be applied and the WireGuard server restarted. Confirm by clicking the “Apply” button.
Go to the “Global Settings” tab and carefully review the information. Your public IP address should be entered in the “Endpoint Address” section. WireGuard-UI will try to find it and fill it in automatically. However, if it fails, you must enter the correct one.
If you need help figuring out your public IP address, our guide on the subject will greatly help.
By default, the system sets the DNS server to “188.8.131.52,” which works great. However, change it in the “DNS Server” field if you want to use a different one.
Of course, if you make any changes, remember to apply them by clicking on the “Save” button and then hitting “Apply Config.”
Step 6: Create a New WireGuard Client
To create a new client that will connect to the WireGuard server to establish a VPN connection, click on the “New Client” button in the upper right corner of the WireGuard-UI.
This opens a modal window, where I recommend you enter only the client name and email and leave the other options as they are by default. I’m convinced you understand what you’re doing if you change them.
Finally, click the “Submit” button to add the client to the WireGuard VPN server.
The WireGuard-UI will do all of the work in the background to generate the necessary public and private keys to enable the VPN connection for the client, as well as automatically set some options related to routing its traffic, the DNS server used, and the internal private IP address it will receive when connecting to the WireGuard server.
If you’re nevertheless curious about what things look like “from the source,” you can look at the final result, which is stored as a JSON file in the “clients” directory of the Docker “db” volume.
Attention! Never edit this file directly; only through the WireGuard-UI interface provided.
Finally, we want to emphasize something significant. It is essential to remember that whatever changes you make to users, always complete the operations with the “Apply Config” button. Otherwise, your changes will be saved but not applied to the WireGuard VPN server, which may lead you to believe that things aren’t working correctly.
Step 7: Setting Up WireGuard Client
We come to the most exciting part, where we will see the results of our efforts so far – configuring the client part and connecting it to the WireGuard VPN server.
Switch to the “Wireguard Clients” to see currently available ones.
From here on, the approach is now specific as to whether we will make an encrypted VPN connection to the server from a mobile device such as a phone or tablet or a desktop workstation, laptop, etc. We will consider both cases.
Connecting to WireGuard from Linux PC using Network Manager
To get the client’s WireGuard configuration file, click the “Download” button on the respective profile. This action will download a file with the name you assigned to the account through WireGuard-UI and the extension “.conf.”
Rename the file to a short and recognizable name without spaces or special characters in it. For example, “vpn-home.conf.” Then import it using
nmcli, a NetworkManager CLI tool, by running the following:
nmcli connection import type wireguard file vpn-home.conf
If you now go and look at the available network connections on your Linux system, you will see that our new WireGuard VPN connection is added and ready to use.
Click on it to activate it.
Send a ping from your desktop (WireGuard client) machine to the WireGuard server’s private network address to ensure everything works properly.
ping -c 3 10.252.1.0
And this is where you have every reason to congratulate yourself because your WireGuard VPN tunnel works as expected!
If you return to the WureGuard-UI and select the “Status” tab, you should see your current active VPN connection there.
Connecting to WireGuard from Mobile Device
Things are considerably easier when you need to connect your mobile device to the WireGuard VPN server. Then, you need to download the official WireGuard client for your operating system: iOS users should go to Apple’s App Store, while Android users should go to Google’s Play Store.
After installing the app on your mobile device, from the WireGuard-UI, click on the corresponding user’s “QR Code” button, which will display the QR code containing all of the information required to import the WireGuard’s VPN profile.
Next, open the WireGuard app on your mobile device, choose “Add a tunnel,” then “Create from QR code,” scan the code from the monitor screen, and that’s it. The profile will be imported automatically.
Then, switch on the profile, and your device will connect to the WireGuard VPN server.
With its modern cryptography, simplicity, and high-performance capabilities, WireGuard has quickly become a popular choice for VPN solutions. Learning how to set up your own WireGuard VPN server and easily manage it via the web-based WireGuard-UI using Docker Compose can benefit individuals and businesses.
First, this can improve your online security and privacy by adding an extra layer of protection when browsing the internet. On top of that, this way, you can also access geographically restricted content and protect your personal and confidential information from potential hackers and cybercriminals.
Setting up may initially seem daunting, but following our detailed guide makes the process smooth and hassle-free. Thank you for using it! Any opinions and comments are most welcome in the section below.