diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index 93997ed..48e3c0c 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -15,14 +15,28 @@ env: # There is a single job in this workflow. It's configured to run on the latest available version of Ubuntu. jobs: - build-and-push-image: + image: runs-on: ubuntu-latest # Sets the permissions granted to the `GITHUB_TOKEN` for the actions in this job. permissions: contents: read packages: write - # + + strategy: + fail-fast: false + matrix: + base-image: [debian, alpine] steps: + - name: Prepare + run: | + if [ "${{ matrix.base-image }}" = "debian" ]; then + echo "DOCKERFILE=openwec.Dockerfile" >> $GITHUB_ENV + echo "FLAVOR_OPTS=" >> $GITHUB_ENV + elif [ "${{ matrix.base-image }}" = "alpine" ]; then + echo "DOCKERFILE=openwec-alpine.Dockerfile" >> $GITHUB_ENV + echo "FLAVOR_OPTS=suffix=-alpine,onlatest=true" >> $GITHUB_ENV + fi + - name: Checkout repository uses: actions/checkout@v4 # Uses the `docker/login-action` action to log in to the Container registry registry using the account and password that will publish the packages. Once published, the packages are scoped to the account defined here. @@ -32,12 +46,19 @@ jobs: registry: ${{ env.REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} + # This step uses [docker/metadata-action](https://github.com/docker/metadata-action#about) to extract tags and labels that will be applied to the specified image. The `id` "meta" allows the output of this step to be referenced in a subsequent step. The `images` value provides the base name for the tags and labels. - name: Extract metadata (tags, labels) for Docker id: meta - uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7 + uses: docker/metadata-action@8e5442c4ef9f78752691e2d8f8d19755c6f78e81 with: images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + tags: | + type=ref,event=branch + type=semver,pattern={{version}} + flavor: | + ${{ env.FLAVOR_OPTS }} + # This step uses the `docker/build-push-action` action to build the image, based on your repository's `Dockerfile`. If the build succeeds, it pushes the image to GitHub Packages. # It uses the `context` parameter to define the build's context as the set of files located in the specified path. For more information, see "[Usage](https://github.com/docker/build-push-action#usage)" in the README of the `docker/build-push-action` repository. # It uses the `tags` and `labels` parameters to tag and label the image with the output from the "meta" step. @@ -45,6 +66,7 @@ jobs: uses: docker/build-push-action@f2a1d5e99d037542a71f64918e516c093c6f3fc4 with: context: . + file: docker/${{ env.DOCKERFILE }} push: true tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} diff --git a/doc/docker.md b/doc/docker.md index 8e3e956..8fdfaeb 100644 --- a/doc/docker.md +++ b/doc/docker.md @@ -1,26 +1,35 @@ -# Docker image +# Container images -The `openwec` docker image enables you to test and deploy openwec easily. It contains two precompiled binaries: `openwec` (cli) and `openwecd` (server). +The `openwec` container image enables you to test and deploy openwec easily. It contains two precompiled binaries: `openwec` (cli) and `openwecd` (server). ## Getting `openwec` image ### From ghcr.io -The `openwec` docker image is automatically built using Github Actions: +The `openwec` container image is automatically built using Github Actions: - On each commit to the `main` branch, the image is built and pushed with the `main` tag. - When a version tag is pushed, the image is built and pushed with a tag corresponding to that version. The latest version tag can be retrieved using the `latest` tag. +The `openwec` container image comes in two flavors: the default, Debian-based image, and a more minimal Alpine-based option tagged with the `-alpine` suffix. + Example: ```bash -$ docker pull ghcr.io/cea-sec/openwec:main +$ docker pull ghcr.io/cea-sec/openwec:latest +$ docker pull ghcr.io/cea-sec/openwec:latest-alpine ``` -### Building the image by yourself +### Building the image by yourself + +`Dockerfiles` are present in the `docker` directory of the repository. You can build it using: + +```bash +$ docker build -t openwec -f docker/openwec.Dockerfile . +``` -A `Dockerfile` is present at the root of the repository. You can build it using: +To build the Alpine image: ```bash -$ docker build -t openwec . +$ docker build -t openwec -f docker/openwec-alpine.Dockerfile . ``` ## Using `openwec` image @@ -143,5 +152,5 @@ $ docker run --rm -it \ -v ./openwec.keytab:/etc/openwec.keytab:ro \ -v ./conf/:/etc/openwec.d/:ro \ -p 5985:5985 \ - ghcr.io/cea-sec/openwec:main -``` \ No newline at end of file + ghcr.io/cea-sec/openwec:latest +``` diff --git a/docker/entrypoint.sh b/docker/entrypoint.sh index 844728d..cfa268b 100755 --- a/docker/entrypoint.sh +++ b/docker/entrypoint.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env sh set -eux diff --git a/docker/openwec-alpine.Dockerfile b/docker/openwec-alpine.Dockerfile new file mode 100644 index 0000000..06adc7d --- /dev/null +++ b/docker/openwec-alpine.Dockerfile @@ -0,0 +1,55 @@ +FROM alpine:3.20 AS chef +RUN apk add --no-cache rust cargo && cargo install cargo-chef +WORKDIR /SRC + +FROM chef AS planner +COPY . . +RUN cargo chef prepare --recipe-path recipe.json + +FROM chef AS builder +# Install system deps +RUN apk upgrade --no-cache && apk add --no-cache \ + build-base \ + cmake \ + clang-dev \ + bash \ + openssl-dev \ + krb5-dev \ + pkgconf \ + rust-bindgen + +COPY --from=planner /SRC/recipe.json recipe.json +# Build dependencies - this is the caching Docker layer! +RUN cargo chef cook --release --recipe-path recipe.json + +# Build application +COPY . . +RUN cargo build --release --locked + + +FROM alpine:3.20 +ARG APP=/usr/src/openwec +ARG DATA=/var/lib/openwec/data +ARG DB=/var/lib/openwec/db + +EXPOSE 5985 5986 +ENV APP_USER=openwec + +RUN apk upgrade --no-cache && apk add --no-cache \ + libgcc \ + libssl3 libcrypto3 \ + krb5-libs \ + && addgroup $APP_USER \ + && adduser -G $APP_USER -D $APP_USER \ + && mkdir -p ${APP} ${DATA} ${DB} + +COPY --from=builder /SRC/target/release/openwec ${APP}/openwec +COPY --from=builder /SRC/target/release/openwecd ${APP}/openwecd +COPY ./docker/entrypoint.sh ${APP}/entrypoint.sh + +RUN chown -R $APP_USER:$APP_USER ${APP} ${DATA} ${DB} + +USER $APP_USER +WORKDIR ${APP} + +CMD ["./entrypoint.sh"] diff --git a/Dockerfile b/docker/openwec.Dockerfile similarity index 98% rename from Dockerfile rename to docker/openwec.Dockerfile index 2715629..cbf0b47 100644 --- a/Dockerfile +++ b/docker/openwec.Dockerfile @@ -30,7 +30,7 @@ ARG APP=/usr/src/openwec ARG DATA=/var/lib/openwec/data ARG DB=/var/lib/openwec/db -EXPOSE 5985 +EXPOSE 5985 5986 ENV APP_USER=openwec ENV DEBIAN_FRONTEND=noninteractive