From fa185b0f9002e9c556d995fdaf93adeadcf2af37 Mon Sep 17 00:00:00 2001 From: Sean Baker Date: Wed, 25 Mar 2026 14:49:02 -0600 Subject: [PATCH 1/5] Added support for MacOS and Linux ARM64 --- .github/workflows/build_and_test_debug.yml | 26 +++++++++++++++++++ .../install_scripts/install_server.sh | 4 +-- src/shadowbox/Taskfile.yml | 16 +++++++++--- src/shadowbox/integration_test/test.sh | 8 +++--- 4 files changed, 46 insertions(+), 8 deletions(-) diff --git a/.github/workflows/build_and_test_debug.yml b/.github/workflows/build_and_test_debug.yml index fff4e8c15..720d90f9f 100644 --- a/.github/workflows/build_and_test_debug.yml +++ b/.github/workflows/build_and_test_debug.yml @@ -81,6 +81,32 @@ jobs: files: | src/shadowbox/server/api.yml + shadowbox-arm64: + name: Shadowbox (arm64) + runs-on: ubuntu-22.04-arm + needs: lint + steps: + - name: Checkout + uses: actions/checkout@v2.3.4 + + - name: Install Node + uses: actions/setup-node@v3 + with: + node-version: 18 + cache: npm + + - name: Install NPM Dependencies + run: npm ci + + - name: Shadowbox Debug Build (arm64) + run: TARGET_ARCH=aarch64 ./task shadowbox:build + + - name: Shadowbox Unit Test + run: ./task shadowbox:test + + - name: Shadowbox Docker Build (arm64) + run: TARGET_ARCH=aarch64 ./task shadowbox:docker:build + manual-install-script: name: Manual Install Script runs-on: ubuntu-latest diff --git a/src/server_manager/install_scripts/install_server.sh b/src/server_manager/install_scripts/install_server.sh index 04013372a..9bf72a095 100755 --- a/src/server_manager/install_scripts/install_server.sh +++ b/src/server_manager/install_scripts/install_server.sh @@ -456,8 +456,8 @@ function set_hostname() { install_shadowbox() { local MACHINE_TYPE MACHINE_TYPE="$(uname -m)" - if [[ "${MACHINE_TYPE}" != "x86_64" ]]; then - log_error "Unsupported machine type: ${MACHINE_TYPE}. Please run this script on a x86_64 machine" + if [[ "${MACHINE_TYPE}" != "x86_64" && "${MACHINE_TYPE}" != "aarch64" && "${MACHINE_TYPE}" != "arm64" ]]; then + log_error "Unsupported machine type: ${MACHINE_TYPE}. Supported architectures: x86_64, aarch64/arm64." exit 1 fi diff --git a/src/shadowbox/Taskfile.yml b/src/shadowbox/Taskfile.yml index fb72a9b87..0dc314145 100644 --- a/src/shadowbox/Taskfile.yml +++ b/src/shadowbox/Taskfile.yml @@ -23,7 +23,7 @@ tasks: vars: TARGET_OS: '{{.TARGET_OS | default "linux"}}' TARGET_ARCH: '{{.TARGET_ARCH | default "x86_64"}}' - GOARCH: '{{get (dict "x86_64" "amd64") .TARGET_ARCH | default .TARGET_ARCH}}' + GOARCH: '{{get (dict "x86_64" "amd64" "aarch64" "arm64") .TARGET_ARCH | default .TARGET_ARCH}}' TARGET_DIR: '{{.TARGET_DIR | default (joinPath .OUTPUT_BASE .TARGET_OS .TARGET_ARCH)}}' NODE_DIR: '{{joinPath .TARGET_DIR "app"}}' BIN_DIR: '{{joinPath .TARGET_DIR "bin"}}' @@ -79,10 +79,19 @@ tasks: # Newer node images have no valid content trust data. # Pin the image node:16.18.0-alpine3.16 by hash. # See image at https://hub.docker.com/_/node/tags?page=1&name=18.18.0-alpine3.18 + # Note: "aarch64" is an alias for "arm64" — Linux ARM64 hosts report "aarch64" via uname -m. NODE_IMAGE: '{{get (dict - "x86_64" "node@sha256:a0b787b0d53feacfa6d606fb555e0dbfebab30573277f1fe25148b05b66fa097" - "arm64" "node@sha256:b4b7a1dd149c65ee6025956ac065a843b4409a62068bd2b0cbafbb30ca2fab3b" + "x86_64" "node@sha256:a0b787b0d53feacfa6d606fb555e0dbfebab30573277f1fe25148b05b66fa097" + "arm64" "node@sha256:b4b7a1dd149c65ee6025956ac065a843b4409a62068bd2b0cbafbb30ca2fab3b" + "aarch64" "node@sha256:b4b7a1dd149c65ee6025956ac065a843b4409a62068bd2b0cbafbb30ca2fab3b" + ) .TARGET_ARCH + }}' + DOCKER_PLATFORM: '{{get + (dict + "x86_64" "linux/amd64" + "arm64" "linux/arm64" + "aarch64" "linux/arm64" ) .TARGET_ARCH }}' env: @@ -103,6 +112,7 @@ tasks: # Build image with given root - | "${DOCKER:-docker}" build --force-rm \ + --platform '{{.DOCKER_PLATFORM}}' \ --build-arg NODE_IMAGE='{{.NODE_IMAGE}}' \ --build-arg VERSION='{{.VERSION}}' \ -f '{{joinPath .TASKFILE_DIR "docker" "Dockerfile"}}' \ diff --git a/src/shadowbox/integration_test/test.sh b/src/shadowbox/integration_test/test.sh index 84b194e6b..0f6adc841 100755 --- a/src/shadowbox/integration_test/test.sh +++ b/src/shadowbox/integration_test/test.sh @@ -100,10 +100,13 @@ function setup() { "${DOCKER}" run -d --rm -p "10080:80" --network="${NET_OPEN}" --network-alias="target" --name="${TARGET_CONTAINER}" "${TARGET_IMAGE}" # Shadowsocks service. + # Start on NET_OPEN first so that -p host port binding works on macOS Docker Desktop + # (Docker Desktop does not publish ports when the initial network is --internal). + # Then connect to NET_BLOCKED so the security isolation tests still pass. declare -ar shadowbox_flags=( -d --rm - --network="${NET_BLOCKED}" + --network="${NET_OPEN}" --network-alias="shadowbox" -p "20443:443" -e "SB_API_PORT=443" @@ -118,8 +121,7 @@ function setup() { "${SHADOWBOX_IMAGE}" ) "${DOCKER}" run "${shadowbox_flags[@]}" - # "${DOCKER}" network connect --alias shadowbox "${NET_BLOCKED}" "${SHADOWBOX_CONTAINER}" - "${DOCKER}" network connect "${NET_OPEN}" "${SHADOWBOX_CONTAINER}" + "${DOCKER}" network connect --alias shadowbox "${NET_BLOCKED}" "${SHADOWBOX_CONTAINER}" # Client service. "${DOCKER}" build --force-rm -t "${CLIENT_IMAGE}" "$(dirname "$0")/client" From 23e468b4340d2f1a59cbdea4494d5131856c6b80 Mon Sep 17 00:00:00 2001 From: Sean Baker Date: Mon, 6 Apr 2026 23:20:18 +0800 Subject: [PATCH 2/5] Skip Chromium install on arm64 Tests passing on ACT --- .github/workflows/build_and_test_debug.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build_and_test_debug.yml b/.github/workflows/build_and_test_debug.yml index 720d90f9f..d68f257b0 100644 --- a/.github/workflows/build_and_test_debug.yml +++ b/.github/workflows/build_and_test_debug.yml @@ -96,7 +96,7 @@ jobs: cache: npm - name: Install NPM Dependencies - run: npm ci + run: PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true npm ci - name: Shadowbox Debug Build (arm64) run: TARGET_ARCH=aarch64 ./task shadowbox:build From 1f1c03cfc43dc77175a434dcb42cf8018e11ff7f Mon Sep 17 00:00:00 2001 From: Sean Baker Date: Tue, 7 Apr 2026 08:33:54 +0800 Subject: [PATCH 3/5] Update build_and_test_debug.yml --- .github/workflows/build_and_test_debug.yml | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build_and_test_debug.yml b/.github/workflows/build_and_test_debug.yml index d68f257b0..6da6dfbfa 100644 --- a/.github/workflows/build_and_test_debug.yml +++ b/.github/workflows/build_and_test_debug.yml @@ -43,8 +43,16 @@ jobs: node-version: 18 cache: npm + - name: Install Go + uses: actions/setup-go@v5 + with: + go-version: '1.21' + cache: false + - name: Install NPM Dependencies run: npm ci + env: + PUPPETEER_SKIP_CHROMIUM_DOWNLOAD: 'true' - name: Lint run: ./task lint @@ -95,8 +103,16 @@ jobs: node-version: 18 cache: npm + - name: Install Go + uses: actions/setup-go@v5 + with: + go-version: '1.21' + cache: false + - name: Install NPM Dependencies - run: PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true npm ci + run: npm ci + env: + PUPPETEER_SKIP_CHROMIUM_DOWNLOAD: 'true' - name: Shadowbox Debug Build (arm64) run: TARGET_ARCH=aarch64 ./task shadowbox:build From eb1ae915a8c7d669104a78dff0abd710dbe62d4b Mon Sep 17 00:00:00 2001 From: Sean Baker Date: Tue, 7 Apr 2026 18:44:45 +0800 Subject: [PATCH 4/5] Update build_and_test_debug.yml Use go.mod --- .github/workflows/build_and_test_debug.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build_and_test_debug.yml b/.github/workflows/build_and_test_debug.yml index 6da6dfbfa..441bc05ed 100644 --- a/.github/workflows/build_and_test_debug.yml +++ b/.github/workflows/build_and_test_debug.yml @@ -46,7 +46,7 @@ jobs: - name: Install Go uses: actions/setup-go@v5 with: - go-version: '1.21' + go-version-file: go.mod cache: false - name: Install NPM Dependencies @@ -106,7 +106,7 @@ jobs: - name: Install Go uses: actions/setup-go@v5 with: - go-version: '1.21' + go-version-file: go.mod cache: false - name: Install NPM Dependencies From 847d66f8e449510e27d28869d4347d6df8133045 Mon Sep 17 00:00:00 2001 From: Sean Baker Date: Tue, 7 Apr 2026 19:39:31 +0800 Subject: [PATCH 5/5] Use original test --- src/shadowbox/integration_test/test.sh | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/shadowbox/integration_test/test.sh b/src/shadowbox/integration_test/test.sh index 0f6adc841..84b194e6b 100755 --- a/src/shadowbox/integration_test/test.sh +++ b/src/shadowbox/integration_test/test.sh @@ -100,13 +100,10 @@ function setup() { "${DOCKER}" run -d --rm -p "10080:80" --network="${NET_OPEN}" --network-alias="target" --name="${TARGET_CONTAINER}" "${TARGET_IMAGE}" # Shadowsocks service. - # Start on NET_OPEN first so that -p host port binding works on macOS Docker Desktop - # (Docker Desktop does not publish ports when the initial network is --internal). - # Then connect to NET_BLOCKED so the security isolation tests still pass. declare -ar shadowbox_flags=( -d --rm - --network="${NET_OPEN}" + --network="${NET_BLOCKED}" --network-alias="shadowbox" -p "20443:443" -e "SB_API_PORT=443" @@ -121,7 +118,8 @@ function setup() { "${SHADOWBOX_IMAGE}" ) "${DOCKER}" run "${shadowbox_flags[@]}" - "${DOCKER}" network connect --alias shadowbox "${NET_BLOCKED}" "${SHADOWBOX_CONTAINER}" + # "${DOCKER}" network connect --alias shadowbox "${NET_BLOCKED}" "${SHADOWBOX_CONTAINER}" + "${DOCKER}" network connect "${NET_OPEN}" "${SHADOWBOX_CONTAINER}" # Client service. "${DOCKER}" build --force-rm -t "${CLIENT_IMAGE}" "$(dirname "$0")/client"