From 43a20f45e8c3632f5c237d974d7b3f56d9c26cb6 Mon Sep 17 00:00:00 2001 From: Antonis Kalipetis Date: Thu, 5 Feb 2026 15:36:21 +0200 Subject: [PATCH 01/11] feat: add Docker support for Upsun CLI with build and push workflow --- .github/workflows/release.yml | 63 +++++++++++++++++++++++++++++++++++ Dockerfile | 13 ++++++++ README.md | 15 +++++++++ 3 files changed, 91 insertions(+) create mode 100644 Dockerfile diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 6b901b91..e8660346 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -7,6 +7,7 @@ on: permissions: contents: write + packages: write jobs: release: @@ -120,3 +121,65 @@ jobs: if: always() run: | rm -rf "${{ steps.signing-keys.outputs.key_dir }}" + + docker: + runs-on: ${{ matrix.runner }} + needs: release + strategy: + matrix: + include: + - runner: ubuntu-latest + platform: linux/amd64 + suffix: amd64 + - runner: ubuntu-24.04-arm + platform: linux/arm64 + suffix: arm64 + permissions: + contents: read + packages: write + steps: + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to GHCR + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Build and push Docker image + uses: docker/build-push-action@v5 + with: + context: https://github.com/${{ github.repository }}.git#${{ github.ref }} + platforms: ${{ matrix.platform }} + push: true + tags: ghcr.io/upsun/cli:${{ github.ref_name }}-${{ matrix.suffix }} + build-args: | + VERSION=${{ github.ref_name }} + cache-from: type=gha,scope=${{ matrix.suffix }} + cache-to: type=gha,mode=max,scope=${{ matrix.suffix }} + + docker-manifest: + runs-on: ubuntu-latest + needs: docker + permissions: + packages: write + steps: + - name: Log in to GHCR + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Create and push manifest + run: | + docker manifest create ghcr.io/upsun/cli:${{ github.ref_name }} \ + ghcr.io/upsun/cli:${{ github.ref_name }}-amd64 \ + ghcr.io/upsun/cli:${{ github.ref_name }}-arm64 + docker manifest push ghcr.io/upsun/cli:${{ github.ref_name }} + docker manifest create ghcr.io/upsun/cli:latest \ + ghcr.io/upsun/cli:${{ github.ref_name }}-amd64 \ + ghcr.io/upsun/cli:${{ github.ref_name }}-arm64 + docker manifest push ghcr.io/upsun/cli:latest diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..364ccf04 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,13 @@ +FROM ubuntu:24.04 + +# Install dependencies +RUN apt-get update && \ + apt-get install -y curl bash git ssh-client && \ + rm -rf /var/lib/apt/lists/* + +# Install Upsun CLI +ARG VERSION= +RUN curl -fsSL https://raw.githubusercontent.com/upsun/cli/main/installer.sh | INSTALL_METHOD=raw VERSION=$VERSION bash + +# Default command +ENTRYPOINT ["upsun"] diff --git a/README.md b/README.md index 77be0ee1..ed706c42 100644 --- a/README.md +++ b/README.md @@ -112,6 +112,20 @@ sudo dnf install -y upsun-cli For manual installation, you can also [download the latest binaries](https://github.com/upsun/cli/releases/latest). +### Docker + +The CLI is also available as a Docker image: + +```console +docker run --rm -it ghcr.io/upsun/cli +``` + +To use a specific version: + +```console +docker run --rm -it ghcr.io/upsun/cli:6.0.0 +``` + ## Upgrade Upgrade using the same tool: @@ -188,6 +202,7 @@ Releases are automated via GitHub Actions. To create a new release: - Sign packages (APK, DEB, RPM) - Create a GitHub release with all artifacts - Update package repositories at repositories.upsun.com + - Build and push Docker image to ghcr.io/upsun/cli ## Licenses From e0e6bdda55cf5bf5b02ca1037fd0312edd36345c Mon Sep 17 00:00:00 2001 From: Antonis Kalipetis Date: Thu, 5 Feb 2026 16:41:43 +0200 Subject: [PATCH 02/11] fix: add --no-install-recommends to apt-get install for smaller image size --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 364ccf04..03c9404d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,7 +2,7 @@ FROM ubuntu:24.04 # Install dependencies RUN apt-get update && \ - apt-get install -y curl bash git ssh-client && \ + apt-get install -y --no-install-recommends curl bash git ssh-client && \ rm -rf /var/lib/apt/lists/* # Install Upsun CLI From 95f5583898a86a7945996853e645bef6721027bf Mon Sep 17 00:00:00 2001 From: Antonis Kalipetis Date: Thu, 5 Feb 2026 16:42:50 +0200 Subject: [PATCH 03/11] fix: add correct named version example Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ed706c42..c43c34d2 100644 --- a/README.md +++ b/README.md @@ -123,7 +123,7 @@ docker run --rm -it ghcr.io/upsun/cli To use a specific version: ```console -docker run --rm -it ghcr.io/upsun/cli:6.0.0 +docker run --rm -it ghcr.io/upsun/cli:v6.0.0 ``` ## Upgrade From 2f4a911e5ba0041b397953a51ab0bf56b2fa4563 Mon Sep 17 00:00:00 2001 From: Miguel Sanchez Gonzalez Date: Mon, 13 Apr 2026 20:37:33 +0200 Subject: [PATCH 04/11] fix(docker): address code review issues in Docker CI workflow - Propagate resolved tag from release job to docker/docker-manifest jobs via job outputs, fixing workflow_dispatch tag propagation - Gate latest manifest push on is_prerelease == false to prevent pre-releases from overwriting latest - Replace deprecated docker manifest create/push with docker buildx imagetools create - Remove packages: write from workflow-level permissions to prevent bleed into the release job; add explicit permissions blocks per job - Add contents: read to docker-manifest job permissions - Pin installer.sh fetch URL to released tag instead of main branch Co-Authored-By: Claude Sonnet 4.6 --- .github/workflows/release.yml | 37 ++++++++++++++++++++++------------- Dockerfile | 2 +- 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 131d498d..4b38bffb 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -20,12 +20,16 @@ on: permissions: contents: write - packages: write jobs: release: runs-on: ubuntu-latest environment: production + permissions: + contents: write + outputs: + tag: ${{ steps.tag.outputs.tag }} + is_prerelease: ${{ steps.tag.outputs.is_prerelease }} steps: - name: Resolve tag @@ -194,19 +198,20 @@ jobs: - name: Build and push Docker image uses: docker/build-push-action@v5 with: - context: https://github.com/${{ github.repository }}.git#${{ github.ref }} + context: https://github.com/${{ github.repository }}.git#${{ needs.release.outputs.tag }} platforms: ${{ matrix.platform }} push: true - tags: ghcr.io/upsun/cli:${{ github.ref_name }}-${{ matrix.suffix }} + tags: ghcr.io/upsun/cli:${{ needs.release.outputs.tag }}-${{ matrix.suffix }} build-args: | - VERSION=${{ github.ref_name }} + VERSION=${{ needs.release.outputs.tag }} cache-from: type=gha,scope=${{ matrix.suffix }} cache-to: type=gha,mode=max,scope=${{ matrix.suffix }} docker-manifest: runs-on: ubuntu-latest - needs: docker + needs: [docker, release] permissions: + contents: read packages: write steps: - name: Log in to GHCR @@ -216,13 +221,17 @@ jobs: username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - name: Create and push manifest + - name: Create and push versioned manifest + run: | + docker buildx imagetools create \ + --tag ghcr.io/upsun/cli:${{ needs.release.outputs.tag }} \ + ghcr.io/upsun/cli:${{ needs.release.outputs.tag }}-amd64 \ + ghcr.io/upsun/cli:${{ needs.release.outputs.tag }}-arm64 + + - name: Create and push latest manifest + if: needs.release.outputs.is_prerelease == 'false' run: | - docker manifest create ghcr.io/upsun/cli:${{ github.ref_name }} \ - ghcr.io/upsun/cli:${{ github.ref_name }}-amd64 \ - ghcr.io/upsun/cli:${{ github.ref_name }}-arm64 - docker manifest push ghcr.io/upsun/cli:${{ github.ref_name }} - docker manifest create ghcr.io/upsun/cli:latest \ - ghcr.io/upsun/cli:${{ github.ref_name }}-amd64 \ - ghcr.io/upsun/cli:${{ github.ref_name }}-arm64 - docker manifest push ghcr.io/upsun/cli:latest + docker buildx imagetools create \ + --tag ghcr.io/upsun/cli:latest \ + ghcr.io/upsun/cli:${{ needs.release.outputs.tag }}-amd64 \ + ghcr.io/upsun/cli:${{ needs.release.outputs.tag }}-arm64 diff --git a/Dockerfile b/Dockerfile index 03c9404d..42777463 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,7 +7,7 @@ RUN apt-get update && \ # Install Upsun CLI ARG VERSION= -RUN curl -fsSL https://raw.githubusercontent.com/upsun/cli/main/installer.sh | INSTALL_METHOD=raw VERSION=$VERSION bash +RUN curl -fsSL https://raw.githubusercontent.com/upsun/cli/$VERSION/installer.sh | INSTALL_METHOD=raw VERSION=$VERSION bash # Default command ENTRYPOINT ["upsun"] From 6155f01772516eb0e70b785c99591c06d16f687a Mon Sep 17 00:00:00 2001 From: Miguel Sanchez Gonzalez Date: Tue, 14 Apr 2026 11:14:08 +0200 Subject: [PATCH 05/11] refactor(docker): simplify workflow and improve Dockerfile cache ordering - Extract IMAGE env var to eliminate repeated ghcr.io/upsun/cli literals - Move ARG VERSION after apt layer so version changes don't bust apt cache - Remove self-explanatory comments from Dockerfile Co-Authored-By: Claude Sonnet 4.6 --- .github/workflows/release.yml | 17 ++++++++++------- Dockerfile | 3 --- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 4b38bffb..74fcec4e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -21,6 +21,9 @@ on: permissions: contents: write +env: + IMAGE: ghcr.io/upsun/cli + jobs: release: runs-on: ubuntu-latest @@ -201,7 +204,7 @@ jobs: context: https://github.com/${{ github.repository }}.git#${{ needs.release.outputs.tag }} platforms: ${{ matrix.platform }} push: true - tags: ghcr.io/upsun/cli:${{ needs.release.outputs.tag }}-${{ matrix.suffix }} + tags: ${{ env.IMAGE }}:${{ needs.release.outputs.tag }}-${{ matrix.suffix }} build-args: | VERSION=${{ needs.release.outputs.tag }} cache-from: type=gha,scope=${{ matrix.suffix }} @@ -224,14 +227,14 @@ jobs: - name: Create and push versioned manifest run: | docker buildx imagetools create \ - --tag ghcr.io/upsun/cli:${{ needs.release.outputs.tag }} \ - ghcr.io/upsun/cli:${{ needs.release.outputs.tag }}-amd64 \ - ghcr.io/upsun/cli:${{ needs.release.outputs.tag }}-arm64 + --tag ${{ env.IMAGE }}:${{ needs.release.outputs.tag }} \ + ${{ env.IMAGE }}:${{ needs.release.outputs.tag }}-amd64 \ + ${{ env.IMAGE }}:${{ needs.release.outputs.tag }}-arm64 - name: Create and push latest manifest if: needs.release.outputs.is_prerelease == 'false' run: | docker buildx imagetools create \ - --tag ghcr.io/upsun/cli:latest \ - ghcr.io/upsun/cli:${{ needs.release.outputs.tag }}-amd64 \ - ghcr.io/upsun/cli:${{ needs.release.outputs.tag }}-arm64 + --tag ${{ env.IMAGE }}:latest \ + ${{ env.IMAGE }}:${{ needs.release.outputs.tag }}-amd64 \ + ${{ env.IMAGE }}:${{ needs.release.outputs.tag }}-arm64 diff --git a/Dockerfile b/Dockerfile index 42777463..45d1a6a2 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,13 +1,10 @@ FROM ubuntu:24.04 -# Install dependencies RUN apt-get update && \ apt-get install -y --no-install-recommends curl bash git ssh-client && \ rm -rf /var/lib/apt/lists/* -# Install Upsun CLI ARG VERSION= RUN curl -fsSL https://raw.githubusercontent.com/upsun/cli/$VERSION/installer.sh | INSTALL_METHOD=raw VERSION=$VERSION bash -# Default command ENTRYPOINT ["upsun"] From a336a4e1bdda64215e33e175166fdb0fed4c037e Mon Sep 17 00:00:00 2001 From: Miguel Sanchez Gonzalez Date: Tue, 14 Apr 2026 17:59:04 +0200 Subject: [PATCH 06/11] fix(docker): install ca-certificates and avoid pipe swallowing curl errors Co-Authored-By: Claude Sonnet 4.6 --- Dockerfile | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 45d1a6a2..888fa6ac 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,10 +1,12 @@ FROM ubuntu:24.04 RUN apt-get update && \ - apt-get install -y --no-install-recommends curl bash git ssh-client && \ + apt-get install -y --no-install-recommends ca-certificates curl bash git ssh-client && \ rm -rf /var/lib/apt/lists/* ARG VERSION= -RUN curl -fsSL https://raw.githubusercontent.com/upsun/cli/$VERSION/installer.sh | INSTALL_METHOD=raw VERSION=$VERSION bash +RUN curl -fsSL https://raw.githubusercontent.com/upsun/cli/$VERSION/installer.sh -o /tmp/installer.sh && \ + INSTALL_METHOD=raw VERSION=$VERSION bash /tmp/installer.sh && \ + rm /tmp/installer.sh ENTRYPOINT ["upsun"] From 5cb2b68a3e2a05708c8474304647f0aef2a24d2e Mon Sep 17 00:00:00 2001 From: Miguel Sanchez Gonzalez Date: Tue, 14 Apr 2026 18:45:18 +0200 Subject: [PATCH 07/11] fix(docker): replace bash with sh and use openssh-client Co-Authored-By: Claude Sonnet 4.6 --- Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 888fa6ac..86ea0203 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,12 +1,12 @@ FROM ubuntu:24.04 RUN apt-get update && \ - apt-get install -y --no-install-recommends ca-certificates curl bash git ssh-client && \ + apt-get install -y --no-install-recommends ca-certificates curl git openssh-client && \ rm -rf /var/lib/apt/lists/* ARG VERSION= RUN curl -fsSL https://raw.githubusercontent.com/upsun/cli/$VERSION/installer.sh -o /tmp/installer.sh && \ - INSTALL_METHOD=raw VERSION=$VERSION bash /tmp/installer.sh && \ + INSTALL_METHOD=raw VERSION=$VERSION sh /tmp/installer.sh && \ rm /tmp/installer.sh ENTRYPOINT ["upsun"] From 5628d201b3d6d1063f1cdb32c4c4cb6ec2808630 Mon Sep 17 00:00:00 2001 From: Miguel Sanchez Gonzalez Date: Tue, 14 Apr 2026 23:30:21 +0200 Subject: [PATCH 08/11] fix(docker): fail fast when VERSION build arg is unset --- Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/Dockerfile b/Dockerfile index 86ea0203..8f08c541 100644 --- a/Dockerfile +++ b/Dockerfile @@ -5,6 +5,7 @@ RUN apt-get update && \ rm -rf /var/lib/apt/lists/* ARG VERSION= +RUN [ -n "$VERSION" ] || { echo "ERROR: VERSION build arg must be set" >&2; exit 1; } RUN curl -fsSL https://raw.githubusercontent.com/upsun/cli/$VERSION/installer.sh -o /tmp/installer.sh && \ INSTALL_METHOD=raw VERSION=$VERSION sh /tmp/installer.sh && \ rm /tmp/installer.sh From e41d6a6cbb3dcbb3c2c172271733caa2a4a3eb09 Mon Sep 17 00:00:00 2001 From: Miguel Sanchez Gonzalez Date: Tue, 14 Apr 2026 23:30:40 +0200 Subject: [PATCH 09/11] fix(docker): copy installer.sh from repo instead of downloading at build time --- Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 8f08c541..15707bde 100644 --- a/Dockerfile +++ b/Dockerfile @@ -6,8 +6,8 @@ RUN apt-get update && \ ARG VERSION= RUN [ -n "$VERSION" ] || { echo "ERROR: VERSION build arg must be set" >&2; exit 1; } -RUN curl -fsSL https://raw.githubusercontent.com/upsun/cli/$VERSION/installer.sh -o /tmp/installer.sh && \ - INSTALL_METHOD=raw VERSION=$VERSION sh /tmp/installer.sh && \ +COPY installer.sh /tmp/installer.sh +RUN INSTALL_METHOD=raw VERSION=$VERSION sh /tmp/installer.sh && \ rm /tmp/installer.sh ENTRYPOINT ["upsun"] From 383891e87c6a1baa4dd0feac866de7e4b33b137b Mon Sep 17 00:00:00 2001 From: Miguel Sanchez Gonzalez Date: Wed, 15 Apr 2026 00:27:21 +0200 Subject: [PATCH 10/11] fix(docker): switch base image from Ubuntu to Alpine Co-Authored-By: Claude Sonnet 4.6 --- Dockerfile | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/Dockerfile b/Dockerfile index 15707bde..ad1a3e9a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,13 +1,10 @@ -FROM ubuntu:24.04 +FROM alpine:3 -RUN apt-get update && \ - apt-get install -y --no-install-recommends ca-certificates curl git openssh-client && \ - rm -rf /var/lib/apt/lists/* +RUN apk add --no-cache ca-certificates curl git openssh-client ARG VERSION= -RUN [ -n "$VERSION" ] || { echo "ERROR: VERSION build arg must be set" >&2; exit 1; } +RUN [ -n "$VERSION" ] || { echo "VERSION is required" >&2; exit 1; } COPY installer.sh /tmp/installer.sh -RUN INSTALL_METHOD=raw VERSION=$VERSION sh /tmp/installer.sh && \ - rm /tmp/installer.sh +RUN INSTALL_METHOD=raw VERSION=$VERSION sh /tmp/installer.sh && rm /tmp/installer.sh -ENTRYPOINT ["upsun"] +ENTRYPOINT ["upsun"] \ No newline at end of file From 922017c53b073d1b5d0c30eb8a44b94a914105a3 Mon Sep 17 00:00:00 2001 From: Patrick Dawkins Date: Tue, 14 Apr 2026 23:41:40 +0100 Subject: [PATCH 11/11] Update README.md --- README.md | 6 ------ 1 file changed, 6 deletions(-) diff --git a/README.md b/README.md index c43c34d2..ad96f8c2 100644 --- a/README.md +++ b/README.md @@ -120,12 +120,6 @@ The CLI is also available as a Docker image: docker run --rm -it ghcr.io/upsun/cli ``` -To use a specific version: - -```console -docker run --rm -it ghcr.io/upsun/cli:v6.0.0 -``` - ## Upgrade Upgrade using the same tool: