Improved Docker image + publish on ghcr.io (#642)
Fix #610 - [x] Native cross-compilation support in Dockerfile. Only `linux/amd64` and `linux/arm64` supported and tested (Tier 1 platform support from Rust) - [x] Cache support for cargo downloads and compilation results in Dockerfile - [x] Open Container's [annotations](https://github.com/opencontainers/image-spec/blob/main/annotations.md) in Dockerfile - [x] GitHub Actions workflow to build the image for both platforms, publishing to ghcr.io on tags and master branch pushes. - [x] Disable use of GitHub Actions cache for tags build, allow manually triggering the workflow with or without cache. - [x] [Attestation artifacts](https://docs.github.com/en/actions/security-for-github-actions/using-artifact-attestations/using-artifact-attestations-to-establish-provenance-for-builds) for builds - [x] Add basic informations about the use of the Docker image in README I also changed the WORKDIR from `/src` to `/work`, because if got me confused with the use of the src folder for the project source in the first stage of the Dockerfile. It doesn't impact anything anyways since you can mount the file where you want and have the program options point to it. **How to test?** _After checking out the branch and making sure you have QEMU installed to build/test_ ```shell # Docker sadly doesn't have yet the way to have locally a tag with multiple platforms # despite being able to pass multiple platforms to the build command, so we have to use two distinct tags. docker build --platform=linux/amd64 --tag test-oxipng-amd:latest --load . docker build --platform=linux/arm64 --tag test-oxipng-arm:latest --load . docker run --rm test-oxipng-amd:latest --version docker run --rm test-oxipng-arm:latest --version # Run on some files docker run --rm -it -v $(pwd):/work test-oxipng-amd:latest -a /work/tests/files/apng_file.png docker run --rm -it -v $(pwd):/work test-oxipng-arm:latest -a /work/tests/files/apng_file.png # Remove the images docker image rm test-oxipng-amd:latest docker image rm test-oxipng-arm:latest ``` For the workflow, see the GitHub Actions logs. If you want to test the ghcr.io publishing you can merge the branch into a fork and see the result. --------- Co-authored-by: Alejandro González <me@alegon.dev>
This commit is contained in:
parent
c81a863e69
commit
ef64dd0768
4 changed files with 141 additions and 10 deletions
4
.dockerignore
Normal file
4
.dockerignore
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
scripts
|
||||
.github
|
||||
.editorconfig
|
||||
.pre-commit-hooks.yaml
|
||||
92
.github/workflows/docker.yml
vendored
Normal file
92
.github/workflows/docker.yml
vendored
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
name: docker
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'master'
|
||||
tags:
|
||||
- 'v*.*.*'
|
||||
pull_request:
|
||||
types:
|
||||
- opened
|
||||
- synchronize
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
use_cache:
|
||||
description: "Use build cache"
|
||||
required: true
|
||||
type: boolean
|
||||
default: true
|
||||
|
||||
env:
|
||||
REGISTRY: ghcr.io
|
||||
# ghcr.io/OWNER/REPO
|
||||
IMAGE_NAME: ${{ github.repository }}
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
id-token: write
|
||||
attestations: write
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
|
||||
# Workaround: https://github.com/docker/build-push-action/issues/461
|
||||
- name: Setup Docker buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
# Login against a Docker registry except on PR
|
||||
# https://github.com/docker/login-action
|
||||
- name: Log into registry ${{ env.REGISTRY }}
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ${{ env.REGISTRY }}
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
# Extract metadata (tags, labels) for Docker
|
||||
# For some reason the title have to be set manually
|
||||
# https://github.com/docker/metadata-action
|
||||
- name: Extract Docker metadata
|
||||
id: meta
|
||||
uses: docker/metadata-action@v5
|
||||
with:
|
||||
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
||||
labels: |
|
||||
org.opencontainers.image.title=Oxipng
|
||||
annotations: |
|
||||
org.opencontainers.image.title=Oxipng
|
||||
|
||||
# Build and push Docker image with Buildx (don't push on PR)
|
||||
# Cache isn't used for tags and on workflow_dispatch if specified
|
||||
# https://github.com/docker/build-push-action
|
||||
- name: Build and push Docker image
|
||||
id: build-and-push
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
platforms: linux/amd64,linux/arm64
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
no-cache: ${{ (github.event_name == 'workflow_dispatch' && !inputs.use_cache) || startsWith(github.ref, 'refs/tags/') }}
|
||||
|
||||
# Attest the build provenance
|
||||
# TODO: enable push to registry when referrers API will be supported by ghcr.io
|
||||
- name: Attest Build Provenance
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: actions/attest-build-provenance@v1
|
||||
with:
|
||||
subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
||||
subject-digest: ${{ steps.build-and-push.outputs.digest }}
|
||||
push-to-registry: false
|
||||
45
Dockerfile
45
Dockerfile
|
|
@ -1,20 +1,45 @@
|
|||
FROM rust:alpine as base
|
||||
# syntax=docker/dockerfile:1
|
||||
FROM --platform=$BUILDPLATFORM tonistiigi/xx AS xx
|
||||
|
||||
COPY . /src
|
||||
FROM --platform=$BUILDPLATFORM rust:1.74-alpine AS base
|
||||
|
||||
RUN rustup update 1.74 && rustup default 1.74
|
||||
|
||||
RUN apk update \
|
||||
&& apk add \
|
||||
RUN apk update && \
|
||||
apk add \
|
||||
gcc \
|
||||
g++
|
||||
g++ \
|
||||
clang
|
||||
|
||||
RUN cd /src && cargo build --release
|
||||
COPY --from=xx / /
|
||||
|
||||
FROM alpine as tool
|
||||
ARG TARGETPLATFORM
|
||||
RUN xx-info env
|
||||
|
||||
COPY --from=base /src/target/release/oxipng /usr/local/bin
|
||||
RUN xx-apk add \
|
||||
gcc \
|
||||
musl-dev \
|
||||
libdeflate
|
||||
|
||||
WORKDIR /src
|
||||
|
||||
COPY . .
|
||||
|
||||
RUN --mount=type=cache,target=/root/.cargo/git/db \
|
||||
--mount=type=cache,target=/root/.cargo/registry/cache \
|
||||
--mount=type=cache,target=/root/.cargo/registry/index \
|
||||
xx-cargo build --release && \
|
||||
xx-verify /src/target/$(xx-cargo --print-target-triple)/release/oxipng && \
|
||||
cp /src/target/$(xx-cargo --print-target-triple)/release/oxipng /src/target/oxipng
|
||||
|
||||
FROM alpine AS tool
|
||||
|
||||
LABEL org.opencontainers.image.title="Oxipng"
|
||||
LABEL org.opencontainers.image.description="Multithreaded PNG optimizer written in Rust"
|
||||
LABEL org.opencontainers.image.authors="Joshua Holmer <jholmer.in@gmail.com>"
|
||||
LABEL org.opencontainers.image.licenses="MIT"
|
||||
LABEL org.opencontainers.image.source="https://github.com/shssoichiro/oxipng"
|
||||
|
||||
COPY --from=base /src/target/oxipng /usr/local/bin
|
||||
|
||||
WORKDIR /work
|
||||
ENTRYPOINT [ "oxipng" ]
|
||||
CMD [ "--help" ]
|
||||
|
|
|
|||
10
README.md
10
README.md
|
|
@ -133,6 +133,16 @@ trunk actions enable trunk-fmt-pre-commit
|
|||
|
||||
[trunk]: https://docs.trunk.io
|
||||
|
||||
## Docker
|
||||
|
||||
A Docker image is availlable at `ghcr.io/shssoichiro/oxipng` for `linux/amd64` and `linux/arm64`.
|
||||
|
||||
You can use it the following way:
|
||||
|
||||
```bash
|
||||
docker run --rm -v $(pwd):/work ghcr.io/shssoichiro/oxipng -o 4 /work/file.png
|
||||
```
|
||||
|
||||
## Library Usage
|
||||
|
||||
Although originally intended to be used as an executable, oxipng can also be used as a library in
|
||||
|
|
|
|||
Loading…
Reference in a new issue