Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed

- Consolidated `commitlint`, `format`, and `lint` CI jobs into a single `lint` job (#42)
- `[profile.release]` tuned in `Cargo.toml` with `lto = true`, `codegen-units = 1`, `strip = true`, `panic = "abort"` for smaller binary size (#60)
- `Dockerfile` builder stage updated to compile against `x86_64-unknown-linux-musl` via `musl-tools` for a fully static binary; runtime stage switched from `debian:bookworm-slim` to `alpine` (#57)
- `get_all`, `get_by_id`, `get_by_squad_number`, and `delete` in `player_service` now return `Result<T, PlayerServiceError>` instead of `Result<T, diesel::result::Error>`, aligning with the `CreateError`/`UpdateError` pattern (#56)
- `codecov.yml` `ignore` list extended with `src/**/mod.rs` to exclude module re-exports from coverage reporting (#78)
- `codecov.yml` comment updated to reflect goal of maximum coverage on business logic layers (#78)
Expand Down
6 changes: 6 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,9 @@ diesel_migrations = "2.3"
libsqlite3-sys = { version = "0.30", features = ["bundled"] }
rocket_okapi = { version = "0.9.0", features = ["swagger"] }
schemars = { version = "1.2" }

[profile.release]
lto = true # link-time optimisation — reduces binary size and improves inlining
codegen-units = 1 # single codegen unit — required for full LTO
strip = true # strip debug symbols (Rust 1.59+)
panic = "abort" # remove unwinding machinery — smaller binary, faster panics
66 changes: 34 additions & 32 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,78 +2,80 @@
# Stage 1: Builder
# This stage builds the application and its dependencies.
# ------------------------------------------------------------------------------
FROM rust:1.88-slim-bookworm AS builder
FROM --platform=linux/amd64 rust:1.88-slim-bookworm AS builder

# Install build dependencies required by rusqlite (bundled feature compiles
# SQLite from source via the cc crate and needs a C compiler)
# -- Install system packages ---------------------------------------------------
# gcc / pkg-config: required by libsqlite3-sys (bundled feature compiles from
# source via the cc crate)
# musl-tools: provides musl-gcc, the C linker required for the
# x86_64-unknown-linux-musl target
RUN apt-get update && apt-get install -y --no-install-recommends \
gcc \
pkg-config \
musl-tools \
&& rm -rf /var/lib/apt/lists/*

RUN rustup target add x86_64-unknown-linux-musl
Comment thread
coderabbitai[bot] marked this conversation as resolved.

WORKDIR /app

# Copy dependency manifests first to leverage layer caching
# -- Pre-build dependencies (cached) ------------------------------------------
# Copy only the manifests and a stub main.rs so Cargo can compile all
# dependencies in isolation. This layer is cached and only invalidated when
# Cargo.toml or Cargo.lock change — not when application source changes.
COPY Cargo.toml Cargo.lock ./

# Stub out a minimal src/main.rs so Cargo can resolve and compile dependencies
# without the real application sources — this layer is only invalidated when
# Cargo.toml or Cargo.lock change.
RUN mkdir src && echo "fn main() {}" > src/main.rs

RUN --mount=type=cache,target=/usr/local/cargo/registry \
--mount=type=cache,target=/app/target \
cargo build --release

# Overlay with the real application sources
CC_x86_64_unknown_linux_musl=musl-gcc \
cargo build --release --target x86_64-unknown-linux-musl

# -- Build application ---------------------------------------------------------
# Overlay with the real sources. The stub main.rs is overwritten by the COPY,
# but Cargo uses mtime to detect changes — touching main.rs after the COPY
# ensures Cargo recompiles the application crate without re-compiling
# dependencies (which remain in the cache-mounted target/).
COPY src/ ./src/
COPY migrations/ ./migrations/
COPY Rocket.toml ./

# Touch main.rs so Cargo detects the change, rebuild only app code, then copy
# the binary out of the cache-mounted target/ into the image layer.
RUN --mount=type=cache,target=/usr/local/cargo/registry \
--mount=type=cache,target=/app/target \
touch src/main.rs && \
cargo build --release && \
cp target/release/rust-samples-rocket-restful /app/rust-samples-rocket-restful
CC_x86_64_unknown_linux_musl=musl-gcc \
cargo build --release --target x86_64-unknown-linux-musl && \
cp target/x86_64-unknown-linux-musl/release/rust-samples-rocket-restful /app/rust-samples-rocket-restful

# ------------------------------------------------------------------------------
# Stage 2: Runtime
# This stage creates the final, minimal image to run the application.
# ------------------------------------------------------------------------------
FROM debian:bookworm-slim AS runtime

# Install curl for health check
RUN apt-get update && apt-get install -y --no-install-recommends \
curl \
&& rm -rf /var/lib/apt/lists/*
FROM --platform=linux/amd64 alpine:3.23 AS runtime

WORKDIR /app

# Metadata labels for the image. These are useful for registries and inspection.
# -- Install system packages ---------------------------------------------------
RUN apk add --no-cache curl

# -- Metadata ------------------------------------------------------------------
LABEL org.opencontainers.image.title="🧪 RESTful API with Rust and Rocket"
LABEL org.opencontainers.image.description="Proof of Concept for a RESTful API made with Rust and Rocket"
LABEL org.opencontainers.image.licenses="MIT"
LABEL org.opencontainers.image.source="https://github.com/nanotaboada/rust-samples-rocket-restful"
LABEL org.sonarsource.docker.dockerfile="/Dockerfile"

# https://rules.sonarsource.com/docker/RSPEC-6504/

# Copy application binary and Rocket configuration
# -- Copy artifacts ------------------------------------------------------------
COPY --from=builder /app/rust-samples-rocket-restful .
COPY --from=builder /app/Rocket.toml ./Rocket.toml

# Copy metadata docs for container registries (e.g.: GitHub Container Registry)
COPY --chmod=444 README.md ./

# Copy entrypoint and healthcheck scripts
COPY --chmod=555 scripts/entrypoint.sh ./entrypoint.sh
COPY --chmod=555 scripts/healthcheck.sh ./healthcheck.sh

# Add system user and prepare volume mount point
RUN addgroup --system rocket && \
adduser --system --ingroup rocket rocket && \
# -- Configure runtime ---------------------------------------------------------
# https://rules.sonarsource.com/docker/RSPEC-6504/
RUN addgroup -S rocket && \
adduser -S -G rocket rocket && \
mkdir -p /storage && \
chown -R rocket:rocket /storage

Expand Down
Loading