# Build stage with cargo-chef
FROM rust:1.90-slim AS chef
WORKDIR /app
RUN cargo install cargo-chef
# Planner stage - analyzes dependencies
FROM chef AS planner
COPY . .
RUN cargo chef prepare --recipe-path recipe.json
# Builder stage - builds dependencies then app
FROM chef AS builder
# Install OpenSSH development packages
RUN apt-get update && \
apt-get install -y pkg-config libssl-dev && \
rm -rf /var/lib/apt/lists/*
COPY --from=planner /app/recipe.json recipe.json
# Build dependencies (this layer is cached)
RUN cargo chef cook --release --recipe-path recipe.json
# Copy source and build app
COPY . .
RUN cargo build --release
# Runtime stage - use Debian Trixie to match builder GLIBC
FROM debian:trixie-slim AS runtime
WORKDIR /app
# Install CA certificates, OpenSSL runtime, openssh-client, curl, and cloudflared
RUN apt-get update && \
apt-get install -y ca-certificates libssl3t64 openssh-client curl && \
curl -L https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64 -o /usr/local/bin/cloudflared && \
chmod +x /usr/local/bin/cloudflared && \
apt-get remove -y curl && \
apt-get autoremove -y && \
rm -rf /var/lib/apt/lists/*
# Create SSH config for Cloudflare tunnel access
RUN mkdir -p /root/.ssh && \
echo "Host *.cnctd.world" > /root/.ssh/config && \
echo " ProxyCommand /usr/local/bin/cloudflared access ssh --hostname %h" >> /root/.ssh/config && \
echo " StrictHostKeyChecking no" >> /root/.ssh/config && \
chmod 600 /root/.ssh/config && \
chown root:root /root/.ssh/config
# Copy binary from builder
COPY --from=builder /app/target/release/cnctd-service-ssh /app/ssh
EXPOSE 8080
CMD ["/app/ssh"]