# Multi-stage Dockerfile for socktop webterm # This reduces the final image size significantly by separating build and runtime # ============================================================================ # Stage 1: Rust Builder # ============================================================================ FROM rust:1.90-slim-bookworm AS rust-builder WORKDIR /build # Install build dependencies RUN apt-get update && \ apt-get install -y --no-install-recommends \ pkg-config \ libssl-dev \ && rm -rf /var/lib/apt/lists/* # Copy only dependency files first for better caching COPY Cargo.toml Cargo.lock ./ # Create dummy source to cache dependencies RUN mkdir src && \ echo "fn main() {}" > src/server.rs && \ echo "pub fn lib() {}" > src/lib.rs && \ cargo build --release && \ rm -rf src target/release/webterm-server target/release/deps/webterm* # Copy actual source code COPY src ./src COPY templates ./templates COPY static ./static # Build the actual application (force rebuild by touching sources) RUN touch src/server.rs src/lib.rs && \ cargo build --release && \ strip target/release/webterm-server # ============================================================================ # Stage 2: Node.js Builder # ============================================================================ FROM node:20-slim AS node-builder WORKDIR /build # Copy package files COPY package.json package-lock.json ./ COPY static ./static # Install only production dependencies RUN npm ci --only=production && \ # Copy static files to node_modules for serving cp static/terminado-addon.js node_modules/ && \ cp static/bg.png node_modules/ && \ cp static/styles.css node_modules/ && \ cp static/terminal.js node_modules/ && \ cp static/favicon.png node_modules/ # ============================================================================ # Stage 3: Runtime Image # ============================================================================ FROM debian:trixie-slim # Avoid prompts from apt ENV DEBIAN_FRONTEND=noninteractive ENV TERM=xterm-256color # Install only runtime dependencies RUN apt-get update && \ apt-get upgrade -y && \ apt-get install -y --no-install-recommends \ # Runtime libraries libssl3 \ ca-certificates \ # For socktop packages curl \ gnupg2 \ # Shell and utilities bash \ procps \ # Health check curl \ && rm -rf /var/lib/apt/lists/* # Add socktop APT repository and install packages RUN curl -fsSL https://jasonwitty.github.io/socktop/KEY.gpg | \ gpg --dearmor -o /usr/share/keyrings/socktop-archive-keyring.gpg && \ echo "deb [signed-by=/usr/share/keyrings/socktop-archive-keyring.gpg] https://jasonwitty.github.io/socktop stable main" > /etc/apt/sources.list.d/socktop.list && \ apt-get update && \ apt-get install -y --no-install-recommends socktop socktop-agent && \ rm -rf /var/lib/apt/lists/* # Create application user (if not already exists from socktop packages) RUN id -u socktop &>/dev/null || useradd -m -s /bin/bash socktop && \ mkdir -p /home/socktop/.config/socktop && \ chown -R socktop:socktop /home/socktop # Set working directory WORKDIR /app # Copy built binary from rust-builder COPY --from=rust-builder /build/target/release/webterm-server /usr/local/bin/webterm-server # Copy templates and static files COPY --from=rust-builder /build/templates ./templates COPY --from=rust-builder /build/static ./static # Copy node_modules from node-builder COPY --from=node-builder /build/node_modules ./node_modules # Copy runtime scripts COPY docker/entrypoint.sh /entrypoint.sh RUN chmod +x /entrypoint.sh # Expose ports # 8082 - webterm HTTP server # 3001 - socktop agent (if used) EXPOSE 8082 3001 # Health check HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ CMD curl -f http://localhost:8082/ || exit 1 # Run as socktop user USER socktop # Set entrypoint ENTRYPOINT ["/entrypoint.sh"] # Default command - run webterm server CMD ["webterm-server", "--host", "0.0.0.0", "--port", "8082"]