# MyCode images, built from this source tree (not from npm).
#   app   : backend (hydrooj + ui-default + packages/mycode), runs as an unprivileged user
#   judge : language toolchains + go-judge sandbox + the same /app tree
# The toolchain layer (judge-base) does not depend on the source, so code changes do not
# re-download compilers.
# Build from the repository root:  docker build -f deploy/Dockerfile --target app .

# Pinned toolchains, copied from official images (faster and more reproducible than apt).
FROM golang:1.23-bookworm AS go
FROM rust:1.83-slim-bookworm AS rust
FROM eclipse-temurin:17-jdk-jammy AS jdk

FROM node:22-bookworm AS judge-base
# The base image already provides gcc/g++ 12, python3 3.11, curl.
# Everything submitted programs may execute lives under /usr (mounted read-only in the sandbox).
COPY --from=go /usr/local/go /usr/local/go
COPY --from=rust /usr/local/rustup/toolchains /usr/local/rustup/toolchains
COPY --from=jdk /opt/java/openjdk /usr/lib/jvm/temurin-17
RUN ln -sf /usr/local/go/bin/go /usr/bin/go \
 && ln -sf /usr/local/go/bin/gofmt /usr/bin/gofmt \
 && ln -sf "$(ls -d /usr/local/rustup/toolchains/*/bin)/rustc" /usr/bin/rustc \
 && for b in java javac jar; do ln -sf /usr/lib/jvm/temurin-17/bin/$b /usr/bin/$b; done \
 && ln -sf /usr/local/bin/node /usr/bin/node \
 && gcc --version | head -1 && g++ --version | head -1 && python3 --version && go version \
 && rustc --version && javac -version && node --version
ARG GO_JUDGE_VERSION=1.14.0
ARG GO_JUDGE_SHA256=
RUN curl -fsSL -o /usr/local/bin/go-judge \
      "https://github.com/criyle/go-judge/releases/download/v${GO_JUDGE_VERSION}/go-judge_${GO_JUDGE_VERSION}_linux_amd64v3" \
 && if [ -n "$GO_JUDGE_SHA256" ]; then echo "$GO_JUDGE_SHA256  /usr/local/bin/go-judge" | sha256sum -c -; fi \
 && chmod 755 /usr/local/bin/go-judge

FROM node:22-bookworm AS app
ENV CI=true YARN_ENABLE_TELEMETRY=0 COREPACK_ENABLE_DOWNLOAD_PROMPT=0
WORKDIR /app
COPY . .
# Exact source of this build, served at /source.tar.gz (AGPL-3.0 section 13).
# .dockerignore keeps secrets, node_modules and build output out of the context.
RUN tar -czf /opt/mycode-source.tar.gz -C /app . \
 && corepack enable \
 && yarn install --immutable \
 && yarn build \
 && yarn build:ui:iconfont \
 && NODE_OPTIONS=--max_old_space_size=8192 yarn build:ui:production:webpack \
 && yarn cache clean --all
ENV CI= NODE_ENV=production HOME=/data/home NODE_APP_INSTANCE=0
COPY deploy/backend-entrypoint.sh /usr/local/bin/mycode-backend
RUN chmod 755 /usr/local/bin/mycode-backend
EXPOSE 8888
CMD ["mycode-backend"]

FROM judge-base AS judge
COPY --from=app /app /app
COPY deploy/judge/mount.yaml /etc/mycode/mount.yaml
COPY deploy/judge-entrypoint.sh /usr/local/bin/mycode-judge
RUN chmod 755 /usr/local/bin/mycode-judge
ENV HOME=/root NODE_ENV=production
CMD ["mycode-judge"]
