From 5b7e2a6d565ced0d6c8804c1375df760f135fdfd Mon Sep 17 00:00:00 2001 From: Guy Tene Date: Tue, 5 May 2026 18:29:24 +0300 Subject: [PATCH] v0.10.1: drop Windows from release matrix; simplify Dockerfile Two release-pipeline fixes shaken out by the first `v0.10.0` tag: - The Windows job failed because the library doesn't compile on `x86_64-pc-windows-msvc`: `src/server/admin.rs` uses `tokio::net::UnixListener` and POSIX `Permissions::set_mode` unconditionally. Drop the target from the matrix until the admin API is `#[cfg(unix)]`-gated. README updated to match. - The Docker job failed with "failed to compute cache key: /usr/local/bin/rusnel: not found". The previous Dockerfile used BuildKit cache mounts on `target/` plus a cross-compile path for arm64; the cache mount got unmounted before the multi-stage `COPY --from=builder` could resolve the binary. Replace with a plain `cargo build --release` under buildx + QEMU emulation, using `gcr.io/distroless/cc-debian12:nonroot` as the runtime base. Slower arm64 build (a few minutes under QEMU) in exchange for a Dockerfile that actually works. Co-authored-by: Cursor --- .github/workflows/release.yml | 7 +++-- CHANGELOG.md | 19 +++++++++++++ Cargo.lock | 2 +- Cargo.toml | 2 +- Dockerfile | 50 +++++++++++++---------------------- README.md | 5 ++-- 6 files changed, 47 insertions(+), 38 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 3992dc7..95f195b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -60,8 +60,11 @@ jobs: os: macos-latest - target: aarch64-apple-darwin os: macos-latest - - target: x86_64-pc-windows-msvc - os: windows-latest + # Windows is not yet supported: src/server/admin.rs uses + # tokio::net::UnixListener + POSIX `Permissions::set_mode` + # unconditionally. Add `x86_64-pc-windows-msvc` back here + # once the admin API is `#[cfg(unix)]`-gated (or backed by a + # named pipe on Windows). steps: - uses: actions/checkout@v4 with: diff --git a/CHANGELOG.md b/CHANGELOG.md index 37f8266..5973c01 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,25 @@ All notable changes to this project are documented in this file. The format is loosely based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.10.1] - 2026-05-05 + +Release-pipeline fixes shaken out by the first `v0.10.0` tag. + +### Fixed + +- **Drop Windows from the release matrix.** The library does not + compile on `x86_64-pc-windows-msvc` because `src/server/admin.rs` + uses `tokio::net::UnixListener` and POSIX `Permissions::set_mode` + unconditionally. Windows can be added back here once the admin API + is `#[cfg(unix)]`-gated (or stubbed with a Windows named pipe). +- **Simplify the Dockerfile** so the multi-arch GHCR image actually + builds. The previous version used BuildKit cache mounts on + `target/` plus a cross-compile path for arm64; the cache mount got + unmounted before the multi-stage `COPY --from=builder` could + resolve the binary, breaking the build. Replaced with a plain + `cargo build --release` under buildx + QEMU emulation, using + `gcr.io/distroless/cc-debian12:nonroot` as the runtime base. + ## [0.10.0] - 2026-05-05 Configuration files. Server and client invocations no longer have to diff --git a/Cargo.lock b/Cargo.lock index ff4a4f4..2b3c3e3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1264,7 +1264,7 @@ dependencies = [ [[package]] name = "rusnel" -version = "0.10.0" +version = "0.10.1" dependencies = [ "anyhow", "axum", diff --git a/Cargo.toml b/Cargo.toml index c897774..de6c954 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rusnel" description = "Rusnel is a fast TCP/UDP tunnel, transported over and encrypted using QUIC protocol. Single executable including both client and server" -version = "0.10.0" +version = "0.10.1" edition = "2021" license = "Apache-2.0" repository = "https://github.com/guyte149/Rusnel" diff --git a/Dockerfile b/Dockerfile index 2a0edc4..3184382 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,51 +1,37 @@ # syntax=docker/dockerfile:1.7 # -# Multi-stage build that produces a static rusnel binary on top of a -# distroless base. The result is a ~10 MB image that runs as non-root -# and contains only the binary plus CA certificates. +# Multi-stage build that produces a small rusnel image (~30 MB) on +# top of a distroless base. Multi-arch (linux/amd64, linux/arm64) is +# handled by buildx via QEMU emulation rather than by cross-compiling +# from the build host — keeps the Dockerfile dead-simple and means +# every supported arch goes through the same build path. The cost is +# slower arm64 builds (a few minutes under QEMU); the benefit is no +# cache-mount fragility and no cross-toolchain plumbing. # # Build for the host arch: # docker build -t rusnel . # -# Build multi-arch (amd64 + arm64) — driven by the release workflow: +# Build multi-arch (driven by .github/workflows/release.yml): # docker buildx build --platform linux/amd64,linux/arm64 -t rusnel . ARG RUST_VERSION=1.83 ARG DEBIAN_VERSION=bookworm -FROM --platform=$BUILDPLATFORM rust:${RUST_VERSION}-${DEBIAN_VERSION} AS builder +FROM rust:${RUST_VERSION}-${DEBIAN_VERSION} AS builder -ARG TARGETARCH WORKDIR /src - -RUN apt-get update \ - && apt-get install -y --no-install-recommends musl-tools pkg-config \ - && rm -rf /var/lib/apt/lists/* \ - && case "$TARGETARCH" in \ - amd64) echo "x86_64-unknown-linux-musl" > /tmp/target ;; \ - arm64) echo "aarch64-unknown-linux-musl" > /tmp/target ;; \ - *) echo "unsupported TARGETARCH=$TARGETARCH" >&2 ; exit 1 ;; \ - esac \ - && rustup target add "$(cat /tmp/target)" \ - && if [ "$TARGETARCH" = "arm64" ] && [ "$(uname -m)" != "aarch64" ]; then \ - apt-get update && apt-get install -y --no-install-recommends \ - gcc-aarch64-linux-gnu \ - && rm -rf /var/lib/apt/lists/*; \ - fi - ENV CARGO_TERM_COLOR=always -ENV CC_aarch64_unknown_linux_musl=aarch64-linux-gnu-gcc -ENV CARGO_TARGET_AARCH64_UNKNOWN_LINUX_MUSL_LINKER=aarch64-linux-gnu-gcc COPY . . -RUN --mount=type=cache,target=/usr/local/cargo/registry \ - --mount=type=cache,target=/src/target \ - TARGET="$(cat /tmp/target)" && \ - cargo build --release --target "$TARGET" && \ - cp "target/$TARGET/release/rusnel" /usr/local/bin/rusnel && \ - strip /usr/local/bin/rusnel || true - -FROM gcr.io/distroless/static-debian12:nonroot +RUN cargo build --release \ + && cp target/release/rusnel /usr/local/bin/rusnel \ + && strip /usr/local/bin/rusnel || true + +# `distroless/cc` rather than `static` because we link against glibc +# (the default rust toolchain target on bookworm). The `:nonroot` +# variant ships a pre-created `nonroot` UID/GID so the final image +# runs unprivileged out of the box. +FROM gcr.io/distroless/cc-debian12:nonroot LABEL org.opencontainers.image.title="rusnel" \ org.opencontainers.image.description="A fast TCP/UDP tunnel over QUIC, written in Rust." \ diff --git a/README.md b/README.md index 420a79b..c4c845a 100644 --- a/README.md +++ b/README.md @@ -46,9 +46,10 @@ cd Rusnel cargo build --release ``` -Pre-built binaries for Linux (x86_64 + aarch64, gnu and musl), macOS -(x86_64 + Apple Silicon), and Windows (x86_64) are attached to each +Pre-built binaries for Linux (x86_64 + aarch64, gnu and musl) and +macOS (x86_64 + Apple Silicon) are attached to each [GitHub release](https://github.com/guyte149/Rusnel/releases). +Windows is not yet supported (the admin API is Unix-socket-only). ### Docker