Commit Graph

25 Commits

Author SHA1 Message Date
jason 6db1facb3b 🔧 Replace curl GitHub downloads with cargo install in rust-tools stage 🔧
The build host's SSL intercept breaks system curl to *.github.com (cert SAN
mismatch). Cargo uses its own bundled TLS stack and is not affected.
- Dockerfile: remove sccache curl download (was failing with SSL error)
- Dockerfile: remove cargo-binstall curl bootstrap (same SSL failure path)
- Dockerfile: replace both with `cargo install cargo-binstall` (Rust TLS, no curl)
- Dockerfile: remove curlrc IPv4 workaround (no curl calls remain in rust-tools)
- Dockerfile: remove jq from apk (was only used for sccache version parsing)
- Dockerfile: remove RUSTC_WRAPPER/SCCACHE_DIR exports from binstall RUN block
- Dockerfile: remove sccache-native cache mount (unused without RUSTC_WRAPPER)

Dockerfile
2026-06-21 19:24:30 -04:00
jason 1d03c20129 🐛 Force IPv4 in rust-tools stage to fix GitHub SSL errors 🐛
IPv6 routing on this host intercepts *.github.com and presents a
certificate for a local domain, causing curl SSL SAN mismatch errors
when downloading sccache and cargo-binstall from GitHub releases.
Same fix as the Go image's 05-custom.sh: write `-4` to /root/.curlrc
at the top of the rust-tools stage so all subsequent curl calls use IPv4.
- Dockerfile: add `printf -- '-4
' > /root/.curlrc` at start of rust-tools stage

Dockerfile
2026-06-21 18:18:30 -04:00
jason 0a06ccafa1 🐛 Replace musl-cross with zig cc wrappers for arm64 cross-compile 🐛
musl-cross does not exist in any Alpine package repo (main, community,
or edge) — both attempts to install it failed at build time.
Zig ships with Alpine (`apk add zig`) and bundles its own musl headers
and stdlib for every target triple, making it a drop-in replacement for
a musl cross-toolchain with zero external dependencies.
Three wrapper scripts are created at install time:
/usr/local/bin/aarch64-linux-musl-gcc → zig cc -target aarch64-linux-musl
/usr/local/bin/aarch64-linux-musl-g++ → zig c++ -target aarch64-linux-musl
/usr/local/bin/aarch64-linux-musl-ar → zig ar
The CARGO_TARGET_AARCH64_UNKNOWN_LINUX_MUSL_LINKER and CC_*/CXX_*/AR_*
env vars are unchanged — they still point to aarch64-linux-musl-gcc,
which now resolves to the zig wrapper.
- Dockerfile: replace musl-cross apk install with zig + wrapper scripts

Dockerfile
2026-06-21 18:17:10 -04:00
jason a10a527f46 🐛 Fix musl-cross install in rust-tools stage 🐛
musl-cross is in the Alpine community repo, which rust:alpine does not
enable by default. `apk add --no-cache musl-cross` failed with
"no such package" on both linux/amd64 and linux/amd64->arm64 stages.
Fix: install curl and jq first (both in main), then fetch musl-cross
from the community repo via --repository flag (no permanent repo change).
- Dockerfile: split rust-tools apk install into main + community steps

Dockerfile
2026-06-21 18:13:05 -04:00
jason fe1598c890 📝 Fix README accuracy and section order 📝
Audit found three accuracy bugs and one section ordering violation:
- Add wasm-opt (binaryen) to WASM tools table — installed via pkmgr
in 05-custom.sh but was missing from the tools reference entirely
- Fix wasm32-emscripten → wasm32-unknown-emscripten in cross-compile
targets table (wrong triple name)
- Move "Install and run container" (dockermgr) from position 10 to
immediately after "Pull" — both are production install paths and must
appear before the Development section per canonical section order rules
- Rename "Build the image locally" → "Development" to match canonical
section naming; it is the last substantive section before License
- README.md: add binaryen/wasm-opt row to WASM tools table
- README.md: correct wasm32-unknown-emscripten triple
- README.md: move Install and run container section to top (after Pull)
- README.md: rename build section to Development; move to end

