Docker entrypoint refactoring (#743)

* Add new env vars for docker

* Add email env vars for docker

* Improve sed for email vars

* Refactor entrypoint.sh file

* Add additional account docker vars

* Add comment for clear command

---------

Co-authored-by: DaanSelen <80752476+DaanSelen@users.noreply.github.com>
This commit is contained in:
Adams
2025-09-15 13:09:14 +03:00
committed by GitHub
parent 919a5e9077
commit b2f306789c
2 changed files with 147 additions and 92 deletions

View File

@@ -91,12 +91,23 @@ Updating WGDashboard is currently in **alpha** stage. While the update process m
## ⚙️ Environment Variables ## ⚙️ Environment Variables
| Variable | Accepted Values | Default | Example | Description | | Variable | Accepted Values | Default | Example | Description |
|---------------|------------------------------------------|-------------------------|------------------------|-----------------------------------------------------------------------------| | ------------------ | ---------------------------------------- | ----------------------- | --------------------- | ----------------------------------------------------------------------- |
| `tz` | Timezone | `Europe/Amsterdam` | `America/New_York` | Sets the container's timezone. Useful for accurate logs and scheduling. | | `tz` | Timezone | `Europe/Amsterdam` | `America/New_York` | Sets the container's timezone. Useful for accurate logs and scheduling. |
| `global_dns` | IPv4 and IPv6 addresses | `9.9.9.9` | `8.8.8.8`, `1.1.1.1` | Default DNS for WireGuard clients. | | `global_dns` | IPv4 and IPv6 addresses | `9.9.9.9` | `8.8.8.8`, `1.1.1.1` | Default DNS for WireGuard clients. |
| `public_ip` | Public IP address | Retrieved automatically | `253.162.134.73` | Used to generate accurate client configs. Needed if container is NATd. | | `public_ip` | Public IP address | Retrieved automatically | `253.162.134.73` | Used to generate accurate client configs. Needed if container is NATd. |
| `wgd_port` | Any port that is allowed for the process | `10086` | `443` | This port is used to set the WGDashboard web port. | | `wgd_port` | Any port that is allowed for the process | `10086` | `443` | This port is used to set the WGDashboard web port. |
| `username` | Any nonempty string | `-` | `admin` | Username for the WGDashboard web interface account. |
| `password` | Any nonempty string | `-` | `s3cr3tP@ss` | Password for the WGDashboard web interface account (stored hashed). |
| `enable_totp` | `true`, `false` | `true` | `false` | Enable TOTPbased twofactor authentication for the account. |
| `wg_autostart` | Wireguard interface name | `false` | `true` | Autostart the WireGuard client when the container launches. |
| `email_server` | SMTP server address | `-` | `smtp.gmail.com` | SMTP server for sending email notifications. |
| `email_port` | SMTP port number | `-` | `587` | Port for connecting to the SMTP server. |
| `email_encryption` | `TLS`, `SSL`, etc. | `-` | `TLS` | Encryption method for email communication. |
| `email_username` | Any non-empty string | `-` | `user@example.com` | Username for SMTP authentication. |
| `email_password` | Any non-empty string | `-` | `app_password` | Password for SMTP authentication. |
| `email_from` | Valid email address | `-` | `noreply@example.com` | Email address used as the sender for notifications. |
| `email_template` | Path to template file | `-` | `your-template` | Custom template for email notifications. |
--- ---

View File

@@ -1,10 +1,55 @@
#!/bin/bash #!/bin/bash
# Path to the configuration file (exists because of previous function).
config_file="/data/wg-dashboard.ini" config_file="/data/wg-dashboard.ini"
trap 'stop_service' SIGTERM trap 'stop_service' SIGTERM
# Hash password with bcrypt
hash_password() {
python3 -c "import bcrypt; print(bcrypt.hashpw('$1'.encode(), bcrypt.gensalt(12)).decode())"
}
# Function to set or update section/key/value in the INI file
set_ini() {
local section="$1" key="$2" value="$3"
local current_value
# Add section if it doesn't exist
grep -q "^\[${section}\]" "$config_file" \
|| printf "\n[%s]\n" "${section}" >> "$config_file"
# Check current value if key exists
if grep -q "^[[:space:]]*${key}[[:space:]]*=" "$config_file"; then
current_value=$(grep "^[[:space:]]*${key}[[:space:]]*=" "$config_file" | cut -d= -f2- | xargs)
# Don't display actual value if it's a password field
if [[ "$key" == *"password"* ]]; then
if [ "$current_value" = "$value" ]; then
echo "- $key is already set correctly (value hidden)"
return 0
fi
sed -i "/^\[${section}\]/,/^\[/{s|^[[:space:]]*${key}[[:space:]]*=.*|${key} = ${value}|}" "$config_file"
echo "- Updated $key (value hidden)"
else
if [ "$current_value" = "$value" ]; then
echo "- $key is already set correctly ($value)"
return 0
fi
sed -i "/^\[${section}\]/,/^\[/{s|^[[:space:]]*${key}[[:space:]]*=.*|${key} = ${value}|}" "$config_file"
echo "- Updated $key to: $value"
fi
else
sed -i "/^\[${section}\]/a ${key} = ${value}" "$config_file"
# Don't display actual value if it's a password field
if [[ "$key" == *"password"* ]]; then
echo "- Added new setting $key (value hidden)"
else
echo "- Added new setting $key: $value"
fi
fi
}
stop_service() { stop_service() {
echo "[WGDashboard] Stopping WGDashboard..." echo "[WGDashboard] Stopping WGDashboard..."
/bin/bash ./wgd.sh stop /bin/bash ./wgd.sh stop
@@ -15,67 +60,59 @@ echo "------------------------- START ----------------------------"
echo "Starting the WireGuard Dashboard Docker container." echo "Starting the WireGuard Dashboard Docker container."
ensure_installation() { ensure_installation() {
# When using a custom directory to store the files, this part moves over and makes sure the installation continues.
echo "Quick-installing..." echo "Quick-installing..."
# Make the wgd.sh script executable. # Make the wgd.sh script executable.
chmod +x "${WGDASH}"/src/wgd.sh chmod +x "${WGDASH}"/src/wgd.sh
cd "${WGDASH}"/src || exit cd "${WGDASH}"/src || exit
# Github issue: https://github.com/donaldzou/WGDashboard/issues/723 # Github issue: https://github.com/donaldzou/WGDashboard/issues/723
echo "Checking for stale pids..." echo "Checking for stale pids..."
if [[ -f ${WGDASH}/src/gunicorn.pid ]]; then if [[ -f ${WGDASH}/src/gunicorn.pid ]]; then
echo "Found stale pid, removing..." echo "Found stale pid, removing..."
rm ${WGDASH}/src/gunicorn.pid rm ${WGDASH}/src/gunicorn.pid
fi fi
# Removing clear shell command from the wgd.sh script to enhance docker logging. # Removing clear shell command from the wgd.sh script to enhance docker logging.
echo "Removing clear command from wgd.sh for better Docker logging." echo "Removing clear command from wgd.sh for better Docker logging."
sed -i '/clear/d' ./wgd.sh sed -i '/clear/d' ./wgd.sh
# Create the databases directory if it does not exist yet. # Create required directories and links
if [ ! -d "/data/db" ]; then if [ ! -d "/data/db" ]; then
echo "Creating database dir" echo "Creating database dir"
mkdir /data/db mkdir -p /data/db
fi fi
# Linking the database on the persistent directory location to where WGDashboard expects.
if [ ! -d "${WGDASH}/src/db" ]; then if [ ! -d "${WGDASH}/src/db" ]; then
ln -s /data/db "${WGDASH}/src/db" ln -s /data/db "${WGDASH}/src/db"
fi fi
# Create the wg-dashboard.ini file if it does not exist yet.
if [ ! -f "${config_file}" ]; then if [ ! -f "${config_file}" ]; then
echo "Creating wg-dashboard.ini file" echo "Creating wg-dashboard.ini file"
touch "${config_file}" touch "${config_file}"
fi fi
# Link the wg-dashboard.ini file from the persistent directory to where WGDashboard expects it.
if [ ! -f "${WGDASH}/src/wg-dashboard.ini" ]; then if [ ! -f "${WGDASH}/src/wg-dashboard.ini" ]; then
ln -s "${config_file}" "${WGDASH}/src/wg-dashboard.ini" ln -s "${config_file}" "${WGDASH}/src/wg-dashboard.ini"
fi fi
# Create the Python virtual environment. # Create the Python virtual environment.
. "${WGDASH}/src/venv/bin/activate" . "${WGDASH}/src/venv/bin/activate"
# Use the bash interpreter to install WGDashboard according to the wgd.sh script. # Use the bash interpreter to install WGDashboard according to the wgd.sh script.
/bin/bash ./wgd.sh install /bin/bash ./wgd.sh install
echo "Looks like the installation succeeded. Moving on." echo "Looks like the installation succeeded. Moving on."
# This first step is to ensure the wg0.conf file exists, and if not, then its copied over from the ephemeral container storage. # Setup WireGuard if needed
# This is done so WGDashboard it works out of the box, it also sets a randomly generated private key.
if [ ! -f "/etc/wireguard/wg0.conf" ]; then if [ ! -f "/etc/wireguard/wg0.conf" ]; then
echo "Standard wg0 Configuration file not found, grabbing template."
cp -a "/configs/wg0.conf.template" "/etc/wireguard/wg0.conf" cp -a "/configs/wg0.conf.template" "/etc/wireguard/wg0.conf"
echo "Setting a secure private key." echo "Setting a secure private key."
local privateKey local privateKey
privateKey=$(wg genkey) privateKey=$(wg genkey)
sed -i "s|^PrivateKey *=.*$|PrivateKey = ${privateKey}|g" /etc/wireguard/wg0.conf sed -i "s|^PrivateKey *=.*$|PrivateKey = ${privateKey}|g" /etc/wireguard/wg0.conf
echo "Done setting template." echo "Done setting template."
else else
echo "Existing wg0 configuration file found, using that." echo "Existing wg0 configuration file found, using that."
@@ -84,63 +121,75 @@ ensure_installation() {
set_envvars() { set_envvars() {
printf "\n------------- SETTING ENVIRONMENT VARIABLES ----------------\n" printf "\n------------- SETTING ENVIRONMENT VARIABLES ----------------\n"
# Check if the file is empty # Check if config file is empty
if [ ! -s "${config_file}" ]; then if [ ! -s "${config_file}" ]; then
echo "Config file is empty. Creating [Peers] section." echo "Config file is empty. Creating initial structure."
# Create [Peers] section with initial values
{
echo "[Peers]"
echo "peer_global_dns = ${global_dns}"
echo "remote_endpoint = ${public_ip}"
echo -e "\n[Server]"
echo "app_port = ${wgd_port}"
} > "${config_file}"
else
echo "Config file is not empty, using pre-existing."
fi fi
echo "Verifying current variables..." echo "Checking basic configuration:"
set_ini Peers peer_global_dns "${global_dns}"
# Check and update the DNS if it has changed
current_dns=$(grep "peer_global_dns = " "${config_file}" | awk '{print $NF}') if [ -z "${public_ip}" ]; then
if [ "${global_dns}" == "$current_dns" ]; then public_ip=$(curl -s ifconfig.me)
echo "DNS is set correctly, moving on." echo "Automatically detected public IP: ${public_ip}"
else
echo "Changing default DNS..."
sed -i "s/^peer_global_dns = .*/peer_global_dns = ${global_dns}/" "${config_file}"
fi fi
# Checking the current set public IP and changing it if it has changed. set_ini Peers remote_endpoint "${public_ip}"
current_public_ip=$(grep "remote_endpoint = " "${config_file}" | awk '{print $NF}') set_ini Server app_port "${wgd_port}"
if [ "${public_ip}" == "" ]; then
default_ip=$(curl -s ifconfig.me) # Account settings - process all parameters
echo "Configuring user account:"
echo "Trying to fetch the Public-IP using ifconfig.me: ${default_ip}" # Basic account variables
sed -i "s/^remote_endpoint = .*/remote_endpoint = ${default_ip}/" "${config_file}" [[ -n "$username" ]] && set_ini Account username "${username}"
elif [ "${current_public_ip}" != "${public_ip}" ]; then
sed -i "s/^remote_endpoint = .*/remote_endpoint = ${public_ip}/" "${config_file}" if [[ -n "$password" ]]; then
else echo "- Setting password"
echo "Public-IP is correct, moving on." set_ini Account password "$(hash_password "${password}")"
fi fi
# Checking the current WGDashboard web port and changing if needed. # Additional account variables
current_wgd_port=$(grep "app_port = " "${config_file}" | awk '{print $NF}') [[ -n "$enable_totp" ]] && set_ini Account enable_totp "${enable_totp}"
if [ "${current_wgd_port}" == "${wgd_port}" ]; then [[ -n "$totp_verified" ]] && set_ini Account totp_verified "${totp_verified}"
echo "Current WGD port is set correctly, moving on." [[ -n "$totp_key" ]] && set_ini Account totp_key "${totp_key}"
else
echo "Changing default WGD port..." # Welcome session
sed -i "s/^app_port = .*/app_port = ${wgd_port}/" "${config_file}" [[ -n "$welcome_session" ]] && set_ini Other welcome_session "${welcome_session}"
# If username and password are set but welcome_session isn't, disable it
if [[ -n "$username" && -n "$password" && -z "$welcome_session" ]]; then
set_ini Other welcome_session "false"
fi fi
# Autostart WireGuard
if [[ -n "$wg_autostart" ]]; then
echo "Configuring WireGuard autostart:"
set_ini WireGuardConfiguration autostart "${wg_autostart}"
fi
# Email (check if any settings need to be configured)
email_vars=("email_server" "email_port" "email_encryption" "email_username" "email_password" "email_from" "email_template")
for var in "${email_vars[@]}"; do
if [ -n "${!var}" ]; then
echo "Configuring email settings:"
break
fi
done
# Email (iterate through all possible fields)
email_fields=("server:email_server" "port:email_port" "encryption:email_encryption"
"username:email_username" "email_password:email_password"
"send_from:email_from" "email_template:email_template")
for field_pair in "${email_fields[@]}"; do
IFS=: read -r field var <<< "$field_pair"
[[ -n "${!var}" ]] && set_ini Email "$field" "${!var}"
done
} }
# === CORE SERVICES === # Start service and monitor logs
start_core() { start_and_monitor() {
printf "\n---------------------- STARTING CORE -----------------------\n" printf "\n---------------------- STARTING CORE -----------------------\n"
# Due to some instances complaining about this, making sure its there every time. # Due to some instances complaining about this, making sure its there every time.
mkdir -p /dev/net mkdir -p /dev/net
mknod /dev/net/tun c 10 200 mknod /dev/net/tun c 10 200
@@ -148,23 +197,19 @@ start_core() {
# Actually starting WGDashboard # Actually starting WGDashboard
echo "Activating Python venv and executing the WireGuard Dashboard service." echo "Activating Python venv and executing the WireGuard Dashboard service."
/bin/bash ./wgd.sh start bash ./wgd.sh start
}
ensure_blocking() {
# Wait a second before continuing, to give the python program some time to get ready. # Wait a second before continuing, to give the python program some time to get ready.
sleep 1s sleep 1
echo -e "\nEnsuring container continuation." echo -e "\nEnsuring container continuation."
# Find and tail the latest error and access logs if they exist # Find and monitor log file
local logdir="${WGDASH}/src/log" local logdir="${WGDASH}/src/log"
latestErrLog=$(find "$logdir" -name "error_*.log" -type f -print | sort -r | head -n 1) latestErrLog=$(find "$logdir" -name "error_*.log" -type f -print | sort -r | head -n 1)
# Only tail the logs if they are found # Only tail the logs if they are found
if [ -n "$latestErrLog" ]; then if [ -n "$latestErrLog" ]; then
tail -f "$latestErrLog" & tail -f "$latestErrLog" &
# Wait for the tail process to end. # Wait for the tail process to end.
wait $! wait $!
else else
@@ -173,8 +218,7 @@ ensure_blocking() {
fi fi
} }
# Execute functions for the WireGuard Dashboard services, then set the environment variables # Main execution flow
ensure_installation ensure_installation
set_envvars set_envvars
start_core start_and_monitor
ensure_blocking