2025-05-13 18:02:15 +00:00

69 lines
28 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!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/master/documentation/getting-started/reverse-proxy/ rel=canonical><link href=../sources/ rel=prev><link href=../../configuration/overview/ 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>Reverse Proxy (HTTPS) - 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="Reverse Proxy (HTTPS) - 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/master/assets/images/social/documentation/getting-started/reverse-proxy.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/master/documentation/getting-started/reverse-proxy/ property=og:url><meta name=twitter:card content=summary_large_image><meta name=twitter:title content="Reverse Proxy (HTTPS) - 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/master/assets/images/social/documentation/getting-started/reverse-proxy.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=#reverse-proxy-for-https 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> Reverse Proxy (HTTPS) </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> <a href=../docker/ class=md-nav__link> <span class=md-ellipsis> Docker </span> </a> </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 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> Reverse Proxy (HTTPS) </span> <span class="md-nav__icon md-icon"></span> </label> <a href=./ class="md-nav__link md-nav__link--active"> <span class=md-ellipsis> Reverse Proxy (HTTPS) </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=#reverse-proxy-for-https class=md-nav__link> <span class=md-ellipsis> Reverse Proxy for HTTPS </span> </a> <nav class=md-nav aria-label="Reverse Proxy for HTTPS"> <ul class=md-nav__list> <li class=md-nav__item> <a href=#reverse-proxy class=md-nav__link> <span class=md-ellipsis> Reverse Proxy </span> </a> </li> <li class=md-nav__item> <a href=#built-in-tls class=md-nav__link> <span class=md-ellipsis> Built-in TLS </span> </a> </li> </ul> </nav> </li> </ul> </nav> </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=#reverse-proxy-for-https class=md-nav__link> <span class=md-ellipsis> Reverse Proxy for HTTPS </span> </a> <nav class=md-nav aria-label="Reverse Proxy for HTTPS"> <ul class=md-nav__list> <li class=md-nav__item> <a href=#reverse-proxy class=md-nav__link> <span class=md-ellipsis> Reverse Proxy </span> </a> </li> <li class=md-nav__item> <a href=#built-in-tls class=md-nav__link> <span class=md-ellipsis> Built-in TLS </span> </a> </li> </ul> </nav> </li> </ul> </nav> </div> </div> </div> <div class=md-content data-md-component=content> <article class="md-content__inner md-typeset"> <h1>Reverse Proxy (HTTPS)</h1> <h2 id=reverse-proxy-for-https>Reverse Proxy for HTTPS</h2> <p>For production deployments, always serve the WireGuard Portal over HTTPS. You have two options to secure your connection:</p> <h3 id=reverse-proxy>Reverse Proxy</h3> <p>Let a frontend proxy handle HTTPS for you. This also frees you from managing certificates manually and is therefore the preferred option. You can use Nginx, Traefik, Caddy or any other proxy. </p> <p>Below is an example using a Docker Compose stack with <a href=https://traefik.io/traefik/ >Traefik</a>. It exposes the WireGuard Portal on <code>https://wg.domain.com</code> and redirects initial HTTP traffic to HTTPS.</p> <div class=highlight><pre><span></span><code><span class=nt>services</span><span class=p>:</span>
<span class=w> </span><span class=nt>reverse-proxy</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">traefik:v3.3</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>command</span><span class=p>:</span>
<span class=w> </span><span class=c1>#- &#39;--log.level=DEBUG&#39;</span>
<span class=w> </span><span class="p p-Indicator">-</span><span class=w> </span><span class=s>&#39;--providers.docker.endpoint=unix:///var/run/docker.sock&#39;</span>
<span class=w> </span><span class="p p-Indicator">-</span><span class=w> </span><span class=s>&#39;--providers.docker.exposedbydefault=false&#39;</span>
<span class=w> </span><span class="p p-Indicator">-</span><span class=w> </span><span class=s>&#39;--entrypoints.web.address=:80&#39;</span>
<span class=w> </span><span class="p p-Indicator">-</span><span class=w> </span><span class=s>&#39;--entrypoints.websecure.address=:443&#39;</span>
<span class=w> </span><span class="p p-Indicator">-</span><span class=w> </span><span class=s>&#39;--entrypoints.websecure.http3&#39;</span>
<span class=w> </span><span class="p p-Indicator">-</span><span class=w> </span><span class=s>&#39;--certificatesresolvers.letsencryptresolver.acme.httpchallenge=true&#39;</span>
<span class=w> </span><span class="p p-Indicator">-</span><span class=w> </span><span class=s>&#39;--certificatesresolvers.letsencryptresolver.acme.httpchallenge.entrypoint=web&#39;</span>
<span class=w> </span><span class="p p-Indicator">-</span><span class=w> </span><span class=s>&#39;--certificatesresolvers.letsencryptresolver.acme.email=your.email@domain.com&#39;</span>
<span class=w> </span><span class="p p-Indicator">-</span><span class=w> </span><span class=s>&#39;--certificatesresolvers.letsencryptresolver.acme.storage=/letsencrypt/acme.json&#39;</span>
<span class=w> </span><span class=c1>#- &#39;--certificatesresolvers.letsencryptresolver.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory&#39; # just for testing</span>
<span class=w> </span><span class=nt>ports</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">80:80</span><span class=w> </span><span class=c1># for HTTP</span>
<span class=w> </span><span class="p p-Indicator">-</span><span class=w> </span><span class="l l-Scalar l-Scalar-Plain">443:443/tcp</span><span class=w> </span><span class=c1># for HTTPS</span>
<span class=w> </span><span class="p p-Indicator">-</span><span class=w> </span><span class="l l-Scalar l-Scalar-Plain">443:443/udp</span><span class=w> </span><span class=c1># for HTTP/3</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">acme-certs:/letsencrypt</span>
<span class=w> </span><span class="p p-Indicator">-</span><span class=w> </span><span class="l l-Scalar l-Scalar-Plain">/var/run/docker.sock:/var/run/docker.sock:ro</span>
<span class=w> </span><span class=nt>labels</span><span class=p>:</span>
<span class=w> </span><span class="p p-Indicator">-</span><span class=w> </span><span class=s>&#39;traefik.enable=true&#39;</span>
<span class=w> </span><span class=c1># HTTP Catchall for redirecting HTTP -&gt; HTTPS</span>
<span class=w> </span><span class="p p-Indicator">-</span><span class=w> </span><span class=s>&#39;traefik.http.routers.dashboard-catchall.rule=Host(`wg.domain.com`)</span><span class=nv> </span><span class=s>&amp;&amp;</span><span class=nv> </span><span class=s>PathPrefix(`/`)&#39;</span>
<span class=w> </span><span class="p p-Indicator">-</span><span class=w> </span><span class=s>&#39;traefik.http.routers.dashboard-catchall.entrypoints=web&#39;</span>
<span class=w> </span><span class="p p-Indicator">-</span><span class=w> </span><span class=s>&#39;traefik.http.routers.dashboard-catchall.middlewares=redirect-to-https&#39;</span>
<span class=w> </span><span class="p p-Indicator">-</span><span class=w> </span><span class=s>&#39;traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https&#39;</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>&quot;10m&quot;</span>
<span class=w> </span><span class=nt>max-file</span><span class=p>:</span><span class=w> </span><span class=s>&quot;3&quot;</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>&quot;51820:51820/udp&quot;</span>
<span class=w> </span><span class=c1># Web UI port (only available on localhost, Traefik will handle the HTTPS)</span>
<span class=w> </span><span class="p p-Indicator">-</span><span class=w> </span><span class=s>&quot;127.0.0.1:8888:8888/tcp&quot;</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>
<span class=w> </span><span class=nt>labels</span><span class=p>:</span>
<span class=w> </span><span class="p p-Indicator">-</span><span class=w> </span><span class=s>&#39;traefik.enable=true&#39;</span>
<span class=w> </span><span class="p p-Indicator">-</span><span class=w> </span><span class=s>&#39;traefik.http.routers.wgportal.rule=Host(`wg.domain.com`)&#39;</span>
<span class=w> </span><span class="p p-Indicator">-</span><span class=w> </span><span class=s>&#39;traefik.http.routers.wgportal.entrypoints=websecure&#39;</span>
<span class=w> </span><span class="p p-Indicator">-</span><span class=w> </span><span class=s>&#39;traefik.http.routers.wgportal.tls.certresolver=letsencryptresolver&#39;</span>
<span class=w> </span><span class="p p-Indicator">-</span><span class=w> </span><span class=s>&#39;traefik.http.routers.wgportal.service=wgportal&#39;</span>
<span class=w> </span><span class="p p-Indicator">-</span><span class=w> </span><span class=s>&#39;traefik.http.services.wgportal.loadbalancer.server.port=8888&#39;</span>
<span class=nt>volumes</span><span class=p>:</span>
<span class=w> </span><span class=nt>acme-certs</span><span class=p>:</span>
</code></pre></div> <p>The WireGuard Portal configuration must be updated accordingly so that the correct external URL is set for the web interface:</p> <div class=highlight><pre><span></span><code><span class=nt>web</span><span class=p>:</span>
<span class=w> </span><span class=nt>external_url</span><span class=p>:</span><span class=w> </span><span class="l l-Scalar l-Scalar-Plain">https://wg.domain.com</span>
</code></pre></div> <h3 id=built-in-tls>Built-in TLS</h3> <p>If you prefer to let WireGuard Portal handle TLS itself, you can use the built-in TLS support. In your <code>config.yaml</code>, under the <code>web</code> section, point to your certificate and key files:</p> <div class=highlight><pre><span></span><code><span class=nt>web</span><span class=p>:</span>
<span class=w> </span><span class=nt>cert_file</span><span class=p>:</span><span class=w> </span><span class="l l-Scalar l-Scalar-Plain">/path/to/your/fullchain.pem</span>
<span class=w> </span><span class=nt>key_file</span><span class=p>:</span><span class=w> </span><span class="l l-Scalar l-Scalar-Plain">/path/to/your/privkey.pem</span>
</code></pre></div> <p>The web server will then use these files to serve HTTPS traffic directly instead of HTTP.</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 &copy; 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>