README.md
2026-06-21 18:02:47 -04:00
jason a6acb207b6 Native cross-compile stage + sccache on by default
Eliminates QEMU arm64 build (was ~15 hours) by adding a
`rust-tools` stage that mirrors the Go image's `go-tools` pattern:
runs on the build platform (amd64), cross-compiles or downloads all
~50 Rust tools for the target arch, and activates sccache throughout.
Build time for linux/arm64: ~15 hours → ~30–60 minutes.
How it works:
- `FROM --platform=$BUILDPLATFORM rust:alpine AS rust-tools` runs natively
- `cargo binstall --target $RUST_TARGET` fetches GitHub release prebuilts
(zero compilation for most tools)
- Missing prebuilts fall back to `cargo install --target` using the
`aarch64-linux-musl-gcc` cross-toolchain (no QEMU, native speed)
- Native (x86_64) sccache installed as RUSTC_WRAPPER so source-compiled
tools are cached across Docker rebuilds
- `CARGO_INSTALL_ROOT=/rust-tools` keeps tool binaries separate from
rustup shims; `COPY --from=rust-tools /rust-tools/bin/` drops them
into the build stage before `05-custom.sh` runs
Pure-Rust / no-OpenSSL feature flags where possible (CGO=0 equivalent):
- `sqlx-cli`: `--features rustls` (was native-tls)
- `sea-orm-cli`: `--features runtime-tokio-rustls` (was native-tls default)
- `trunk`: already defaults to rustls — no change needed
- `probe-rs`: prebuilt if available, silently skipped otherwise (needs libusb)
sccache is now active by default in all login shells via profile.d/rust.sh
(`RUSTC_WRAPPER=sccache`); opt out with `-e RUSTC_WRAPPER=`.
- Dockerfile: add 110-line rust-tools stage with musl cross-toolchain,
sccache, cargo-binstall, all tool installs for target arch
- Dockerfile: COPY --from=rust-tools before 05-custom.sh RUN step
- Dockerfile: set RUSTC_WRAPPER in build stage; drop unused cargo-registry
and cargo-git cache mounts (no longer needed there)
- rootfs/root/docker/setup/05-custom.sh: remove cargo-binstall bootstrap
and all cargo binstall/install blocks; add RUSTC_WRAPPER to profile.d
- README.md: document rust-tools stage, native cross-compile architecture,
expected build times, sccache-on-by-default, pure-Rust feature flags,
updated cache mount ID table

Dockerfile
README.md
rootfs/root/docker/setup/05-custom.sh
2026-06-21 17:58:20 -04:00
jason 20cd92f941 📝 Fix README accuracy: rust-workflow invocation and cache mount IDs 📝
Two inaccuracies corrected:
- rust-workflow is not run automatically on `docker run` with no args;
the container starts in monitoring mode and rust-workflow must be
called explicitly — update all examples to pass `rust-workflow` as
the command argument and rename the section heading accordingly
- Cache mount IDs in the BuildKit section were missing the per-arch
suffix; corrected to apk-cache-<arch>, cargo-git-<arch>,
rustup-downloads-<arch>, sccache-build-<arch> and added a note
explaining why per-arch IDs are used in multi-platform builds
- README.md: fix default-behavior section and cache mount ID table

README.md
2026-06-21 17:32:45 -04:00
jason 33adba3b32 🏗️ Add multi-arch (amd64 + arm64) build support 🏗️
Register QEMU binfmt handlers and fix cache mounts + binstall
resilience so the image builds correctly on both platforms.
- Dockerfile: declare ARG TARGETARCH in build stage; suffix all
arch-specific cache mount ids with ${TARGETARCH} so amd64 and
arm64 get isolated apk, rustup-downloads, cargo-git, and sccache
caches — cargo-registry stays shared (source is arch-neutral)
- rootfs/root/docker/setup/05-custom.sh: append || true to the main
cargo binstall -y block so a single tool with no arm64-musl prebuilt
and a failing source fallback does not abort the entire layer; add
comment explaining the intent

