From 3f57389f6c5c4ce4c62536ea3716917b1af573dd Mon Sep 17 00:00:00 2001 From: Xevion Date: Thu, 10 Jul 2025 11:01:09 -0500 Subject: [PATCH] feat: improve dockerfile, better stages --- Dockerfile | 63 ++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 44 insertions(+), 19 deletions(-) diff --git a/Dockerfile b/Dockerfile index dba1a55..2c1b255 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,45 +1,70 @@ # Build Stage -FROM rust:1.81.0 as builder +FROM rust:1.81.0-alpine as builder +# Install build dependencies +RUN apk add --no-cache \ + musl-dev \ + pkgconfig \ + openssl-dev + +WORKDIR /usr/src RUN USER=root cargo new --bin time-banner -WORKDIR ./time-banner -ENV CARGO_REGISTRIES_CRATES_IO_PROTOCOL=sparse -COPY ./Cargo.toml ./Cargo.toml +WORKDIR /usr/src/time-banner + +# Copy dependency files for better layer caching +COPY ./Cargo.toml ./Cargo.lock* ./build.rs ./ +# Copy the timezone data file needed by build.rs +COPY ./src/abbr_tz ./src/abbr_tz + # Build empty app with downloaded dependencies to produce a stable image layer for next build RUN cargo build --release # Build web app with own code RUN rm src/*.rs -ADD . ./ +COPY ./src ./src RUN rm ./target/release/deps/time_banner* RUN cargo build --release +# Strip the binary to reduce size +RUN strip target/release/time-banner -FROM debian:bullseye-slim +# Runtime Stage - Alpine for smaller size and musl compatibility +FROM alpine:3.19 ARG APP=/usr/src/app +ARG APP_USER=appuser +ARG UID=1000 +ARG GID=1000 -RUN apt-get update \ - && apt-get install -y ca-certificates tzdata \ - && rm -rf /var/lib/apt/lists/* +# Install runtime dependencies +RUN apk add --no-cache \ + ca-certificates \ + tzdata -ENV TZ=Etc/UTC \ - APP_USER=appuser +ENV TZ=Etc/UTC -RUN groupadd $APP_USER \ - && useradd -g $APP_USER $APP_USER \ +# Create user with specific UID/GID +RUN addgroup -g $GID -S $APP_USER \ + && adduser -u $UID -D -S -G $APP_USER $APP_USER \ && mkdir -p ${APP} -COPY --from=builder /time-banner/target/release/time-banner ${APP}/time-banner -COPY --from=builder /time-banner/src/fonts ${APP}/fonts -COPY --from=builder /time-banner/src/templates ${APP}/templates +# Copy application files +COPY --from=builder --chown=$APP_USER:$APP_USER /usr/src/time-banner/target/release/time-banner ${APP}/time-banner +COPY --from=builder --chown=$APP_USER:$APP_USER /usr/src/time-banner/src/fonts ${APP}/fonts +COPY --from=builder --chown=$APP_USER:$APP_USER /usr/src/time-banner/src/templates ${APP}/templates -RUN chown -R $APP_USER:$APP_USER ${APP} +# Set proper permissions +RUN chmod +x ${APP}/time-banner USER $APP_USER WORKDIR ${APP} -EXPOSE 3000 -ENV PORT 3000 +# Use ARG for build-time configuration, ENV for runtime +ARG PORT=3000 +ENV PORT=${PORT} +EXPOSE ${PORT} +# Add health check (using wget since curl isn't in Alpine by default) +HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ + CMD wget --quiet --tries=1 --spider http://localhost:${PORT}/health || exit 1 CMD ["./time-banner"] \ No newline at end of file