Files
felhom.eu/controller/BUILDING.md
T
2026-02-13 16:51:10 +01:00

6.1 KiB
Executable File

Building & Publishing felhom-controller

Prerequisites

  • Docker installed on your build machine
  • Docker Buildx plugin (for multi-arch builds — included with Docker Desktop, may need install on Linux)
  • Access to Gitea at gitea.dooplex.hu

Step 1: Enable Gitea Container Registry

Gitea has a built-in container registry. Check if it's enabled:

# SSH into your k3s node or wherever Gitea runs
# Check Gitea config (app.ini)
kubectl exec -it -n <namespace> deploy/gitea -- cat /data/gitea/conf/app.ini | grep -A5 '\[packages\]'

If the [packages] section is missing or ENABLED=false, add/update:

[packages]
ENABLED = true

Then restart Gitea:

kubectl rollout restart deploy/gitea -n <namespace>

Verify it works:

# Login to the registry (use your Gitea username + password or access token)
docker login gitea.dooplex.hu
# Username: admin
# Password: <your-gitea-password-or-token>

If login succeeds, the registry is working. The image URL pattern is: gitea.dooplex.hu/<owner>/<image>:<tag>

Step 2: Sync app assets before building

The container image includes app logos and screenshots. Sync them from the felhom.eu website repo before building:

# If the website repo is checked out alongside this repo:
make sync-assets

# Or specify the path explicitly:
make sync-assets WEBSITE_ASSETS_DIR=/home/admin/repos/felhom.eu/website/assets

# Verify
ls assets/*.webp

If you skip this step, the dashboard will work but show no app logos/screenshots (the onerror handler hides broken images gracefully).

Step 3: Build for single architecture (quick test)

cd ~/repos/deploy-felhom-compose

# Build for your current architecture
docker build \
    --build-arg VERSION=$(git describe --tags --always 2>/dev/null || echo "0.1.0") \
    --build-arg GIT_COMMIT=$(git rev-parse --short HEAD 2>/dev/null || echo "unknown") \
    -t gitea.dooplex.hu/admin/felhom-controller:latest \
    -t gitea.dooplex.hu/admin/felhom-controller:0.1.0 \
    .

# Push
docker push gitea.dooplex.hu/admin/felhom-controller:latest
docker push gitea.dooplex.hu/admin/felhom-controller:0.1.0

Step 4: Build for both architectures (production)

You need both amd64 (N100 mini PCs) and arm64 (Raspberry Pi). Use Docker Buildx:

# One-time: Create a buildx builder that supports multi-arch
docker buildx create --name felhom-builder --use --bootstrap

# Verify it supports the architectures we need
docker buildx inspect felhom-builder
# Should show: linux/amd64, linux/arm64 in Platforms

# Build + push multi-arch image in one step
docker buildx build \
    --platform linux/amd64,linux/arm64 \
    --build-arg VERSION=0.1.0 \
    --build-arg GIT_COMMIT=$(git rev-parse --short HEAD) \
    -t gitea.dooplex.hu/admin/felhom-controller:latest \
    -t gitea.dooplex.hu/admin/felhom-controller:0.1.0 \
    --push \
    .

Note: --push is required with multi-arch builds because buildx doesn't store multi-platform images in the local Docker cache. It pushes directly to the registry.

If buildx multi-arch doesn't work (missing QEMU)

On Linux you might need QEMU for cross-compilation:

# Install QEMU user-mode emulation
sudo apt-get install -y qemu-user-static binfmt-support

# Register QEMU with Docker
docker run --rm --privileged multiarch/qemu-user-static --reset -p yes

# Verify
docker buildx ls

Alternative: Build natively on each architecture

If you don't want to cross-compile, build on each machine:

# On the N100 (amd64):
docker build -t gitea.dooplex.hu/admin/felhom-controller:latest-amd64 .
docker push gitea.dooplex.hu/admin/felhom-controller:latest-amd64

# On the Pi (arm64):
docker build -t gitea.dooplex.hu/admin/felhom-controller:latest-arm64 .
docker push gitea.dooplex.hu/admin/felhom-controller:latest-arm64

# Then create a manifest list to combine them:
docker manifest create gitea.dooplex.hu/admin/felhom-controller:latest \
    gitea.dooplex.hu/admin/felhom-controller:latest-amd64 \
    gitea.dooplex.hu/admin/felhom-controller:latest-arm64
docker manifest push gitea.dooplex.hu/admin/felhom-controller:latest

Step 5: Deploy on a customer node

On the customer's machine, the docker-compose.yml for the controller references the image from the registry:

services:
  felhom-controller:
    image: gitea.dooplex.hu/admin/felhom-controller:latest
    # ...

Pull and start:

# Login to registry on the customer node (one-time)
docker login gitea.dooplex.hu

# Start the controller
cd /opt/docker/felhom-controller
docker compose pull
docker compose up -d

# Verify
docker compose logs -f
curl -s http://localhost:8080/api/health

Step 6: Updating the controller

When you release a new version:

# On your build machine:
docker buildx build \
    --platform linux/amd64,linux/arm64 \
    --build-arg VERSION=0.2.0 \
    -t gitea.dooplex.hu/admin/felhom-controller:latest \
    -t gitea.dooplex.hu/admin/felhom-controller:0.2.0 \
    --push .

# On the customer node (manually for now; auto-update comes in Phase 5):
cd /opt/docker/felhom-controller
docker compose pull
docker compose up -d

Makefile shortcuts

The Makefile has convenience targets:

make docker-build      # Build for current platform
make docker-buildx     # Build multi-arch + push
make docker-push       # Push current platform image

Troubleshooting

"unauthorized" when pushing

docker logout gitea.dooplex.hu
docker login gitea.dooplex.hu

Gitea registry not accessible

Check if Gitea's HTTPS is working and the domain resolves:

curl -v https://gitea.dooplex.hu/v2/
# Should return: {"errors":[{"code":"UNAUTHORIZED",...}]}

Build fails on arm64 via QEMU (too slow or errors)

Cross-compiling Go via QEMU can be slow. Since the Go binary itself is cross-compiled (CGO_ENABLED=0), only the Debian packages in the runtime stage need QEMU. Alternative: build the Go binary natively, then build only the runtime Docker layer via buildx.

Image too large

Expected sizes:

  • Go binary: ~15-20 MB
  • Runtime image (debian-slim + docker-cli + restic + pg_dump): ~250-350 MB

To reduce: consider Alpine instead of Debian slim, but test pg_dump/mysqldump compatibility first.