Build Your Own Secure VPN

Deploy a WireGuard VPN server as a container on ALPON X5 AI or ALPON X4 through ALPON Cloud: generate client keys, build and push the server image, deploy it with Host Network and Privileged enabled, configure the client, and test the tunnel with a sample Nginx container.

Deploy a WireGuard VPN on ALPON

Turn your ALPON X5 AI or ALPON X4 into a private WireGuard VPN server. Whether you are securing your internet connection or creating a private network for remote access, this guide walks you through everything — from generating client keys and building the server container to deploying it through ALPON Cloud and connecting your devices.

ALPON X5 AI ALPON X4 WireGuard VPN
ALPON · Tutorial · Containers · Networking
How do I deploy a WireGuard VPN on ALPON?

Generate a WireGuard key pair and pre-shared key on the client, build the private-network server image from the Dockerfile in this guide and push it to your Sixfab Container Registry, then use the Applications → Deploy panel on ALPON Cloud to launch it on your ALPON X5 AI or ALPON X4 with the CLIENT_PUBLIC_KEY and CLIENT_PSK environment variables, Host Network, and Privileged enabled. Read the server's public key from the container shell, write it into client.conf, and connect from the WireGuard app on port 22222.

Overview

WireGuard is a fast, modern VPN protocol with a small, auditable code base. Running it as a container on an ALPON X5 AI or ALPON X4 gives you a powerful and flexible VPN endpoint on your own network: the client generates its own keys and configuration, while the server container uses the keys you pass in as environment variables to establish the tunnel.

The steps below are identical on ALPON X4 and ALPON X5 AI. For protocol details and client apps, see the official WireGuard documentation.

Before you start

You need an ALPON X5 AI or ALPON X4 registered on ALPON Cloud, and Docker installed on your build machine to build and push the image — grab it from the official Docker website if you don't have it yet. New to container deployment? Start with Containerize Apps for ALPON.

Forward a port on your router: if your ALPON is behind a router (like most home setups), forward port 22222 from your router to the ALPON. Check your router's manual for instructions — this makes the VPN reachable from outside your network.

Set up a domain name: to reach your VPN from outside, you need a domain name or a dynamic DNS (DynDNS) service so the connection keeps working when your public IP address changes. Popular options are DuckDNS and No-IP.

Reserved subnets

