Brings up the whole platform behind a single Caddy entrypoint so the
routing topology can be exercised end-to-end before any feature code
lands. Same Caddyfile shape (admin / data plane / dashboard) maps to
single-process MVP today and will map to cluster mode later by
swapping the upstream lists, not by restructuring the proxy.
* caddy/Caddyfile — dev: HTTP only, picloud and dashboard upstreams
by service name. caddy/Caddyfile.prod — Let's Encrypt for
PICLOUD_DOMAIN with PICLOUD_ADMIN_EMAIL.
* docker/orchestrator.Dockerfile — multi-stage build of the
`picloud` all-in-one against the pinned 1.92 toolchain; debian
slim runtime, non-root user, /healthz HEALTHCHECK.
* docker/dashboard.Dockerfile — node:24-alpine builder + caddy
runtime that serves the static SPA with SPA fallback.
* docker-compose.yml — postgres + picloud + dashboard + caddy,
Caddy exposed on host :8000 (configurable), Postgres on :15432
(loopback only). Health-gated startup ordering.
* docker-compose.prod.yml — overlay: removes Postgres host
mapping, expands Caddy to 80/443/443udp, swaps Caddyfile.prod,
adds restart policy.
* .env.example documents every knob the compose stack reads.
Verified via `docker compose up -d`:
* `curl :8000/healthz` → 200 ok (orchestrator)
* `curl :8000/api/admin/scripts` → 404 (manager, routed correctly)
* `curl :8000/api/execute/<id>` → 404 (orchestrator, routed correctly)
* `curl :8000/` → SPA index served (dashboard via Caddy)
* `curl :8000/favicon.svg` → 200 image/svg+xml
* Postgres healthy and reachable on 127.0.0.1:15432.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
49 lines
1.5 KiB
Docker
49 lines
1.5 KiB
Docker
# syntax=docker/dockerfile:1.7
|
|
|
|
# Build stage — compiles the `picloud` all-in-one binary against the
|
|
# pinned toolchain from rust-toolchain.toml.
|
|
FROM rust:1.92-slim-bookworm AS builder
|
|
|
|
WORKDIR /build
|
|
|
|
# System libs needed for the build (sqlx + reqwest pull rustls so we
|
|
# don't need OpenSSL; pkg-config still helps a few transitive crates).
|
|
RUN apt-get update \
|
|
&& apt-get install -y --no-install-recommends pkg-config \
|
|
&& rm -rf /var/lib/apt/lists/*
|
|
|
|
# Copy the workspace. We could split deps from sources with cargo-chef
|
|
# for better layer caching; defer that until build times become a
|
|
# bottleneck — current cold build is well under a minute on a laptop.
|
|
COPY rust-toolchain.toml Cargo.toml Cargo.lock ./
|
|
COPY crates ./crates
|
|
|
|
RUN --mount=type=cache,target=/usr/local/cargo/registry \
|
|
--mount=type=cache,target=/build/target \
|
|
cargo build --release --bin picloud \
|
|
&& cp target/release/picloud /tmp/picloud
|
|
|
|
# Runtime stage — debian-slim is ~30MB and has the CA bundle we need
|
|
# for outbound HTTPS in v1.1+.
|
|
FROM debian:bookworm-slim AS runtime
|
|
|
|
RUN apt-get update \
|
|
&& apt-get install -y --no-install-recommends ca-certificates curl \
|
|
&& rm -rf /var/lib/apt/lists/* \
|
|
&& useradd --create-home --shell /usr/sbin/nologin --uid 10001 picloud
|
|
|
|
COPY --from=builder /tmp/picloud /usr/local/bin/picloud
|
|
|
|
USER picloud
|
|
WORKDIR /home/picloud
|
|
|
|
ENV PICLOUD_BIND=0.0.0.0:8080 \
|
|
RUST_LOG=info
|
|
|
|
EXPOSE 8080
|
|
|
|
HEALTHCHECK --interval=10s --timeout=2s --start-period=5s --retries=3 \
|
|
CMD curl -fsS http://127.0.0.1:8080/healthz || exit 1
|
|
|
|
ENTRYPOINT ["/usr/local/bin/picloud"]
|