# WyOJ web image. # # Build context is the REPOSITORY ROOT (see ../docker-compose.yml): # docker build -t wyoj-web -f web/Dockerfile . # # The context has to be the root because the web image also needs the judger # tree: # * uoj_judger/run/formatter -- used by dataSyncProblemData() on the web # * uoj_judger/include/testlib.h -- served by /download.php # * judge_client.zip -- served by /judge/download/judger # ../.dockerignore keeps the database dump and ./uoj_data out of the context. # # v8js is needed by app/models/UOJBlogEditor.php (markdown -> HTML), and the # yaml extension by yaml_parse() in that same file. # # NOTE on web/v8js.zip: it is a 397 KB local tarball (upstream phpv8/v8js, # patched build used in production) and is tracked by git on purpose, so that a # clean clone builds without network access to github.com. If you would rather # not track it: add it back to .gitignore and replace the COPY below with # RUN git clone --depth=1 https://github.com/phpv8/v8js.git /tmp/pear/download/v8js # (note: `git clone -b ` does not work with a raw commit id). FROM ubuntu:20.04 LABEL org.opencontainers.image.source=https://git.ryp.org.cn/wyoj/wyoj-raw LABEL org.opencontainers.image.description="WyOJ Web" LABEL org.opencontainers.image.licenses=MIT ENV DEBIAN_FRONTEND=noninteractive # --------------------------------------------------------------------------- # System packages # # libv8 7.5 only exists in the bionic PPA, hence the mixed release. Importing # the PPA key from a keyserver is flaky (and keyserver.ubuntu.com may be # unreachable); if it fails we mark just that one repo trusted so the build # does not depend on a keyserver being up. # --------------------------------------------------------------------------- RUN dpkg -s gnupg >/dev/null 2>&1 || (apt-get update && apt-get install -y gnupg); \ echo "deb http://ppa.launchpad.net/stesie/libv8/ubuntu bionic main" \ > /etc/apt/sources.list.d/stesie-libv8.list; \ if ! apt-key adv --keyserver keyserver.ubuntu.com --recv-keys D858A0DF; then \ echo "WARN: could not import the libv8 PPA key; marking that repo trusted"; \ sed -i 's|^deb |deb [trusted=yes] |' /etc/apt/sources.list.d/stesie-libv8.list; \ fi; \ apt-get update && apt-get install -y \ git vim ntp zip unzip curl wget \ apache2 libapache2-mod-xsendfile libapache2-mod-php \ php php-dev php-pear php-zip php-mysql php-mbstring php-gd php-intl php-xsl \ g++ make re2c libv8-7.5-dev libyaml-dev && \ yes | pecl install yaml && \ rm -rf /var/lib/apt/lists/* # --------------------------------------------------------------------------- # v8js + yaml extensions # --------------------------------------------------------------------------- COPY web/v8js.zip /tmp/pear/download/ RUN set -eux; \ cd /tmp/pear/download; \ unzip -q v8js.zip; \ cd v8js; \ phpize; \ ./configure --with-php-config=/usr/bin/php-config --with-v8js=/opt/libv8-7.5; \ make -j"$(nproc)"; \ make install; \ cd /; \ rm -rf /tmp/pear/download/v8js # Enable the extensions for both SAPIs instead of patching php.ini by line # number (the old `sed -i '912a\...' /etc/php/7.4/apache2/php.ini` broke the # moment the base image changed). RUN set -eux; \ for sapi in apache2 cli; do \ printf 'extension=v8js.so\nextension=yaml.so\n' > "/etc/php/7.4/${sapi}/conf.d/20-uoj.ini"; \ done; \ php -m | grep -qx v8js; \ php -m | grep -qx yaml # --------------------------------------------------------------------------- # Judger tree # # The web needs this too (see the header comment). Only run/formatter is # actually executed here; the judge clients' self-update zip is built from the # sources so that they recompile it themselves (judge_client runs # `make clean && make` after unzipping). # # The zip is written to /opt/uoj/judge_client.zip, *not* into app/storage -- # app/storage is a bind mount at runtime and would shadow it. install.sh -i # copies it into place. # --------------------------------------------------------------------------- COPY judger /opt/uoj/judger RUN set -eux; \ make -C /opt/uoj/judger/uoj_judger run/formatter -j"$(nproc)"; \ cd /opt/uoj/judger; \ zip -q -r -y /opt/uoj/judge_client.zip judge_client uoj_judger \ -x 'uoj_judger/data' 'uoj_judger/data/*' \ 'uoj_judger/work/*' 'uoj_judger/result/*' \ 'uoj_judger/run/formatter' \ 'log/*' '*.o'; \ unzip -l /opt/uoj/judge_client.zip | tail -2 # --------------------------------------------------------------------------- # Application # # ADD comes last so that editing PHP/CSS only invalidates the cheap layers. # `install.sh -p` prepares apache/php config and the /var/www/uoj symlink; it # does not touch the database (that happens at container start). # --------------------------------------------------------------------------- ADD web /opt/uoj/web WORKDIR /opt/uoj/web RUN chmod +x install.sh docker-entrypoint.sh && bash install.sh -p ENV LANG=C.UTF-8 TZ=Asia/Shanghai EXPOSE 80 CMD ["/bin/sh", "/opt/uoj/web/docker-entrypoint.sh"]