diff --git a/.env.example b/.env.example deleted file mode 100644 index 892bef9..0000000 --- a/.env.example +++ /dev/null @@ -1,5 +0,0 @@ -# Copy to .env, set values, and never commit .env. -# Used by archive/docker-compose-macmini.yml and archive/docker-compose-logos.yml for tunnel HTTP Basic auth. - -TUNNEL_AUTH_USER= -TUNNEL_AUTH_PASS= diff --git a/.gitignore b/.gitignore index bcd9512..61441de 100644 --- a/.gitignore +++ b/.gitignore @@ -18,3 +18,4 @@ __pycache__/ # OS .DS_Store +archive/ \ No newline at end of file diff --git a/dist/tunnel-client b/dist/tunnel-client new file mode 100755 index 0000000..6d60e55 Binary files /dev/null and b/dist/tunnel-client differ diff --git a/dist/tunnel-server b/dist/tunnel-server new file mode 100755 index 0000000..5c6034e Binary files /dev/null and b/dist/tunnel-server differ diff --git a/docker-compose.production.yml b/docker-compose.production.yml deleted file mode 100644 index 97dab45..0000000 --- a/docker-compose.production.yml +++ /dev/null @@ -1,12 +0,0 @@ -services: - tunnel-server: - build: - context: . - target: server - image: git.nixc.us/colin/better-argo-tunnels:production - - tunnel-client: - build: - context: . - target: client - image: git.nixc.us/colin/better-argo-tunnels:client-production diff --git a/ship.sh b/ship.sh index 2571a3b..eb18d0c 100755 --- a/ship.sh +++ b/ship.sh @@ -1,8 +1,17 @@ #!/usr/bin/env bash -# Reliable release: commit → local binaries → multi-arch images → GHCR → git push. -# Only input: commit message. Edit CONSTANTS to change registry/platforms. # -# Usage: ./ship.sh "your message" +# Fixed pipeline (do not reorder or skip steps): +# 1. git add -A +# 2. git commit (normal if staged changes exist, else --allow-empty with the same message) +# 3. GIT_COMMIT = current HEAD (baked into Go binaries inside each image via Dockerfile ARG) +# 4. docker login ghcr.io +# 5. For each of server + client targets: per-arch buildx --push (linux/amd64, linux/arm64), then imagetools manifest +# 6. git push GIT_REMOTE BRANCH +# +# Usage: ./ship.sh +# Requires: git, docker (buildx), gh; remote "github"; gh token with write:packages for GHCR. +# +# Multi-arch: Intel/AMD 64-bit (linux/amd64) and ARM64 (linux/arm64), one manifest tag each for server and client. set -euo pipefail @@ -15,47 +24,60 @@ COMMIT_MSG="$*" ROOT="$(cd "$(dirname "$0")" && pwd)" cd "$ROOT" -# --- CONSTANTS --- +# --- release targets (edit only here) --- GITHUB_OWNER="Leopere" -GITHUB_REPO="better-argo-tunnels" REGISTRY_BASE="ghcr.io/leopere/better-argo-tunnels" TAG_SERVER="production" TAG_CLIENT="client-production" -PLATFORMS="linux/amd64,linux/arm64,linux/arm/v7" +# Exactly two platforms → one multi-arch manifest per image (amd64 + arm64). +PLATFORMS="linux/amd64,linux/arm64" GIT_REMOTE="github" # --- end --- -for cmd in gh docker git go; do +for cmd in git docker gh; do command -v "$cmd" >/dev/null 2>&1 || { - echo "error: need $cmd in PATH" >&2 + echo "ship: fatal: missing required command: $cmd" >&2 exit 1 } done +if ! docker buildx version >/dev/null 2>&1; then + echo "ship: fatal: docker buildx not available" >&2 + exit 1 +fi BRANCH="$(git branch --show-current)" if [[ -z "$BRANCH" ]]; then - echo "error: detached HEAD" >&2 + echo "ship: fatal: detached HEAD" >&2 + exit 1 +fi +if ! git remote get-url "$GIT_REMOTE" >/dev/null 2>&1; then + echo "ship: fatal: git remote '$GIT_REMOTE' is not configured" >&2 exit 1 fi -echo "==> git add -A" +echo "==> [1/6] git add -A" git add -A -if git diff --cached --quiet; then - echo "error: nothing to commit" >&2 - exit 1 -fi -echo "==> git commit" -git commit -m "$COMMIT_MSG" +echo "==> [2/6] git commit" +if git diff --cached --quiet; then + git commit --allow-empty -m "$COMMIT_MSG" +else + git commit -m "$COMMIT_MSG" +fi GIT_COMMIT="$(git rev-parse HEAD)" -BA=(--build-arg "GIT_COMMIT=$GIT_COMMIT") -LDFLAGS="-s -w -X github.com/nixc/reverse-ssh-traefik/internal/buildinfo.Commit=${GIT_COMMIT}" +BA=(--build-arg "GIT_COMMIT=${GIT_COMMIT}") +echo "==> GIT_COMMIT=${GIT_COMMIT}" -echo "==> go build → dist/" -mkdir -p dist -CGO_ENABLED=0 go build -ldflags="$LDFLAGS" -o dist/tunnel-server ./cmd/server/ -CGO_ENABLED=0 go build -ldflags="$LDFLAGS" -o dist/tunnel-client ./cmd/client/ +echo "==> [3/6] docker login ghcr.io" +if ! token="$(gh auth token)" || [[ -z "${token}" ]]; then + echo "ship: fatal: gh auth token empty" >&2 + exit 1 +fi +if ! printf '%s' "$token" | docker login ghcr.io -u "$GITHUB_OWNER" --password-stdin; then + echo "ship: fatal: docker login ghcr.io failed (need: gh auth refresh -h github.com -s write:packages -s read:packages)" >&2 + exit 1 +fi pick_builder() { if docker buildx inspect orbstack >/dev/null 2>&1; then @@ -71,6 +93,7 @@ platform_slug() { echo "${p//\//-}" } +# Per-arch push then single multi-arch manifest (orbstack/docker driver compatible). push_multi() { local target="$1" local final_tag="$2" @@ -78,15 +101,15 @@ push_multi() { local base="${final_tag%:*}" local name="${final_tag##*:}" local arch_refs=() + local p slug arch_tag IFS=',' read -ra plats <<< "$PLATFORMS" for p in "${plats[@]}"; do p="${p// /}" [[ -z "$p" ]] && continue - local slug slug="$(platform_slug "$p")" - local arch_tag="${base}:${name}-${slug}" - echo "==> docker buildx $target $p → $arch_tag" + arch_tag="${base}:${name}-${slug}" + echo "==> [4/6] docker buildx push ${target} ${p} -> ${arch_tag}" docker buildx build \ "${BA[@]}" \ --builder "$builder" \ @@ -94,28 +117,24 @@ push_multi() { --target "$target" \ -t "$arch_tag" \ --push \ + --provenance=false \ "$ROOT" arch_refs+=("$arch_tag") done + echo "==> [5/6] imagetools manifest ${final_tag}" docker buildx imagetools create -t "$final_tag" "${arch_refs[@]}" } BUILDER="$(pick_builder)" +echo "==> buildx builder: ${BUILDER}" SERVER_TAG="${REGISTRY_BASE}:${TAG_SERVER}" CLIENT_TAG="${REGISTRY_BASE}:${TAG_CLIENT}" -echo "==> ghcr.io login (needs gh token with write:packages)" -echo "$(gh auth token)" | docker login ghcr.io -u "$GITHUB_OWNER" --password-stdin - push_multi server "$SERVER_TAG" "$BUILDER" push_multi client "$CLIENT_TAG" "$BUILDER" -if ! git remote get-url "$GIT_REMOTE" >/dev/null 2>&1; then - echo "error: git remote '$GIT_REMOTE' missing" >&2 - exit 1 -fi -echo "==> git push $GIT_REMOTE $BRANCH" +echo "==> [6/6] git push ${GIT_REMOTE} ${BRANCH}" git push "$GIT_REMOTE" "$BRANCH" -echo "==> ok commit=$GIT_COMMIT" -echo " $SERVER_TAG $CLIENT_TAG" +echo "ship: ok commit=${GIT_COMMIT}" +echo "ship: images ${SERVER_TAG} ${CLIENT_TAG} (multi-arch: ${PLATFORMS})" diff --git a/stack.production.yml b/stack.production.yml deleted file mode 100644 index 77c2da6..0000000 --- a/stack.production.yml +++ /dev/null @@ -1,51 +0,0 @@ -networks: - traefik: - external: true - -services: - tunnel-server: - image: git.nixc.us/colin/better-argo-tunnels:production - networks: - - traefik - environment: - SSH_PORT: "2222" - PORT_RANGE_START: "10000" - PORT_RANGE_END: "10100" - TRAEFIK_SSH_HOST: "ingress.nixc.us:65522" - TRAEFIK_SSH_USER: "root" - TRAEFIK_SSH_KEY: "/keys/deploy_key" - SWARM_SERVICE_NAME: "better-argo-tunnels_tunnel-server" - TRAEFIK_ENTRYPOINT: "websecure" - TRAEFIK_CERT_RESOLVER: "letsencryptresolver" - HOSTNAME: "{{.Node.Hostname}}" - NODE_ID: "{{.Node.ID}}" - SERVICE_NAME: "{{.Service.Name}}" - TASK_ID: "{{.Task.ID}}" - ENVIRONMENT: "production" - volumes: - # Tunnel user's keys on ingress.nixc.us (clients connect here; authorized_keys = tunnel user's) - - /home/tunnel/.ssh/tunnel_host_key:/keys/host_key:ro - - /home/tunnel/.ssh/authorized_keys:/keys/authorized_keys:ro - - /home/tunnel/.ssh/ca-userkey:/keys/deploy_key:ro - - /home/tunnel/.ssh/ca-userkey-cert.pub:/keys/deploy_key-cert.pub:ro - ports: - - target: 2222 - published: 2222 - protocol: tcp - mode: host - deploy: - replicas: 1 - placement: - constraints: - - node.hostname == ingress.nixc.us - labels: - traefik.enable: "true" - traefik.docker.network: "traefik" - # Dynamic tunnel labels are added at runtime via docker service update. - update_config: - order: stop-first - failure_action: rollback - delay: 0s - parallelism: 1 - restart_policy: - condition: on-failure