From 7355ffa75c882a0572d077e2981e8961bf3a9abc Mon Sep 17 00:00:00 2001 From: Bo Jeanes Date: Sun, 11 Sep 2022 18:43:55 +1000 Subject: [PATCH 1/9] Build docker images --- .github/workflows/ci.yml | 91 +++++++++++++++++++++++++++++++++++++++- Dockerfile | 16 +++++-- Dockerfile.alpine | 34 +++++++++++++++ 3 files changed, 135 insertions(+), 6 deletions(-) create mode 100644 Dockerfile.alpine diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ad3b883..1c3f88d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -242,7 +242,9 @@ jobs: prerelease: name: Create a pre-release if: github.ref == 'refs/heads/main' - needs: build + needs: + - build + - docker runs-on: ubuntu-latest steps: - name: Checkout code @@ -310,4 +312,89 @@ jobs: name: "Unstable (built from master)" body: ${{ steps.changelog_reader.outputs.changes }} files: ${{ steps.artifacts.outputs.files }} - gzip: false \ No newline at end of file + gzip: false + + docker: + needs: + - tests + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Set up QEMU + uses: docker/setup-qemu-action@v2 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2 + + - name: Docker meta + id: meta + uses: docker/metadata-action@v4 + with: + images: | + ${{ github.repository }} + ghcr.io/${{ github.repository }} + tags: | + type=sha,format=short + type=edge,branch=main + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} + type=semver,pattern={{major}},enable=${{ !contains(github.ref, 'v0.') }} + type=ref,enable=true,priority=600,prefix=br-,suffix=,event=branch + type=ref,enable=true,priority=600,prefix=,suffix=,event=tag + type=ref,enable=true,priority=600,prefix=pr-,suffix=,event=pr + - name: Docker meta + id: meta-alpine + uses: docker/metadata-action@v4 + with: + flavour: + suffix=-alpine + images: | + ${{ github.repository }} + ghcr.io/${{ github.repository }} + tags: | + type=sha,format=short + type=edge,branch=main + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} + type=semver,pattern={{major}},enable=${{ !contains(github.ref, 'v0.') }} + type=ref,enable=true,priority=600,prefix=br-,suffix=,event=branch + type=ref,enable=true,priority=600,prefix=,suffix=,event=tag + type=ref,enable=true,priority=600,prefix=pr-,suffix=,event=pr + + - name: Login to GitHub Container Registry + uses: docker/login-action@v2 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Login to DockerHub + uses: docker/login-action@v2 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Build and push (alpine) + uses: docker/build-push-action@v3 + with: + context: . + platforms: | + linux/arm64 + linux/amd64 + push: true + file: Dockerfile.alpine + tags: ${{ steps.meta-alpine.outputs.tags }} + labels: ${{ steps.meta-alpine.outputs.labels }} + - name: Build and push + uses: docker/build-push-action@v3 + with: + context: . + platforms: | + linux/arm/v7 + linux/arm64 + linux/amd64 + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index b14a550..7e7e864 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,8 +1,11 @@ # -*- mode: dockerfile -*- -FROM rust:1.63-alpine AS builder +FROM rust:1.63 AS builder -RUN apk add --no-cache musl-dev +RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ + --mount=type=cache,target=/var/lib/apt,sharing=locked \ + apt update && apt-get --no-install-recommends install -y \ + libudev-dev # Build a cacheable layer with project dependencies RUN USER=rust cargo new /home/rust/sungrow-winets @@ -22,8 +25,13 @@ ADD --chown=rust:rust . ./ RUN cargo build --release # Now, we need to build our _real_ Docker container, copying in `bump-api`. -FROM alpine:latest -RUN apk --no-cache add ca-certificates +FROM debian:bullseye-slim + +RUN rm -f /etc/apt/apt.conf.d/docker-clean; echo 'Binary::apt::APT::Keep-Downloaded-Packages "true";' > /etc/apt/apt.conf.d/keep-cache +RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ + --mount=type=cache,target=/var/lib/apt,sharing=locked \ + apt update && apt-get --no-install-recommends install -y \ + libudev1 COPY --from=builder \ /home/rust/modbus-mqtt/target/release/modbus-mqtt \ diff --git a/Dockerfile.alpine b/Dockerfile.alpine new file mode 100644 index 0000000..b14a550 --- /dev/null +++ b/Dockerfile.alpine @@ -0,0 +1,34 @@ +# -*- mode: dockerfile -*- + +FROM rust:1.63-alpine AS builder + +RUN apk add --no-cache musl-dev + +# Build a cacheable layer with project dependencies +RUN USER=rust cargo new /home/rust/sungrow-winets +RUN USER=rust cargo new /home/rust/tokio_modbus-winets +RUN USER=rust cargo new /home/rust/modbus-mqtt +WORKDIR /home/rust/modbus-mqtt +ADD --chown=rust:rust Cargo.lock modbus-mqtt/Cargo.toml ./ +RUN cargo build --release + +# # Delete files & directories which shouldn't exist for the workspace +# RUN rm -rf src + +# Add our source code. +ADD --chown=rust:rust . ./ + +# Build our application. +RUN cargo build --release + +# Now, we need to build our _real_ Docker container, copying in `bump-api`. +FROM alpine:latest +RUN apk --no-cache add ca-certificates + +COPY --from=builder \ + /home/rust/modbus-mqtt/target/release/modbus-mqtt \ + /usr/local/bin/ + +ENV RUST_LOG=warn,modbus_mqtt=info + +ENTRYPOINT ["/usr/local/bin/modbus-mqtt"] From c4fb085931704c1c7f525efdef97a76e53b24248 Mon Sep 17 00:00:00 2001 From: Bo Jeanes Date: Mon, 12 Sep 2022 08:26:55 +1000 Subject: [PATCH 2/9] Improve build caching --- .dockerignore | 4 ++- .github/workflows/ci.yml | 75 +++++++++++++++++----------------------- 2 files changed, 34 insertions(+), 45 deletions(-) diff --git a/.dockerignore b/.dockerignore index 3d3202d..29c586b 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,2 +1,4 @@ +.git Dockerfile -**/README.md \ No newline at end of file +README.md +/target/ \ No newline at end of file diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1c3f88d..d217dbf 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -28,28 +28,17 @@ jobs: export DEBIAN_FRONTEND=noninteractive sudo apt-get clean && sudo apt-get update sudo apt-get install -y pkg-config libudev-dev - - name: Cache cargo registry - uses: actions/cache@v1 + - name: Cargo cache + uses: actions/cache@v2 with: - path: ~/.cargo/registry - key: ${{ runner.os }}-cargo-registry-toolchain.outputs.rustc_hash }}-${{ hashFiles('**/Cargo.lock') }} + path: | + ~/.cargo/git + ~/.cargo/registry + ./target + key: ${{ runner.os }}-cargo-${{ steps.rust-toolchain.outputs.rustc_hash }}-${{ hashFiles('**/Cargo.lock') }} restore-keys: | - ${{ runner.os }}-cargo-registry- - - name: Cache cargo index - uses: actions/cache@v1 - with: - path: ~/.cargo/git - key: ${{ runner.os }}-cargo-index-toolchain.outputs.rustc_hash }}-${{ hashFiles('**/Cargo.lock') }} - restore-keys: | - ${{ runner.os }}-cargo-index- - - name: Cache cargo build - uses: actions/cache@v1 - with: - path: target - key: ${{ runner.os }}-cargo-build-target-${{ steps.rust-toolchain.outputs.rustc_hash }}-${{ hashFiles('**/Cargo.lock') }} - restore-keys: | - ${{ runner.os }}-cargo-build-target-${{ steps.rust-toolchain.outputs.rustc_hash }}- - ${{ runner.os }}-cargo-build-target- + ${{ runner.os }}-cargo-${{ steps.rust-toolchain.outputs.rustc_hash }}- + ${{ runner.os }}-cargo - name: Run tests uses: actions-rs/cargo@v1 with: @@ -73,30 +62,17 @@ jobs: export DEBIAN_FRONTEND=noninteractive sudo apt-get clean && sudo apt-get update sudo apt-get install -y pkg-config libudev-dev - - name: Cache cargo registry - uses: actions/cache@v1 + - name: Cargo cache + uses: actions/cache@v2 with: - path: ~/.cargo/registry - key: ${{ runner.os }}-cargo-registry-${{ steps.rust-toolchain.outputs.rustc_hash }}-${{ hashFiles('**/Cargo.lock') }} + path: | + ~/.cargo/git + ~/.cargo/registry + ./target + key: ${{ runner.os }}-cargo-${{ steps.rust-toolchain.outputs.rustc_hash }}-${{ hashFiles('**/Cargo.lock') }} restore-keys: | - ${{ runner.os }}-cargo-registry-${{ steps.rust-toolchain.outputs.rustc_hash }}- - ${{ runner.os }}-cargo-registry- - - name: Cache cargo index - uses: actions/cache@v1 - with: - path: ~/.cargo/git - key: ${{ runner.os }}-cargo-index-${{ steps.rust-toolchain.outputs.rustc_hash }}-${{ hashFiles('**/Cargo.lock') }} - restore-keys: | - ${{ runner.os }}-cargo-index-${{ steps.rust-toolchain.outputs.rustc_hash }}- - ${{ runner.os }}-cargo-index- - - name: Cache cargo build - uses: actions/cache@v1 - with: - path: target - key: ${{ runner.os }}-cargo-build-target-${{ steps.rust-toolchain.outputs.rustc_hash }}-${{ hashFiles('**/Cargo.lock') }} - restore-keys: | - ${{ runner.os }}-cargo-build-target-${{ steps.rust-toolchain.outputs.rustc_hash }}- - ${{ runner.os }}-cargo-build-target- + ${{ runner.os }}-cargo-${{ steps.rust-toolchain.outputs.rustc_hash }}- + ${{ runner.os }}-cargo - name: Check rustfmt uses: actions-rs/cargo@v1 with: @@ -150,9 +126,16 @@ jobs: uses: actions/cache@v2 with: path: | + ~/.cargo/git ~/.cargo/registry ./target - key: build-cargo-registry-${{matrix.TARGET}} + key: ${{ runner.os }}-cargo-${{matrix.TARGET}}-${{ steps.rust-toolchain.outputs.rustc_hash }}-${{ hashFiles('**/Cargo.lock') }} + restore-keys: | + ${{ runner.os }}-cargo-${{matrix.TARGET}}-${{ steps.rust-toolchain.outputs.rustc_hash }} + ${{ runner.os }}-cargo-${{matrix.TARGET}}- + ${{ runner.os }}-cargo-${{ steps.rust-toolchain.outputs.rustc_hash }}-${{ hashFiles('**/Cargo.lock') }} + ${{ runner.os }}-cargo-${{ steps.rust-toolchain.outputs.rustc_hash }}- + ${{ runner.os }}-cargo - name: Setup cross linux toolchain if: contains(matrix.TARGET, '-linux-') && !startsWith(matrix.TARGET, 'x86_64-') run: | @@ -387,6 +370,8 @@ jobs: file: Dockerfile.alpine tags: ${{ steps.meta-alpine.outputs.tags }} labels: ${{ steps.meta-alpine.outputs.labels }} + cache-from: type=gha + cache-to: type=gha,mode=max - name: Build and push uses: docker/build-push-action@v3 with: @@ -397,4 +382,6 @@ jobs: linux/amd64 push: true tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} \ No newline at end of file + labels: ${{ steps.meta.outputs.labels }} + cache-from: type=gha + cache-to: type=gha,mode=max \ No newline at end of file From 0ce38aea9739510b7b30488bd2a1495c358fc9db Mon Sep 17 00:00:00 2001 From: Bo Jeanes Date: Mon, 12 Sep 2022 09:42:14 +1000 Subject: [PATCH 3/9] Try to workaround docker/buildx#395 --- Dockerfile | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/Dockerfile b/Dockerfile index 7e7e864..3deb1f5 100644 --- a/Dockerfile +++ b/Dockerfile @@ -13,7 +13,10 @@ RUN USER=rust cargo new /home/rust/tokio_modbus-winets RUN USER=rust cargo new /home/rust/modbus-mqtt WORKDIR /home/rust/modbus-mqtt ADD --chown=rust:rust Cargo.lock modbus-mqtt/Cargo.toml ./ -RUN cargo build --release +RUN mkdir -p /home/rust/modbus-mqtt/target/release +RUN --mount=type=cache,target=/home/rust/modbus-mqtt/target,sharing=locked \ + --mount-type=cache,target=/usr/local/cargo/registry,sharing=locked \ + cargo build --release # # Delete files & directories which shouldn't exist for the workspace # RUN rm -rf src @@ -22,7 +25,9 @@ RUN cargo build --release ADD --chown=rust:rust . ./ # Build our application. -RUN cargo build --release +RUN --mount=type=cache,target=/home/rust/modbus-mqtt/target,sharing=locked \ + --mount-type=cache,target=/usr/local/cargo/registry,sharing=locked \ + cargo build --release --offline && mv target/release/modbus-mqtt ./bin # Now, we need to build our _real_ Docker container, copying in `bump-api`. FROM debian:bullseye-slim @@ -34,8 +39,8 @@ RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ libudev1 COPY --from=builder \ - /home/rust/modbus-mqtt/target/release/modbus-mqtt \ - /usr/local/bin/ + /home/rust/modbus-mqtt/bin \ + /usr/local/bin/modbus-mqtt ENV RUST_LOG=warn,modbus_mqtt=info From e7d993abd47c6d18780b6782911bcc4ba08af445 Mon Sep 17 00:00:00 2001 From: Bo Jeanes Date: Mon, 12 Sep 2022 10:08:36 +1000 Subject: [PATCH 4/9] Fix typo in Dockerfile --- Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 3deb1f5..9376a3f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -15,7 +15,7 @@ WORKDIR /home/rust/modbus-mqtt ADD --chown=rust:rust Cargo.lock modbus-mqtt/Cargo.toml ./ RUN mkdir -p /home/rust/modbus-mqtt/target/release RUN --mount=type=cache,target=/home/rust/modbus-mqtt/target,sharing=locked \ - --mount-type=cache,target=/usr/local/cargo/registry,sharing=locked \ + --mount=type=cache,target=/usr/local/cargo/registry,sharing=locked \ cargo build --release # # Delete files & directories which shouldn't exist for the workspace @@ -26,7 +26,7 @@ ADD --chown=rust:rust . ./ # Build our application. RUN --mount=type=cache,target=/home/rust/modbus-mqtt/target,sharing=locked \ - --mount-type=cache,target=/usr/local/cargo/registry,sharing=locked \ + --mount=type=cache,target=/usr/local/cargo/registry,sharing=locked \ cargo build --release --offline && mv target/release/modbus-mqtt ./bin # Now, we need to build our _real_ Docker container, copying in `bump-api`. From 3c13f4da1707f72c83749fef65cbcacc376ec9d8 Mon Sep 17 00:00:00 2001 From: Bo Jeanes Date: Mon, 12 Sep 2022 10:39:53 +1000 Subject: [PATCH 5/9] Fails with --ofline --- .github/workflows/ci.yml | 2 ++ Dockerfile | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d217dbf..c16b874 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -180,6 +180,8 @@ jobs: if: contains(matrix.TARGET, '-linux-') run: | # some additional configuration for cross-compilation on linux + # TODO: can this be done with `RUSTFLAGS += -C linker=$(DEB_HOST_GNU_TYPE)-gcc`? + cat >>~/.cargo/config < Date: Sun, 18 Sep 2022 08:32:47 +1000 Subject: [PATCH 6/9] Try again to workaround docker/buildx#395 --- .github/workflows/ci.yml | 46 +++++++++++++++++++++++++++++----------- 1 file changed, 34 insertions(+), 12 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c16b874..7ea9f9e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -361,19 +361,41 @@ jobs: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - - name: Build and push (alpine) - uses: docker/build-push-action@v3 + # Work around https://github.com/docker/buildx/issues/395 + # - name: create small fs for docker cache + # run: | + # df -h + # sudo swapon --show + # sudo dd if=/dev/zero of=/swapfile1 bs=1M count=6K + # sudo chmod 600 /swapfile1 + # sudo mkswap /swapfile1 + # sudo swapon /swapfile1 + # sudo swapon --show + # sudo free -h + # sudo systemctl stop docker + # sudo mount -t tmpfs -o size=9G tmpfs /var/lib/docker + # df -h + # sudo systemctl start docker + - name: Run Docker on tmpfs + uses: JonasAlfredsson/docker-on-tmpfs@v1 with: - context: . - platforms: | - linux/arm64 - linux/amd64 - push: true - file: Dockerfile.alpine - tags: ${{ steps.meta-alpine.outputs.tags }} - labels: ${{ steps.meta-alpine.outputs.labels }} - cache-from: type=gha - cache-to: type=gha,mode=max + tmpfs_size: 5 + swap_size: 4 + + # - name: Build and push (alpine) + # uses: docker/build-push-action@v3 + # with: + # context: . + # platforms: | + # linux/arm64 + # linux/amd64 + # push: true + # file: Dockerfile.alpine + # tags: ${{ steps.meta-alpine.outputs.tags }} + # labels: ${{ steps.meta-alpine.outputs.labels }} + # cache-from: type=gha + # cache-to: type=gha,mode=max + - name: Build and push uses: docker/build-push-action@v3 with: From 97071eb5e89be10a7dd13e11e566f433ba3fc8be Mon Sep 17 00:00:00 2001 From: Bo Jeanes Date: Sun, 18 Sep 2022 09:06:06 +1000 Subject: [PATCH 7/9] Fix typo --- .github/workflows/ci.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7ea9f9e..3377679 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -329,11 +329,12 @@ jobs: type=ref,enable=true,priority=600,prefix=br-,suffix=,event=branch type=ref,enable=true,priority=600,prefix=,suffix=,event=tag type=ref,enable=true,priority=600,prefix=pr-,suffix=,event=pr + - name: Docker meta id: meta-alpine uses: docker/metadata-action@v4 with: - flavour: + flavor: suffix=-alpine images: | ${{ github.repository }} From 72eb2b728154eba172febf700fed8457668e100a Mon Sep 17 00:00:00 2001 From: Bo Jeanes Date: Sun, 18 Sep 2022 09:30:06 +1000 Subject: [PATCH 8/9] Give up on ARMv7 builds for now --- .github/workflows/ci.yml | 55 +++++++++++++++------------------------- 1 file changed, 21 insertions(+), 34 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3377679..163b161 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -362,47 +362,34 @@ jobs: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - # Work around https://github.com/docker/buildx/issues/395 - # - name: create small fs for docker cache - # run: | - # df -h - # sudo swapon --show - # sudo dd if=/dev/zero of=/swapfile1 bs=1M count=6K - # sudo chmod 600 /swapfile1 - # sudo mkswap /swapfile1 - # sudo swapon /swapfile1 - # sudo swapon --show - # sudo free -h - # sudo systemctl stop docker - # sudo mount -t tmpfs -o size=9G tmpfs /var/lib/docker - # df -h - # sudo systemctl start docker - - name: Run Docker on tmpfs - uses: JonasAlfredsson/docker-on-tmpfs@v1 - with: - tmpfs_size: 5 - swap_size: 4 - - # - name: Build and push (alpine) - # uses: docker/build-push-action@v3 + # Work around https://github.com/docker/buildx/issues/395 (this causes "no space left on device") + # - name: Run Docker on tmpfs + # uses: JonasAlfredsson/docker-on-tmpfs@v1 # with: - # context: . - # platforms: | - # linux/arm64 - # linux/amd64 - # push: true - # file: Dockerfile.alpine - # tags: ${{ steps.meta-alpine.outputs.tags }} - # labels: ${{ steps.meta-alpine.outputs.labels }} - # cache-from: type=gha - # cache-to: type=gha,mode=max + # tmpfs_size: 5 + # swap_size: 4 + + - name: Build and push (alpine) + uses: docker/build-push-action@v3 + with: + context: . + platforms: | + linux/arm64 + linux/amd64 + push: true + file: Dockerfile.alpine + tags: ${{ steps.meta-alpine.outputs.tags }} + labels: ${{ steps.meta-alpine.outputs.labels }} + cache-from: type=gha + cache-to: type=gha,mode=max - name: Build and push uses: docker/build-push-action@v3 with: context: . + # Disabled due to https://github.com/docker/buildx/issues/395 + # linux/arm/v7 platforms: | - linux/arm/v7 linux/arm64 linux/amd64 push: true From dbbb9b7d4276da2516a913faf77f9da40eb3fec3 Mon Sep 17 00:00:00 2001 From: Bo Jeanes Date: Sun, 18 Sep 2022 13:58:36 +1000 Subject: [PATCH 9/9] Don't build docker images for branches unless PR --- .github/workflows/ci.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 163b161..4e51772 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -3,6 +3,8 @@ name: CI on: push: + tags-ignore: + - unstable pull_request: env: @@ -300,6 +302,7 @@ jobs: gzip: false docker: + if: github.ref == 'refs/heads/main' || github.event_name == 'pull_request' needs: - tests runs-on: ubuntu-latest