Dockerfile
rootfs/root/docker/setup/05-custom.sh
2026-06-14 03:09:10 -04:00
jason 62fac76033 🐛 Update entrypoint.sh and functions library from current template 🐛
Stale copies called __initialize_default_templates, __initialize_config_dir,
and __initialize_data_dir which are not in the old functions library,
causing container startup failures. Replaced with current template
versions (202606041210-git) which no longer call those missing functions.
- rootfs/usr/local/bin/entrypoint.sh: update to current template
- rootfs/usr/local/etc/docker/functions/entrypoint.sh: update to current template

rootfs/usr/local/bin/entrypoint.sh
rootfs/usr/local/etc/docker/functions/entrypoint.sh
2026-06-05 18:26:30 -04:00
jason 2e2d83b0cb 🐛 Fix resolv.conf: add search . and ndots:0 to block domain search 🐛
--domainname on the container sets the kernel domainname, which c-ares
uses to infer a search domain even when /etc/resolv.conf has no search
line. This caused c-ares to query github.com.casjay.work AAAA and get
the host's own IPv6 address, routing all outbound HTTPS to the local
nginx instead of the real server.
Adding 'search .' and 'options ndots:0' explicitly disables search
domain inference regardless of the kernel domainname setting.
- rootfs/usr/local/etc/resolv.conf: add search . and options ndots:0

rootfs/usr/local/etc/resolv.conf
2026-06-05 14:36:27 -04:00
jason 85f6eb5383 🐛 Fix container DNS: ship resolv.conf without search domain 🐛
Hosts with a search domain cause containers to inherit it. When the
zone has a wildcard AAAA record, public hostnames resolve to the host's
own IPv6 address instead of the real server, breaking all outbound
HTTPS and DNS from inside the container.
The entrypoint already has a hook: if /usr/local/etc/resolv.conf
exists it replaces /etc/resolv.conf at container startup. Ship a
clean resolv.conf with Cloudflare + Google DNS and no search domain
so container DNS is always correct regardless of host configuration.
- rootfs/usr/local/etc/resolv.conf: new file — clean DNS, no search domain

rootfs/usr/local/etc/resolv.conf
2026-06-05 12:37:17 -04:00
jason 7ce8f56a03 🔧 Add Gitea Actions workflow files 🔧
Generate .gitea/workflows/build*.yml from updated actions.template:
latest build uses yymm + latest tags (latest pushed last); versioned
builds hardcode the version tag.
?? .gitea/

.gitea/
2026-06-04 16:26:42 -04:00
jason fb4be2d9d7 🔧 Deleted workflow files 🔧
.gitea/workflows/docker.yaml
2026-06-04 16:22:08 -04:00
jason 29c51880ca 🔧 Update docker functions/entrypoint.sh to latest 🔧
Synced from casjay-dotfiles templates. Updated functions now check
for existence before copying template-files directories, skipping
gracefully when they are absent.
- rootfs/usr/local/etc/docker/functions/entrypoint.sh: updated to latest

rootfs/usr/local/etc/docker/functions/entrypoint.sh
2026-06-04 11:52:20 -04:00
jason ebbe149916 🗑️ Remove unused template-files from rootfs 🗑️
The init framework now checks for existence before copying; empty
placeholder directories are no longer needed in the image layer.
- rootfs/usr/local/share/template-files/: removed entirely

rootfs/usr/local/share/template-files/config/env/default.sample
rootfs/usr/local/share/template-files/config/env/examples/00-directory.sh
rootfs/usr/local/share/template-files/config/env/examples/addresses.sh
rootfs/usr/local/share/template-files/config/env/examples/certbot.sh
rootfs/usr/local/share/template-files/config/env/examples/couchdb.sh
rootfs/usr/local/share/template-files/config/env/examples/dockerd.sh
rootfs/usr/local/share/template-files/config/env/examples/global.sh
rootfs/usr/local/share/template-files/config/env/examples/healthcheck.sh
rootfs/usr/local/share/template-files/config/env/examples/mariadb.sh
rootfs/usr/local/share/template-files/config/env/examples/mongodb.sh
rootfs/usr/local/share/template-files/config/env/examples/networking.sh
rootfs/usr/local/share/template-files/config/env/examples/other.sh
rootfs/usr/local/share/template-files/config/env/examples/php.sh
rootfs/usr/local/share/template-files/config/env/examples/postgres.sh
rootfs/usr/local/share/template-files/config/env/examples/redis.sh
rootfs/usr/local/share/template-files/config/env/examples/services.sh
rootfs/usr/local/share/template-files/config/env/examples/ssl.sh
rootfs/usr/local/share/template-files/config/env/examples/supabase.sh
rootfs/usr/local/share/template-files/config/env/examples/webservers.sh
rootfs/usr/local/share/template-files/config/env/examples/zz-entrypoint.sh
rootfs/usr/local/share/template-files/config/.gitkeep
rootfs/usr/local/share/template-files/data/.gitkeep
rootfs/usr/local/share/template-files/defaults/.gitkeep
2026-06-04 11:21:16 -04:00
jason d917070c1a 🗃️ Could you paste the actual diff content? 🗃️
Could you paste the actual diff content?

Dockerfile
README.md
2026-05-31 23:21:21 -04:00
jason 293247c98c 📝 rewrite README and fix setup script tool installs 📝
- README rewritten from 137 → 439 lines: full tool tables, env var reference, volume/cache guide, cross-compile target matrix, sccache remote backend docs, BuildKit cache mount info
- Update image name from `casjaysdevdocker/rust` to `casjaysdev/rust` throughout
- Add `clang-dev`, `llvm-dev`, `openssl-libs-static` to build deps; add `perf` (non-fatal) for flamegraph/samply support
- Fix rustup nightly component flag syntax (split into two `--component` flags)
- Move `cargo-nextest` to fallback block with `--locked`; rename `typos` → `typos-cli` and `cargo-flamegraph` → `flamegraph` to match correct crate names

README.md
rootfs/root/docker/setup/05-custom.sh
2026-05-31 20:52:51 -04:00
jason dcb16d9762 📝 Rewrite README.md with full documentation 📝
Complete rewrite of README.md to document the default rust-workflow
behavior, all installed tools (organized by category), the full cache
strategy (BuildKit mounts + runtime volumes + sccache), cross-compile
targets and tooling, miri usage, environment variables, and docker-compose
example with all volumes wired up.
- README.md: add default-workflow quickstart; add tool tables for linting,
formatting, testing, coverage, benchmarking, profiling, fuzzing,
debugging, inspection, build/release, cross-compile, WASM, docs, and
dev-loop categories; add cache section covering BuildKit --mount cache
IDs, named volumes, host bind mounts, sccache activation and remote
backends; add cross-compile section with pure-Rust/zigbuild/cross usage
and caveats table; add miri section; update env vars table with
SCCACHE_DIR, CARGO_INCREMENTAL, RUSTC_WRAPPER, CARGO_WORKDIR,
CARGO_BUILD_TARGET; update docker run and docker-compose examples to
include all three volumes

