diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index 9dc6946..1767226 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,16 @@ 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 with: images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + 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,7 +63,7 @@ jobs: uses: docker/build-push-action@f2a1d5e99d037542a71f64918e516c093c6f3fc4 with: context: . - file: docker/openwec.Dockerfile + 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 085ac86..8fdfaeb 100644 --- a/doc/docker.md +++ b/doc/docker.md @@ -10,9 +10,12 @@ 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:latest +$ docker pull ghcr.io/cea-sec/openwec:latest-alpine ``` ### Building the image by yourself @@ -23,6 +26,12 @@ $ docker pull ghcr.io/cea-sec/openwec:latest $ docker build -t openwec -f docker/openwec.Dockerfile . ``` +To build the Alpine image: + +```bash +$ docker build -t openwec -f docker/openwec-alpine.Dockerfile . +``` + ## Using `openwec` image The `openwec` image does not come with any predefined configuration. 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"]