constellate 0.3.6

Rust-powered CLI + live editor for curated markdown workspaces (requirements, docs, ADRs, audits, support, status-driven tasks) that build/serve/CRUD a themeable knowledge portal from a single binary.
# syntax=docker/dockerfile:1.6

ARG RUST_VERSION=1.91
ARG RUST_IMAGE=rust:${RUST_VERSION}-slim-bookworm
ARG APP_NAME=constellate

FROM --platform=$BUILDPLATFORM ${RUST_IMAGE} AS build
ARG APP_NAME=constellate
WORKDIR /app

# Prefer sparse protocol for faster and cache-friendly dependency downloads.
ENV CARGO_REGISTRIES_CRATES_IO_PROTOCOL=sparse \
    CARGO_TERM_COLOR=always \
    APP_NAME=${APP_NAME}

# Prebuild dependencies to take advantage of Docker layer caching.
COPY Cargo.toml Cargo.lock build.rs ./
RUN mkdir src \
    && echo 'fn main() {}' > src/main.rs \
    && cargo build --locked --release \
    && rm -rf src

COPY . .
# Touch the primary entrypoint so Cargo notices real sources even if their
# timestamps are older than the stubbed file from the dependency warmup layer.
RUN touch src/main.rs \
    && cargo build --locked --release --bin "${APP_NAME}"

FROM debian:bookworm-slim AS runtime
ARG APP_NAME=constellate
ARG APP_USER=constellate
ARG APP_HOME=/srv/${APP_NAME}
ARG WORKSPACE_DIR=/workspace
ARG BUILD_DATE="unknown"
ARG VCS_REF="unknown"
ARG VERSION="dev"

LABEL org.opencontainers.image.title="Constellate" \
      org.opencontainers.image.description="A Rust CLI that turns curated markdown collections into a static, themeable knowledge portal." \
      org.opencontainers.image.url="https://github.com/onjin/constellate" \
      org.opencontainers.image.source="https://github.com/onjin/constellate" \
      org.opencontainers.image.vendor="Constellate" \
      org.opencontainers.image.licenses="MIT" \
      org.opencontainers.image.version="${VERSION}" \
      org.opencontainers.image.revision="${VCS_REF}" \
      org.opencontainers.image.created="${BUILD_DATE}"

# Install only the runtime essentials and clean up apt metadata to keep the image small.
RUN apt-get update \
    && apt-get install -y --no-install-recommends ca-certificates tini \
    && rm -rf /var/lib/apt/lists/*

RUN groupadd --system ${APP_USER} \
    && useradd --system --create-home --home-dir ${APP_HOME} --gid ${APP_USER} --shell /usr/sbin/nologin ${APP_USER} \
    && mkdir -p ${WORKSPACE_DIR}

WORKDIR /
COPY --from=build /app/target/release/${APP_NAME} /usr/local/bin/${APP_NAME}
RUN chown -R ${APP_USER}:${APP_USER} ${APP_HOME} ${WORKSPACE_DIR}
VOLUME ["${WORKSPACE_DIR}"]

USER ${APP_USER}
EXPOSE 8080

ENTRYPOINT ["/usr/bin/tini", "--", "constellate"]
CMD ["serve", "--input", "/workspace", "--output", "/workspace/dist", "--host", "0.0.0.0", "-p", "8080"]