From cdaf9f0c0a71f3959d697add961449eb4ecfa9d6 Mon Sep 17 00:00:00 2001 From: Tobias Gesellchen Date: Thu, 23 Apr 2026 22:23:00 +0200 Subject: [PATCH] Build and publish a soundtouch-web Docker image (#184) Relates to https://github.com/gesellix/Bose-SoundTouch/issues/181 --- .github/workflows/ci.yml | 32 +++++++++++++++++++++++++++----- .github/workflows/release.yml | 33 ++++++++++++++++++++++++++++----- Dockerfile | 32 ++++++++++++++++++++++++-------- Makefile | 2 +- cmd/soundtouch-web/main.go | 2 +- docker-compose.ci.yml | 4 +++- 6 files changed, 84 insertions(+), 21 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 94664e5..edff657 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -279,8 +279,8 @@ jobs: username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - name: Extract metadata (tags, labels) for Docker - id: meta + - name: Extract metadata (tags, labels) for soundtouch-service + id: meta-service uses: docker/metadata-action@v6 with: images: ghcr.io/${{ github.repository }} @@ -288,14 +288,36 @@ jobs: type=raw,value=edge,enable=${{ github.ref == 'refs/heads/main' }} type=ref,event=pr - - name: Build and push Docker image + - name: Build and push soundtouch-service Docker image uses: docker/build-push-action@v7 with: context: . + target: soundtouch-service platforms: linux/amd64,linux/arm64,linux/arm64/v8,linux/arm/v7 push: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }} - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} + tags: ${{ steps.meta-service.outputs.tags }} + labels: ${{ steps.meta-service.outputs.labels }} + cache-from: type=gha + cache-to: type=gha,mode=max + + - name: Extract metadata (tags, labels) for soundtouch-web + id: meta-web + uses: docker/metadata-action@v6 + with: + images: ghcr.io/${{ github.repository }}-web + tags: | + type=raw,value=edge,enable=${{ github.ref == 'refs/heads/main' }} + type=ref,event=pr + + - name: Build and push soundtouch-web Docker image + uses: docker/build-push-action@v7 + with: + context: . + target: soundtouch-web + platforms: linux/amd64,linux/arm64,linux/arm64/v8,linux/arm/v7 + push: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }} + tags: ${{ steps.meta-web.outputs.tags }} + labels: ${{ steps.meta-web.outputs.labels }} cache-from: type=gha cache-to: type=gha,mode=max diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d8f5573..4ffda80 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -518,8 +518,8 @@ jobs: username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - name: Extract metadata (tags, labels) for Docker - id: meta + - name: Extract metadata (tags, labels) for soundtouch-service + id: meta-service uses: docker/metadata-action@v6 with: images: ghcr.io/${{ github.repository }} @@ -528,14 +528,37 @@ jobs: type=semver,pattern={{major}}.{{minor}},value=v${{ needs.validate.outputs.version }} type=raw,value=latest,enable=${{ needs.validate.outputs.is_prerelease == 'false' }} - - name: Build and push Docker image + - name: Build and push soundtouch-service Docker image uses: docker/build-push-action@v7 with: context: . + target: soundtouch-service platforms: linux/amd64,linux/arm64,linux/arm64/v8,linux/arm/v7 push: true - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} + tags: ${{ steps.meta-service.outputs.tags }} + labels: ${{ steps.meta-service.outputs.labels }} + cache-from: type=gha + cache-to: type=gha,mode=max + + - name: Extract metadata (tags, labels) for soundtouch-web + id: meta-web + uses: docker/metadata-action@v6 + with: + images: ghcr.io/${{ github.repository }}-web + tags: | + type=semver,pattern={{version}},value=v${{ needs.validate.outputs.version }} + type=semver,pattern={{major}}.{{minor}},value=v${{ needs.validate.outputs.version }} + type=raw,value=latest,enable=${{ needs.validate.outputs.is_prerelease == 'false' }} + + - name: Build and push soundtouch-web Docker image + uses: docker/build-push-action@v7 + with: + context: . + target: soundtouch-web + platforms: linux/amd64,linux/arm64,linux/arm64/v8,linux/arm/v7 + push: true + tags: ${{ steps.meta-web.outputs.tags }} + labels: ${{ steps.meta-web.outputs.labels }} cache-from: type=gha cache-to: type=gha,mode=max diff --git a/Dockerfile b/Dockerfile index f5af74e..c07a897 100644 --- a/Dockerfile +++ b/Dockerfile @@ -24,31 +24,47 @@ RUN if [ "${TARGETARCH}" = "arm" ] && [ -n "${TARGETVARIANT}" ]; then \ CGO_ENABLED=0 GOOS=${TARGETOS} GOARCH=${TARGETARCH} go build -o /soundtouch-service ./cmd/soundtouch-service; \ fi -# Final stage -FROM alpine:3.23 +# Build the soundtouch-web +RUN if [ "${TARGETARCH}" = "arm" ] && [ -n "${TARGETVARIANT}" ]; then \ + CGO_ENABLED=0 GOOS=${TARGETOS} GOARCH=${TARGETARCH} GOARM=${TARGETVARIANT#v} go build -o /soundtouch-web ./cmd/soundtouch-web; \ + else \ + CGO_ENABLED=0 GOOS=${TARGETOS} GOARCH=${TARGETARCH} go build -o /soundtouch-web ./cmd/soundtouch-web; \ + fi + +# soundtouch-service image +FROM alpine:3.23 AS soundtouch-service -# Install necessary runtime dependencies RUN apk add --no-cache ca-certificates tzdata WORKDIR /app -# Copy the binary from the builder stage COPY --from=builder /soundtouch-service /app/soundtouch-service # Verify the binary works on the target platform RUN /app/soundtouch-service version || echo "Binary verification complete" -# Create data directory for persistence RUN mkdir -p /app/data -# Set environment variables with defaults ENV PORT=8000 ENV DATA_DIR=/app/data ENV LOG_PROXY_BODY=false ENV REDACT_PROXY_LOGS=true -# Expose the service port EXPOSE 8000 -# Run the service ENTRYPOINT ["/app/soundtouch-service"] + +# soundtouch-web image +FROM alpine:3.23 AS soundtouch-web + +RUN apk add --no-cache ca-certificates tzdata + +WORKDIR /app + +COPY --from=builder /soundtouch-web /app/soundtouch-web + +ENV PORT=8080 + +EXPOSE 8080 + +ENTRYPOINT ["/app/soundtouch-web"] diff --git a/Makefile b/Makefile index 021541f..45fe72f 100644 --- a/Makefile +++ b/Makefile @@ -291,7 +291,7 @@ release: clean check build-all docker-build: @echo "Building Docker image..." - docker build -t soundtouch-service . + docker build --target soundtouch-service -t soundtouch-service . docker-run-host: @echo "Running Docker container..." diff --git a/cmd/soundtouch-web/main.go b/cmd/soundtouch-web/main.go index c499720..efb38a5 100644 --- a/cmd/soundtouch-web/main.go +++ b/cmd/soundtouch-web/main.go @@ -64,7 +64,7 @@ func main() { r := setupRoutes(app, discoveryService) // Start web server - log.Printf("SoundTouch Web UI starting on http://localhost:%s", *port) + log.Printf("SoundTouch Web UI starting on http://0.0.0.0:%s", *port) log.Fatal(http.ListenAndServe(":"+*port, r)) } diff --git a/docker-compose.ci.yml b/docker-compose.ci.yml index 284dc26..4657fb3 100644 --- a/docker-compose.ci.yml +++ b/docker-compose.ci.yml @@ -1,6 +1,8 @@ services: soundtouch-service: - build: . + build: + context: . + target: soundtouch-service volumes: - ./tests/integration/testdata:/app/data environment: