From 168a1ae8040b963fe0b03c69d970baccf689882e Mon Sep 17 00:00:00 2001 From: Flo Date: Sun, 1 Mar 2026 16:17:57 +0100 Subject: [PATCH 01/21] Full refactoring --- .github/workflows/pull-request.yml | 36 ++++++ Dockerfile | 106 ++++++++---------- README.md | 14 +++ dependencies/novnc.Dockerfile | 6 + dependencies/websockify.Dockerfile | 5 + docker-bake.hcl | 57 ++++++++++ .../nginx/sites-enabled}/vnc.conf | 0 localfs/{ => etc}/supervisord.conf | 2 +- .../xdg/openbox/autostart} | 0 localfs/{ => etc/xdg/tint2}/tint2rc | 0 localfs/{ => usr/local/bin}/startup.sh | 0 11 files changed, 163 insertions(+), 63 deletions(-) create mode 100644 .github/workflows/pull-request.yml create mode 100644 README.md create mode 100644 dependencies/novnc.Dockerfile create mode 100644 dependencies/websockify.Dockerfile create mode 100644 docker-bake.hcl rename localfs/{nginx => etc/nginx/sites-enabled}/vnc.conf (100%) rename localfs/{ => etc}/supervisord.conf (97%) rename localfs/{openbox-autostart => etc/xdg/openbox/autostart} (100%) rename localfs/{ => etc/xdg/tint2}/tint2rc (100%) rename localfs/{ => usr/local/bin}/startup.sh (100%) diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml new file mode 100644 index 0000000..fce7b98 --- /dev/null +++ b/.github/workflows/pull-request.yml @@ -0,0 +1,36 @@ +name: PR + +on: + pull_request: # Run tests for any PRs. + +jobs: + prepare: + runs-on: ubuntu-latest + outputs: + matrix: ${{ steps.generate.outputs.matrix }} + steps: + - + name: Checkout + uses: actions/checkout@v4 + - + name: Generate matrix + id: generate + uses: docker/bake-action/subaction/matrix@v6 + with: + target: base-gui + fields: matrix.base + + validate: + runs-on: ubuntu-latest + needs: + - prepare + strategy: + fail-fast: true + matrix: + include: ${{ fromJson(needs.prepare.outputs.matrix) }} + steps: + - + name: Validate + uses: docker/bake-action@v6 + with: + targets: ${{ matrix.target }} diff --git a/Dockerfile b/Dockerfile index 4e0cddd..1beb5e8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,78 +1,60 @@ -ARG OS=debian:bookworm-slim +# syntax=docker/dockerfile:1.19 +# check=skip=SecretsUsedInArgOrEnv -# Multistage build +# The base-image to be used +ARG OS=debian:trixie-slim -# Stage 1: Get novnc -FROM bitnami/git:latest as novnc - -ARG NOVNC_VERSION=v1.5.0 - -WORKDIR /app -RUN git clone --depth 1 --branch ${NOVNC_VERSION} https://github.com/novnc/novnc - -# Stage 2: Final image +# The build starts here. FROM $OS -LABEL Name=base-gui Author=max06/base-gui Flavor=$OS - -ARG PKG="apt-get install --no-install-recommends -y --ignore-missing" - -ENV LANG en_US.UTF-8 -ENV LC_ALL ${LANG} +ARG OS -ENV USER_ID=1000 GROUP_ID=1000 -ENV APP=unknown -ENV PASSWORD="" -ENV UMASK=0022 -ENV ALLOW_DIRECT_VNC=false - -# Prepare installation -RUN apt-get -q update -RUN LC_ALL=C DEBIAN_FRONTEND=noninteractive ${PKG} lsb-release - -# Install all the stuff -RUN LC_ALL=C DEBIAN_FRONTEND=noninteractive ${PKG} \ - gosu \ - locales \ - openbox \ - supervisor \ - tigervnc-common \ - tigervnc-tools \ - tigervnc-standalone-server \ - tint2 \ - python3-pip \ - python3-venv \ - nginx-light - -# Cleanup -RUN apt-get clean && \ - apt-get autoremove && \ - rm -rf /var/lib/apt/lists/* && \ - rm -rf /var/cache/fontconfig/* - -# novnc installation and patching -COPY --from=novnc /app/novnc/ /opt/novnc/ -RUN sed -i "s/UI.initSetting('resize', 'off')/UI.initSetting('resize', 'remote')/g" /opt/novnc/app/ui.js +LABEL Name=base-gui Author=max06/base-gui Flavor=$OS +# Container Language +ENV LANG=en_US.UTF-8 +ENV LC_ALL=${LANG} + +# App options +ENV USER_ID=1000 GROUP_ID=1000 APP=unknown UMASK=0022 PASSWORD="" ALLOW_DIRECT_VNC=false + +# Configure apt and install required packages +RUN \ + rm -f /etc/apt/apt.conf.d/docker-clean; \ + echo 'Binary::apt::APT::Keep-Downloaded-Packages "true";' > /etc/apt/apt.conf.d/keep-cache +RUN \ + --mount=type=cache,target=/var/cache/apt,sharing=locked \ + --mount=type=cache,target=/var/lib/apt,sharing=locked \ + apt -q update && \ + LC_ALL=C DEBIAN_FRONTEND=noninteractive apt install --no-install-recommends -y --ignore-missing \ + gosu \ + locales \ + openbox \ + supervisor \ + tigervnc-common \ + tigervnc-tools \ + tigervnc-standalone-server \ + tint2 \ + ca-certificates \ + python3-minimal \ + python3-setuptools \ + nginx-light && \ + rm /var/cache/fontconfig/* + +# novnc installation +COPY --from=novnc /tmp/ /opt/novnc/ # install websockify -RUN python3 -m venv /opt/websockify -RUN /opt/websockify/bin/pip3 install websockify - -# prepare nginx -COPY localfs/nginx/vnc.conf /etc/nginx/sites-enabled/vnc.conf +RUN --mount=type=bind,from=websockify,source=/tmp,target=/tmp/websockify,rw \ + cd /tmp/websockify && \ + python3 setup.py install -# Place our own configuration files -COPY localfs/supervisord.conf /etc/ -COPY localfs/startup.sh /usr/local/bin/ -COPY localfs/tint2rc /etc/xdg/tint2/ -COPY localfs/openbox-autostart /etc/xdg/openbox/autostart +# Copy configuration files and scripts +COPY localfs/ / RUN chmod +x /usr/local/bin/startup.sh # Add user to avoid root and create directories RUN mkdir -p /app /data - -# Set working dir WORKDIR /app # Web viewer diff --git a/README.md b/README.md new file mode 100644 index 0000000..93830eb --- /dev/null +++ b/README.md @@ -0,0 +1,14 @@ +Available Options: + +At buildtime: +ARG OS=debian:trixie-slim +ARG NOVNC_VERSION=v1.6.0 +ENV LANG=en_US.UTF-8 + +At runtime: +ENV LANG=en_US.UTF-8 (inherited) +ENV USER_ID=1000 GROUP_ID=1000 +ENV APP=unknown +ENV UMASK=0022 +ENV PASSWORD="" +ENV ALLOW_DIRECT_VNC=false diff --git a/dependencies/novnc.Dockerfile b/dependencies/novnc.Dockerfile new file mode 100644 index 0000000..7b67c5a --- /dev/null +++ b/dependencies/novnc.Dockerfile @@ -0,0 +1,6 @@ +FROM alpine + +ARG VERSION + +ADD https://github.com/novnc/novnc.git#${VERSION} /tmp +RUN sed -i "s/UI.initSetting('resize', 'off')/UI.initSetting('resize', 'remote')/g" /tmp/app/ui.js diff --git a/dependencies/websockify.Dockerfile b/dependencies/websockify.Dockerfile new file mode 100644 index 0000000..42655e8 --- /dev/null +++ b/dependencies/websockify.Dockerfile @@ -0,0 +1,5 @@ +FROM alpine + +ARG VERSION + +ADD https://github.com/novnc/websockify.git#${VERSION} /tmp diff --git a/docker-bake.hcl b/docker-bake.hcl new file mode 100644 index 0000000..9d288b8 --- /dev/null +++ b/docker-bake.hcl @@ -0,0 +1,57 @@ + +group "default" { + targets = ["base-gui"] +} + +variable "TAG" { + default = "dev" +} + +target "novnc" { + args = { + VERSION = "v1.6.0" + } + + dockerfile = "./dependencies/novnc.Dockerfile" +} + +target "websockify" { + args = { + VERSION = "v0.13.0" + } + + dockerfile = "./dependencies/websockify.Dockerfile" +} + + +target "base-gui" { + name = "base-gui-${base}" + + args = { + OS = "debian:${base}" + } + + matrix = { + base = ["bookworm", "bookworm-slim", "trixie", "trixie-slim"] + } + + platforms = ["linux/amd64", "linux/arm64"] + + contexts = { + novnc = "target:novnc" + websockify = "target:websockify" + } + + tags = [ + "max06net/base-gui:${TAG}-${base}" + ] + + output = ["type=cacheonly"] +} + +target "dev" { + inherits = ["base-gui-trixie-slim"] + platforms = ["linux/amd64"] + tags = ["local/base-gui:dev"] + output = ["type=docker"] +} diff --git a/localfs/nginx/vnc.conf b/localfs/etc/nginx/sites-enabled/vnc.conf similarity index 100% rename from localfs/nginx/vnc.conf rename to localfs/etc/nginx/sites-enabled/vnc.conf diff --git a/localfs/supervisord.conf b/localfs/etc/supervisord.conf similarity index 97% rename from localfs/supervisord.conf rename to localfs/etc/supervisord.conf index b0cdc0e..21e6df7 100644 --- a/localfs/supervisord.conf +++ b/localfs/etc/supervisord.conf @@ -1,9 +1,9 @@ [supervisord] nodaemon=true pidfile=/tmp/supervisord.pid +logfile=/dev/null logfile_maxbytes=0 - [program:x11] priority=0 command=/usr/bin/Xtigervnc -desktop "%(ENV_APP)s" %(ENV_VNC_ARGS)s :0 diff --git a/localfs/openbox-autostart b/localfs/etc/xdg/openbox/autostart similarity index 100% rename from localfs/openbox-autostart rename to localfs/etc/xdg/openbox/autostart diff --git a/localfs/tint2rc b/localfs/etc/xdg/tint2/tint2rc similarity index 100% rename from localfs/tint2rc rename to localfs/etc/xdg/tint2/tint2rc diff --git a/localfs/startup.sh b/localfs/usr/local/bin/startup.sh similarity index 100% rename from localfs/startup.sh rename to localfs/usr/local/bin/startup.sh From c28eddf4d3820f816530201c6be32bb2ae444637 Mon Sep 17 00:00:00 2001 From: Flo Date: Sun, 1 Mar 2026 16:22:46 +0100 Subject: [PATCH 02/21] f --- .github/workflows/pull-request.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index fce7b98..c5d5d52 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -18,7 +18,7 @@ jobs: uses: docker/bake-action/subaction/matrix@v6 with: target: base-gui - fields: matrix.base + fields: targets validate: runs-on: ubuntu-latest From fbf372eb91d17d75760e85d49a4e672a03b5d790 Mon Sep 17 00:00:00 2001 From: Flo Date: Sun, 1 Mar 2026 16:23:52 +0100 Subject: [PATCH 03/21] f --- .github/workflows/pull-request.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index c5d5d52..44f2ed9 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -18,7 +18,7 @@ jobs: uses: docker/bake-action/subaction/matrix@v6 with: target: base-gui - fields: targets + fields: platforms validate: runs-on: ubuntu-latest From ce8d4ea5f62c808830bb0f725e5f499522cec598 Mon Sep 17 00:00:00 2001 From: Flo Date: Sun, 1 Mar 2026 16:27:27 +0100 Subject: [PATCH 04/21] f --- .github/workflows/pull-request.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index 44f2ed9..1eceedf 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -21,16 +21,18 @@ jobs: fields: platforms validate: - runs-on: ubuntu-latest + runs-on: ${{ startsWith(matrix.platforms, 'linux/arm') && 'ubuntu-24.04-arm' || 'ubuntu-latest' }} needs: - prepare strategy: - fail-fast: true + fail-fast: false matrix: include: ${{ fromJson(needs.prepare.outputs.matrix) }} steps: - - name: Validate + name: Build uses: docker/bake-action@v6 with: targets: ${{ matrix.target }} + set: | + *.platform=${{ matrix.platforms }} From 1dd5ec573f9d1d6715a62f23b42b677f5631aa88 Mon Sep 17 00:00:00 2001 From: Flo Date: Sun, 1 Mar 2026 16:59:04 +0100 Subject: [PATCH 05/21] add artifact --- .github/workflows/pull-request.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index 1eceedf..98aaf50 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -36,3 +36,10 @@ jobs: targets: ${{ matrix.target }} set: | *.platform=${{ matrix.platforms }} + *.output=type=tar,dest=/tmp/${{ matrix.target }}.tar + + - name: Upload artifact + uses: actions/upload-artifact@v4 + with: + name: image-${{ matrix.target }}-${{ matrix.platforms == 'linux/amd64' && 'amd64' || 'arm64' }} + path: /tmp/${{ matrix.target }}.tar From b26fb228f1a17eab66467f3c13c4657e65e36704 Mon Sep 17 00:00:00 2001 From: Flo Date: Sun, 1 Mar 2026 17:27:46 +0100 Subject: [PATCH 06/21] test --- .github/workflows/pull-request.yml | 79 ++++++++++++++++++++++++++++-- 1 file changed, 75 insertions(+), 4 deletions(-) diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index 98aaf50..4d713aa 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -29,17 +29,88 @@ jobs: matrix: include: ${{ fromJson(needs.prepare.outputs.matrix) }} steps: + - + name: Dockerhub Login + uses: docker/login-action@v1.10.0 + with: + username: max06net + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - + name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: max06net/base-gui - name: Build + id: build uses: docker/bake-action@v6 with: targets: ${{ matrix.target }} set: | *.platform=${{ matrix.platforms }} - *.output=type=tar,dest=/tmp/${{ matrix.target }}.tar + *.labels=${{ steps.meta.outputs.labels }} + *.tags="max06net/base-gui" + *.base-gui-*.outputs=type=image,push-by-digest=true,name-canonical=true,push=true + + - name: Export digest + run: | + mkdir -p ${{ runner.temp }}/digests + digest="${{ steps.build.outputs.digest }}" + touch "${{ runner.temp }}/digests/${digest#sha256:}" - - name: Upload artifact + - name: Upload digest uses: actions/upload-artifact@v4 with: - name: image-${{ matrix.target }}-${{ matrix.platforms == 'linux/amd64' && 'amd64' || 'arm64' }} - path: /tmp/${{ matrix.target }}.tar + name: digests-${{ matrix.target }}-${{ startsWith(matrix.platforms, 'linux/arm') && 'arm64' || 'amd64' }} + path: ${{ runner.temp }}/digests/* + if-no-files-found: error + retention-days: 1 + + + merge: + runs-on: ubuntu-latest + needs: + - prepare + - validate + strategy: + fail-fast: false + matrix: + include: ${{ fromJson(needs.prepare.outputs.matrix) }} + steps: + - + name: Download digests + uses: actions/download-artifact@v4 + with: + path: ${{ runner.temp }}/digests + pattern: digests-${{ matrix.target }}* + merge-multiple: true + + - + name: Dockerhub Login + uses: docker/login-action@v1.10.0 + with: + username: max06net + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: max06net/base-gui + tags: | + type=ref,prefix=pr-,suffix=,event=pr + + - name: Create manifest list and push + working-directory: ${{ runner.temp }}/digests + run: | + docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \ + $(printf 'max06net/base-gui@sha256:%s ' *) + + - name: Inspect image + run: | + docker buildx imagetools inspect max06net/base-gui:${{ steps.meta.outputs.version }} From bd5b6e69faf08e2e1ed7ab54f7578052700b65ad Mon Sep 17 00:00:00 2001 From: Flo Date: Sun, 1 Mar 2026 17:29:43 +0100 Subject: [PATCH 07/21] f --- .github/workflows/pull-request.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index 4d713aa..732d2cd 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -50,7 +50,7 @@ jobs: targets: ${{ matrix.target }} set: | *.platform=${{ matrix.platforms }} - *.labels=${{ steps.meta.outputs.labels }} + *.labels="${{ steps.meta.outputs.labels }}" *.tags="max06net/base-gui" *.base-gui-*.outputs=type=image,push-by-digest=true,name-canonical=true,push=true From 38ce03f71e4128ab97611b049d2b908253c0ca2a Mon Sep 17 00:00:00 2001 From: Flo Date: Sun, 1 Mar 2026 17:30:21 +0100 Subject: [PATCH 08/21] f --- .github/workflows/pull-request.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index 732d2cd..b63cc18 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -50,7 +50,6 @@ jobs: targets: ${{ matrix.target }} set: | *.platform=${{ matrix.platforms }} - *.labels="${{ steps.meta.outputs.labels }}" *.tags="max06net/base-gui" *.base-gui-*.outputs=type=image,push-by-digest=true,name-canonical=true,push=true From 7655f96c5a8e19f6377ccb7a6a08e899ddbb4b70 Mon Sep 17 00:00:00 2001 From: Flo Date: Sun, 1 Mar 2026 17:33:35 +0100 Subject: [PATCH 09/21] f --- .github/workflows/pull-request.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index b63cc18..7c74c5f 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -51,7 +51,7 @@ jobs: set: | *.platform=${{ matrix.platforms }} *.tags="max06net/base-gui" - *.base-gui-*.outputs=type=image,push-by-digest=true,name-canonical=true,push=true + base-gui-*.output=type=image,push-by-digest=true,name-canonical=true,push=true - name: Export digest run: | From 7fcd0744fe27a812e6456c68ab8d70f1991a5e0e Mon Sep 17 00:00:00 2001 From: Flo Date: Sun, 1 Mar 2026 17:35:59 +0100 Subject: [PATCH 10/21] f --- .github/workflows/pull-request.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index 7c74c5f..0568acb 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -50,7 +50,7 @@ jobs: targets: ${{ matrix.target }} set: | *.platform=${{ matrix.platforms }} - *.tags="max06net/base-gui" + *.tags=max06net/base-gui base-gui-*.output=type=image,push-by-digest=true,name-canonical=true,push=true - name: Export digest From 82f85283e7434f0ddc006991c4baaf489f1afc65 Mon Sep 17 00:00:00 2001 From: Flo Date: Sun, 1 Mar 2026 17:40:17 +0100 Subject: [PATCH 11/21] f --- .github/workflows/pull-request.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index 0568acb..65b1801 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -41,7 +41,7 @@ jobs: id: meta uses: docker/metadata-action@v5 with: - images: max06net/base-gui + images: docker.io/max06net/base-gui - name: Build id: build @@ -50,7 +50,7 @@ jobs: targets: ${{ matrix.target }} set: | *.platform=${{ matrix.platforms }} - *.tags=max06net/base-gui + *.tags=docker.io/max06net/base-gui base-gui-*.output=type=image,push-by-digest=true,name-canonical=true,push=true - name: Export digest From 9bbb105b1fbb52de68606a61c98372df44c7c626 Mon Sep 17 00:00:00 2001 From: Flo Date: Sun, 1 Mar 2026 17:41:22 +0100 Subject: [PATCH 12/21] f --- .github/workflows/pull-request.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index 65b1801..fa6351e 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -29,6 +29,10 @@ jobs: matrix: include: ${{ fromJson(needs.prepare.outputs.matrix) }} steps: + - + name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + - name: Dockerhub Login uses: docker/login-action@v1.10.0 From 460356b8b284d8e7879234651ce9611b6dccd9a6 Mon Sep 17 00:00:00 2001 From: Flo Date: Thu, 5 Mar 2026 14:42:23 +0100 Subject: [PATCH 13/21] t --- .github/workflows/pull-request.yml | 75 +++++++++++++++++------------- 1 file changed, 43 insertions(+), 32 deletions(-) diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index fa6351e..0392e61 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -1,7 +1,7 @@ name: PR on: - pull_request: # Run tests for any PRs. + pull_request: jobs: prepare: @@ -17,8 +17,8 @@ jobs: id: generate uses: docker/bake-action/subaction/matrix@v6 with: - target: base-gui - fields: platforms + targets: base-gui + fields: target,platforms validate: runs-on: ${{ startsWith(matrix.platforms, 'linux/arm') && 'ubuntu-24.04-arm' || 'ubuntu-latest' }} @@ -29,49 +29,50 @@ jobs: matrix: include: ${{ fromJson(needs.prepare.outputs.matrix) }} steps: + - + name: Checkout + uses: actions/checkout@v4 + - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Dockerhub Login - uses: docker/login-action@v1.10.0 + uses: docker/login-action@v3 with: username: max06net password: ${{ secrets.DOCKERHUB_TOKEN }} - - name: Docker meta - id: meta - uses: docker/metadata-action@v5 - with: - images: docker.io/max06net/base-gui - - - name: Build + name: Build and push by digest id: build uses: docker/bake-action@v6 with: targets: ${{ matrix.target }} set: | - *.platform=${{ matrix.platforms }} - *.tags=docker.io/max06net/base-gui - base-gui-*.output=type=image,push-by-digest=true,name-canonical=true,push=true + ${{ matrix.target }}.platform=${{ matrix.platforms }} + ${{ matrix.target }}.tags=docker.io/max06net/base-gui + ${{ matrix.target }}.output=${{ endsWith(matrix.target, 'trixie-slim') && 'type=image,push-by-digest=true,name-canonical=true,push=true' || 'type=cacheonly' }} - - name: Export digest + - + name: Export digest + if: endsWith(matrix.target, 'trixie-slim') run: | - mkdir -p ${{ runner.temp }}/digests + mkdir -p ${{ runner.temp }}/digests/${{ matrix.target }} digest="${{ steps.build.outputs.digest }}" - touch "${{ runner.temp }}/digests/${digest#sha256:}" + touch "${{ runner.temp }}/digests/${{ matrix.target }}/${digest#sha256:}" - - name: Upload digest + - + name: Upload digest + if: endsWith(matrix.target, 'trixie-slim') uses: actions/upload-artifact@v4 with: name: digests-${{ matrix.target }}-${{ startsWith(matrix.platforms, 'linux/arm') && 'arm64' || 'amd64' }} - path: ${{ runner.temp }}/digests/* + path: ${{ runner.temp }}/digests/${{ matrix.target }}/* if-no-files-found: error retention-days: 1 - merge: runs-on: ubuntu-latest needs: @@ -80,40 +81,50 @@ jobs: strategy: fail-fast: false matrix: - include: ${{ fromJson(needs.prepare.outputs.matrix) }} + target: + - base-gui-trixie-slim steps: - name: Download digests uses: actions/download-artifact@v4 with: path: ${{ runner.temp }}/digests - pattern: digests-${{ matrix.target }}* + pattern: digests-${{ matrix.target }}-* merge-multiple: true - name: Dockerhub Login - uses: docker/login-action@v1.10.0 + uses: docker/login-action@v3 with: username: max06net password: ${{ secrets.DOCKERHUB_TOKEN }} - - name: Set up Docker Buildx + - + name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - - name: Docker meta + - + name: Docker meta id: meta uses: docker/metadata-action@v5 with: - images: max06net/base-gui + images: docker.io/max06net/base-gui + # matrix.target is e.g. "base-gui-trixie-slim" + # Strip the "base-gui-" prefix to get a clean distro suffix: "trixie-slim" tags: | - type=ref,prefix=pr-,suffix=,event=pr + type=ref,prefix=pr-,suffix=-${{ matrix.target != '' && matrix.target || 'unknown' }},event=pr + flavor: | + suffix=-${{ matrix.target }},onlatest=false - - name: Create manifest list and push + - + name: Create manifest list and push working-directory: ${{ runner.temp }}/digests run: | - docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \ - $(printf 'max06net/base-gui@sha256:%s ' *) + docker buildx imagetools create \ + $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \ + $(printf 'docker.io/max06net/base-gui@sha256:%s ' *) - - name: Inspect image + - + name: Inspect image run: | - docker buildx imagetools inspect max06net/base-gui:${{ steps.meta.outputs.version }} + docker buildx imagetools inspect docker.io/max06net/base-gui:${{ steps.meta.outputs.version }} From 15720ba898f3a913503e0594069874dde1fa9e35 Mon Sep 17 00:00:00 2001 From: Flo Date: Thu, 5 Mar 2026 14:43:52 +0100 Subject: [PATCH 14/21] t --- .github/workflows/pull-request.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index 0392e61..1be8327 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -17,7 +17,7 @@ jobs: id: generate uses: docker/bake-action/subaction/matrix@v6 with: - targets: base-gui + target: base-gui fields: target,platforms validate: From 2943f82625996739802b1e6b3b42fd598dc44c89 Mon Sep 17 00:00:00 2001 From: Flo Date: Thu, 5 Mar 2026 14:46:54 +0100 Subject: [PATCH 15/21] t --- .github/workflows/pull-request.yml | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index 1be8327..368eeab 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -7,7 +7,7 @@ jobs: prepare: runs-on: ubuntu-latest outputs: - matrix: ${{ steps.generate.outputs.matrix }} + matrix: ${{ steps.filter.outputs.matrix }} steps: - name: Checkout @@ -17,8 +17,14 @@ jobs: id: generate uses: docker/bake-action/subaction/matrix@v6 with: - target: base-gui fields: target,platforms + - + name: Filter matrix + id: filter + run: | + matrix=$(echo '${{ steps.generate.outputs.matrix }}' | \ + jq -c '[.[] | select(.target | startswith("base-gui-"))]') + echo "matrix=$matrix" >> $GITHUB_OUTPUT validate: runs-on: ${{ startsWith(matrix.platforms, 'linux/arm') && 'ubuntu-24.04-arm' || 'ubuntu-latest' }} From 03db114892578ee3a78a2fce4e45229ce6baf46c Mon Sep 17 00:00:00 2001 From: Flo Date: Thu, 5 Mar 2026 14:50:35 +0100 Subject: [PATCH 16/21] t --- .github/workflows/pull-request.yml | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index 368eeab..be2863f 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -53,13 +53,24 @@ jobs: - name: Build and push by digest id: build + if: endsWith(matrix.target, 'trixie-slim') uses: docker/bake-action@v6 with: targets: ${{ matrix.target }} set: | ${{ matrix.target }}.platform=${{ matrix.platforms }} ${{ matrix.target }}.tags=docker.io/max06net/base-gui - ${{ matrix.target }}.output=${{ endsWith(matrix.target, 'trixie-slim') && 'type=image,push-by-digest=true,name-canonical=true,push=true' || 'type=cacheonly' }} + ${{ matrix.target }}.output=type=image,push-by-digest=true,name-canonical=true,push=true + + - + name: Build (cache only) + if: "!endsWith(matrix.target, 'trixie-slim')" + uses: docker/bake-action@v6 + with: + targets: ${{ matrix.target }} + set: | + ${{ matrix.target }}.platform=${{ matrix.platforms }} + ${{ matrix.target }}.output=type=cacheonly - name: Export digest From a34c054e7b14688206af55ff8e1c0664698911fe Mon Sep 17 00:00:00 2001 From: Flo Date: Thu, 5 Mar 2026 14:55:03 +0100 Subject: [PATCH 17/21] t --- .github/workflows/pull-request.yml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index be2863f..5b61537 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -61,6 +61,8 @@ jobs: ${{ matrix.target }}.platform=${{ matrix.platforms }} ${{ matrix.target }}.tags=docker.io/max06net/base-gui ${{ matrix.target }}.output=type=image,push-by-digest=true,name-canonical=true,push=true + provenance: false + metadata-file: ${{ runner.temp }}/bake-metadata.json - name: Build (cache only) @@ -76,9 +78,9 @@ jobs: name: Export digest if: endsWith(matrix.target, 'trixie-slim') run: | - mkdir -p ${{ runner.temp }}/digests/${{ matrix.target }} - digest="${{ steps.build.outputs.digest }}" - touch "${{ runner.temp }}/digests/${{ matrix.target }}/${digest#sha256:}" + mkdir -p ${{ runner.temp }}/digests + digest=$(jq -r 'to_entries[0].value."containerimage.digest"' ${{ runner.temp }}/bake-metadata.json) + touch "${{ runner.temp }}/digests/${digest#sha256:}" - name: Upload digest @@ -86,7 +88,7 @@ jobs: uses: actions/upload-artifact@v4 with: name: digests-${{ matrix.target }}-${{ startsWith(matrix.platforms, 'linux/arm') && 'arm64' || 'amd64' }} - path: ${{ runner.temp }}/digests/${{ matrix.target }}/* + path: ${{ runner.temp }}/digests/* if-no-files-found: error retention-days: 1 From 9b239c9cdcd74ca5822ee809591fb3d9d8cc3bcb Mon Sep 17 00:00:00 2001 From: Flo Date: Thu, 5 Mar 2026 14:58:21 +0100 Subject: [PATCH 18/21] t --- .github/workflows/pull-request.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index 5b61537..9480ff1 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -62,7 +62,6 @@ jobs: ${{ matrix.target }}.tags=docker.io/max06net/base-gui ${{ matrix.target }}.output=type=image,push-by-digest=true,name-canonical=true,push=true provenance: false - metadata-file: ${{ runner.temp }}/bake-metadata.json - name: Build (cache only) @@ -79,7 +78,7 @@ jobs: if: endsWith(matrix.target, 'trixie-slim') run: | mkdir -p ${{ runner.temp }}/digests - digest=$(jq -r 'to_entries[0].value."containerimage.digest"' ${{ runner.temp }}/bake-metadata.json) + digest=$(echo '${{ steps.build.outputs.metadata }}' | jq -r '."${{ matrix.target }}"."containerimage.digest"') touch "${{ runner.temp }}/digests/${digest#sha256:}" - From 28ba1187582f9f72273e0ec988eac741d0ad0130 Mon Sep 17 00:00:00 2001 From: Flo Date: Thu, 5 Mar 2026 15:07:59 +0100 Subject: [PATCH 19/21] t --- .github/workflows/pull-request.yml | 10 +++------- docker-bake.hcl | 2 +- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index 9480ff1..d365cb8 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -23,7 +23,7 @@ jobs: id: filter run: | matrix=$(echo '${{ steps.generate.outputs.matrix }}' | \ - jq -c '[.[] | select(.target | startswith("base-gui-"))]') + jq -c '[.[] | select(.target | IN("novnc", "websockify", "dev") | not)]') echo "matrix=$matrix" >> $GITHUB_OUTPUT validate: @@ -100,7 +100,7 @@ jobs: fail-fast: false matrix: target: - - base-gui-trixie-slim + - trixie-slim steps: - name: Download digests @@ -127,12 +127,8 @@ jobs: uses: docker/metadata-action@v5 with: images: docker.io/max06net/base-gui - # matrix.target is e.g. "base-gui-trixie-slim" - # Strip the "base-gui-" prefix to get a clean distro suffix: "trixie-slim" tags: | - type=ref,prefix=pr-,suffix=-${{ matrix.target != '' && matrix.target || 'unknown' }},event=pr - flavor: | - suffix=-${{ matrix.target }},onlatest=false + type=ref,prefix=pr-,suffix=-${{ matrix.target }},event=pr - name: Create manifest list and push diff --git a/docker-bake.hcl b/docker-bake.hcl index 9d288b8..4a12764 100644 --- a/docker-bake.hcl +++ b/docker-bake.hcl @@ -25,7 +25,7 @@ target "websockify" { target "base-gui" { - name = "base-gui-${base}" + name = "${base}" args = { OS = "debian:${base}" From 1a458db550ecb4d25be0ef71d3edb7622e490b1b Mon Sep 17 00:00:00 2001 From: Flo Date: Sat, 14 Mar 2026 15:16:55 +0100 Subject: [PATCH 20/21] Fix devcontainer --- .devcontainer/devcontainer.json | 33 ++++++++++++++++++++++----------- docker-bake.hcl | 2 +- 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 5896a31..7c4a5a2 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -2,15 +2,8 @@ // README at: https://github.com/devcontainers/templates/tree/main/src/docker-existing-dockerfile { "name": "Base Gui", - "build": { - // Sets the run context to one level up instead of the .devcontainer folder. - "context": "..", - // Update the 'dockerFile' property if you aren't using the standard 'Dockerfile' filename. - "dockerfile": "../Dockerfile", - "args": { - "OS": "debian:bookworm" - } - }, + // Build using `docker buildx build dev` if image can't be found. + "image": "local/base-gui:dev", // Features to add to the dev container. More info: https://containers.dev/features. "features": { "ghcr.io/devcontainers/features/git:1": {}, @@ -19,11 +12,29 @@ // Use 'forwardPorts' to make a list of ports inside the container available locally. "forwardPorts": [ 4000 - ] + ], // Uncomment the next line to run commands after the container is created. // "postCreateCommand": "cat /etc/os-release", // Configure tool-specific properties. - // "customizations": {}, + "mounts": [ + { + "source": "${localEnv:HOME}${localEnv:USERPROFILE}/.claude.json", + "target": "/home/vscode/.claude.json", + "type": "bind" + }, + { + "source": "${localEnv:HOME}${localEnv:USERPROFILE}/.claude", + "target": "/home/vscode/.claude", + "type": "bind" + } + ], + "customizations": { + "vscode": { + "extensions": [ + "Anthropic.claude-code" + ] + } + } // Uncomment to connect as an existing user other than the container default. More info: https://aka.ms/dev-containers-non-root. // "remoteUser": "devcontainer" } diff --git a/docker-bake.hcl b/docker-bake.hcl index 4a12764..3ac1c50 100644 --- a/docker-bake.hcl +++ b/docker-bake.hcl @@ -50,7 +50,7 @@ target "base-gui" { } target "dev" { - inherits = ["base-gui-trixie-slim"] + inherits = ["trixie-slim"] platforms = ["linux/amd64"] tags = ["local/base-gui:dev"] output = ["type=docker"] From a8847f6bf00b518f842546a4d833b9843258c132 Mon Sep 17 00:00:00 2001 From: Flo Date: Sat, 14 Mar 2026 15:29:48 +0100 Subject: [PATCH 21/21] Adapt workflow for releases --- .github/workflows/docker-publish.yml | 176 +++++++++++++++++---------- 1 file changed, 112 insertions(+), 64 deletions(-) diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml index ac0e62e..6431bf6 100644 --- a/.github/workflows/docker-publish.yml +++ b/.github/workflows/docker-publish.yml @@ -3,85 +3,133 @@ name: Docker on: push: branches: - - master # Will be `dev` + - master tags: - - v* # Publish `v1.2.3` tags as releases. - - pull_request: # Run tests for any PRs. - + - v* jobs: - test: # See also https://docs.docker.com/docker-hub/builds/automated-testing/ + prepare: runs-on: ubuntu-latest - + outputs: + matrix: ${{ steps.filter.outputs.matrix }} + targets: ${{ steps.targets.outputs.targets }} steps: - - uses: actions/checkout@v2 - - - name: Run tests + - + name: Checkout + uses: actions/checkout@v4 + - + name: Generate matrix + id: generate + uses: docker/bake-action/subaction/matrix@v6 + with: + fields: target,platforms + - + name: Filter matrix + id: filter + run: | + matrix=$(echo '${{ steps.generate.outputs.matrix }}' | \ + jq -c '[.[] | select(.target | IN("novnc", "websockify", "dev") | not)]') + echo "matrix=$matrix" >> $GITHUB_OUTPUT + - + name: Extract unique targets + id: targets run: | - if [ -f docker-compose.test.yml ]; then - docker-compose --file docker-compose.test.yml build - docker-compose --file docker-compose.test.yml run sut - else - docker build --build-arg OS="debian:trixie-slim" --file Dockerfile . - fi + targets=$(echo '${{ steps.filter.outputs.matrix }}' | \ + jq -c '[.[].target] | unique') + echo "targets=$targets" >> $GITHUB_OUTPUT build: - runs-on: ubuntu-latest - - needs: test # Ensure test job passes before pushing image. - if: github.event_name == 'push' - permissions: - contents: read - packages: write - + runs-on: ${{ startsWith(matrix.platforms, 'linux/arm') && 'ubuntu-24.04-arm' || 'ubuntu-latest' }} + needs: + - prepare strategy: + fail-fast: false matrix: - os: [bookworm-slim, bookworm, trixie, trixie-slim] - include: - - os: bookworm-slim - image: debian:bookworm-slim - - os: bookworm - image: debian:bookworm - - os: trixie-slim - image: debian:trixie-slim - - os: trixie - image: debian:trixie - + include: ${{ fromJson(needs.prepare.outputs.matrix) }} steps: - - name: Set up QEMU - uses: docker/setup-qemu-action@v2 - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v2 - - - name: Dockerhub Login - uses: docker/login-action@v1.10.0 + - + name: Checkout + uses: actions/checkout@v4 + - + name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + - + name: Dockerhub Login + uses: docker/login-action@v3 with: username: max06net password: ${{ secrets.DOCKERHUB_TOKEN }} + - + name: Build and push by digest + id: build + uses: docker/bake-action@v6 + with: + targets: ${{ matrix.target }} + set: | + ${{ matrix.target }}.platform=${{ matrix.platforms }} + ${{ matrix.target }}.tags=docker.io/max06net/base-gui + ${{ matrix.target }}.output=type=image,push-by-digest=true,name-canonical=true,push=true + provenance: false + - + name: Export digest + run: | + mkdir -p ${{ runner.temp }}/digests + digest=$(echo '${{ steps.build.outputs.metadata }}' | jq -r '."${{ matrix.target }}"."containerimage.digest"') + touch "${{ runner.temp }}/digests/${digest#sha256:}" + - + name: Upload digest + uses: actions/upload-artifact@v4 + with: + name: digests-${{ matrix.target }}-${{ startsWith(matrix.platforms, 'linux/arm') && 'arm64' || 'amd64' }} + path: ${{ runner.temp }}/digests/* + if-no-files-found: error + retention-days: 1 - - name: Docker meta + merge: + runs-on: ubuntu-latest + needs: + - prepare + - build + strategy: + fail-fast: false + matrix: + target: ${{ fromJson(needs.prepare.outputs.targets) }} + steps: + - + name: Download digests + uses: actions/download-artifact@v4 + with: + path: ${{ runner.temp }}/digests + pattern: digests-${{ matrix.target }}-* + merge-multiple: true + - + name: Dockerhub Login + uses: docker/login-action@v3 + with: + username: max06net + password: ${{ secrets.DOCKERHUB_TOKEN }} + - + name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + - + name: Docker meta id: meta - uses: docker/metadata-action@v3 + uses: docker/metadata-action@v5 with: - images: max06net/base-gui + images: docker.io/max06net/base-gui tags: | - type=semver,pattern={{version}}-${{ matrix.os }} - type=semver,pattern={{major}}.{{minor}}-${{ matrix.os }} - type=semver,pattern={{major}}-${{ matrix.os }} - type=edge,branch=master,suffix=-${{ matrix.os }} - - - name: Build and push Docker images - uses: docker/build-push-action@v4 - with: - build-args: | - OS=${{ !matrix.image && matrix.os || matrix.image }} - # platforms: # optional - pull: true - push: true - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} - platforms: linux/amd64,linux/arm64 - # env: - # OS: ${{ matrix.os }} + type=semver,pattern={{version}},suffix=-${{ matrix.target }} + type=semver,pattern={{major}}.{{minor}},suffix=-${{ matrix.target }} + type=semver,pattern={{major}},suffix=-${{ matrix.target }} + type=edge,branch=master,suffix=-${{ matrix.target }} + - + name: Create manifest list and push + working-directory: ${{ runner.temp }}/digests + run: | + docker buildx imagetools create \ + $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \ + $(printf 'docker.io/max06net/base-gui@sha256:%s ' *) + - + name: Inspect image + run: | + docker buildx imagetools inspect docker.io/max06net/base-gui:${{ steps.meta.outputs.version }}