Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,44 @@
# Version control
.git
.gitignore
.gitattributes
.gitmodules
.github

# Documentation & metadata
README.md
LICENSE.md
CLAUDE.md
docs/

# Kubernetes manifests
k8/

# IDE & OS files
.idea/
*.swp
*.swo
*~
**/.DS_Store

# Build artifacts & temp files
*.o
*.bs
*.pid
*.pm.tdy
logs/*
tmp/*

# Local data (mounted at runtime, not baked in)
webwork-open-problem-library/
private/

# Node modules (npm install runs in Dockerfile)
node_modules
public/node_modules
lib/PG/htdocs/node_modules

# Generated assets (built in Dockerfile)
public/**/*.min.js
public/**/*.min.css
public/static-assets.json
69 changes: 69 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
name: Integration Tests

on:
push:
branches: [main, development]
pull_request:
branches: [main, development]

jobs:
test:
runs-on: ubuntu-latest
timeout-minutes: 20

steps:
- name: Checkout with submodules
uses: actions/checkout@v4
with:
submodules: recursive

- name: Build Docker image
run: docker build -t renderer-test .

- name: Start container
run: |
docker run -d \
--name renderer-test \
-p 3000:3000 \
-e MOJO_MODE=development \
-v "${{ github.workspace }}/t/ci/fixtures:/usr/app/private/test:ro" \
renderer-test \
morbo -l 'http://*:3000' ./script/renderer

- name: Wait for health
run: |
for i in $(seq 1 30); do
if curl -sf --max-time 5 http://localhost:3000/health >/dev/null 2>&1; then
echo "Renderer healthy after $((i * 2))s"
exit 0
fi
sleep 2
done
echo "Renderer failed to start"
docker logs renderer-test 2>&1 | tail -50
exit 1

- name: PG unit tests (informational)
continue-on-error: true
run: |
docker exec renderer-test bash -c \
'export PG_ROOT=/usr/app/lib/PG && cd $PG_ROOT && prove -lr \
t/macros t/contexts t/math_objects t/pg_problems t/units'

- name: Smoke tests
run: bash t/ci/01-smoke.sh

- name: Render parity tests
run: bash t/ci/02-render-parity.sh

- name: Answer cycle tests
run: bash t/ci/03-answer-cycle.sh

- name: Endpoint tests
run: bash t/ci/04-endpoints.sh

- name: Cleanup
if: always()
run: |
docker stop renderer-test 2>/dev/null || true
docker rm renderer-test 2>/dev/null || true
63 changes: 57 additions & 6 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
FROM ubuntu:20.04
# Stage 1: Builder — install all build tools, compile Perl XS modules, generate JS/CSS assets
FROM ubuntu:24.04 AS builder
LABEL org.opencontainers.image.source=https://github.com/openwebwork/renderer

WORKDIR /usr/app
Expand Down Expand Up @@ -41,12 +42,13 @@ RUN apt-get update \
libdata-structure-util-perl \
liblocale-maketext-lexicon-perl \
libyaml-libyaml-perl \
&& curl -fsSL https://deb.nodesource.com/setup_16.x | bash - \
&& curl -fsSL https://deb.nodesource.com/setup_22.x | bash - \
&& apt-get install -y --no-install-recommends --no-install-suggests nodejs \
&& apt-get clean \
&& rm -fr /var/lib/apt/lists/* /tmp/*

RUN cpanm install Mojo::Base Statistics::R::IO::Rserve Date::Format Future::AsyncAwait Crypt::JWT IO::Socket::SSL CGI::Cookie \
COPY cpanfile .
RUN cpanm --installdeps . \
&& rm -fr ./cpanm /root/.cpanm /tmp/*

COPY . .
Expand All @@ -55,12 +57,61 @@ RUN cp renderer.conf.dist renderer.conf

RUN cp conf/pg_config.yml lib/PG/conf/pg_config.yml

RUN cd public/ && npm install && cd ..
# Install all npm deps (including devDependencies for asset generation),
# then prune to production-only for the runtime image.
RUN cd public/ && npm install && npm prune --omit=dev && cd ..

RUN cd lib/PG/htdocs && npm install && cd ../../..
RUN cd lib/PG/htdocs && npm install && npm prune --omit=dev && cd ../../..

# Stage 2: Runtime — only what's needed to serve requests
FROM ubuntu:24.04

LABEL org.opencontainers.image.source=https://github.com/openwebwork/renderer

WORKDIR /usr/app
ARG DEBIAN_FRONTEND=noninteractive
ENV TZ=America/New_York

RUN apt-get update \
&& apt-get install -y --no-install-recommends --no-install-suggests \
apt-utils \
curl \
dvipng \
openssl \
libgd-perl \
imagemagick \
libdbi-perl \
libjson-perl \
libcgi-pm-perl \
libjson-xs-perl \
ca-certificates \
libstorable-perl \
libdatetime-perl \
libuuid-tiny-perl \
libtie-ixhash-perl \
libhttp-async-perl \
libnet-ssleay-perl \
libarchive-zip-perl \
libcrypt-ssleay-perl \
libclass-accessor-perl \
libstring-shellquote-perl \
libproc-processtable-perl \
libmath-random-secure-perl \
libdata-structure-util-perl \
liblocale-maketext-lexicon-perl \
libyaml-libyaml-perl \
&& apt-get clean \
&& rm -fr /var/lib/apt/lists/* /tmp/*

# Copy cpanm-installed Perl modules (XS .so + pure Perl) and Mojo binaries.
# Copies all of /usr/local/ to stay architecture-independent (avoids hardcoding aarch64/x86_64 paths).
COPY --from=builder /usr/local /usr/local

# Copy the full app tree (includes pruned node_modules and generated assets)
COPY --from=builder /usr/app /usr/app

EXPOSE 3000

HEALTHCHECK CMD curl -I localhost:3000/health

CMD hypnotoad -f ./script/renderer
CMD ["hypnotoad", "-f", "./script/renderer"]
64 changes: 58 additions & 6 deletions Dockerfile_with_OPL
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
FROM ubuntu:20.04
# Stage 1: Builder — install all build tools, compile Perl XS modules, generate JS/CSS assets
FROM ubuntu:24.04 AS builder
LABEL org.opencontainers.image.source=https://github.com/openwebwork/renderer

WORKDIR /usr/app
Expand Down Expand Up @@ -41,12 +42,13 @@ RUN apt-get update \
libdata-structure-util-perl \
liblocale-maketext-lexicon-perl \
libyaml-libyaml-perl \
&& curl -fsSL https://deb.nodesource.com/setup_16.x | bash - \
&& curl -fsSL https://deb.nodesource.com/setup_22.x | bash - \
&& apt-get install -y --no-install-recommends --no-install-suggests nodejs \
&& apt-get clean \
&& rm -fr /var/lib/apt/lists/* /tmp/*

RUN cpanm install Mojo::Base Statistics::R::IO::Rserve Date::Format Future::AsyncAwait Crypt::JWT IO::Socket::SSL CGI::Cookie \
COPY cpanfile .
RUN cpanm --installdeps . \
&& rm -fr ./cpanm /root/.cpanm /tmp/*

ENV MOJO_MODE=production
Expand All @@ -66,12 +68,62 @@ RUN cp renderer.conf.dist renderer.conf

RUN cp conf/pg_config.yml lib/PG/conf/pg_config.yml

RUN npm install
# Install all npm deps (including devDependencies for asset generation),
# then prune to production-only for the runtime image.
RUN cd public/ && npm install && npm prune --omit=dev && cd ..

RUN cd lib/PG/htdocs && npm install && cd ../../..
RUN cd lib/PG/htdocs && npm install && npm prune --omit=dev && cd ../../..

# Stage 2: Runtime — only what's needed to serve requests
FROM ubuntu:24.04

LABEL org.opencontainers.image.source=https://github.com/openwebwork/renderer

WORKDIR /usr/app
ARG DEBIAN_FRONTEND=noninteractive
ENV TZ=America/New_York
ENV MOJO_MODE=production

RUN apt-get update \
&& apt-get install -y --no-install-recommends --no-install-suggests \
apt-utils \
curl \
dvipng \
openssl \
libgd-perl \
imagemagick \
libdbi-perl \
libjson-perl \
libcgi-pm-perl \
libjson-xs-perl \
ca-certificates \
libstorable-perl \
libdatetime-perl \
libuuid-tiny-perl \
libtie-ixhash-perl \
libhttp-async-perl \
libnet-ssleay-perl \
libarchive-zip-perl \
libcrypt-ssleay-perl \
libclass-accessor-perl \
libstring-shellquote-perl \
libproc-processtable-perl \
libmath-random-secure-perl \
libdata-structure-util-perl \
liblocale-maketext-lexicon-perl \
libyaml-libyaml-perl \
&& apt-get clean \
&& rm -fr /var/lib/apt/lists/* /tmp/*

# Copy cpanm-installed Perl modules (XS .so + pure Perl) and Mojo binaries.
# Copies all of /usr/local/ to stay architecture-independent (avoids hardcoding aarch64/x86_64 paths).
COPY --from=builder /usr/local /usr/local

# Copy the full app tree (includes OPL, pruned node_modules, and generated assets)
COPY --from=builder /usr/app /usr/app

EXPOSE 3000

HEALTHCHECK CMD curl -I localhost:3000/health

CMD hypnotoad -f ./script/renderer
CMD ["hypnotoad", "-f", "./script/renderer"]
Loading