diff --git a/.github/workflows/release-binary.yaml b/.github/workflows/release.yaml similarity index 54% rename from .github/workflows/release-binary.yaml rename to .github/workflows/release.yaml index 7e3e772..0b3c7b1 100644 --- a/.github/workflows/release-binary.yaml +++ b/.github/workflows/release.yaml @@ -1,4 +1,4 @@ -name: Release Binary +name: Release on: release: @@ -9,8 +9,12 @@ on: description: "Skip binary publish" required: false default: "false" - skip_announce: - description: "Skip announce" + skip_docker: + description: "Skip docker publish" + required: false + default: "false" + skip_homebrew: + description: "Skip homebrew publish" required: false default: "false" @@ -31,6 +35,19 @@ jobs: with: go-version-file: go.mod + # Setup QEMU, buildx and login to DockerHub, required for GoReleaser + - name: Set up QEMU + uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1 + + - name: Login to DockerHub + uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + - name: Run GoReleaser uses: goreleaser/goreleaser-action@9c156ee8a17a598857849441385a2041ef570552 # v6.3.0 with: @@ -39,7 +56,8 @@ jobs: args: > release --clean ${{ github.event.inputs.skip_publish == 'true' && ' --skip publish' || '' }} - ${{ github.event.inputs.skip_announce == 'true' && ' --skip announce' || '' }} + ${{ github.event.inputs.skip_docker == 'true' && ' --skip docker' || '' }} + ${{ github.event.inputs.skip_homebrew == 'true' && ' --skip homebrew' || '' }} env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} HOMEBREW_TAP_GITHUB_TOKEN: ${{ secrets.HOMEBREW_TAP_GITHUB_TOKEN }} \ No newline at end of file diff --git a/.goreleaser.yaml b/.goreleaser.yaml index fef63ba..e6debd7 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -68,6 +68,36 @@ homebrew_casks: system_command "/usr/bin/xattr", args: ["-dr", "com.apple.quarantine", "#{staged_path}/mcpd"] end +dockers: + - goarch: amd64 + use: buildx + image_templates: + - "mzdotai/mcpd:{{ .Tag }}-amd64" + - "mzdotai/mcpd:latest-amd64" + build_flag_templates: + - "--pull" + - "--platform=linux/amd64" + - "--label=org.opencontainers.image.version={{ .Tag }}" + - goarch: arm64 + use: buildx + image_templates: + - "mzdotai/mcpd:{{ .Tag }}-arm64" + - "mzdotai/mcpd:latest-arm64" + build_flag_templates: + - "--pull" + - "--platform=linux/arm64" + - "--label=org.opencontainers.image.version={{ .Tag }}" + +docker_manifests: + - name_template: "mzdotai/mcpd:{{ .Tag }}" + image_templates: + - "mzdotai/mcpd:{{ .Tag }}-amd64" + - "mzdotai/mcpd:{{ .Tag }}-arm64" + - name_template: "mzdotai/mcpd:latest" + image_templates: + - "mzdotai/mcpd:latest-amd64" + - "mzdotai/mcpd:latest-arm64" + changelog: disable: true diff --git a/Dockerfile b/Dockerfile index 56b52c8..34b3bdc 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,22 +1,16 @@ # syntax=docker/dockerfile:1 -# ============================================================================== -# Builder Stage: Fetch uv binaries -# ============================================================================== -FROM ghcr.io/astral-sh/uv:0.7.20 AS uv-builder - # ============================================================================== # Final Stage: Build the production image. # Includes NodeJS to give mcpd access to the npx binary. # ============================================================================== -FROM node:current-alpine3.22 +FROM node:24.5.0-alpine3.22 # --- Metadata --- -# The version label should be dynamically overridden in a CI/CD pipeline -# (e.g., --label "org.opencontainers.image.version=${GIT_TAG}"). LABEL org.opencontainers.image.authors="Mozilla AI " LABEL org.opencontainers.image.description="A container for the mcpd application." -LABEL org.opencontainers.image.version="1.0.0" +# The version label should be dynamically overridden in a CI/CD pipeline +LABEL org.opencontainers.image.version="dev" ARG MCPD_USER=mcpd ARG MCPD_HOME=/home/$MCPD_USER @@ -24,14 +18,26 @@ ARG MCPD_HOME=/home/$MCPD_USER # Sensible defaults but can be easily overridden by the user with `docker run -e KEY=VALUE`. ENV MCPD_API_PORT=8090 ENV MCPD_LOG_LEVEL=info +ENV MCPD_LOG_PATH=/var/log/mcpd/mcpd.log +ENV MCPD_CONFIG_FILE=/etc/mcpd/.mcpd.toml +ENV MCPD_RUNTIME_FILE=/home/mcpd/.config/mcpd/secrets.prd.toml + +USER root + +# Installs python, pip and tools +RUN apk add --no-cache \ + python3=3.12.11-r0 \ + py3-pip=25.1.1-r0 \ + py3-setuptools=80.9.0-r0 \ + py3-wheel=0.46.1-r0 + +# Installs 'tini', a lightweight init system to properly manage processes. +RUN apk add --no-cache tini=0.19.0-r3 -# - Installs 'tini', a lightweight init system to properly manage processes. # - Adds a dedicated non-root group and user for security (using the ARG). # - Creates necessary directories for configs, logs, and user data. # - Sets correct ownership for the non-root user. -USER root -RUN apk add --no-cache python3 py3-pip tini && \ - addgroup -S $MCPD_USER && \ +RUN addgroup -S $MCPD_USER && \ adduser -D -S -h $MCPD_HOME -G $MCPD_USER $MCPD_USER && \ mkdir -p \ $MCPD_HOME/.config/mcpd \ @@ -39,8 +45,8 @@ RUN apk add --no-cache python3 py3-pip tini && \ /etc/mcpd && \ chown -R $MCPD_USER:$MCPD_USER $MCPD_HOME /var/log/mcpd -# Copy binaries from the dedicated 'uv-builder' stage. -COPY --from=uv-builder /uv /uvx /usr/local/bin/ +# Copy uv/uvx binaries from image. +COPY --from=ghcr.io/astral-sh/uv:0.8.4 /uv /uvx /usr/local/bin/ # Copy application binary and set ownership to the non-root user. # IMPORTANT: Config/secrets are NOT copied. They should be mounted at runtime. @@ -59,6 +65,13 @@ ENTRYPOINT ["/sbin/tini", "--"] CMD mcpd daemon \ --addr 0.0.0.0:$MCPD_API_PORT \ --log-level $MCPD_LOG_LEVEL \ - --log-path /var/log/mcpd/mcpd.log \ - --config-file /etc/mcpd/.mcpd.toml \ - --runtime-file /home/mcpd/.config/mcpd/secrets.prd.toml \ No newline at end of file + --log-path $MCPD_LOG_PATH \ + --config-file $MCPD_CONFIG_FILE \ + --runtime-file $MCPD_RUNTIME_FILE + +# Example run: +# docker run -p 8090:8090 +# -v $PWD/.mcpd.toml:/etc/mcpd/.mcpd.toml \ +# -v HOME/.config/mcpd/secrets.dev.toml:/home/mcpd/.config/mcpd/secrets.prd.toml \ +# -e MCPD_LOG_LEVEL=debug \ +# mzdotai/mcpd:v0.0.2 \ No newline at end of file diff --git a/docker-compose.yaml b/docker-compose.yaml index 0861d8e..2f4e437 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -2,13 +2,13 @@ services: mcpd: build: context: . - args: - MCPD_API_PORT: ${MCPD_API_PORT:-8090} container_name: mcpd - env_file: .env environment: MCPD_API_PORT: ${MCPD_API_PORT:-8090} MCPD_LOG_LEVEL: ${MCPD_LOG_LEVEL:-INFO} + MCPD_LOG_PATH: ${MCPD_LOG_PATH:-/var/log/mcpd/mcpd.log} + MCPD_CONFIG_FILE: ${MCPD_CONFIG_FILE:-/etc/mcpd/.mcpd.toml} + MCPD_RUNTIME_FILE: ${MCPD_RUNTIME_FILE:-/home/mcpd/.config/mcpd/secrets.prd.toml} ports: - "${MCPD_API_PORT:-8090}:${MCPD_API_PORT:-8090}" volumes: diff --git a/internal/cmd/basecmd.go b/internal/cmd/basecmd.go index f60f7b1..90f7300 100644 --- a/internal/cmd/basecmd.go +++ b/internal/cmd/basecmd.go @@ -24,7 +24,7 @@ var ( // Version is used by other packages to retrieve the build version of mcpd. func Version() string { - return fmt.Sprintf("mcpd %s (%s), built %s", version, commit, date) + return fmt.Sprintf("mcpd v%s (%s), built %s", version, commit, date) } // AppName returns the name of the mcpd application.