Add Dockerfile, TrueNAS SCALE compose file and image publishing on release
CI / test (push) Successful in 57s
Release / release (push) Successful in 2m34s

This commit is contained in:
Veillax committed 2026-10-27 18:36:06 -06:00
1 parent 6ff6f5f4c7
commit e0694b2374
5 files changed
+79 -6

No files matched your search

+23
View File
@@ -37,3 +37,26 @@ jobs:
env:
TOKEN: ${{ secrets.RELEASE_TOKEN || secrets.GITHUB_TOKEN }}
run: sh deploy/publish-release.sh "${GITHUB_REF_NAME}"
# Skipped when the repository variable PUBLISH_DOCKER is "false", or fails alone
# if this runner has no Docker: the release above is already published by then.
# Optional secret REGISTRY_TOKEN (and variable REGISTRY_USER): an access token
# with package write permission, for servers where the job token can't push.
- name: Build and push the container image
if: ${{ vars.PUBLISH_DOCKER != 'false' }}
env:
REGISTRY_TOKEN: ${{ secrets.REGISTRY_TOKEN || secrets.GITHUB_TOKEN }}
REGISTRY_USER: ${{ vars.REGISTRY_USER || github.actor }}
run: |
host=${GITHUB_SERVER_URL#*://}
owner=$(echo "$GITHUB_REPOSITORY_OWNER" | tr 'A-Z' 'a-z')
image="$host/$owner/beach"
echo "$REGISTRY_TOKEN" | docker login "$host" -u "$REGISTRY_USER" --password-stdin
# a container-driver builder can build several architectures in one go
docker buildx create --name release --driver docker-container --use >/dev/null 2>&1 || docker buildx use release
tags="-t $image:$GITHUB_REF_NAME"
case "$GITHUB_REF_NAME" in
*-*) ;; # pre-releases (v1.0.0-rc1) don't move :latest
*) tags="$tags -t $image:latest" ;;
esac
docker buildx build --platform linux/amd64 $tags --push .
+20
View File
@@ -0,0 +1,20 @@
# syntax=docker/dockerfile:1
# Packages the binary deploy/build.sh already built (dist/bin/linux_<arch>/beach), so no
# emulation is needed. Build it with: sh deploy/build.sh && docker buildx build .
#
# Beach runs as root in the container: to start and stop containers it must read the
# Docker socket, and the socket's group id differs from host to host. smartmontools is
# there for the optional "smartctl" source (it also needs the devices passed in).
FROM alpine:3.22
ARG TARGETARCH
LABEL org.opencontainers.image.title="Beach" \
org.opencontainers.image.description="One-page control panel for a homelab: containers, pools, disks and tunnels" \
org.opencontainers.image.source="https://git.veillax.com/Veillax/beach" \
org.opencontainers.image.licenses="MIT"
RUN apk add --no-cache ca-certificates smartmontools \
&& mkdir /data
COPY dist/bin/linux_${TARGETARCH}/beach /beach
VOLUME ["/data"]
EXPOSE 8095
ENTRYPOINT ["/beach"]
CMD ["-listen", ":8095", "-data", "/data/beach.db"]
+18 -5
View File
@@ -31,15 +31,28 @@ There are two flags only: `-listen` and `-data`. There is no config file or envi
## Running in Docker
Mount the Docker socket (this gives the container control of Docker, which is what the start/stop buttons need) and, for host metrics, run it with the host's `/proc` visible:
Tagged releases publish an image to this server's container registry (`git.veillax.com/veillax/beach`).
To build one yourself: `sh deploy/build.sh && docker buildx build -t beach .`.
Mount the Docker socket (this gives the container control of Docker, which is what the start/stop buttons need):
```
docker run -d --name beach -p 127.0.0.1:8095:8095 -v beach:/data \
-v /var/run/docker.sock:/var/run/docker.sock \
beach -data /data/beach.db
docker run -d --name beach -p 127.0.0.1:8095:8095 -v beach:/data -v /var/run/docker.sock:/var/run/docker.sock git.veillax.com/veillax/beach:latest
```
(There is no published image yet: build one from `go build` output in a `scratch`/`distroless` image.)
CPU, memory, load and uptime are the host's even inside a container; the filesystem list is the container's own,
so on TrueNAS rely on its API for pools and disks.
## TrueNAS SCALE
1. Apps, then Discover Apps, then Custom App, then Install via YAML. Paste [deploy/docker-compose.yml](deploy/docker-compose.yml)
and change the data path to a dataset (for example `/mnt/<pool>/apps/beach`).
2. If the registry is private, add it under Apps, Configuration, Docker Registry Settings first.
3. Open `http://<truenas-ip>:8095`, create the administrator, then in **Settings** add TrueNAS (`https://<truenas-ip>`
and an API key from Credentials, API Keys; tick "self-signed certificate" if needed), Docker, and Hammerhead.
smartctl in the container needs the disks passed in (`privileged: true`); TrueNAS's API already reports SMART data and
temperatures, so you can leave it off.
## Security notes
+3 -1
View File
@@ -4,6 +4,7 @@
# deploy/build.sh [version] version defaults to `git describe`
#
# Output:
# dist/bin/<os>_<arch>/beach the raw binary (the Docker image uses the linux ones)
# dist/beach_<version>_<os>_<arch>.tar.gz or .zip
# dist/SHA256SUMS
#
@@ -17,7 +18,7 @@ VERSION=${1:-$(git describe --tags --always 2>/dev/null || echo dev)}
TARGETS=${TARGETS:-"linux/amd64 windows/amd64"}
rm -rf dist
mkdir -p dist/stage
mkdir -p dist/bin dist/stage
for t in $TARGETS; do
os=${t%/*}
arch=${t#*/}
@@ -29,6 +30,7 @@ for t in $TARGETS; do
for c in $CMDS; do
echo "building $c $VERSION for $os/$arch"
CGO_ENABLED=0 GOOS=$os GOARCH=$arch go build -trimpath -ldflags "-s -w -X main.version=$VERSION" -o "$stage/$c$ext" "./cmd/$c"
mkdir -p "dist/bin/${os}_${arch}" && cp "$stage/$c$ext" "dist/bin/${os}_${arch}/"
done
for f in LICENSE README.md; do
[ -f "$f" ] && cp "$f" "$stage/"
+15
View File
@@ -0,0 +1,15 @@
# Beach as a TrueNAS SCALE app (Apps -> Discover Apps -> Custom App -> Install via YAML),
# or on any Docker host. Change the image to match your registry and the release you want.
services:
beach:
image: git.veillax.com/veillax/beach:latest
restart: unless-stopped
ports:
- "8095:8095"
volumes:
# Beach's database. On TrueNAS use a dataset path, e.g. /mnt/<pool>/apps/beach
- /mnt/tank/apps/beach:/data
# Lets Beach list, start and stop containers. This gives it control of Docker.
- /var/run/docker.sock:/var/run/docker.sock
# Only for the optional smartctl source; TrueNAS's API already reports SMART data.
# privileged: true