diff --git a/.github/workflows/partial-publish.yaml b/.github/workflows/partial-publish.yaml index 4b80f19..698665c 100644 --- a/.github/workflows/partial-publish.yaml +++ b/.github/workflows/partial-publish.yaml @@ -64,3 +64,16 @@ jobs: --build-arg COMMIT=$(git rev-parse HEAD) \ --build-arg BUILD_TIME=$(date -u +"%Y-%m-%dT%H:%M:%SZ") \ --platform linux/amd64,linux/arm64,linux/arm/v7 . + + - name: build release tagged the rootless image + if: ${{ inputs.release == true }} + run: | + docker build --push --no-cache \ + --tag ghcr.io/hay-kot/homebox:nightly-rootless \ + --tag ghcr.io/hay-kot/homebox:latest-rootless \ + --tag ghcr.io/hay-kot/homebox:${{ inputs.tag }}-rootless \ + --build-arg VERSION=${{ inputs.tag }} \ + --build-arg COMMIT=$(git rev-parse HEAD) \ + --build-arg BUILD_TIME=$(date -u +"%Y-%m-%dT%H:%M:%SZ") \ + --platform linux/amd64,linux/arm64,linux/arm/v7 \ + --file Dockerfile.rootless . diff --git a/Dockerfile.rootless b/Dockerfile.rootless new file mode 100644 index 0000000..e1c98aa --- /dev/null +++ b/Dockerfile.rootless @@ -0,0 +1,53 @@ + +# Build Nuxt +FROM node:17-alpine as frontend-builder +WORKDIR /app +RUN npm install -g pnpm +COPY frontend/package.json frontend/pnpm-lock.yaml ./ +RUN pnpm install --frozen-lockfile --shamefully-hoist +COPY frontend . +RUN pnpm build + +# Build API +FROM golang:alpine AS builder +ARG BUILD_TIME +ARG COMMIT +ARG VERSION +RUN apk update && \ + apk upgrade && \ + apk add --update git build-base gcc g++ + +WORKDIR /go/src/app +COPY ./backend . +RUN go get -d -v ./... +RUN rm -rf ./app/api/public +COPY --from=frontend-builder /app/.output/public ./app/api/static/public +RUN CGO_ENABLED=0 GOOS=linux go build \ + -ldflags "-s -w -X main.commit=$COMMIT -X main.buildTime=$BUILD_TIME -X main.version=$VERSION" \ + -o /go/bin/api \ + -v ./app/api/*.go && \ + chmod +x /go/bin/api && \ + # create a directory so that we can copy it in the next stage + mkdir /data + +# Production Stage +FROM gcr.io/distroless/static + +ENV HBOX_MODE=production +ENV HBOX_STORAGE_DATA=/data/ +ENV HBOX_STORAGE_SQLITE_URL=/data/homebox.db?_fk=1 + +# Copy the binary and the (empty) /data dir and +# change the ownership to the low-privileged user +COPY --from=builder --chown=nonroot /go/bin/api /app +COPY --from=builder --chown=nonroot /data /data + +LABEL Name=homebox Version=0.0.1 +LABEL org.opencontainers.image.source="https://github.com/hay-kot/homebox" +EXPOSE 7745 +VOLUME [ "/data" ] + +# Drop root and run as low-privileged user +USER nonroot +ENTRYPOINT [ "/app" ] +CMD [ "/data/config.yml" ] diff --git a/README.md b/README.md index 611a530..8b98704 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,10 @@ [Configuration & Docker Compose](https://hay-kot.github.io/homebox/quick-start) ```bash +# If using the rootless image, ensure data +# folder has correct permissions +mkdir -p /path/to/data/folder +chown 65532:65532 -R /path/to/data/folder docker run -d \ --name homebox \ --restart unless-stopped \ @@ -23,6 +27,7 @@ docker run -d \ --env TZ=Europe/Bucharest \ --volume /path/to/data/folder/:/data \ ghcr.io/hay-kot/homebox:latest +# ghcr.io/hay-kot/homebox:latest-rootless ``` ## Credits diff --git a/docs/docs/quick-start.md b/docs/docs/quick-start.md index e0ad87b..8081ea5 100644 --- a/docs/docs/quick-start.md +++ b/docs/docs/quick-start.md @@ -4,14 +4,24 @@ Great for testing out the application, but not recommended for stable use. Checkout the docker-compose for the recommended deployment. +For each image there are two tags, respectively the regular tag and $TAG-rootless, which uses a non-root image. + ```sh -docker run -d \ +# If using the rootless image, ensure data +# folder has correct permissions +$ mkdir -p /path/to/data/folder +$ chown 65532:65532 -R /path/to/data/folder +# --------------------------------------- +# Run the image +$ docker run -d \ --name homebox \ --restart unless-stopped \ --publish 3100:7745 \ --env TZ=Europe/Bucharest \ --volume /path/to/data/folder/:/data \ ghcr.io/hay-kot/homebox:latest +# ghcr.io/hay-kot/homebox:latest-rootless + ``` ## Docker-Compose @@ -22,6 +32,7 @@ version: "3.4" services: homebox: image: ghcr.io/hay-kot/homebox:latest +# image: ghcr.io/hay-kot/homebox:latest-rootless container_name: homebox restart: always environment: @@ -38,6 +49,9 @@ volumes: driver: local ``` +!!! note + If you use the `rootless` image, and instead of using named volumes you would prefer using a hostMount directly (e.g., `volumes: [ /path/to/data/folder:/data ]`) you need to `chown` the chosen directory in advance to the `65532` user (as shown in the Docker example above). + ## Env Variables & Configuration | Variable | Default | Description |