feat(compose): full-stack Caddy + docker-compose wiring
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>
This commit is contained in:
48
docker/orchestrator.Dockerfile
Normal file
48
docker/orchestrator.Dockerfile
Normal file
@@ -0,0 +1,48 @@
|
||||
# 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"]
|
||||
Reference in New Issue
Block a user