README.md
2026-05-31 11:47:18 -04:00
jason 17141ceb5b Add BuildKit cache mounts, sccache, and full tooling suite
Cache strategy: BuildKit --mount=type=cache on apk and cargo/rustup/sccache
directories so docker build never re-downloads packages between runs.
sccache is available as a compilation cache; mount /root/.cache/sccache at
runtime to persist compiled artifacts across container invocations.
Added gdb, a nightly toolchain (miri + rust-src), and a broad set of
linting, formatting, debugging, fuzzing, and analysis tools.
- Dockerfile: add # syntax=docker/dockerfile:1 pragma; add BuildKit cache
mount for /var/cache/apk on the packages RUN step; add cache mounts for
cargo/registry (shared), cargo/git, rustup/downloads, and sccache on the
custom commands RUN step; add SCCACHE_DIR and CARGO_INCREMENTAL ENV vars;
extend VOLUME to include /root/.cache/sccache
- rootfs/root/docker/setup/05-custom.sh: add gdb to system packages;
install nightly toolchain (minimal profile) with miri + rust-src; extend
binstall block with sccache, typos, taplo-cli, cargo-sort, cargo-hack,
cargo-criterion, dprint, cargo-careful, cargo-public-api,
cargo-spellcheck, cargo-geiger, grcov; add fallback cargo installs for
cargo-udeps, cargo-fuzz, cargo-minimal-versions; export SCCACHE_DIR and
CARGO_INCREMENTAL in /etc/profile.d/rust.sh; create /root/.cache/sccache

Dockerfile
rootfs/root/docker/setup/05-custom.sh
2026-05-31 11:43:13 -04:00
jason e36a6888dd Build rust image with full toolchain, workflow, and utilities
Install latest stable Rust at build time via rustup-init with SHA256
verification. Add 30 cross-compile targets, cargo-binstall, and a
comprehensive set of cargo development tools. Match the official
rust:alpine env-var convention (RUSTUP_HOME / CARGO_HOME) and declare
those paths as Docker VOLUMEs. Add the Go-image pattern: rust-workflow
runs automatically when the container is invoked with no args, while
explicit commands pass through unchanged. Copy language-agnostic
healthcheck, copy, and symlink utilities from the Go image.
- Dockerfile: WORKDIR /app in final stage; add RUSTUP_HOME, CARGO_HOME,
RUSTUP_TOOLCHAIN ENV vars; extend VOLUME to include cargo and rustup paths
- rootfs/root/docker/setup/05-custom.sh: full Rust toolchain install —
build deps (build-base musl-dev clang lld cmake openssl-dev), SHA256-
verified rustup-init, stable toolchain with rust-src/rust-analyzer/
llvm-tools-preview, 30 cross-compile targets, cargo-binstall bootstrap,
cargo tool suite via binstall, cross-linker config.toml, /usr/local/bin
symlinks, ~/.cargo and ~/.rustup home symlinks, /etc/profile.d/rust.sh
- rootfs/usr/local/bin/rust-workflow: default workflow script —
fmt --check → clippy -D warnings → test --all → build --release;
honours CARGO_WORKDIR and CARGO_BUILD_TARGET env vars
- rootfs/usr/local/bin/entrypoint.sh: __no_exit guarded by $# -eq 0 in
START_SERVICES block; * catch-all now calls rust-workflow on no args
- rootfs/usr/local/bin/healthcheck: copied from Go image (HTTP/TCP/
process/file health probe)
- rootfs/usr/local/bin/copy: copied from Go image (recursive copy utility)
- rootfs/usr/local/bin/symlink: copied from Go image (symlink utility)

Dockerfile
rootfs/root/docker/setup/05-custom.sh
rootfs/usr/local/bin/copy
rootfs/usr/local/bin/entrypoint.sh
rootfs/usr/local/bin/healthcheck
rootfs/usr/local/bin/rust-workflow
rootfs/usr/local/bin/symlink
2026-05-31 11:33:51 -04:00
jason 4143ac6d72 🔧 Update configuration files 🔧
Dockerfile
.env.scripts
.gitattributes
.gitea/workflows/docker.yaml
.gitignore
rootfs/etc/profile.d/rust.sh
rootfs/root/docker/setup/00-init.sh
rootfs/root/docker/setup/01-system.sh
rootfs/root/docker/setup/02-packages.sh
rootfs/root/docker/setup/03-files.sh
rootfs/root/docker/setup/04-users.sh
rootfs/root/docker/setup/05-custom.sh
rootfs/root/docker/setup/06-post.sh
rootfs/root/docker/setup/07-cleanup.sh
rootfs/usr/local/bin/copy
rootfs/usr/local/bin/entrypoint.sh
rootfs/usr/local/bin/healthcheck
rootfs/usr/local/bin/symlink
rootfs/usr/local/etc/docker/init.d/00-rust.sh
rootfs/usr/local/share/cargo/config.toml
rootfs/usr/local/share/template-files/config/env/default.sample
rootfs/usr/local/share/template-files/config/env/examples/zz-entrypoint.sh
2026-05-31 11:10:48 -04:00
jason c44d678c9c 🔧 Update scripts and add CA cert update 🔧
Update all container scripts to 202605241245-git and add CA certificate
update step after package installation.
- rootfs/root/docker/setup/00-init.sh: updated to latest template
- rootfs/root/docker/setup/01-system.sh: updated to latest template
- rootfs/root/docker/setup/02-packages.sh: add update-ca-certificates/update-ca-trust step
- rootfs/root/docker/setup/03-files.sh: updated to latest template
- rootfs/root/docker/setup/04-users.sh: updated to latest template
- rootfs/root/docker/setup/05-custom.sh: updated to latest template
- rootfs/root/docker/setup/06-post.sh: updated to latest template
- rootfs/root/docker/setup/07-cleanup.sh: updated to latest template
- rootfs/usr/local/bin/entrypoint.sh: updated to 202605241245-git
- rootfs/usr/local/bin/pkmgr: updated to 202605241245-git
- rootfs/usr/local/etc/docker/functions/entrypoint.sh: updated to 202605241245-git

rootfs/root/docker/setup/00-init.sh
rootfs/root/docker/setup/01-system.sh
rootfs/root/docker/setup/02-packages.sh
rootfs/root/docker/setup/03-files.sh
rootfs/root/docker/setup/04-users.sh
rootfs/root/docker/setup/05-custom.sh
rootfs/root/docker/setup/06-post.sh
rootfs/root/docker/setup/07-cleanup.sh
rootfs/usr/local/bin/entrypoint.sh
rootfs/usr/local/bin/pkmgr
rootfs/usr/local/etc/docker/functions/entrypoint.sh
2026-05-24 21:46:52 -04:00
jason 36e0fccdfe 🗃️ rootfs: shield internal entrypoint PID files from /run/*.pid sweeps 🗃️
Update the embedded entrypoint copies in rootfs/ to match the
upstream template change. Internal state files renamed to dotfiles
so they're not matched by `/run/*.pid` cleanup globs:
- /run/init.d/entrypoint.pid -> /run/.entrypoint.pid
- /run/no_exit.pid -> /run/.no_exit.pid
- /run/backup.pid -> /run/.backup.pid
- /run/__start_init_scripts.pid -> /run/.start_init_scripts.pid
Per-service PIDs in /run/init.d/ are unchanged.

Dockerfile
.env.scripts
rootfs/usr/local/bin/copy
rootfs/usr/local/bin/entrypoint.sh
rootfs/usr/local/bin/healthcheck
rootfs/usr/local/bin/symlink
rootfs/usr/local/etc/docker/functions/entrypoint.sh
rootfs/usr/local/etc/docker/init.d/00-rust.sh
rootfs/usr/local/share/template-files/config/env/default.sample
rootfs/usr/local/share/template-files/config/env/examples/zz-entrypoint.sh
2026-05-05 19:14:03 -04:00
jason 3514fc596f 🗃️ readme: rename rootfs/ to volumes/ for compose context 🗃️
Aligns README install/run snippets with the new convention split:
rootfs/ for Dockerfile-build content (image filesystem), volumes/
for docker-compose host bind-mounts. Compose mounts, host bind
paths, and runtime data dirs are renamed; Dockerfile COPY/ADD
sources (where present) are preserved.

README.md
2026-05-05 14:36:27 -04:00
jason db7d7dba0e 🦈🏠🐜 Initial Commit 🐜🦈🏠 2026-05-01 06:43:50 -04:00