Last active
July 2, 2026 20:03
-
-
Save dedworks/2c3def2ffde3dafd8494860b78b8b70b to your computer and use it in GitHub Desktop.
gluetun-mullvad-rotate: Automate randomly choosing a Mullvad VPN server based on SERVER_CITIES variable in docker_compose.yml
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| # Depends: jq (https://stedolan.github.io/jq/) | |
| default_compose="/docker/compose/gluetun/docker-compose.yml" | |
| compose="${1:-$default_compose}" | |
| relays_url="https://api.mullvad.net/www/relays/all/" | |
| fail() { printf "%s: %s\n" "$0" "$*"; exit 1; } | |
| read_var() { | |
| declare -g $1="$(sed -n '/^\s*- '$1'=/{s///;p}' "$compose")" | |
| [[ -z "${!1}" ]] && fail "Couldn't read '$1' value from '$compose'." | |
| } | |
| extract_hostnames() { | |
| jq -r \ | |
| --arg cities "$SERVER_CITIES" \ | |
| --arg vpntype "$VPN_TYPE" \ | |
| ' | |
| . as $mullvad | |
| | $cities | split(",") | |
| | [ .[] | sub(" (?<state>[A-Z][A-Z]$)"; ", " + .state) ] | |
| | . as $cities | |
| | $mullvad | .[] | |
| | select(.active==true) | |
| | select(.city_name as $c | any($cities[]; . == $c)) | |
| | select(.type == $vpntype) | |
| | .hostname | |
| ' | |
| } | |
| type jq &>/dev/null || | |
| fail "jq not installed or not in PATH (https://stedolan.github.io/jq/)" | |
| read_var VPN_TYPE | |
| read_var SERVER_CITIES | |
| read_var SERVER_HOSTNAMES | |
| servers=$(curl -s "$relays_url" | extract_hostnames) | |
| servers=$(grep -v "^$SERVER_HOSTNAMES$" <<<$servers) # Don't pick current server | |
| [[ -z "$servers" ]] && | |
| fail "No candidate servers returned for cities '$SERVER_CITIES'." | |
| server="$(shuf -n1 <<< "$servers")" | |
| printf "New server: %s\tOld server: %s\n" "$server" "$SERVER_HOSTNAMES" | |
| sed -i~ "s/^\(\s*- SERVER_HOSTNAMES\)=.*/\1=$server/" "$compose" && | |
| rm -f "$compose~" | |
| docker-compose --file "$compose" pull | |
| docker-compose --file "$compose" up -d |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment