diff --git a/.cargo/config.toml b/.cargo/config.toml new file mode 100644 index 0000000..e58648c --- /dev/null +++ b/.cargo/config.toml @@ -0,0 +1,5 @@ +[target.x86_64-unknown-linux-gnu] +linker = "x86_64-linux-gnu-gcc" + +[target.aarch64-unknown-linux-gnu] +linker = "aarch64-linux-gnu-gcc" diff --git a/.dockerignore b/.dockerignore index 6d7a285..2b24392 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,5 +1,6 @@ /target -.tbcfg *.txt *.log +*.sh +/recipe_repo \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index 1503acb..50d70c8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2019,13 +2019,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe" [[package]] -name = "openssl-sys" -version = "0.9.115" +name = "openssl-src" +version = "300.6.1+3.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "158fe5b292746440aa6e7a7e690e55aeb72d41505e2804c23c6973ad0e9c9781" +checksum = "46eb8fb9fb3b61ce1c0f8a026c4c1a0714d3a9e138e7fbde78753ce2babc3846" +dependencies = [ + "cc", +] + +[[package]] +name = "openssl-sys" +version = "0.9.117" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b47e7e6bb2c38cd930d25a23b40fa52e068c10e85f3e03a7f5ba5aaca5713695" dependencies = [ "cc", "libc", + "openssl-src", "pkg-config", "vcpkg", ] @@ -2937,6 +2947,7 @@ dependencies = [ "libgit2-sys", "libtbr", "log", + "openssl-sys", "redis", "reqwest", "serde", diff --git a/Cargo.toml b/Cargo.toml index afcc656..ff5ead7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,3 +29,4 @@ tokio-util = { version = "0.7.18", features = ["io"] } uuid = { version = "1.20.0", features = ["v4"] } tokio-postgres = "0.7.17" chrono = "0.4.45" +openssl-sys = { version = "0.9.117", features = ["vendored"] } diff --git a/Dockerfile b/Dockerfile index 442836b..f1774a7 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,43 +1,135 @@ -FROM rustlang/rust:nightly-slim AS builder - +# syntax=docker/dockerfile:1 +FROM --platform=$BUILDPLATFORM lukemathwalker/cargo-chef:latest-rust-slim-bookworm AS chef WORKDIR /app -# Install build dependencies -RUN apt update && apt install -y \ - musl-tools \ - musl-dev \ - build-essential \ - libssl-dev \ +# ----------------------------------------------------------------------- +# Stage 1: Prepare the recipe +# ----------------------------------------------------------------------- +FROM chef AS planner +COPY . . +RUN cargo chef prepare --recipe-path recipe.json + +# ----------------------------------------------------------------------- +# Stage 2: Build the dependencies & application +# ----------------------------------------------------------------------- +FROM chef AS builder + +# Capture Docker's target platform variables +ARG TARGETPLATFORM +ARG TARGETARCH +ARG TARGETVARIANT + +# Install host tools needed for compilation (including cmake and clang for aws-lc-sys) +RUN apt-get update && apt-get install -y \ + clang \ + llvm \ + cmake \ + make \ + pkg-config \ + perl \ + libssl-dev + +# Enable multiarch support so we can download foreign architecture .so and .h files +RUN dpkg --add-architecture amd64 && \ + dpkg --add-architecture arm64 + +# Setup target-specific environment variables manually based on target architecture +RUN apt-get update && \ + if [ "$TARGETARCH" = "amd64" ]; then \ + apt-get install -y gcc-x86-64-linux-gnu g++-x86-64-linux-gnu libssl-dev; \ + echo "TARGET_TRIPLE=x86_64-unknown-linux-gnu" >> /env_config; \ + echo "CC_x86_64_unknown_linux_gnu=/usr/bin/x86_64-linux-gnu-gcc" >> /env_config; \ + echo "CXX_x86_64_unknown_linux_gnu=/usr/bin/x86_64-linux-gnu-g++" >> /env_config; \ + echo "CC=/usr/bin/x86_64-linux-gnu-gcc" >> /env_config; \ + echo "CXX=/usr/bin/x86_64-linux-gnu-g++" >> /env_config; \ + echo "CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_LINKER=/usr/bin/x86_64-linux-gnu-gcc" >> /env_config; \ + echo "OPENSSL_DIR=/usr" >> /env_config; \ + if [ "$TARGETVARIANT" = "v3" ]; then \ + echo "export RUSTFLAGS='-C target-cpu=x86-64-v3'" >> /env_config; \ + fi \ + elif [ "$TARGETARCH" = "arm64" ]; then \ + apt-get install -y gcc-aarch64-linux-gnu g++-aarch64-linux-gnu libssl-dev; \ + echo "TARGET_TRIPLE=aarch64-unknown-linux-gnu" >> /env_config; \ + echo "CC_aarch64_unknown_linux_gnu=/usr/bin/aarch64-linux-gnu-gcc" >> /env_config; \ + echo "CXX_aarch64_unknown_linux_gnu=/usr/bin/aarch64-linux-gnu-g++" >> /env_config; \ + echo "CC=/usr/bin/aarch64-linux-gnu-gcc" >> /env_config; \ + echo "CXX=/usr/bin/aarch64-linux-gnu-g++" >> /env_config; \ + echo "CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=/usr/bin/aarch64-linux-gnu-gcc" >> /env_config; \ + echo "OPENSSL_DIR=/usr" >> /env_config; \ + fi + +# Force openssl-sys to download, compile, and statically link OpenSSL safely +ENV OPENSSL_STATIC=1 +ENV OPENSSL_VENDED=1 + +# Tell cargo to allow cross-compiling build scripts +ENV PKG_CONFIG_ALLOW_CROSS=1 + +# Load the environment configurations and download Rust target targets +RUN . /env_config && \ + rustup target add "$TARGET_TRIPLE" + +# Tell aws-lc-sys exactly how to build via CMake +ENV AWS_LC_SYS_CMAKE_BUILDER=1 +ENV AWS_LC_SYS_PREBUILT_NASM=1 + +COPY .cargo /app/.cargo + +# Cache and build only the dependencies (the chef recipe) +COPY --from=planner /app/recipe.json recipe.json +RUN . /env_config && \ + cargo chef cook --release --target "$TARGET_TRIPLE" --recipe-path recipe.json + +# Copy actual source code +COPY . . + +# Build the main application using cached dependencies +RUN . /env_config && \ + cargo build --release --target "$TARGET_TRIPLE" && \ + cp target/${TARGET_TRIPLE}/release/tbm-git-repo-service /tbm-git-repo-service + +# ----------------------------------------------------------------------- +# Stage 3: Minimal Runtime +# ----------------------------------------------------------------------- +# We dynamically anchor the platform to a base architecture to stop Docker +# from panicking over micro-variants like v3 during runtime container setup. +FROM --platform=$TARGETPLATFORM debian:bookworm-slim AS runtime-base + +# Trick Buildx: force the runner to resolve back to basic broad platforms +# so it can execute native container processes like apt-get without errors. +FROM --platform=linux/amd64 debian:bookworm-slim AS runtime-amd64 +FROM --platform=linux/arm64 debian:bookworm-slim AS runtime-arm64 + +# Select the clean runtime environment matching your target layout +FROM runtime-$TARGETARCH AS final-runtime +WORKDIR /app + +ENV TZ=Asia/Bangkok + +# Install runtime dependencies if needed (like ca-certificates or openssl) +RUN apt-get update && apt-get install -y --no-install-recommends \ + ca-certificates \ + libssl3 \ + zlib1g \ curl \ pkg-config \ ca-certificates \ - protobuf-compiler \ - zlib1g + openssh-client \ + tzdata && ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone \ + && rm -rf /var/lib/apt/lists/* -# Copy dependency files first for better caching -COPY Cargo.toml Cargo.lock ./ -COPY ./src ./src -COPY build.rs ./ -COPY tbm-proto ./tbm-proto +COPY --from=builder /tbm-git-repo-service /app/tbm-git-repo-service +COPY --from=builder /app/.tbcfg /app/.tbcfg -# Download config -RUN curl -X GET https://pakin-inspiron-15-3530.tail110d9.ts.net/pakin/tbm-git-repo-service/releases/download/config/.tbcfg -o .tbcfg +RUN mkdir -p /root/.ssh && \ + ssh-keyscan 192.168.10.159 >> /root/.ssh/known_hosts -# Build the application -ENV RUSTFLAGS="-C target-feature=+crt-static" -RUN cargo build --release +# RUN cp /usr/src/app/target/release/tbm-git-repo-service /usr/src/app/ +# RUN cp /usr/src/app/.tbcfg /usr/src/app/ -# Builder -FROM gcr.io/distroless/cc - -# Copy the binary -COPY --from=builder /app/target/release/tbm-git-repo-service / -COPY --from=builder /app/.tbcfg / - -# Create data directory +# RUN rm -rf /usr/src/app/target EXPOSE 36583 -# Environment defaults CMD ["./tbm-git-repo-service"] \ No newline at end of file diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..f13f929 --- /dev/null +++ b/build.sh @@ -0,0 +1 @@ +docker build --pull --platform linux/amd64,linux/arm64 -t pakin-inspiron-15-3530.tail110d9.ts.net/pakin/recipe-repo . \ No newline at end of file diff --git a/push.sh b/push.sh new file mode 100755 index 0000000..53bbea8 --- /dev/null +++ b/push.sh @@ -0,0 +1 @@ +docker push pakin-inspiron-15-3530.tail110d9.ts.net/pakin/server-m2:latest