From da2be181a4d2887363f6f7cd4003ae65f2857353 Mon Sep 17 00:00:00 2001 From: Aleksander <170264518+t-aleksander@users.noreply.github.com> Date: Wed, 8 Apr 2026 11:53:06 +0200 Subject: [PATCH 1/9] new one liner --- docker-compose2.0/docker-compose.setup.yaml | 42 +++ docker-compose2.0/setup.sh | 291 ++++++++++++++++++++ 2 files changed, 333 insertions(+) create mode 100644 docker-compose2.0/docker-compose.setup.yaml create mode 100755 docker-compose2.0/setup.sh diff --git a/docker-compose2.0/docker-compose.setup.yaml b/docker-compose2.0/docker-compose.setup.yaml new file mode 100644 index 0000000..9275234 --- /dev/null +++ b/docker-compose2.0/docker-compose.setup.yaml @@ -0,0 +1,42 @@ +services: + core: + restart: always + image: ghcr.io/defguard/defguard:${DEFGUARD_CORE_TAG:?DEFGUARD_CORE_TAG is required} + env_file: .env + environment: + DEFGUARD_DB_HOST: db + DEFGUARD_DB_PORT: 5432 + DEFGUARD_ADOPT_EDGE: "edge:50051" + DEFGUARD_ADOPT_GATEWAY: "gateway:50066" + depends_on: + - db + - edge + - gateway + ports: + - "8000:8000" + + edge: + restart: always + image: ghcr.io/defguard/defguard-proxy:${DEFGUARD_PROXY_TAG:?DEFGUARD_PROXY_TAG is required} + volumes: + - ./.volumes/certs/edge:/etc/defguard/certs + ports: + - "8080:8080" + + gateway: + restart: always + image: ghcr.io/defguard/gateway:${DEFGUARD_GATEWAY_TAG:?DEFGUARD_GATEWAY_TAG is required} + cap_add: + - NET_ADMIN + volumes: + - ./.volumes/certs/gateway:/etc/defguard/certs + environment: + DEFGUARD_STATS_PERIOD: 10 + HEALTH_PORT: 55003 + + db: + restart: always + image: postgres:18-alpine + env_file: .env + volumes: + - ./.volumes/db:/var/lib/postgresql diff --git a/docker-compose2.0/setup.sh b/docker-compose2.0/setup.sh new file mode 100755 index 0000000..0527e74 --- /dev/null +++ b/docker-compose2.0/setup.sh @@ -0,0 +1,291 @@ +#!/usr/bin/env bash +# shellcheck shell=bash +set -euo pipefail + +# Defguard setup script +# Usage: bash <(curl -sSL https://raw.githubusercontent.com/defguard/deployment/main/docker-compose2.0/setup.sh) +# +# Options: +# --dev use development images +# --pre-release use pre-release images +# --help show this help and exit + +COMPOSE_FILE_URL="https://raw.githubusercontent.com/defguard/deployment/main/docker-compose2.0/docker-compose.setup.yaml" +COMPOSE_FILE="./docker-compose.setup.yaml" +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" 2>/dev/null && pwd || pwd)" +COMPOSE_FILE_LOCAL="${SCRIPT_DIR}/docker-compose.setup.yaml" + +DEFGUARD_CORE_TAG="latest" +DEFGUARD_PROXY_TAG="latest" +DEFGUARD_GATEWAY_TAG="latest" +IMAGE_MODE="latest" + +check_character_support() { + echo -e "$1" | grep -q "$1" +} + +init_term() { + if check_character_support "√"; then + TXT_CHECK="✓" + TXT_BEGIN="▶" + TXT_SUB="▷" + TXT_X="✗" + else + TXT_CHECK="+" + TXT_BEGIN=">>" + TXT_SUB=">" + TXT_X="x" + fi + + if [[ $TERM == *"256"* ]]; then + C_RED="\033[31m" + C_GREEN="\033[32m" + C_YELLOW="\033[33m" + C_LRED="\033[91m" + C_LGREEN="\033[92m" + C_LYELLOW="\033[93m" + C_LBLUE="\033[94m" + C_BOLD="\033[1m" + C_BG_GREY="\033[100m" + C_END="\033[0m" + else + C_RED="" + C_GREEN="" + C_YELLOW="" + C_LRED="" + C_LGREEN="" + C_LYELLOW="" + C_LBLUE="" + C_BOLD="" + C_BG_GREY="" + C_END="" + fi +} + +info() { echo -e " ${TXT_BEGIN} $*"; } +success() { echo -e " ${C_LGREEN}${TXT_CHECK}${C_END} $*"; } +warn() { echo -e " ${C_LYELLOW}${TXT_X}${C_END} $*"; } +error() { echo -e " ${C_LRED}${TXT_X}${C_END} $*" >&2; } +die() { error "$*"; exit 1; } +section() { echo -e "\n${C_BOLD}$*${C_END}\n"; } + +print_header() { + echo -e "${C_LBLUE}" + cat << 'LOGO' + # + ## # + ## ## # # ## # + ## ## # # # # + # ## # #### # #### ##### #### # # #### ### #### # + # ## ## # ## # ## # # # # # # # # # ## + ## ## # # ######## # # # # # # # # # + # ## ## # # # ## # ##### # # ###### # # # + # ## # # ## # # # # # # # # # # ## + ## ## #### # ##### # ####### #### # #### # # #### # + ## ## # # # + ## # ####### + # +LOGO + echo -e "${C_END}" + echo "Defguard docker-compose 2.0 setup script" + echo -e "Copyright ©2023-2026 ${C_BOLD}defguard sp. z o.o.${C_END} <${C_BG_GREY}${C_YELLOW}https://defguard.net/${C_END}>" + echo +} + +usage() { + echo "Usage: $(basename "$0") [OPTIONS]" + echo + echo "Available options:" + echo " --dev use development images" + echo " --pre-release use pre-release images" + echo " --help show this help and exit" + echo + exit 0 +} + +parse_args() { + while [[ $# -gt 0 ]]; do + case "$1" in + --dev) + IMAGE_MODE="dev" + DEFGUARD_CORE_TAG="dev" + DEFGUARD_PROXY_TAG="dev" + DEFGUARD_GATEWAY_TAG="dev" + shift ;; + --pre-release) + IMAGE_MODE="pre-release" + DEFGUARD_CORE_TAG="pre-release" + DEFGUARD_PROXY_TAG="pre-release" + DEFGUARD_GATEWAY_TAG="pre-release" + shift ;; + --help|-h) + usage ;; + *) + die "Unknown option: $1. Run with --help for usage." ;; + esac + done +} + +gen_secret() { + if command -v openssl &>/dev/null; then + openssl rand -hex 32 + else + tr -dc 'a-f0-9' /dev/null | head -c 64 + fi +} + +get_host_ip() { + local ip="" + if command -v ip &>/dev/null; then + ip=$(ip route get 1.1.1.1 2>/dev/null | awk '{for(i=1;i<=NF;i++) if($i=="src") print $(i+1); exit}') + fi + if [[ -z "$ip" ]] && command -v ipconfig &>/dev/null; then + ip=$(ipconfig getifaddr en0 2>/dev/null || ipconfig getifaddr en1 2>/dev/null || true) + fi + if [[ -z "$ip" ]]; then + ip=$(hostname -I 2>/dev/null | awk '{print $1}') + fi + printf '%s' "${ip:-127.0.0.1}" +} + +check_deps() { + section "Checking dependencies" + + if ! command -v docker &>/dev/null; then + die "Docker is not installed. Please install it first: https://docs.docker.com/get-docker/" + fi + success "Docker found: $(docker --version)" + + if ! docker compose version &>/dev/null 2>&1; then + die "Docker Compose plugin is not installed. Please install it: https://docs.docker.com/compose/install/" + fi + success "Docker Compose found: $(docker compose version --short)" + + if ! command -v curl &>/dev/null && ! command -v wget &>/dev/null; then + die "Neither curl nor wget is available. Please install one of them." + fi +} + +check_volumes() { + if [[ -d ".volumes" ]]; then + die ".volumes directory already exists. Remove it before running setup, or this may overwrite an existing installation." + fi +} + +download_compose_file() { + section "Preparing compose file" + + if [[ -f "$COMPOSE_FILE" ]]; then + success "Found existing ${COMPOSE_FILE} – skipping download." + return + fi + + if [[ -f "$COMPOSE_FILE_LOCAL" ]]; then + cp "$COMPOSE_FILE_LOCAL" "$COMPOSE_FILE" + success "Loaded compose file from local path." + return + fi + + info "Downloading docker-compose.setup.yaml..." + if command -v curl &>/dev/null; then + curl -sSfL "$COMPOSE_FILE_URL" -o "$COMPOSE_FILE" + else + wget -qO "$COMPOSE_FILE" "$COMPOSE_FILE_URL" + fi + success "Compose file downloaded." +} + +write_env() { + section "Generating configuration" + + if [[ -f ".env" ]]; then + warn ".env already exists – skipping generation. Remove it to regenerate." + return + fi + + local secret_key auth_secret gw_secret yubibridge_secret db_password + secret_key=$(gen_secret) + auth_secret=$(gen_secret) + gw_secret=$(gen_secret) + yubibridge_secret=$(gen_secret) + db_password=$(gen_secret | head -c 24) + + case "$IMAGE_MODE" in + dev) info "Image mode: ${C_RED}development${C_END}" ;; + pre-release) info "Image mode: ${C_YELLOW}pre-release${C_END}" ;; + *) info "Image mode: ${C_GREEN}latest${C_END}" ;; + esac + + cat > .env << EOF +# Defguard – generated by setup.sh on $(date -u +"%Y-%m-%dT%H:%M:%SZ") + +DEFGUARD_CORE_TAG=${DEFGUARD_CORE_TAG} +DEFGUARD_PROXY_TAG=${DEFGUARD_PROXY_TAG} +DEFGUARD_GATEWAY_TAG=${DEFGUARD_GATEWAY_TAG} + +POSTGRES_DB=defguard +POSTGRES_USER=defguard +POSTGRES_PASSWORD=${db_password} + +DEFGUARD_DB_NAME=defguard +DEFGUARD_DB_USER=defguard +DEFGUARD_DB_PASSWORD=${db_password} + +DEFGUARD_SECRET_KEY=${secret_key} +DEFGUARD_AUTH_SECRET=${auth_secret} +DEFGUARD_GATEWAY_SECRET=${gw_secret} +DEFGUARD_YUBIBRIDGE_SECRET=${yubibridge_secret} +EOF + + success ".env written." +} + +launch() { + section "Starting Defguard" + + mkdir -p .volumes/certs/edge + mkdir -p .volumes/certs/gateway + mkdir -p .volumes/db + + info "Pulling images (this may take a moment)..." + docker compose -f "$COMPOSE_FILE" pull + + info "Starting services..." + docker compose -f "$COMPOSE_FILE" up -d + + success "All services started." +} + +show_wizard_info() { + local wizard_url + wizard_url="http://$(get_host_ip):8000" + + echo + echo -e " ${TXT_BEGIN} Services status:" + echo + docker compose -f "$COMPOSE_FILE" ps + echo + echo -e "${C_LGREEN}${C_BOLD} ${TXT_CHECK} All containers are up. ${C_END}" + echo + echo -e "${C_LGREEN}${C_BOLD} ╔══════════════════════════════════════════════════════╗" + echo -e " ║ ║" + echo -e " ║ Continue setup in your browser: ║" + printf " ║ %-51s║\n" "${wizard_url}" + echo -e " ║ ║" + echo -e " ╚══════════════════════════════════════════════════════╝${C_END}" + echo +} + +main() { + init_term + parse_args "$@" + print_header + check_deps + check_volumes + download_compose_file + write_env + launch + show_wizard_info +} + +main "$@" From dbe8b4f218ca682c746838972d7dda50bf00bf46 Mon Sep 17 00:00:00 2001 From: Aleksander <170264518+t-aleksander@users.noreply.github.com> Date: Wed, 8 Apr 2026 12:04:35 +0200 Subject: [PATCH 2/9] Update setup.sh --- docker-compose2.0/setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose2.0/setup.sh b/docker-compose2.0/setup.sh index 0527e74..95d3db7 100755 --- a/docker-compose2.0/setup.sh +++ b/docker-compose2.0/setup.sh @@ -10,7 +10,7 @@ set -euo pipefail # --pre-release use pre-release images # --help show this help and exit -COMPOSE_FILE_URL="https://raw.githubusercontent.com/defguard/deployment/main/docker-compose2.0/docker-compose.setup.yaml" +COMPOSE_FILE_URL="https://raw.githubusercontent.com/defguard/deployment/one-liner-2.0/docker-compose2.0/docker-compose.setup.yaml" COMPOSE_FILE="./docker-compose.setup.yaml" SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" 2>/dev/null && pwd || pwd)" COMPOSE_FILE_LOCAL="${SCRIPT_DIR}/docker-compose.setup.yaml" From 99a88e01cf2defdabe093b2aa107ddde5cdaf5fd Mon Sep 17 00:00:00 2001 From: Aleksander <170264518+t-aleksander@users.noreply.github.com> Date: Thu, 9 Apr 2026 09:24:58 +0200 Subject: [PATCH 3/9] remove secrets generation --- docker-compose2.0/setup.sh | 5 ----- 1 file changed, 5 deletions(-) diff --git a/docker-compose2.0/setup.sh b/docker-compose2.0/setup.sh index 95d3db7..3d50570 100755 --- a/docker-compose2.0/setup.sh +++ b/docker-compose2.0/setup.sh @@ -230,11 +230,6 @@ POSTGRES_PASSWORD=${db_password} DEFGUARD_DB_NAME=defguard DEFGUARD_DB_USER=defguard DEFGUARD_DB_PASSWORD=${db_password} - -DEFGUARD_SECRET_KEY=${secret_key} -DEFGUARD_AUTH_SECRET=${auth_secret} -DEFGUARD_GATEWAY_SECRET=${gw_secret} -DEFGUARD_YUBIBRIDGE_SECRET=${yubibridge_secret} EOF success ".env written." From b77a4d767961f8b1b82b8202bc1f587a3e9565a1 Mon Sep 17 00:00:00 2001 From: Aleksander <170264518+t-aleksander@users.noreply.github.com> Date: Thu, 9 Apr 2026 09:26:54 +0200 Subject: [PATCH 4/9] Change services restart to unless-stopped --- docker-compose2.0/docker-compose.setup.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docker-compose2.0/docker-compose.setup.yaml b/docker-compose2.0/docker-compose.setup.yaml index 9275234..ae2b8cb 100644 --- a/docker-compose2.0/docker-compose.setup.yaml +++ b/docker-compose2.0/docker-compose.setup.yaml @@ -1,6 +1,6 @@ services: core: - restart: always + restart: unless-stopped image: ghcr.io/defguard/defguard:${DEFGUARD_CORE_TAG:?DEFGUARD_CORE_TAG is required} env_file: .env environment: @@ -16,7 +16,7 @@ services: - "8000:8000" edge: - restart: always + restart: unless-stopped image: ghcr.io/defguard/defguard-proxy:${DEFGUARD_PROXY_TAG:?DEFGUARD_PROXY_TAG is required} volumes: - ./.volumes/certs/edge:/etc/defguard/certs @@ -24,7 +24,7 @@ services: - "8080:8080" gateway: - restart: always + restart: unless-stopped image: ghcr.io/defguard/gateway:${DEFGUARD_GATEWAY_TAG:?DEFGUARD_GATEWAY_TAG is required} cap_add: - NET_ADMIN @@ -35,7 +35,7 @@ services: HEALTH_PORT: 55003 db: - restart: always + restart: unless-stopped image: postgres:18-alpine env_file: .env volumes: From af2dfa85b4f08fbc86efd59ebe082a109717d5ac Mon Sep 17 00:00:00 2001 From: Aleksander <170264518+t-aleksander@users.noreply.github.com> Date: Thu, 9 Apr 2026 09:37:24 +0200 Subject: [PATCH 5/9] Set default image tags to pre-release --- docker-compose2.0/setup.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docker-compose2.0/setup.sh b/docker-compose2.0/setup.sh index 3d50570..4049b40 100755 --- a/docker-compose2.0/setup.sh +++ b/docker-compose2.0/setup.sh @@ -15,10 +15,10 @@ COMPOSE_FILE="./docker-compose.setup.yaml" SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" 2>/dev/null && pwd || pwd)" COMPOSE_FILE_LOCAL="${SCRIPT_DIR}/docker-compose.setup.yaml" -DEFGUARD_CORE_TAG="latest" -DEFGUARD_PROXY_TAG="latest" -DEFGUARD_GATEWAY_TAG="latest" -IMAGE_MODE="latest" +DEFGUARD_CORE_TAG="pre-release" +DEFGUARD_PROXY_TAG="pre-release" +DEFGUARD_GATEWAY_TAG="pre-release" +IMAGE_MODE="pre-release" check_character_support() { echo -e "$1" | grep -q "$1" From 3aac12ee57874f3d9558f87ccc06fa6d20cfe871 Mon Sep 17 00:00:00 2001 From: Aleksander <170264518+t-aleksander@users.noreply.github.com> Date: Thu, 9 Apr 2026 14:42:28 +0200 Subject: [PATCH 6/9] change port --- docker-compose2.0/docker-compose.setup.yaml | 4 ++++ docker-compose2.0/setup.sh | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/docker-compose2.0/docker-compose.setup.yaml b/docker-compose2.0/docker-compose.setup.yaml index ae2b8cb..0c7561a 100644 --- a/docker-compose2.0/docker-compose.setup.yaml +++ b/docker-compose2.0/docker-compose.setup.yaml @@ -18,6 +18,7 @@ services: edge: restart: unless-stopped image: ghcr.io/defguard/defguard-proxy:${DEFGUARD_PROXY_TAG:?DEFGUARD_PROXY_TAG is required} + env_file: .env volumes: - ./.volumes/certs/edge:/etc/defguard/certs ports: @@ -26,6 +27,7 @@ services: gateway: restart: unless-stopped image: ghcr.io/defguard/gateway:${DEFGUARD_GATEWAY_TAG:?DEFGUARD_GATEWAY_TAG is required} + env_file: .env cap_add: - NET_ADMIN volumes: @@ -33,6 +35,8 @@ services: environment: DEFGUARD_STATS_PERIOD: 10 HEALTH_PORT: 55003 + ports: + - "51820:51820/udp" db: restart: unless-stopped diff --git a/docker-compose2.0/setup.sh b/docker-compose2.0/setup.sh index 4049b40..bd83bbb 100755 --- a/docker-compose2.0/setup.sh +++ b/docker-compose2.0/setup.sh @@ -11,9 +11,9 @@ set -euo pipefail # --help show this help and exit COMPOSE_FILE_URL="https://raw.githubusercontent.com/defguard/deployment/one-liner-2.0/docker-compose2.0/docker-compose.setup.yaml" -COMPOSE_FILE="./docker-compose.setup.yaml" +COMPOSE_FILE="./docker-compose.yaml" SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" 2>/dev/null && pwd || pwd)" -COMPOSE_FILE_LOCAL="${SCRIPT_DIR}/docker-compose.setup.yaml" +COMPOSE_FILE_LOCAL="${SCRIPT_DIR}/docker-compose.yaml" DEFGUARD_CORE_TAG="pre-release" DEFGUARD_PROXY_TAG="pre-release" From b4bd90ab156a7235a29abe588a2ae24548907216 Mon Sep 17 00:00:00 2001 From: Aleksander <170264518+t-aleksander@users.noreply.github.com> Date: Thu, 9 Apr 2026 14:57:01 +0200 Subject: [PATCH 7/9] add test --- .github/workflows/test2.yml | 56 +++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 .github/workflows/test2.yml diff --git a/.github/workflows/test2.yml b/.github/workflows/test2.yml new file mode 100644 index 0000000..5efb756 --- /dev/null +++ b/.github/workflows/test2.yml @@ -0,0 +1,56 @@ +name: Test setup script 2.0 + +on: + push: + branches: + - main + - one-liner-2.0 + paths: + - 'docker-compose2.0/**' + - '.github/workflows/test2.yml' + pull_request: + branches: + - main + paths: + - 'docker-compose2.0/**' + - '.github/workflows/test2.yml' + +jobs: + test: + name: Test setup script 2.0 + runs-on: [self-hosted, Linux, X64] + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Login to GitHub container registry + uses: docker/login-action@v2 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Create working directory + run: mkdir temp + + - name: Copy compose file + run: cp docker-compose2.0/docker-compose.setup.yaml temp/docker-compose.yaml + + - name: Run setup script + working-directory: temp + run: bash ../docker-compose2.0/setup.sh + + - name: Wait for stack to be ready + run: sleep 15s + + - name: Test health endpoint + run: curl -f http://localhost:8000/api/v1/health + + - name: Stop compose stack + if: always() + working-directory: temp + run: docker compose down -v + + - name: Cleanup + if: always() + run: sudo rm -rf temp From e16149d680f9e2681a61f1d8e79670e2cdf2e2af Mon Sep 17 00:00:00 2001 From: Aleksander <170264518+t-aleksander@users.noreply.github.com> Date: Fri, 10 Apr 2026 11:19:05 +0200 Subject: [PATCH 8/9] dont duplicate tests --- .github/workflows/test2.yml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/.github/workflows/test2.yml b/.github/workflows/test2.yml index 5efb756..be1e1fa 100644 --- a/.github/workflows/test2.yml +++ b/.github/workflows/test2.yml @@ -4,16 +4,15 @@ on: push: branches: - main - - one-liner-2.0 paths: - - 'docker-compose2.0/**' - - '.github/workflows/test2.yml' + - "docker-compose2.0/**" + - ".github/workflows/test2.yml" pull_request: branches: - main paths: - - 'docker-compose2.0/**' - - '.github/workflows/test2.yml' + - "docker-compose2.0/**" + - ".github/workflows/test2.yml" jobs: test: From e870fab2272b213a0b3943407f0926fa5a78a776 Mon Sep 17 00:00:00 2001 From: Aleksander <170264518+t-aleksander@users.noreply.github.com> Date: Fri, 10 Apr 2026 11:21:44 +0200 Subject: [PATCH 9/9] remove unused stuff --- docker-compose2.0/setup.sh | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/docker-compose2.0/setup.sh b/docker-compose2.0/setup.sh index bd83bbb..f3ed45c 100755 --- a/docker-compose2.0/setup.sh +++ b/docker-compose2.0/setup.sh @@ -203,11 +203,7 @@ write_env() { return fi - local secret_key auth_secret gw_secret yubibridge_secret db_password - secret_key=$(gen_secret) - auth_secret=$(gen_secret) - gw_secret=$(gen_secret) - yubibridge_secret=$(gen_secret) + local db_password db_password=$(gen_secret | head -c 24) case "$IMAGE_MODE" in