feat: publish optional alpine image variant (#4900)

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Amir Raminfar
2026-08-08 16:14:32 +00:00
committed by GitHub
co-authored by Claude Opus 5
parent 770dcbbfde
commit cea3d13e93
5 changed files with 101 additions and 0 deletions
+27
View File
@@ -125,6 +125,18 @@ jobs:
type=semver,pattern={{version}},prefix=v
type=semver,pattern={{major}}.{{minor}},prefix=v
type=semver,pattern={{major}},prefix=v
- name: Docker meta for alpine variant
id: meta-alpine
uses: docker/metadata-action@dc802804100637a589fabce1cb79ff13a1411302 # v6.2.0
with:
images: |
amir20/dozzle
ghcr.io/amir20/dozzle
tags: |
type=raw,value=alpine
type=semver,pattern={{version}},prefix=v,suffix=-alpine
type=semver,pattern={{major}}.{{minor}},prefix=v,suffix=-alpine
type=semver,pattern={{major}},prefix=v,suffix=-alpine
- name: Writing certs to file
run: |
echo "${{ secrets.TTL_KEY }}" > shared_key.pem
@@ -141,6 +153,21 @@ jobs:
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Build and push alpine variant
uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7.3.0
with:
push: true
sbom: true
context: .
target: alpine
platforms: linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64/v8
tags: ${{ steps.meta-alpine.outputs.tags }}
build-args: TAG=${{ steps.meta.outputs.version }}
labels: ${{ steps.meta-alpine.outputs.labels }}
# No cache-to. This shares every stage up to the builder with the step
# above, which already exported them, and the alpine stage itself is
# three COPYs. Exporting again would only overwrite that step's index.
cache-from: type=gha
git-release:
needs: [buildx]
name: Github Release
+21
View File
@@ -39,6 +39,15 @@ jobs:
images: |
amir20/dozzle
ghcr.io/amir20/dozzle
- name: Docker meta for alpine variant
id: meta-alpine
uses: docker/metadata-action@dc802804100637a589fabce1cb79ff13a1411302 # v6.2.0
with:
images: |
amir20/dozzle
ghcr.io/amir20/dozzle
flavor: |
suffix=-alpine,onlatest=true
- name: Short SHA
id: sha
run: echo "short=${GITHUB_SHA::7}" >> "$GITHUB_OUTPUT"
@@ -57,3 +66,15 @@ jobs:
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Build and push alpine variant
uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7.3.0
with:
context: .
push: true
target: alpine
platforms: linux/amd64,linux/arm64/v8
tags: ${{ steps.meta-alpine.outputs.tags }}
build-args: TAG=${{ steps.meta.outputs.version }}-${{ steps.sha.outputs.short }}
labels: ${{ steps.meta-alpine.outputs.labels }}
# No cache-to. See the note in deploy.yml.
cache-from: type=gha
+13
View File
@@ -58,6 +58,19 @@ RUN --mount=type=cache,target=/go/pkg/mod --mount=type=cache,target=/root/.cache
RUN mkdir /data
# Optional variant published as :alpine for platforms that bind-mount a shell
# wrapper over the entrypoint. Must stay above the scratch stage so that the
# last stage remains the default build target.
FROM alpine:3.24 AS alpine
COPY --from=builder /data /data
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt
COPY --from=builder /dozzle/dozzle /dozzle
EXPOSE 8080
ENTRYPOINT ["/dozzle"]
FROM scratch
COPY --from=builder /data /data
+19
View File
@@ -61,6 +61,25 @@ Here is a Docker Compose example:
For advanced options like [authentication](https://dozzle.dev/guide/authentication), [remote hosts](https://dozzle.dev/guide/remote-hosts), or common [questions](https://dozzle.dev/guide/faq), see the documentation at [dozzle.dev](https://dozzle.dev/guide/getting-started).
### Image Tags
Images are published to both [Docker Hub](https://hub.docker.com/r/amir20/dozzle) and [ghcr.io](https://github.com/amir20/dozzle/pkgs/container/dozzle) with identical tags.
| Tag | Description |
| ----------------------------------------------- | ---------------------------------------------------------------------- |
| `latest` | Most recent release. Recommended for most users. |
| `v10.6.15` | An exact release. Pin this for reproducible deployments. |
| `v10.6` | Latest patch within that minor version. Picks up bug fixes only. |
| `v10` | Latest release within that major version. Picks up new features too. |
| `alpine` | Same as `latest`, but on an Alpine base instead of `scratch`. |
| `v10.6.15-alpine`, `v10.6-alpine`, `v10-alpine` | Alpine variants of the version tags above. |
| `master` | Built from the `master` branch on every push. Unreleased and unstable. |
| `pr-1234`, `pr-1234-alpine` | Built from pull request #1234, for testing a fix before it ships. |
The default images are built `FROM scratch` and contain only the Dozzle binary, which is why they are around 7 MB compressed. That also means there is no shell inside them. Use the `alpine` variants only if something in your setup needs one, most commonly platforms that bind-mount a `#!/bin/sh` wrapper over the container entrypoint such as Unraid's per-container Tailscale toggle. See the [FAQ](https://dozzle.dev/guide/faq) for details.
Avoid `latest` and `master` in production. `latest` moves on every release and `master` is unreleased code.
## Swarm Mode
Dozzle works with Docker Swarm. You can run Dozzle as a global service:
+21
View File
@@ -21,6 +21,27 @@ docker compose up -d dozzle
User settings, notification rules, and other state are stored in `/data` (see below), so keep that volume mounted across upgrades. For production use, pin a specific tag (e.g. `amir20/dozzle:v8.14.1`) rather than `latest` so upgrades are deliberate. Release notes are published on the [GitHub releases page](https://github.com/amir20/dozzle/releases). Rolling back is as simple as redeploying an older tag.
## My platform wraps the container entrypoint and Dozzle fails with `no such file or directory`
The default image is built `FROM scratch`, so it contains the Dozzle binary and nothing else. No shell, no interpreter.
Some platforms add optional features by bind-mounting a `#!/bin/sh` wrapper over the container entrypoint and re-exec'ing the original one. Unraid's per-container Tailscale toggle works this way, as do some sidecar and init injectors. Without `/bin/sh` in the image the wrapper cannot be executed and the container exits with an error naming the wrapper rather than the missing shell:
```
exec /opt/unraid/tailscale: no such file or directory
```
For these cases use the `alpine` variant, which is the same binary on an Alpine base:
```sh
docker run \
--volume=/var/run/docker.sock:/var/run/docker.sock \
-p 8080:8080 \
amir20/dozzle:alpine
```
Versioned tags follow the same pattern (`amir20/dozzle:v8.14.1-alpine`). The scratch-based `latest` stays the recommended image for everything else, since it has a much smaller footprint and no distro packages to patch.
## What is stored in `/data` and how do I back it up?
The `/data` directory is where Dozzle persists anything that needs to survive a container restart: