From de6ad0557703aff49481fe3e5c5cdd12c1e85eb0 Mon Sep 17 00:00:00 2001
From: mojothemonkey2 <117033380+mojothemonkey2@users.noreply.github.com>
Date: Tue, 13 Dec 2022 18:50:14 +0000
Subject: [PATCH] Manage Wireguard restarts from docker container (#267)

---
 Dockerfile          |  8 ++++----
 README.md           | 16 ++++++++++++++++
 docker-compose.yaml |  2 ++
 init.sh             | 23 +++++++++++++++++++++++
 4 files changed, 45 insertions(+), 4 deletions(-)
 create mode 100755 init.sh

diff --git a/Dockerfile b/Dockerfile
index 21394c1..a30cefe 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -62,17 +62,17 @@ FROM alpine:3.16
 RUN addgroup -S wgui && \
     adduser -S -D -G wgui wgui
 
-RUN apk --no-cache add ca-certificates
+RUN apk --no-cache add ca-certificates wireguard-tools jq
 
 WORKDIR /app
 
 RUN mkdir -p db
 
 # Copy binary files
-COPY --from=builder --chown=wgui:wgui /build/wg-ui /app
-
+COPY --from=builder --chown=wgui:wgui /build/wg-ui .
 RUN chmod +x wg-ui
+COPY init.sh .
 
 EXPOSE 5000/tcp
 HEALTHCHECK CMD ["wget","--output-document=-","--quiet","--tries=1","http://127.0.0.1:5000/_health"]
-ENTRYPOINT ["./wg-ui"]
+ENTRYPOINT ["./init.sh"]
diff --git a/README.md b/README.md
index 3f87609..5e77d58 100644
--- a/README.md
+++ b/README.md
@@ -34,6 +34,7 @@ Note:
 
 - There is a Status option that needs docker to be able to access the network of the host in order to read the 
 wireguard interface stats. See the `cap_add` and `network_mode` options on the docker-compose.yaml
+- Similarly the `WGUI_MANAGE_START` and `WGUI_MANAGE_RESTART` settings need the same access, in order to restart the wireguard interface.
 - Because the `network_mode` is set to `host`, we don't need to specify the exposed ports. The app will listen on port `5000` by default.
 
 
@@ -75,6 +76,15 @@ These environment variables are used to set the defaults used in `New Client` di
 | `WGUI_DEFAULT_CLIENT_USE_SERVER_DNS`        | Boolean value [`0`, `f`, `F`, `false`, `False`, `FALSE`, `1`, `t`, `T`, `true`, `True`, `TRUE`] (default `true`) |
 | `WGUI_DEFAULT_CLIENT_ENABLE_AFTER_CREATION` | Boolean value [`0`, `f`, `F`, `false`, `False`, `FALSE`, `1`, `t`, `T`, `true`, `True`, `TRUE`] (default `true`) |
 
+### Docker only
+
+These environment variables only apply to the docker container.
+
+| Variable              | Description                                                                      |
+|-----------------------|----------------------------------------------------------------------------------|
+| `WGUI_MANAGE_START`   | Start/stop WireGaurd when the container is started/stopped. (default `false`)    |
+| `WGUI_MANAGE_RESTART` | Auto restart WireGuard when we Apply Config changes in the UI. (default `false`) |
+
 ### Email configuration
 
 To use custom `wg.conf` template set the `WG_CONF_TEMPLATE` environment variable to a path to such file. Make sure `wireguard-ui` will be able to work with it - use [default template](templates/wg.conf) for reference.
@@ -168,6 +178,12 @@ rc-service wgui start
 rc-update add wgui default
 ```
 
+### docker
+
+Set `WGUI_MANAGE_RESTART=true` to manage Wireguard interface restarts.
+Using `WGUI_MANAGE_START=true` can also replace the function of `wg-quick@wg0` service, to start Wireguard at boot, by running the container with `restart: unless-stopped`.
+These settings can also pick up changes to Wireguard Config File Path, after restarting the container.
+
 ## Build
 
 ### Build docker image
diff --git a/docker-compose.yaml b/docker-compose.yaml
index f5be7b2..a7d49c0 100644
--- a/docker-compose.yaml
+++ b/docker-compose.yaml
@@ -16,6 +16,8 @@ services:
       - WGUI_USERNAME=alpha
       - WGUI_PASSWORD=this-unusual-password
       - WG_CONF_TEMPLATE
+      - WGUI_MANAGE_START=false
+      - WGUI_MANAGE_RESTART=false
     logging:
       driver: json-file
       options:
diff --git a/init.sh b/init.sh
new file mode 100755
index 0000000..08b98e8
--- /dev/null
+++ b/init.sh
@@ -0,0 +1,23 @@
+#!/bin/bash
+
+# extract wg config file path, or use default
+conf="$(jq -r .config_file_path db/server/global_settings.json || echo /etc/wireguard/wg0.conf)"
+
+# manage wireguard stop/start with the container
+case $WGUI_MANAGE_START in (1|t|T|true|True|TRUE)
+    wg-quick up "$conf"
+    trap 'wg-quick down "$conf"' SIGTERM # catches container stop
+esac
+
+# manage wireguard restarts
+case $WGUI_MANAGE_RESTART in (1|t|T|true|True|TRUE)
+    [[ -f $conf ]] || touch "$conf" # inotifyd needs file to exist
+    inotifyd - "$conf":w | while read -r event file; do
+        wg-quick down "$file"
+        wg-quick up "$file"
+    done &
+esac
+
+
+./wg-ui &
+wait $!