FROM julia:1.12.5-trixie AS builder

RUN apt-get update && apt-get install -y build-essential && rm -rf /var/lib/apt/lists/*

ENV JULIA_DEPOT_PATH="/opt/julia_depot"
ENV HOME="/tmp"
# Generic setup to avoid problems with re-precompilation on different architectures
# Loses performance but greatly improves startup times. The image might also be more
# bloated.
ENV JULIA_CPU_TARGET="generic"

WORKDIR /app

COPY Project.toml Manifest.toml ./
RUN julia -e 'using Pkg; Pkg.add("PackageCompiler")'
RUN julia --project=/app -e 'using Pkg; Pkg.instantiate()'

# Use a placeholder source file so dependency setup is stable until server code changes.
RUN mkdir -p src && echo "module CodeExecutionServer; end" > src/CodeExecutionServer.jl
COPY scripts/build_sysimage.jl scripts/precompile_workload.jl ./scripts/

# Build worker-only sysimage (Oscar/IOCapture/Distributed).
RUN julia --project=/app scripts/build_sysimage.jl

COPY src/ ./src/
COPY scripts/run_server.jl ./scripts/run_server.jl

# Precompile the project with the real server code. JULIA_CPU_TARGET (set
# above) makes these package images portable, so the server process reuses
# them at runtime instead of recompiling on first load.
RUN julia --project=/app -e 'using Pkg; Pkg.precompile()'

# Warm the worker startup path: precompile CodeExecutionServer and its deps
# against the worker sysimage - a separate pkgimage cache, keyed to that
# sysimage. Flags mirror spawn_workers' addprocs call so the cache the
# workers look up at runtime is exactly the one baked here, and no worker
# precompiles on its own.
RUN julia --sysimage=/app/worker_sysimage.so --project=/app -t 2,1 -e 'using CodeExecutionServer'


FROM julia:1.12.5-trixie AS runtime

ENV JULIA_DEPOT_PATH="/opt/julia_depot"
ENV HOME="/tmp"
# Must match the builder's value exactly
ENV JULIA_CPU_TARGET="generic"

WORKDIR /app

RUN useradd -m -s /bin/bash sandbox

# Copy only runtime artifacts from builder stage.
COPY --from=builder --chown=sandbox:sandbox /opt/julia_depot /opt/julia_depot
COPY --from=builder --chown=sandbox:sandbox /app/Project.toml /app/Manifest.toml ./
COPY --from=builder --chown=sandbox:sandbox /app/src ./src
COPY --from=builder --chown=sandbox:sandbox /app/scripts/run_server.jl ./scripts/
COPY --from=builder --chown=sandbox:sandbox /app/worker_sysimage.so /app/worker_sysimage.so

ENV WORKER_SYSIMAGE_PATH="/app/worker_sysimage.so"

USER sandbox

EXPOSE 8080

CMD ["julia", "--project=/app", "scripts/run_server.jl"]
