diff --git a/Dockerfile b/Dockerfile index ca4cb21..80c7541 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,38 +1,38 @@ -FROM rust:1.75-slim-bookworm +# syntax=docker/dockerfile:1 -# Install system dependencies -RUN apt-get update && apt-get install -y \ - curl \ - git \ +# ── Stage 1: builder ────────────────────────────────────────────────────────── +# Pinned digest for reproducibility +FROM rust:1.75-slim-bookworm@sha256:70c2a016184099262fd7cee46f3d35fec3568c45c62f87e37f7f665f766b1f74 AS builder + +RUN apt-get update && apt-get install -y --no-install-recommends \ pkg-config \ libssl-dev \ build-essential \ && rm -rf /var/lib/apt/lists/* -# Add WASM target RUN rustup target add wasm32-unknown-unknown -# Install Stellar CLI -RUN curl -sSL https://github.com/stellar/stellar-cli/releases/download/v22.0.1/stellar-cli-22.0.1-x86_64-unknown-linux-gnu.tar.gz \ - | tar -xz -C /usr/local/bin - WORKDIR /app -# Cache dependencies +# Cache dependencies before copying full source COPY Cargo.toml ./ COPY contracts/governance/Cargo.toml contracts/governance/Cargo.toml COPY contracts/token/Cargo.toml contracts/token/Cargo.toml - -# Create stub lib files for dependency caching RUN mkdir -p contracts/governance/src contracts/token/src \ - && echo '#![no_std] soroban_sdk::contractimpl_empty!();' > contracts/governance/src/lib.rs \ - && echo '#![no_std] soroban_sdk::contractimpl_empty!();' > contracts/token/src/lib.rs \ + && echo 'pub fn main() {}' > contracts/governance/src/lib.rs \ + && echo 'pub fn main() {}' > contracts/token/src/lib.rs \ && cargo fetch || true -# Copy full source COPY . . -# Install cargo tools -# RUN cargo install cargo-tarpaulin --locked +RUN cargo build --release --target wasm32-unknown-unknown + +# ── Stage 2: runtime ────────────────────────────────────────────────────────── +# Minimal image — contains only the compiled WASM artifacts +FROM debian:bookworm-slim@sha256:0104b334637a5f19aa9c983a91b54c89887c0984081f2068983107a6f6c21eeb AS runtime + +WORKDIR /app/artifacts + +COPY --from=builder /app/target/wasm32-unknown-unknown/release/*.wasm ./ -CMD ["make", "test"] +CMD ["ls", "-lh", "/app/artifacts"] diff --git a/README.md b/README.md index 203226a..2f697bd 100644 --- a/README.md +++ b/README.md @@ -362,10 +362,27 @@ Key variables: `NETWORK`, `STELLAR_RPC_URL`, `STELLAR_SECRET_KEY`, `GOVERNANCE_C ### With Docker +The Dockerfile uses a **multi-stage build** to keep the final image small and free of build tooling: + +| Stage | Base image | Purpose | +|-------|-----------|---------| +| `builder` | `rust:1.75-slim-bookworm` (pinned digest) | Compiles WASM binaries | +| `runtime` | `debian:bookworm-slim` (pinned digest) | Ships only the `.wasm` artifacts | + +Both base images are pinned to a specific digest for reproducibility. + ```bash +# Start a dev shell (builder stage — full Rust toolchain) docker compose up docker compose run --rm dev make test docker compose run --rm dev make build + +# Build the minimal runtime image (WASM artifacts only) +docker compose --profile artifacts build artifacts + +# Or build directly with Docker +docker build --target builder -t cosmosvote:builder . # dev / CI +docker build --target runtime -t cosmosvote:runtime . # production artifact image ``` ### Without Docker diff --git a/docker-compose.yml b/docker-compose.yml index 9f6f083..b28bfb3 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -5,6 +5,7 @@ services: build: context: . dockerfile: Dockerfile + target: builder # full toolchain for development volumes: - .:/app - cargo-cache:/usr/local/cargo/registry @@ -16,6 +17,14 @@ services: - stellar-node command: bash + artifacts: + build: + context: . + dockerfile: Dockerfile + target: runtime # minimal image with WASM artifacts only + profiles: + - artifacts + stellar-node: image: stellar/quickstart:latest ports: