mirror of
https://github.com/h44z/wg-portal.git
synced 2025-06-28 09:17:00 +00:00
83 lines
36 KiB
HTML
83 lines
36 KiB
HTML
<!doctype html><html lang=en class=no-js> <head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1"><meta name=description content="Manage WireGuard Peers and Interface using a beautiful and simple web UI."><link href=https://wgportal.org/v2.0.3/documentation/getting-started/docker/ rel=canonical><link href=../binaries/ rel=prev><link href=../helm/ rel=next><link rel=icon href=../../../assets/images/favicon-large.png><meta name=generator content="mkdocs-1.6.1, mkdocs-material-9.6.14"><title>Docker - WireGuard Portal</title><link rel=stylesheet href=../../../assets/stylesheets/main.342714a4.min.css><link rel=stylesheet href=../../../assets/stylesheets/palette.06af60db.min.css><link rel=stylesheet href=../../../stylesheets/extra.css><script>__md_scope=new URL("../../..",location),__md_hash=e=>[...e].reduce(((e,_)=>(e<<5)-e+_.charCodeAt(0)),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+"."+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+"."+e,JSON.stringify(_))}catch(e){}}</script><meta property=og:type content=website><meta property=og:title content="Docker - WireGuard Portal"><meta property=og:description content="Manage WireGuard Peers and Interface using a beautiful and simple web UI."><meta property=og:image content=https://wgportal.org/v2.0.3/assets/images/social/documentation/getting-started/docker.png><meta property=og:image:type content=image/png><meta property=og:image:width content=1200><meta property=og:image:height content=630><meta content=https://wgportal.org/v2.0.3/documentation/getting-started/docker/ property=og:url><meta name=twitter:card content=summary_large_image><meta name=twitter:title content="Docker - WireGuard Portal"><meta name=twitter:description content="Manage WireGuard Peers and Interface using a beautiful and simple web UI."><meta name=twitter:image content=https://wgportal.org/v2.0.3/assets/images/social/documentation/getting-started/docker.png></head> <body dir=ltr data-md-color-scheme=default data-md-color-primary=white data-md-color-accent=indigo> <input class=md-toggle data-md-toggle=drawer type=checkbox id=__drawer autocomplete=off> <input class=md-toggle data-md-toggle=search type=checkbox id=__search autocomplete=off> <label class=md-overlay for=__drawer></label> <div data-md-component=skip> <a href=#image-usage class=md-skip> Skip to content </a> </div> <div data-md-component=announce> </div> <div data-md-color-scheme=default data-md-component=outdated hidden> </div> <header class=md-header data-md-component=header> <nav class="md-header__inner md-grid" aria-label=Header> <a href=../../.. title="WireGuard Portal" class="md-header__button md-logo" aria-label="WireGuard Portal" data-md-component=logo> <img src=../../../assets/images/logo.svg alt=logo> </a> <label class="md-header__button md-icon" for=__drawer> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M3 6h18v2H3zm0 5h18v2H3zm0 5h18v2H3z"/></svg> </label> <div class=md-header__title data-md-component=header-title> <div class=md-header__ellipsis> <div class=md-header__topic> <span class=md-ellipsis> WireGuard Portal </span> </div> <div class=md-header__topic data-md-component=header-topic> <span class=md-ellipsis> Docker </span> </div> </div> </div> <label class="md-header__button md-icon" for=__search> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg> </label> <div class=md-search data-md-component=search role=dialog> <label class=md-search__overlay for=__search></label> <div class=md-search__inner role=search> <form class=md-search__form name=search> <input type=text class=md-search__input name=query aria-label=Search placeholder=Search autocapitalize=off autocorrect=off autocomplete=off spellcheck=false data-md-component=search-query required> <label class="md-search__icon md-icon" for=__search> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11z"/></svg> </label> <nav class=md-search__options aria-label=Search> <button type=reset class="md-search__icon md-icon" title=Clear aria-label=Clear tabindex=-1> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/></svg> </button> </nav> </form> <div class=md-search__output> <div class=md-search__scrollwrap tabindex=0 data-md-scrollfix> <div class=md-search-result data-md-component=search-result> <div class=md-search-result__meta> Initializing search </div> <ol class=md-search-result__list role=presentation></ol> </div> </div> </div> </div> </div> <div class=md-header__source> <a href=https://github.com/h44z/wg-portal title="Go to repository" class=md-source data-md-component=source> <div class="md-source__icon md-icon"> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 448 512"><!-- Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc.--><path d="M439.55 236.05 244 40.45a28.87 28.87 0 0 0-40.81 0l-40.66 40.63 51.52 51.52c27.06-9.14 52.68 16.77 43.39 43.68l49.66 49.66c34.23-11.8 61.18 31 35.47 56.69-26.49 26.49-70.21-2.87-56-37.34L240.22 199v121.85c25.3 12.54 22.26 41.85 9.08 55a34.34 34.34 0 0 1-48.55 0c-17.57-17.6-11.07-46.91 11.25-56v-123c-20.8-8.51-24.6-30.74-18.64-45L142.57 101 8.45 235.14a28.86 28.86 0 0 0 0 40.81l195.61 195.6a28.86 28.86 0 0 0 40.8 0l194.69-194.69a28.86 28.86 0 0 0 0-40.81"/></svg> </div> <div class=md-source__repository> h44z/wg-portal </div> </a> </div> </nav> </header> <div class=md-container data-md-component=container> <nav class=md-tabs aria-label=Tabs data-md-component=tabs> <div class=md-grid> <ul class=md-tabs__list> <li class=md-tabs__item> <a href=../../.. class=md-tabs__link> Home </a> </li> <li class="md-tabs__item md-tabs__item--active"> <a href=../../overview/ class=md-tabs__link> Documentation </a> </li> </ul> </div> </nav> <main class=md-main data-md-component=main> <div class="md-main__inner md-grid"> <div class="md-sidebar md-sidebar--primary" data-md-component=sidebar data-md-type=navigation> <div class=md-sidebar__scrollwrap> <div class=md-sidebar__inner> <nav class="md-nav md-nav--primary md-nav--lifted" aria-label=Navigation data-md-level=0> <label class=md-nav__title for=__drawer> <a href=../../.. title="WireGuard Portal" class="md-nav__button md-logo" aria-label="WireGuard Portal" data-md-component=logo> <img src=../../../assets/images/logo.svg alt=logo> </a> WireGuard Portal </label> <div class=md-nav__source> <a href=https://github.com/h44z/wg-portal title="Go to repository" class=md-source data-md-component=source> <div class="md-source__icon md-icon"> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 448 512"><!-- Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc.--><path d="M439.55 236.05 244 40.45a28.87 28.87 0 0 0-40.81 0l-40.66 40.63 51.52 51.52c27.06-9.14 52.68 16.77 43.39 43.68l49.66 49.66c34.23-11.8 61.18 31 35.47 56.69-26.49 26.49-70.21-2.87-56-37.34L240.22 199v121.85c25.3 12.54 22.26 41.85 9.08 55a34.34 34.34 0 0 1-48.55 0c-17.57-17.6-11.07-46.91 11.25-56v-123c-20.8-8.51-24.6-30.74-18.64-45L142.57 101 8.45 235.14a28.86 28.86 0 0 0 0 40.81l195.61 195.6a28.86 28.86 0 0 0 40.8 0l194.69-194.69a28.86 28.86 0 0 0 0-40.81"/></svg> </div> <div class=md-source__repository> h44z/wg-portal </div> </a> </div> <ul class=md-nav__list data-md-scrollfix> <li class=md-nav__item> <a href=../../.. class=md-nav__link> <span class=md-ellipsis> Home </span> </a> </li> <li class="md-nav__item md-nav__item--active md-nav__item--section md-nav__item--nested"> <input class="md-nav__toggle md-toggle " type=checkbox id=__nav_2 checked> <label class=md-nav__link for=__nav_2 id=__nav_2_label tabindex> <span class=md-ellipsis> Documentation </span> <span class="md-nav__icon md-icon"></span> </label> <nav class=md-nav data-md-level=1 aria-labelledby=__nav_2_label aria-expanded=true> <label class=md-nav__title for=__nav_2> <span class="md-nav__icon md-icon"></span> Documentation </label> <ul class=md-nav__list data-md-scrollfix> <li class=md-nav__item> <a href=../../overview/ class=md-nav__link> <span class=md-ellipsis> Overview </span> </a> </li> <li class="md-nav__item md-nav__item--active md-nav__item--nested"> <input class="md-nav__toggle md-toggle " type=checkbox id=__nav_2_2 checked> <label class=md-nav__link for=__nav_2_2 id=__nav_2_2_label tabindex=0> <span class=md-ellipsis> Getting Started </span> <span class="md-nav__icon md-icon"></span> </label> <nav class=md-nav data-md-level=2 aria-labelledby=__nav_2_2_label aria-expanded=true> <label class=md-nav__title for=__nav_2_2> <span class="md-nav__icon md-icon"></span> Getting Started </label> <ul class=md-nav__list data-md-scrollfix> <li class=md-nav__item> <a href=../binaries/ class=md-nav__link> <span class=md-ellipsis> Binaries </span> </a> </li> <li class="md-nav__item md-nav__item--active"> <input class="md-nav__toggle md-toggle" type=checkbox id=__toc> <label class="md-nav__link md-nav__link--active" for=__toc> <span class=md-ellipsis> Docker </span> <span class="md-nav__icon md-icon"></span> </label> <a href=./ class="md-nav__link md-nav__link--active"> <span class=md-ellipsis> Docker </span> </a> <nav class="md-nav md-nav--secondary" aria-label="Table of contents"> <label class=md-nav__title for=__toc> <span class="md-nav__icon md-icon"></span> Table of contents </label> <ul class=md-nav__list data-md-component=toc data-md-scrollfix> <li class=md-nav__item> <a href=#image-usage class=md-nav__link> <span class=md-ellipsis> Image Usage </span> </a> </li> <li class=md-nav__item> <a href=#wireguard-interface-handling class=md-nav__link> <span class=md-ellipsis> WireGuard Interface Handling </span> </a> </li> <li class=md-nav__item> <a href=#image-versioning class=md-nav__link> <span class=md-ellipsis> Image Versioning </span> </a> <nav class=md-nav aria-label="Image Versioning"> <ul class=md-nav__list> <li class=md-nav__item> <a href=#semantic-versioned-tags class=md-nav__link> <span class=md-ellipsis> Semantic versioned tags </span> </a> </li> <li class=md-nav__item> <a href=#the-latest-tag class=md-nav__link> <span class=md-ellipsis> The latest tag </span> </a> </li> <li class=md-nav__item> <a href=#the-master-tag class=md-nav__link> <span class=md-ellipsis> The master tag </span> </a> </li> </ul> </nav> </li> <li class=md-nav__item> <a href=#configuration class=md-nav__link> <span class=md-ellipsis> Configuration </span> </a> </li> </ul> </nav> </li> <li class=md-nav__item> <a href=../helm/ class=md-nav__link> <span class=md-ellipsis> Helm </span> </a> </li> <li class=md-nav__item> <a href=../sources/ class=md-nav__link> <span class=md-ellipsis> Sources </span> </a> </li> <li class=md-nav__item> <a href=../reverse-proxy/ class=md-nav__link> <span class=md-ellipsis> Reverse Proxy (HTTPS) </span> </a> </li> </ul> </nav> </li> <li class="md-nav__item md-nav__item--nested"> <input class="md-nav__toggle md-toggle md-toggle--indeterminate" type=checkbox id=__nav_2_3> <label class=md-nav__link for=__nav_2_3 id=__nav_2_3_label tabindex=0> <span class=md-ellipsis> Configuration </span> <span class="md-nav__icon md-icon"></span> </label> <nav class=md-nav data-md-level=2 aria-labelledby=__nav_2_3_label aria-expanded=false> <label class=md-nav__title for=__nav_2_3> <span class="md-nav__icon md-icon"></span> Configuration </label> <ul class=md-nav__list data-md-scrollfix> <li class=md-nav__item> <a href=../../configuration/overview/ class=md-nav__link> <span class=md-ellipsis> Overview </span> </a> </li> <li class=md-nav__item> <a href=../../configuration/examples/ class=md-nav__link> <span class=md-ellipsis> Examples </span> </a> </li> </ul> </nav> </li> <li class=md-nav__item> <a href=../../upgrade/v1/ class=md-nav__link> <span class=md-ellipsis> Upgrade </span> </a> </li> <li class=md-nav__item> <a href=../../monitoring/prometheus/ class=md-nav__link> <span class=md-ellipsis> Monitoring </span> </a> </li> <li class=md-nav__item> <a href=../../rest-api/api-doc/ class=md-nav__link> <span class=md-ellipsis> REST API </span> </a> </li> </ul> </nav> </li> </ul> </nav> </div> </div> </div> <div class="md-sidebar md-sidebar--secondary" data-md-component=sidebar data-md-type=toc> <div class=md-sidebar__scrollwrap> <div class=md-sidebar__inner> <nav class="md-nav md-nav--secondary" aria-label="Table of contents"> <label class=md-nav__title for=__toc> <span class="md-nav__icon md-icon"></span> Table of contents </label> <ul class=md-nav__list data-md-component=toc data-md-scrollfix> <li class=md-nav__item> <a href=#image-usage class=md-nav__link> <span class=md-ellipsis> Image Usage </span> </a> </li> <li class=md-nav__item> <a href=#wireguard-interface-handling class=md-nav__link> <span class=md-ellipsis> WireGuard Interface Handling </span> </a> </li> <li class=md-nav__item> <a href=#image-versioning class=md-nav__link> <span class=md-ellipsis> Image Versioning </span> </a> <nav class=md-nav aria-label="Image Versioning"> <ul class=md-nav__list> <li class=md-nav__item> <a href=#semantic-versioned-tags class=md-nav__link> <span class=md-ellipsis> Semantic versioned tags </span> </a> </li> <li class=md-nav__item> <a href=#the-latest-tag class=md-nav__link> <span class=md-ellipsis> The latest tag </span> </a> </li> <li class=md-nav__item> <a href=#the-master-tag class=md-nav__link> <span class=md-ellipsis> The master tag </span> </a> </li> </ul> </nav> </li> <li class=md-nav__item> <a href=#configuration class=md-nav__link> <span class=md-ellipsis> Configuration </span> </a> </li> </ul> </nav> </div> </div> </div> <div class=md-content data-md-component=content> <article class="md-content__inner md-typeset"> <h1>Docker</h1> <h2 id=image-usage>Image Usage</h2> <p>The WireGuard Portal Docker image is available on both <a href=https://hub.docker.com/r/wgportal/wg-portal>Docker Hub</a> and <a href=https://github.com/h44z/wg-portal/pkgs/container/wg-portal>GitHub Container Registry</a>. It is built on the official Alpine Linux base image and comes pre-packaged with all necessary WireGuard dependencies.</p> <p>This container allows you to establish WireGuard VPN connections without relying on a host system that supports WireGuard or using the <code>linuxserver/wireguard</code> Docker image.</p> <p>The recommended method for deploying WireGuard Portal is via Docker Compose for ease of configuration and management.</p> <p>A sample docker-compose.yml (managing WireGuard interfaces directly on the host) is provided below:</p> <div class=highlight><pre><span></span><code><span class=nn>---</span>
|
|
<span class=nt>services</span><span class=p>:</span>
|
|
<span class=w> </span><span class=nt>wg-portal</span><span class=p>:</span>
|
|
<span class=w> </span><span class=nt>image</span><span class=p>:</span><span class=w> </span><span class="l l-Scalar l-Scalar-Plain">wgportal/wg-portal:v2</span>
|
|
<span class=w> </span><span class=nt>container_name</span><span class=p>:</span><span class=w> </span><span class="l l-Scalar l-Scalar-Plain">wg-portal</span>
|
|
<span class=w> </span><span class=nt>restart</span><span class=p>:</span><span class=w> </span><span class="l l-Scalar l-Scalar-Plain">unless-stopped</span>
|
|
<span class=w> </span><span class=nt>logging</span><span class=p>:</span>
|
|
<span class=w> </span><span class=nt>options</span><span class=p>:</span>
|
|
<span class=w> </span><span class=nt>max-size</span><span class=p>:</span><span class=w> </span><span class=s>"10m"</span>
|
|
<span class=w> </span><span class=nt>max-file</span><span class=p>:</span><span class=w> </span><span class=s>"3"</span>
|
|
<span class=w> </span><span class=nt>cap_add</span><span class=p>:</span>
|
|
<span class=w> </span><span class="p p-Indicator">-</span><span class=w> </span><span class="l l-Scalar l-Scalar-Plain">NET_ADMIN</span>
|
|
<span class=w> </span><span class=c1># Use host network mode for WireGuard and the UI. Ensure that access to the UI is properly secured.</span>
|
|
<span class=w> </span><span class=nt>network_mode</span><span class=p>:</span><span class=w> </span><span class=s>"host"</span>
|
|
<span class=w> </span><span class=nt>volumes</span><span class=p>:</span>
|
|
<span class=w> </span><span class=c1># left side is the host path, right side is the container path</span>
|
|
<span class=w> </span><span class="p p-Indicator">-</span><span class=w> </span><span class="l l-Scalar l-Scalar-Plain">/etc/wireguard:/etc/wireguard</span>
|
|
<span class=w> </span><span class="p p-Indicator">-</span><span class=w> </span><span class="l l-Scalar l-Scalar-Plain">./data:/app/data</span>
|
|
<span class=w> </span><span class="p p-Indicator">-</span><span class=w> </span><span class="l l-Scalar l-Scalar-Plain">./config:/app/config</span>
|
|
</code></pre></div> <p>By default, the webserver for the UI is listening on port <strong>8888</strong> on all available interfaces.</p> <p>Volumes for <code>/app/data</code> and <code>/app/config</code> should be used ensure data persistence across container restarts.</p> <h2 id=wireguard-interface-handling>WireGuard Interface Handling</h2> <p>WireGuard Portal supports managing WireGuard interfaces through three distinct deployment methods, providing flexibility based on your system architecture and operational preferences:</p> <ul> <li> <p><strong>Directly on the host system</strong>: WireGuard Portal can control WireGuard interfaces natively on the host, without using containers. This setup is ideal for environments where direct access to system networking is preferred. To use this method, you need to set the network mode to <code>host</code> in your docker-compose.yml file. <div class=highlight><pre><span></span><code><span class=nt>services</span><span class=p>:</span>
|
|
<span class=w> </span><span class=nt>wg-portal</span><span class=p>:</span>
|
|
<span class=w> </span><span class="l l-Scalar l-Scalar-Plain">...</span>
|
|
<span class=w> </span><span class="l l-Scalar l-Scalar-Plain">network_mode</span><span class="p p-Indicator">:</span><span class=w> </span><span class=s>"host"</span>
|
|
<span class=w> </span><span class="l l-Scalar l-Scalar-Plain">...</span>
|
|
</code></pre></div></p> <blockquote> <p><img alt=⚠ class=twemoji src=https://cdn.jsdelivr.net/gh/jdecked/twemoji@15.1.0/assets/svg/26a0.svg title=:warning:> If host networking is used, the WireGuard Portal UI will be accessible on all the host's IP addresses if the listening address is set to <code>:8888</code> in the configuration file. To avoid this, you can bind the listening address to a specific IP address, for example, the loopback address (<code>127.0.0.1:8888</code>). It is also possible to deploy firewall rules to restrict access to the WireGuard Portal UI.</p> </blockquote> </li> <li> <p><strong>Within the WireGuard Portal Docker container</strong>: WireGuard interfaces can be managed directly from within the WireGuard Portal container itself. This is the recommended approach when running WireGuard Portal via Docker, as it encapsulates all functionality in a single, portable container without requiring a separate WireGuard host or image. <div class=highlight><pre><span></span><code><span class=nt>services</span><span class=p>:</span>
|
|
<span class=w> </span><span class=nt>wg-portal</span><span class=p>:</span>
|
|
<span class=w> </span><span class=nt>image</span><span class=p>:</span><span class=w> </span><span class="l l-Scalar l-Scalar-Plain">wgportal/wg-portal:v2</span>
|
|
<span class=w> </span><span class=nt>container_name</span><span class=p>:</span><span class=w> </span><span class="l l-Scalar l-Scalar-Plain">wg-portal</span>
|
|
<span class=w> </span><span class="l l-Scalar l-Scalar-Plain">...</span>
|
|
<span class=w> </span><span class=nt>cap_add</span><span class=p>:</span>
|
|
<span class=w> </span><span class="p p-Indicator">-</span><span class=w> </span><span class="l l-Scalar l-Scalar-Plain">NET_ADMIN</span>
|
|
<span class=w> </span><span class=nt>ports</span><span class=p>:</span>
|
|
<span class=w> </span><span class=c1># host port : container port</span>
|
|
<span class=w> </span><span class=c1># WireGuard port, needs to match the port in wg-portal interface config (add one port mapping for each interface)</span>
|
|
<span class=w> </span><span class="p p-Indicator">-</span><span class=w> </span><span class=s>"51820:51820/udp"</span><span class=w> </span>
|
|
<span class=w> </span><span class=c1># Web UI port</span>
|
|
<span class=w> </span><span class="p p-Indicator">-</span><span class=w> </span><span class=s>"8888:8888/tcp"</span>
|
|
<span class=w> </span><span class=nt>sysctls</span><span class=p>:</span>
|
|
<span class=w> </span><span class="p p-Indicator">-</span><span class=w> </span><span class="l l-Scalar l-Scalar-Plain">net.ipv4.conf.all.src_valid_mark=1</span>
|
|
<span class=w> </span><span class=nt>volumes</span><span class=p>:</span>
|
|
<span class=w> </span><span class=c1># host path : container path</span>
|
|
<span class=w> </span><span class="p p-Indicator">-</span><span class=w> </span><span class="l l-Scalar l-Scalar-Plain">./wg/data:/app/data</span>
|
|
<span class=w> </span><span class="p p-Indicator">-</span><span class=w> </span><span class="l l-Scalar l-Scalar-Plain">./wg/config:/app/config</span>
|
|
</code></pre></div></p> </li> <li> <p><strong>Via a separate Docker container</strong>: WireGuard Portal can interface with and control WireGuard running in another Docker container, such as the <a href=https://docs.linuxserver.io/images/docker-wireguard/ >linuxserver/wireguard</a> image. This method is useful in setups that already use <code>linuxserver/wireguard</code> or where you want to isolate the VPN backend from the portal frontend. For this, you need to set the network mode to <code>service:wireguard</code> in your docker-compose.yml file, <code>wireguard</code> is the service name of your WireGuard container. <div class=highlight><pre><span></span><code><span class=nt>services</span><span class=p>:</span>
|
|
<span class=w> </span><span class=nt>wg-portal</span><span class=p>:</span>
|
|
<span class=w> </span><span class=nt>image</span><span class=p>:</span><span class=w> </span><span class="l l-Scalar l-Scalar-Plain">wgportal/wg-portal:v2</span>
|
|
<span class=w> </span><span class=nt>container_name</span><span class=p>:</span><span class=w> </span><span class="l l-Scalar l-Scalar-Plain">wg-portal</span>
|
|
<span class=w> </span><span class="l l-Scalar l-Scalar-Plain">...</span>
|
|
<span class=w> </span><span class=nt>cap_add</span><span class=p>:</span>
|
|
<span class=w> </span><span class="p p-Indicator">-</span><span class=w> </span><span class="l l-Scalar l-Scalar-Plain">NET_ADMIN</span>
|
|
<span class=w> </span><span class=nt>network_mode</span><span class=p>:</span><span class=w> </span><span class=s>"service:wireguard"</span><span class=w> </span><span class=c1># So we ensure to stay on the same network as the wireguard container.</span>
|
|
<span class=w> </span><span class=nt>volumes</span><span class=p>:</span>
|
|
<span class=w> </span><span class=c1># host path : container path</span>
|
|
<span class=w> </span><span class="p p-Indicator">-</span><span class=w> </span><span class="l l-Scalar l-Scalar-Plain">./wg/etc:/etc/wireguard</span>
|
|
<span class=w> </span><span class="p p-Indicator">-</span><span class=w> </span><span class="l l-Scalar l-Scalar-Plain">./wg/data:/app/data</span>
|
|
<span class=w> </span><span class="p p-Indicator">-</span><span class=w> </span><span class="l l-Scalar l-Scalar-Plain">./wg/config:/app/config</span>
|
|
|
|
<span class=w> </span><span class=nt>wireguard</span><span class=p>:</span>
|
|
<span class=w> </span><span class=nt>image</span><span class=p>:</span><span class=w> </span><span class="l l-Scalar l-Scalar-Plain">lscr.io/linuxserver/wireguard:latest</span>
|
|
<span class=w> </span><span class=nt>container_name</span><span class=p>:</span><span class=w> </span><span class="l l-Scalar l-Scalar-Plain">wireguard</span>
|
|
<span class=w> </span><span class=nt>restart</span><span class=p>:</span><span class=w> </span><span class="l l-Scalar l-Scalar-Plain">unless-stopped</span>
|
|
<span class=w> </span><span class=nt>cap_add</span><span class=p>:</span>
|
|
<span class=w> </span><span class="p p-Indicator">-</span><span class=w> </span><span class="l l-Scalar l-Scalar-Plain">NET_ADMIN</span>
|
|
<span class=w> </span><span class=nt>ports</span><span class=p>:</span>
|
|
<span class=w> </span><span class=c1># host port : container port</span>
|
|
<span class=w> </span><span class="p p-Indicator">-</span><span class=w> </span><span class=s>"51820:51820/udp"</span><span class=w> </span><span class=c1># WireGuard port, needs to match the port in wg-portal interface config</span>
|
|
<span class=w> </span><span class="p p-Indicator">-</span><span class=w> </span><span class=s>"8888:8888/tcp"</span><span class=w> </span><span class=c1># Noticed that the port of the web UI is exposed in the wireguard container.</span>
|
|
<span class=w> </span><span class=nt>volumes</span><span class=p>:</span>
|
|
<span class=w> </span><span class="p p-Indicator">-</span><span class=w> </span><span class="l l-Scalar l-Scalar-Plain">./wg/etc:/config/wg_confs</span><span class=w> </span><span class=c1># We share the configuration (wgx.conf) between wg-portal and wireguard</span>
|
|
<span class=w> </span><span class=nt>sysctls</span><span class=p>:</span>
|
|
<span class=w> </span><span class="p p-Indicator">-</span><span class=w> </span><span class="l l-Scalar l-Scalar-Plain">net.ipv4.conf.all.src_valid_mark=1</span>
|
|
</code></pre></div> As the <code>linuxserver/wireguard</code> image uses <em>wg-quick</em> to manage the interfaces, you need to have at least the following configuration set for WireGuard Portal: <div class=highlight><pre><span></span><code><span class=nt>core</span><span class=p>:</span>
|
|
<span class=w> </span><span class=c1># The WireGuard container uses wg-quick to manage the WireGuard interfaces - this conflicts with WireGuard Portal during startup.</span>
|
|
<span class=w> </span><span class=c1># To avoid this, we need to set the restore_state option to false so that wg-quick can create the interfaces.</span>
|
|
<span class=w> </span><span class=nt>restore_state</span><span class=p>:</span><span class=w> </span><span class="l l-Scalar l-Scalar-Plain">false</span>
|
|
<span class=w> </span><span class=c1># Usually, there are no existing interfaces in the WireGuard container, so we can set this to false.</span>
|
|
<span class=w> </span><span class=nt>import_existing</span><span class=p>:</span><span class=w> </span><span class="l l-Scalar l-Scalar-Plain">false</span>
|
|
<span class=nt>advanced</span><span class=p>:</span>
|
|
<span class=w> </span><span class=c1># WireGuard Portal needs to export the WireGuard configuration as wg-quick config files so that the WireGuard container can use them.</span>
|
|
<span class=w> </span><span class=nt>config_storage_path</span><span class=p>:</span><span class=w> </span><span class="l l-Scalar l-Scalar-Plain">/etc/wireguard/</span>
|
|
</code></pre></div></p> </li> </ul> <h2 id=image-versioning>Image Versioning</h2> <p>All images are hosted on Docker Hub at <a href=https://hub.docker.com/r/wgportal/wg-portal>https://hub.docker.com/r/wgportal/wg-portal</a> or in the <a href=https://github.com/h44z/wg-portal/pkgs/container/wg-portal>GitHub Container Registry</a>.</p> <p>Version <strong>2</strong> is the current stable release. Version <strong>1</strong> has moved to legacy status and is no longer recommended.</p> <p>There are three types of tags in the repository:</p> <h4 id=semantic-versioned-tags>Semantic versioned tags</h4> <p>For example, <code>2.0.0-rc.1</code> or <code>v2.0.0-rc.1</code>.</p> <p>These are official releases of WireGuard Portal. For production deployments of WireGuard Portal, we strongly recommend using one of these versioned tags instead of the latest or canary tags.</p> <p>There are different types of these tags:</p> <ul> <li>Major version tags: <code>v2</code> or <code>2</code>. These tags always refer to the latest image for WireGuard Portal version <strong>2</strong>.</li> <li>Minor version tags: <code>v2.x</code> or <code>2.0</code>. These tags always refer to the latest image for WireGuard Portal version <strong>2.x</strong>.</li> <li>Specific version tags (patch version): <code>v2.0.0</code> or <code>2.0.0</code>. These tags denote a very specific release. They correspond to the GitHub tags that we make, and you can see the release notes for them here: <a href=https://github.com/h44z/wg-portal/releases>https://github.com/h44z/wg-portal/releases</a>. Once these tags for a specific version show up in the Docker repository, they will never change. </li> </ul> <h4 id=the-latest-tag>The <code>latest</code> tag</h4> <p>The lastest tag is the latest stable release of WireGuard Portal. For version <strong>2</strong>, this is the same as the <code>v2</code> tag.</p> <h4 id=the-master-tag>The <code>master</code> tag</h4> <p>This is the most recent build to the main branch! It changes a lot and is very unstable.</p> <p>We recommend that you don't use it except for development purposes or to test the latest features.</p> <h2 id=configuration>Configuration</h2> <p>You can configure WireGuard Portal using a YAML configuration file. The filepath of the YAML configuration file defaults to <code>/app/config/config.yaml</code>. It is possible to override the configuration filepath using the environment variable <strong>WG_PORTAL_CONFIG</strong>.</p> <p>By default, WireGuard Portal uses an SQLite database. The database is stored in <code>/app/data/sqlite.db</code>.</p> <p>You should mount those directories as a volume:</p> <ul> <li><code>/app/data</code></li> <li><code>/app/config</code></li> </ul> <p>A detailed description of the configuration options can be found <a href=../../configuration/overview/ >here</a>.</p> <p>If you want to access configuration files in wg-quick format, you can mount the <code>/etc/wireguard</code> directory inside the container to a location of your choice. Also enable the <code>config_storage_path</code> option in the configuration file: <div class=highlight><pre><span></span><code><span class=nt>advanced</span><span class=p>:</span>
|
|
<span class=w> </span><span class=nt>config_storage_path</span><span class=p>:</span><span class=w> </span><span class="l l-Scalar l-Scalar-Plain">/etc/wireguard</span>
|
|
</code></pre></div></p> </article> </div> <script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith("__tabbed_"))</script> </div> </main> <!-- Application footer --> <footer class=md-footer> <!-- Further information --> <div class="md-footer-meta md-typeset" style="background-color: #fff;"> <div class="md-footer-meta__inner md-grid" style="background-color: #fff;"> <!-- Copyright and theme information --> <div class=md-footer-copyright> <div class=md-footer-copyright__highlight style="color: rgb(38, 38, 38);"> Copyright © 2023-2025 WireGuard Portal Project </div> <div style="color: rgb(38, 38, 38);"> Made with <a href=https://squidfunk.github.io/mkdocs-material/ target=_blank rel=noopener style="color: black;"> Material for MkDocs </a> </div> </div> <!-- Social links --> <div class=md-social> <a href=https://github.com/h44z/wg-portal target=_blank rel=noopener title=github.com class=md-social__link> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 480 512"><!-- Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc.--><path d="M186.1 328.7c0 20.9-10.9 55.1-36.7 55.1s-36.7-34.2-36.7-55.1 10.9-55.1 36.7-55.1 36.7 34.2 36.7 55.1M480 278.2c0 31.9-3.2 65.7-17.5 95-37.9 76.6-142.1 74.8-216.7 74.8-75.8 0-186.2 2.7-225.6-74.8-14.6-29-20.2-63.1-20.2-95 0-41.9 13.9-81.5 41.5-113.6-5.2-15.8-7.7-32.4-7.7-48.8 0-21.5 4.9-32.3 14.6-51.8 45.3 0 74.3 9 108.8 36 29-6.9 58.8-10 88.7-10 27 0 54.2 2.9 80.4 9.2 34-26.7 63-35.2 107.8-35.2 9.8 19.5 14.6 30.3 14.6 51.8 0 16.4-2.6 32.7-7.7 48.2 27.5 32.4 39 72.3 39 114.2m-64.3 50.5c0-43.9-26.7-82.6-73.5-82.6-18.9 0-37 3.4-56 6-14.9 2.3-29.8 3.2-45.1 3.2-15.2 0-30.1-.9-45.1-3.2-18.7-2.6-37-6-56-6-46.8 0-73.5 38.7-73.5 82.6 0 87.8 80.4 101.3 150.4 101.3h48.2c70.3 0 150.6-13.4 150.6-101.3m-82.6-55.1c-25.8 0-36.7 34.2-36.7 55.1s10.9 55.1 36.7 55.1 36.7-34.2 36.7-55.1-10.9-55.1-36.7-55.1"/></svg> </a> <a href=https://hub.docker.com/r/wgportal/wg-portal target=_blank rel=noopener title=hub.docker.com class=md-social__link> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 640 512"><!-- Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc.--><path d="M349.9 236.3h-66.1v-59.4h66.1zm0-204.3h-66.1v60.7h66.1zm78.2 144.8H362v59.4h66.1zm-156.3-72.1h-66.1v60.1h66.1zm78.1 0h-66.1v60.1h66.1zm276.8 100c-14.4-9.7-47.6-13.2-73.1-8.4-3.3-24-16.7-44.9-41.1-63.7l-14-9.3-9.3 14c-18.4 27.8-23.4 73.6-3.7 103.8-8.7 4.7-25.8 11.1-48.4 10.7H2.4c-8.7 50.8 5.8 116.8 44 162.1 37.1 43.9 92.7 66.2 165.4 66.2 157.4 0 273.9-72.5 328.4-204.2 21.4.4 67.6.1 91.3-45.2 1.5-2.5 6.6-13.2 8.5-17.1zm-511.1-27.9h-66v59.4h66.1v-59.4zm78.1 0h-66.1v59.4h66.1zm78.1 0h-66.1v59.4h66.1zm-78.1-72.1h-66.1v60.1h66.1z"/></svg> </a> <a href=https://twitter.com/chris_h44z target=_blank rel=noopener title=twitter.com class=md-social__link> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 512 512"><!-- Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc.--><path d="M459.37 151.716c.325 4.548.325 9.097.325 13.645 0 138.72-105.583 298.558-298.558 298.558-59.452 0-114.68-17.219-161.137-47.106 8.447.974 16.568 1.299 25.34 1.299 49.055 0 94.213-16.568 130.274-44.832-46.132-.975-84.792-31.188-98.112-72.772 6.498.974 12.995 1.624 19.818 1.624 9.421 0 18.843-1.3 27.614-3.573-48.081-9.747-84.143-51.98-84.143-102.985v-1.299c13.969 7.797 30.214 12.67 47.431 13.319-28.264-18.843-46.781-51.005-46.781-87.391 0-19.492 5.197-37.36 14.294-52.954 51.655 63.675 129.3 105.258 216.365 109.807-1.624-7.797-2.599-15.918-2.599-24.04 0-57.828 46.782-104.934 104.934-104.934 30.213 0 57.502 12.67 76.67 33.137 23.715-4.548 46.456-13.32 66.599-25.34-7.798 24.366-24.366 44.833-46.132 57.827 21.117-2.273 41.584-8.122 60.426-16.243-14.292 20.791-32.161 39.308-52.628 54.253"/></svg> </a> </div> </div> </div> </footer> </div> <div class=md-dialog data-md-component=dialog> <div class="md-dialog__inner md-typeset"></div> </div> <script id=__config type=application/json>{"base": "../../..", "features": ["content.code.copy", "navigation.instant", "navigation.tabs", "navigation.expand"], "search": "../../../assets/javascripts/workers/search.d50fe291.min.js", "tags": null, "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version": "Select version"}, "version": {"default": "latest", "provider": "mike"}}</script> <script src=../../../assets/javascripts/bundle.13a4f30d.min.js></script> </body> </html> |