Skip to content

Commit 79d7e90

Browse files
author
Paul C
committed
wolfdisk: publish multi-arch Docker image to GHCR
- wolfdisk/docker/Dockerfile: debian-slim base with fuse3, binaries copied per-arch via TARGETARCH. - wolfdisk/docker/entrypoint.sh: first-run bootstrap. Creates the data directory via `wolfdisk init`, writes /etc/wolfdisk/config.toml from env vars (WOLFDISK_NODE_ID, WOLFDISK_ROLE, WOLFDISK_BIND, WOLFDISK_MODE, comma-separated WOLFDISK_PEERS, WOLFDISK_DATA_DIR, WOLFDISK_MOUNT), then execs `wolfdisk mount --mountpoint $MOUNT`. - .github/workflows/wolfdisk-docker-publish.yml: cross-compiles both musl targets, then buildx+QEMU assembles a multi-arch image and pushes to ghcr.io/wolfsoftwaresystemsltd/wolfdisk:{latest,<version>}.
1 parent d296363 commit 79d7e90

3 files changed

Lines changed: 216 additions & 0 deletions

File tree

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
name: WolfDisk — Publish Docker Image
2+
3+
on:
4+
push:
5+
branches: [main]
6+
paths:
7+
- 'wolfdisk/Cargo.toml'
8+
- 'wolfdisk/src/**'
9+
- 'wolfdisk/docker/**'
10+
- '.github/workflows/wolfdisk-docker-publish.yml'
11+
workflow_dispatch:
12+
13+
jobs:
14+
build-binaries:
15+
strategy:
16+
matrix:
17+
include:
18+
- target: x86_64-unknown-linux-musl
19+
arch: amd64
20+
runner: ubuntu-latest
21+
- target: aarch64-unknown-linux-musl
22+
arch: arm64
23+
runner: ubuntu-latest
24+
25+
runs-on: ${{ matrix.runner }}
26+
defaults:
27+
run:
28+
working-directory: wolfdisk
29+
steps:
30+
- uses: actions/checkout@v4
31+
32+
- name: Install Rust
33+
uses: dtolnay/rust-toolchain@stable
34+
with:
35+
targets: ${{ matrix.target }}
36+
37+
- name: Install cross
38+
run: cargo install cross --git https://github.com/cross-rs/cross
39+
working-directory: .
40+
41+
- name: Build static binaries
42+
run: cross build --release --target ${{ matrix.target }}
43+
44+
- name: Stage binaries
45+
run: |
46+
mkdir -p dist/${{ matrix.arch }}
47+
cp target/${{ matrix.target }}/release/wolfdisk dist/${{ matrix.arch }}/wolfdisk
48+
cp target/${{ matrix.target }}/release/wolfdiskctl dist/${{ matrix.arch }}/wolfdiskctl
49+
chmod +x dist/${{ matrix.arch }}/wolfdisk dist/${{ matrix.arch }}/wolfdiskctl
50+
51+
- name: Upload artifact
52+
uses: actions/upload-artifact@v4
53+
with:
54+
name: wolfdisk-binaries-${{ matrix.arch }}
55+
path: wolfdisk/dist/${{ matrix.arch }}/
56+
57+
publish:
58+
needs: build-binaries
59+
runs-on: ubuntu-latest
60+
permissions:
61+
contents: read
62+
packages: write
63+
steps:
64+
- uses: actions/checkout@v4
65+
66+
- name: Get version
67+
id: version
68+
run: echo "version=$(grep '^version' wolfdisk/Cargo.toml | head -1 | sed 's/.*\"\(.*\)\".*/\1/')" >> "$GITHUB_OUTPUT"
69+
70+
- name: Download amd64 binaries
71+
uses: actions/download-artifact@v4
72+
with:
73+
name: wolfdisk-binaries-amd64
74+
path: wolfdisk/dist/amd64
75+
76+
- name: Download arm64 binaries
77+
uses: actions/download-artifact@v4
78+
with:
79+
name: wolfdisk-binaries-arm64
80+
path: wolfdisk/dist/arm64
81+
82+
- name: Ensure binaries are executable
83+
run: chmod +x wolfdisk/dist/amd64/* wolfdisk/dist/arm64/*
84+
85+
- name: Set up QEMU
86+
uses: docker/setup-qemu-action@v3
87+
88+
- name: Set up Docker Buildx
89+
uses: docker/setup-buildx-action@v3
90+
91+
- name: Log in to GHCR
92+
uses: docker/login-action@v3
93+
with:
94+
registry: ghcr.io
95+
username: ${{ github.actor }}
96+
password: ${{ secrets.GITHUB_TOKEN }}
97+
98+
- name: Build and push multi-arch image
99+
uses: docker/build-push-action@v5
100+
with:
101+
context: wolfdisk
102+
file: wolfdisk/docker/Dockerfile
103+
platforms: linux/amd64,linux/arm64
104+
push: true
105+
tags: |
106+
ghcr.io/wolfsoftwaresystemsltd/wolfdisk:latest
107+
ghcr.io/wolfsoftwaresystemsltd/wolfdisk:${{ steps.version.outputs.version }}

wolfdisk/docker/Dockerfile

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# WolfDisk Docker Container — distributed FUSE filesystem
2+
#
3+
# Runs in --network host mode with /dev/fuse. Pre-built static musl binaries
4+
# are placed under dist/<arch>/ by the publish workflow; this Dockerfile
5+
# copies the right one based on TARGETARCH.
6+
#
7+
# Usage:
8+
# docker run -d --name wolfdisk --network host \
9+
# --cap-add SYS_ADMIN --device /dev/fuse:/dev/fuse \
10+
# --security-opt apparmor:unconfined \
11+
# -v wolfdisk-config:/etc/wolfdisk \
12+
# -v wolfdisk-data:/var/lib/wolfdisk \
13+
# -v /mnt/wolfdisk:/mnt/wolfdisk:rshared \
14+
# -e WOLFDISK_ROLE=client \
15+
# -e WOLFDISK_PEERS=<leader_ip:8550> \
16+
# ghcr.io/wolfsoftwaresystemsltd/wolfdisk:latest
17+
18+
FROM debian:bookworm-slim
19+
20+
ARG TARGETARCH
21+
22+
RUN apt-get update && apt-get install -y --no-install-recommends \
23+
fuse3 \
24+
procps \
25+
ca-certificates \
26+
&& rm -rf /var/lib/apt/lists/*
27+
28+
RUN mkdir -p /etc/wolfdisk /var/lib/wolfdisk /mnt/wolfdisk
29+
30+
COPY dist/${TARGETARCH}/wolfdisk /usr/local/bin/wolfdisk
31+
COPY dist/${TARGETARCH}/wolfdiskctl /usr/local/bin/wolfdiskctl
32+
COPY docker/entrypoint.sh /entrypoint.sh
33+
34+
RUN chmod +x /usr/local/bin/wolfdisk /usr/local/bin/wolfdiskctl /entrypoint.sh
35+
36+
EXPOSE 8550/tcp
37+
EXPOSE 9878/tcp
38+
39+
VOLUME ["/etc/wolfdisk", "/var/lib/wolfdisk"]
40+
41+
ENTRYPOINT ["/entrypoint.sh"]

wolfdisk/docker/entrypoint.sh

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
#!/bin/bash
2+
set -e
3+
4+
# ─── WolfDisk Docker Entrypoint ──────────────────────────────────────────────
5+
# Writes /etc/wolfdisk/config.toml from env vars on first run, initialises
6+
# the data directory, then mounts the filesystem.
7+
8+
CONFIG="/etc/wolfdisk/config.toml"
9+
DATA_DIR="${WOLFDISK_DATA_DIR:-/var/lib/wolfdisk}"
10+
MOUNT="${WOLFDISK_MOUNT:-/mnt/wolfdisk}"
11+
12+
mkdir -p "$(dirname "$CONFIG")" "$MOUNT" "$DATA_DIR"
13+
14+
if [ ! -c /dev/fuse ]; then
15+
echo "✗ /dev/fuse not found inside the container."
16+
echo " Run with: --device /dev/fuse:/dev/fuse (and usually --privileged or --cap-add SYS_ADMIN)"
17+
exit 1
18+
fi
19+
20+
wolfdisk --config "$CONFIG" init --data-dir "$DATA_DIR" >/dev/null 2>&1 || true
21+
22+
if [ ! -f "$CONFIG" ]; then
23+
NODE_ID="${WOLFDISK_NODE_ID:-$(hostname)}"
24+
ROLE="${WOLFDISK_ROLE:-client}"
25+
BIND="${WOLFDISK_BIND:-0.0.0.0:8550}"
26+
MODE="${WOLFDISK_MODE:-shared}"
27+
28+
# Parse comma-separated WOLFDISK_PEERS into a TOML array
29+
peers_toml=""
30+
if [ -n "$WOLFDISK_PEERS" ]; then
31+
IFS=',' read -ra parts <<< "$WOLFDISK_PEERS"
32+
first=1
33+
for p in "${parts[@]}"; do
34+
p="${p// /}"
35+
[ -z "$p" ] && continue
36+
if [ $first -eq 1 ]; then
37+
peers_toml="\"$p\""
38+
first=0
39+
else
40+
peers_toml="$peers_toml, \"$p\""
41+
fi
42+
done
43+
fi
44+
45+
cat > "$CONFIG" <<EOF
46+
[node]
47+
id = "$NODE_ID"
48+
role = "$ROLE"
49+
bind = "$BIND"
50+
data_dir = "$DATA_DIR"
51+
52+
[cluster]
53+
peers = [$peers_toml]
54+
55+
[replication]
56+
mode = "$MODE"
57+
factor = 3
58+
chunk_size = 4194304
59+
60+
[mount]
61+
path = "$MOUNT"
62+
allow_other = true
63+
EOF
64+
echo "→ Wrote $CONFIG (role=$ROLE, peers=[$peers_toml])"
65+
fi
66+
67+
echo "→ Mounting WolfDisk at $MOUNT..."
68+
exec wolfdisk --config "$CONFIG" mount --mountpoint "$MOUNT" "$@"

0 commit comments

Comments
 (0)