Avoid using the subnets 100.0.0.0/16 and 10.42.0.0/24 for your VPN, as these are reserved for the ALPON's default applications. This guide uses custom subnets instead to keep things running smoothly.

  1. 1

    Generate your client keys

    The client creates its own private key, public key, and pre-shared key (PSK). Follow the instructions for your operating system; whichever you use, you end up with the same three files.

    For Linux users

    Install the WireGuard tools, then generate the private and public keys and the pre-shared key:

    bash · Linux
    # Install WireGuard tools
    sudo apt-get update
    sudo apt-get install wireguard-tools
    
    # Generate private key and public key
    
    wg genkey | tee client-private.key | wg pubkey > client-public.key
    
    # Generate pre-shared key (PSK)
    
    wg genpsk > client.psk

    For macOS users

    Install the WireGuard tools with Homebrew (a macOS package manager), then run the same key commands:

    zsh · macOS
    # Install WireGuard tools
    brew install wireguard-tools
    
    # Generate private key and public key
    
    wg genkey | tee client-private.key | wg pubkey > client-public.key
    
    # Generate pre-shared key (PSK)
    
    wg genpsk > client.psk

    For Windows users

    Windows doesn't support the WireGuard tools directly in the command line, but you have two easy options.

    Option 1 — use the WireGuard app. Download and install the Windows application from the WireGuard official website, then open a command prompt and run:

    cmd · Windows
    :: Generate private key and public key
    wg genkey > client-private.key
    type client-private.key | wg pubkey > client-public.key
    
    :: Generate pre-shared key (PSK)
    
    wg genpsk > client.psk

    Option 2 — use WSL (Windows Subsystem for Linux). If you prefer, install WSL and follow the Linux steps above.

    What you'll have

    • client-private.key: the client's private key (keep it safe!).
    • client-public.key: the client's public key (share this with the server).
    • client.psk: the pre-shared key (PSK).
  2. 2

    Add the WireGuard server container

    Now configure the ALPON as your VPN server using a container. The Dockerfile below sets up a WireGuard server that generates its own key pair at build time and reads the client's public key (CLIENT_PUBLIC_KEY) and pre-shared key (CLIENT_PSK) from environment variables. Save it as Dockerfile:

    Dockerfile
    FROM alpine:latest
    
    RUN apk update && apk add wireguard-tools wireguard-tools-wg-quick bash gettext
    RUN mkdir -p /etc/wireguard
    WORKDIR /etc/wireguard
    RUN umask 077
    
    # Generate server keys
    RUN wg genkey | tee server.key | wg pubkey > server.pub
    
    # Create WireGuard server configuration template
    RUN echo "[Interface]" > /etc/wireguard/wg0.conf.template && \\
        echo "Address = 10.200.0.1/24, fd09:4722::1/64" >> /etc/wireguard/wg0.conf.template && \\
        echo "ListenPort = 22222" >> /etc/wireguard/wg0.conf.template && \\
        echo "PrivateKey = $(cat server.key)" >> /etc/wireguard/wg0.conf.template && \\
        echo "[Peer]" >> /etc/wireguard/wg0.conf.template && \\
        echo "PublicKey = \\${CLIENT_PUBLIC_KEY}" >> /etc/wireguard/wg0.conf.template && \\
        echo "PresharedKey = \\${CLIENT_PSK}" >> /etc/wireguard/wg0.conf.template && \\
        echo "AllowedIPs = 10.200.0.2/32, fd09:4722::2/128" >> /etc/wireguard/wg0.conf.template
    
    # Set the command to generate the config and start WireGuard
    CMD sh -c "envsubst < /etc/wireguard/wg0.conf.template > /etc/wireguard/wg0.conf && \\
               wg-quick up /etc/wireguard/wg0.conf && \\
               sleep infinity"

    Open a terminal on your computer, navigate to the folder with your Dockerfile, and build the arm64 image:

    bash · build the image
    docker buildx build --platform linux/arm64 -t private-network:latest ./

    Then log in to Sixfab Registry, click + Add Container, and follow the prompts to push the image.

    Pushing images to the Sixfab Container Registry

    For the full walkthrough of tagging and pushing an image, see Update Containers from the Sixfab Container Registry and the Deploy Applications page.

  3. 3

    Deploy the container on ALPON

    Once the image is in the Sixfab Container Registry, open your device in ALPON Cloud, go to the Applications section, and click + Deploy. In the Deploy Container window, use these settings:

    Container Name private-network
    Image The private-network image and tag you pushed to the Sixfab Container Registry.
    Environment Click + Add More and add the two variables in the table below with your client's values from step 1.
    Enable Host Network Turn this on.
    Privileged Turn this on so the container can create the wg0 interface.
    KeyValue
    CLIENT_PUBLIC_KEYContents of client-public.key
    CLIENT_PSKContents of client.psk

    Click + Deploy to start the WireGuard server on the device.

  4. 4

    Get the server's public key

    After the private-network container is deployed, open its shell from ALPON Cloud using the shell button shown below.

    ALPON Cloud Applications section with the shell button for the private-network container highlighted
    The container shell button in the Applications section of ALPON Cloud.

    In the container shell, print the server's public key and copy the output — this is your server-public-key:

    container shell · private-network
    cat server.pub
  5. 5

    Configure your client

    The client needs its own configuration file, client.conf, built from the server's public key and the pre-shared key. Here is an example configuration:

    client.conf
    [Interface]
    Address = 10.200.0.2/32, fd09:4722::2/128
    DNS = 1.1.1.1
    PrivateKey = <client-private-key>
    
    [Peer]
    PublicKey = <server-public-key>
    PresharedKey = <client-psk>
    AllowedIPs = 10.200.0.1/32, fd09:4722::1/128
    Endpoint = <your-public-ip-or-domain>:22222
    PersistentKeepalive = 25

    Replace the following placeholders:

    • <client-private-key>: the client's private key (from client-private.key).
    • <server-public-key>: the server's public key (from server.pub inside the container).
    • <client-psk>: the pre-shared key (from client.psk).
    • <your-public-ip-or-domain>: the public IP or domain of the server.
  6. 6

    Connect to your VPN

    Import the config. On the client device, open the WireGuard app, click + → Import from file, and select client.conf.

    Activate the VPN. In the WireGuard app, toggle the switch to connect, then verify the connection by checking the status in the app.

  7. 7

    Test your connection

    Make sure everything works by deploying a simple Nginx server on the ALPON and reaching it through the tunnel. In the Applications section, click + Deploy and use these settings:

    Container Name nginx-test
    Image Turn on “I would like to use my own container path” and enter nginx:latest.
    Ports Click + Add More and add the port mapping in the table below.
    FromTo
    3108080

    Click Deploy to start the application, then open the server's VPN address in a browser on the connected client:

    browser · Nginx over the VPN
    http://10.200.0.1:31080

    If the client is connected successfully, the Nginx welcome screen appears in your browser.

Troubleshooting: container crashes and wg0 already exists

If the container crashes or is restarted, it may fail with RTNETLINK answers: File exists because the wg0 interface is still defined on the host. This happens when the container is stopped abruptly and the interface is not cleaned up. To resolve it, delete the interface manually on the ALPON:

bash · on the ALPON
sudo ip link del wg0
Ready when…
  • The private-network container shows as running in the Applications section.
  • The WireGuard app on the client reports the tunnel as connected.
  • The Nginx welcome page loads at http://10.200.0.1:31080 from the client.

You now have a private VPN running inside a container on the ALPON. The client handles its own key generation and configuration, while the server uses the provided keys to establish the connection. For further assistance, refer to the WireGuard documentation.

Production image policy: Replace floating :latest references with a reviewed immutable tag or digest, then record the selected version for rollback.


Did this page help you?