diff --git a/.github/workflows/build_and_push_docker.yml b/.github/workflows/build_and_push_docker.yml index 621a25ca..18b63d3d 100644 --- a/.github/workflows/build_and_push_docker.yml +++ b/.github/workflows/build_and_push_docker.yml @@ -9,6 +9,7 @@ on: inputs: version: required: false + description: 'Select which branch/version of DOMjudge/DOMjudge to use' env: REGISTRY: ghcr.io diff --git a/.github/workflows/shellcheck.yml b/.github/workflows/shellcheck.yml index 99cb18cd..c6fd65e9 100644 --- a/.github/workflows/shellcheck.yml +++ b/.github/workflows/shellcheck.yml @@ -7,9 +7,6 @@ on: pull_request: branches: - main - pull_request_target: - branches: - - main jobs: shellcheck: diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml deleted file mode 100644 index 2d94c460..00000000 --- a/.gitlab-ci.yml +++ /dev/null @@ -1,148 +0,0 @@ -include: '.tarball-release.yml' - -image: docker:latest - -stages: - - test - - deploy - -variables: - FF_DISABLE_UMASK_FOR_DOCKER_EXECUTOR: "true" # see https://gitlab.com/gitlab-org/gitlab-runner/-/issues/1736 - GITLABCI_VERSION: "2.1" - GITLABCI_IMAGE: "gitlabci" - CONTRIBUTOR_IMAGE: "domjudge/domjudge-contributor" - DOMJUDGE_VERSION: - value: "M.m.pp" - description: "The DOMjudge version, Change this variable to 7.3.3 to release the 7.3.3 dockers. The file should be available on the domjudge.org webserver." - DOMJUDGE_LATEST: - value: "true" - description: "Whether this is the latest release" - -# Docker Login steps -.release_template: &release_docker - services: - - docker:dind - -.registry_template: ®istry_gitlab - <<: *release_docker - stage: test - before_script: - - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY - -.registry_template: ®istry_dockerhub - <<: *release_docker - stage: deploy - before_script: - - docker login -u $DOCKER_HUB_USERNAME -p $DOCKER_HUB_ACCESS_TOKEN - -.job_template: &job_check-pr - stage: test - services: - - docker:dind - except: - - main - -.matrix_contributor_template: &matrix_contributor_template - timeout: 90 minutes - parallel: - matrix: - - ARCH: [amd64, arm64v8] - -.job_template: &ci_template - script: - - cd docker-gitlabci - - > - if [[ -z $DOCKER_HUB_USERNAME ]]; then - BASE=$CI_REGISTRY_IMAGE/$GITLABCI_IMAGE - else - BASE="domjudge/"$GITLABCI_IMAGE - fi - - sh ./build.sh $GITLABCI_VERSION $BASE - - docker push $BASE:$GITLABCI_VERSION - -pr-ci: - <<: *registry_gitlab - <<: *ci_template - except: - - main - -release-ci: - <<: *registry_dockerhub - <<: *ci_template - only: - refs: - - main - -check-pr-contributor: - <<: *job_check-pr - <<: *matrix_contributor_template - script: - - cd docker-contributor - - docker pull $CONTRIBUTOR_IMAGE:${ARCH} || true - - docker build --build-arg ARCH=${ARCH}/ . - -release-contributor-arch: - <<: *registry_dockerhub - <<: *matrix_contributor_template - only: - refs: - - main - script: - - cd docker-contributor - - docker pull $CONTRIBUTOR_IMAGE:${ARCH} || true - - docker build -t $CONTRIBUTOR_IMAGE:${ARCH} --build-arg ARCH=${ARCH}/ . - - docker push $CONTRIBUTOR_IMAGE:${ARCH} - -release-contributor-latest: - <<: *registry_dockerhub - only: - refs: - - main - needs: - - release-contributor-arch - script: - - docker manifest create $CONTRIBUTOR_IMAGE:latest -a $CONTRIBUTOR_IMAGE:amd64 -a $CONTRIBUTOR_IMAGE:arm64v8 - - docker manifest push $CONTRIBUTOR_IMAGE:latest - -release-DOMjudge: - <<: *registry_dockerhub - when: manual - allow_failure: false - only: - - main - script: - - cd docker - - sh ./build.sh $DOMJUDGE_VERSION - - > - for IMG in domserver judgehost default-judgehost-chroot; do - docker push domjudge/$IMG:$DOMJUDGE_VERSION - if [ ${DOMJUDGE_LATEST} == "true" ]; then - docker tag domjudge/$IMG:$DOMJUDGE_VERSION domjudge/$IMG:latest - docker push domjudge/$IMG:latest - fi - done - -check-pr-DOMjudge: - <<: *job_check-pr - script: - - set -x - - HUBURL="https://registry.hub.docker.com/v2/repositories/domjudge/domserver/tags" - - apk add jq curl - - TAG=$(curl $HUBURL|jq '.results | sort_by(.name) | .[length-2].name') - - TAG=${TAG//\"} - - cd docker - - sh ./build.sh "$TAG" - - | - # check that there are no world-writable files - # (this is mainly a regression test for FF_DISABLE_UMASK_FOR_DOCKER_EXECUTOR) - # ignore symbolic links, because they always have mode "rwxrwxrwx" - # ignore directories with restricted deletion flag (e.g. /tmp), because they are fine - # ignore character devices (e.g. /chroot/domjudge/dev/* in image domjudge/judgehost are fine) - for IMG in domserver judgehost; do - files=$(docker run --rm --pull=never "domjudge/$IMG:$TAG" find / -xdev -perm -o+w ! -type l ! \( -type d -a -perm -+t \) ! -type c) - if [ -n "$files" ]; then - echo "error: image docker/$IMG contains world-writable files:" >&2 - printf "%s\n" "$files" >&2 - exit 1 - fi - done diff --git a/.tarball-release.yml b/.tarball-release.yml deleted file mode 100644 index 705627e9..00000000 --- a/.tarball-release.yml +++ /dev/null @@ -1,29 +0,0 @@ -# The jobs to do a manual DOMjudge release -createtar: - stage: test - when: manual - image: domjudge/gitlabci:2.1 - script: - - echo -e "\e[0Ksection_start:`date +%s`:buildrelease\r\e[0KBuild of release tarball" - - wget https://raw.githubusercontent.com/DOMjudge/domjudge-scripts/main/make_release.sh - - sh ./make_release.sh $DOMJUDGE_VERSION - - echo -e "\e[0Ksection_end:`date +%s`:buildrelease\r\e[0K" - - echo -e "\e[0Ksection_start:`date +%s`:aptpackages\r\e[0KInstall the expected packages for new release" - - apt update - - apt install -y acl zip unzip mariadb-server apache2 php php-fpm php-gd php-cli php-intl php-mbstring php-mysql php-curl php-json php-xml php-zip composer ntp - - apt install -y make pkg-config sudo debootstrap libcgroup-dev php-cli php-curl php-json php-xml php-zip lsof procps - - echo -e "\e[0Ksection_end:`date +%s`:aptpackages\r\e[0K" - - echo -e "\e[0Ksection_start:`date +%s`:testtar\r\e[0KTest the release tarball" - - tar zxvf domjudge-${DOMJUDGE_VERSION}.tar.gz - - cd domjudge-${DOMJUDGE_VERSION} - - ./configure - - make build - - make clean - - make all - - make clean - - make docs - - make clean - - make submitclient - - echo -e "\e[0Ksection_end:`date +%s`:testtar\r\e[0K" - - echo "See the new_release_howto.txt (L28/domjudge-scripts) for the next step." - diff --git a/docker-contributor/Dockerfile b/docker-contributor/Dockerfile index 85780c97..86a97ff4 100644 --- a/docker-contributor/Dockerfile +++ b/docker-contributor/Dockerfile @@ -1,9 +1,11 @@ ARG ARCH= -FROM "${ARCH}ubuntu:jammy" +FROM "${ARCH}ubuntu:noble" LABEL maintainer="DOMjudge team " ENV DEBIAN_FRONTEND=noninteractive \ CONTAINER_TIMEZONE=Europe/Amsterdam \ + UID=1000 \ + GID=1000 \ MYSQL_HOST=mariadb \ MYSQL_USER=domjudge \ MYSQL_DATABASE=domjudge \ @@ -12,25 +14,26 @@ ENV DEBIAN_FRONTEND=noninteractive \ FPM_MAX_CHILDREN=40 \ DJ_SKIP_MAKE=0 \ DJ_DB_INSTALL_BARE=0 \ - PHPSUPPORTED="7.2 7.3 7.4 8.0 8.1 8.2" \ - DEFAULTPHPVERSION="8.1" \ - APTINSTALL="apt install -y -o Dpkg::Options::=--force-confdef -o Dpkg::Options::=--force-confold" + PHPSUPPORTED="8.1 8.2 8.3 8.4" \ + DEFAULTPHPVERSION="8.4" \ + DEFAULTWEBSERVER="nginx" \ + APTINSTALL="apt-get install -y -o Dpkg::Options::=--force-confdef -o Dpkg::Options::=--force-confold" # Install required packages and clean up afterwards to make this image layer smaller -RUN apt update \ - && apt install --no-install-recommends --no-install-suggests -y \ - dumb-init autoconf automake git acl \ +RUN apt-get update \ + && apt-get install --no-install-recommends --no-install-suggests -y \ + curl dumb-init autoconf automake git acl \ gcc g++ make zip unzip mariadb-client \ - nginx php8.1 php8.1-cli php8.1-fpm php8.1-zip \ - php8.1-gd php8.1-curl php8.1-mysql php8.1-intl \ - php8.1-gmp php8.1-xml php8.1-mbstring php8.1-xdebug php8.1-pcov \ - bsdmainutils ntp \ + nginx php8.3 php8.3-cli php8.3-fpm php8.3-zip \ + php8.3-gd php8.3-curl php8.3-mysql php8.3-intl \ + php8.3-gmp php8.3-xml php8.3-mbstring php8.3-xdebug php8.3-pcov \ + bsdmainutils ntp lsof \ linuxdoc-tools linuxdoc-tools-text groff \ python3-sphinx python3-sphinx-rtd-theme python3-pip fontconfig python3-yaml \ texlive-latex-recommended texlive-latex-extra \ texlive-fonts-recommended texlive-lang-european latexmk \ sudo debootstrap libcgroup-dev procps \ - default-jre-headless default-jdk \ + default-jre-headless default-jdk-headless \ supervisor apache2-utils lsb-release \ libcurl4-gnutls-dev libjsoncpp-dev libmagic-dev \ enscript lpr ca-certificates less vim \ @@ -42,36 +45,37 @@ RUN ln -sf /dev/stdout /var/log/nginx/access.log \ && ln -sf /dev/stderr /var/log/nginx/error.log \ && mkdir -p /run/php +# Remove default ubuntu user +RUN userdel ubuntu && groupdel ubuntu || true # Set up users -RUN useradd -m domjudge \ +RUN groupadd -g $GID domjudge \ + && useradd -u $UID -g $GID -m domjudge \ && groupadd domjudge-run \ && for id in $(seq 0 4); do useradd -d /nonexistent -g nogroup -s /bin/false "domjudge-run-$id"; done # Install composer -RUN apt update && \ - apt install --no-install-recommends --no-install-suggests -y ca-certificates \ - && rm -rf /var/lib/apt/lists/* \ - && php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" && php composer-setup.php \ +RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" && php composer-setup.php \ && mv /composer.phar /usr/local/bin/composer # Install all supported PHP versions -RUN add-apt-repository ppa:ondrej/php -y && apt update -RUN for VERSION in $PHPSUPPORTED; do \ - if [ "${VERSION}" != "8.1" ]; then \ +RUN add-apt-repository ppa:ondrej/php -y && apt-get update && \ + for VERSION in $PHPSUPPORTED; do \ + if [ "${VERSION}" != "8.3" ]; then \ $APTINSTALL php${VERSION}; \ fi; \ - done -RUN PACKAGES=$(dpkg-query -f '${binary:Package}\n' -W|grep "^php.*-"); \ + done && \ + PACKAGES=$(dpkg-query -f '${binary:Package}\n' -W|grep "^php.*-") && \ for PACKAGE in $PACKAGES; do \ PACKAGEALLVERSIONS="" && \ for VERSION in $PHPSUPPORTED; do \ - if [ "${VERSION}" != "8.1" ]; then \ + if [ "${VERSION}" != "8.3" ]; then \ PACKAGEALLVERSIONS="$PACKAGEALLVERSIONS php${VERSION}-${PACKAGE#php*-}"; \ fi; \ done; \ $APTINSTALL $PACKAGEALLVERSIONS; \ - done -RUN update-alternatives --set php /usr/bin/php${DEFAULTPHPVERSION} + done && \ + update-alternatives --set php /usr/bin/php${DEFAULTPHPVERSION} && \ + rm -rf /var/lib/apt/lists/* # Set up alternatives for PHP-FPM RUN for VERSION in $PHPSUPPORTED; do \ @@ -86,9 +90,25 @@ COPY ["php-config", "/php-config"] RUN for VERSION in $PHPSUPPORTED; do \ cp -Rf /php-config/* /etc/php/${VERSION}/cli/conf.d; \ cp -Rf /php-config/* /etc/php/${VERSION}/fpm/conf.d; \ - done; \ + done; \ rm -Rf /php-config +# Install blackfire probe +RUN for VERSION in $PHPSUPPORTED; do \ + # Blackfire is not available yet for PHP 8.4 + if [ "${VERSION}" != "8.4" ]; then \ + version=$(php${VERSION} -r "echo PHP_MAJOR_VERSION.PHP_MINOR_VERSION.(PHP_ZTS ? '-zts' : '');") \ + && architecture=$(uname -m) \ + && curl -v -A "Docker" -o /tmp/blackfire-probe.tar.gz -D - -L -s https://blackfire.io/api/v1/releases/probe/php/linux/$architecture/$version \ + && mkdir -p /tmp/blackfire \ + && tar zxpf /tmp/blackfire-probe.tar.gz -C /tmp/blackfire \ + && mv /tmp/blackfire/blackfire-*.so $(php${VERSION} -r "echo ini_get ('extension_dir');")/blackfire.so \ + && printf "extension=blackfire.so\nblackfire.agent_socket=tcp://blackfire:8307\n" > /etc/php/${VERSION}/fpm/conf.d/blackfire.ini \ + && printf "extension=blackfire.so\nblackfire.agent_socket=tcp://blackfire:8307\n" > /etc/php/${VERSION}/cli/conf.d/blackfire.ini \ + && rm -rf /tmp/blackfire /tmp/blackfire-probe.tar.gz; \ + fi; \ + done + # Disable Xdebug by default RUN phpdismod xdebug diff --git a/docker-contributor/README.md b/docker-contributor/README.md index 3488b496..41324f83 100644 --- a/docker-contributor/README.md +++ b/docker-contributor/README.md @@ -9,7 +9,7 @@ The container includes the following: * Set up or update the database. * Set up the webserver. * Create a chroot. -* PHP-FPM and nginx for running the web interface. +* PHP-FPM and apache2 or nginx for running the web interface. * Two running judgedaemons using a chroot. * Scripts for reading the log files of the webserver and the judgedaemons. * A script to create a dummy DOMjudge user and submit all test submissions. @@ -37,7 +37,7 @@ Next, if you are on Linux make sure you have cgroups enabled. See the [DOMjudge Now you can run DOMjudge itself using the following command: ```bash -docker run -v [path-to-domjudge-checkout]:[path-to-domjudge-checkout] -v /sys/fs/cgroup:/sys/fs/cgroup:ro --link dj-mariadb:mariadb -it -e PROJECT_DIR=[path-to-domjudge-checkout] -p 12345:80 --name domjudge --privileged domjudge/domjudge-contributor +docker run -v [path-to-domjudge-checkout]:[path-to-domjudge-checkout] -v /sys/fs/cgroup:/sys/fs/cgroup:ro --link dj-mariadb:mariadb -it -e UID="$(id -u)" -e GID="$(id -g)" -e PROJECT_DIR=[path-to-domjudge-checkout] -p 12345:80 --name domjudge --privileged domjudge/domjudge-contributor ``` Make sure you replace `[path-to-domjudge-checkout]` with the path to your local DOMjudge checkout. On recent macOS and Windows Docker builds, you should add `:cached` at the end of the volume (i.e. `-v [path-to-domjudge-checkout]:[path-to-domjudge-checkout]:cached`) to speed up the webserver a lot. @@ -57,6 +57,8 @@ bin/dj_setup_database install-examples The following environment variables are supported by the container: +* `UID` (defaults to `1000`): the ID of the user to run DOMjudge as. Should match the host OS user ID. +* `GID` (defaults to `1000`): the ID of the group to run DOMjudge as. Should match the host OS group ID. * `CONTAINER_TIMEZONE` (defaults to `Europe/Amsterdam`): allows you to change the timezone used inside the container. * `MYSQL_HOST` (defaults to `mariadb`): set the host to connect to for MySQL. Can be hostname or IP. Docker will add hostnames for any containers you `--link`, so in the example above, the MariaDB container will be available under the hostname `mariadb`. * `MYSQL_USER` (defaults to `domjudge`): set the user to use for connecting to MySQL. @@ -65,6 +67,7 @@ The following environment variables are supported by the container: * `MYSQL_DATABASE` (defaults to `domjudge`): set the database to use. * `FPM_MAX_CHILDREN` (defaults to `40`): the maximum number of PHP FPM children to spawn. * `DJ_SKIP_MAKE` (defaults to `0`): set to `1` to skip the maintainer setup and install commands. This will speed up the startup process of the container and is useful if this is already done before. +* `DEFAULTWEBSERVER` (defaults to `nginx`): set to `apache2` to use the Apache2 httpd server as default webserver. #### Passwords through files @@ -95,6 +98,8 @@ If you have named your container something other than `domjudge`, be sure to cha The following commands are available: +* `apache2-access-log`: tail the access log of apache2. +* `apache2-error-log`: tail the error log of apache2. * `nginx-access-log`: tail the access log of nginx. * `nginx-error-log`: tail the error log of nginx. * `judgedaemon-log 0` and `judgedaemon-log 1`: tail the log of the first / second judgeaemon. @@ -103,6 +108,7 @@ The following commands are available: * `xdebug-enable`: enable Xdebug debugging. See note below * `xdebug-disable`: disable Xdebug debugging. See note below * `switch-php `: switch to using the given PHP version. +* `switch-webserver `: switch to using the given webserver. Of course, you can always run `docker exec -it domjudge bash` to get a bash shell inside the container. @@ -112,7 +118,7 @@ To restart any of the services, run the following: docker exec -it domjudge supervisorctl restart [service] ``` -where `[service]` is one of `nginx`, `php`, `judgedaemon0` or `judgedaemon1`. +where `[service]` is one of `apache2`, `nginx`, `php`, `judgedaemon0` or `judgedaemon1`. ### Xdebug diff --git a/docker-contributor/scripts/bin/apache2-access-log b/docker-contributor/scripts/bin/apache2-access-log new file mode 100644 index 00000000..418d6c1b --- /dev/null +++ b/docker-contributor/scripts/bin/apache2-access-log @@ -0,0 +1,2 @@ +#!/bin/bash +supervisorctl tail -f apache2 diff --git a/docker-contributor/scripts/bin/apache2-error-log b/docker-contributor/scripts/bin/apache2-error-log new file mode 100644 index 00000000..be78e366 --- /dev/null +++ b/docker-contributor/scripts/bin/apache2-error-log @@ -0,0 +1,2 @@ +#!/bin/bash +supervisorctl tail -f apache2 stderr diff --git a/docker-contributor/scripts/bin/switch-webserver b/docker-contributor/scripts/bin/switch-webserver new file mode 100644 index 00000000..7db0184c --- /dev/null +++ b/docker-contributor/scripts/bin/switch-webserver @@ -0,0 +1,14 @@ +#!/bin/bash +WEBSERVER=$1 +if [ "${WEBSERVER}" = "nginx" ] +then + sudo supervisorctl stop apache2 + sudo supervisorctl start nginx +elif [ "${WEBSERVER}" = "apache2" ] +then + sudo supervisorctl stop nginx + sudo supervisorctl start apache2 +else + echo "Usage: $0 [apache2|nginx]" + exit 1 +fi diff --git a/docker-contributor/scripts/start.sh b/docker-contributor/scripts/start.sh index 910f7da7..1b085741 100644 --- a/docker-contributor/scripts/start.sh +++ b/docker-contributor/scripts/start.sh @@ -9,6 +9,11 @@ function file_or_env { fi } +echo "[..] Changing user/group ID" +sudo groupmod -g "${GID}" domjudge +sudo usermod -u "${UID}" domjudge +echo "[ok] User ID set to ${UID} and group ID set to ${GID}"; echo + echo "[..] Setting timezone" sudo ln -snf "/usr/share/zoneinfo/${CONTAINER_TIMEZONE}" /etc/localtime echo "${CONTAINER_TIMEZONE}" | sudo tee /etc/timezone @@ -144,6 +149,23 @@ sudo sed -i '/error_log/d' $NGINX_CONFIG_FILE # Use debug front controller sudo sed -i 's/app\.php/app_dev.php/g' $NGINX_CONFIG_FILE sudo sed -i 's/app\\\.php/app\\_dev.php/g' $NGINX_CONFIG_FILE + +# Configure Apache2 +APACHE2_CONFIG_FILE=/etc/apache2/conf-available/domjudge.conf +sudo cp etc/apache.conf $APACHE2_CONFIG_FILE +sudo a2enmod proxy_fcgi setenvif rewrite +sudo cp "/etc/apache2/conf-available/php$DEFAULTPHPVERSION-fpm.conf" /etc/apache2/conf-available/php-domjudge-fpm.conf +sudo sed -i 's/proxy:unix:.*|/proxy:unix:\/var\/run\/php-fpm-domjudge.sock|/' /etc/apache2/conf-available/php-domjudge-fpm.conf +sudo a2enconf php-domjudge-fpm domjudge +sudo rm -f /etc/apache2/sites-enabled/000-default.conf +# Run DOMjudge in root +sudo sed -i '/^#/,/^#<\/VirtualHost>/ s/#//' $APACHE2_CONFIG_FILE +sudo sed -i 's/^Alias \/domjudge/#Alias \/domjudge/' $APACHE2_CONFIG_FILE +# Run as user and group 'domjudge' +sudo sed -i 's//User domjudge\nGroup domjudge\n/' $APACHE2_CONFIG_FILE +# Redirect logs to stdout/stderr +sudo sed -i 's//TransferLog \/dev\/stdout\nErrorLog \/dev\/stderr\n/' $APACHE2_CONFIG_FILE + # Set up permissions (make sure the script does not stop if this fails, as this will happen on macOS / Windows) sudo chown domjudge: "${PROJECT_DIR}/webapp/var" echo "[ok] Webserver config installed"; echo @@ -171,4 +193,14 @@ echo "[ok] Sudoers configuration added"; echo sudo sed -i "s|PROJECT_DIR|${PROJECT_DIR}|" /etc/supervisor/conf.d/judgedaemon.conf sudo sed -i "s|PROJECT_DIR|${PROJECT_DIR}|" /etc/supervisor/conf.d/judgedaemonextra.conf +echo "[..] Configuring default webserver" +if [ "${DEFAULTWEBSERVER}" = "apache2" ] || [ "${DEFAULTWEBSERVER}" = "nginx" ] +then + sudo sed -i "s|autostart=false|autostart=true|" "/etc/supervisor/conf.d/$DEFAULTWEBSERVER.conf" +else + echo "Unsupported webserver '$DEFAULTWEBSERVER'" + exit 1 +fi +echo "[ok] Configured default webserver"; echo + exec sudo supervisord -n -c /etc/supervisor/supervisord.conf diff --git a/docker-contributor/supervisor/apache2.conf b/docker-contributor/supervisor/apache2.conf new file mode 100644 index 00000000..cd8eba5d --- /dev/null +++ b/docker-contributor/supervisor/apache2.conf @@ -0,0 +1,5 @@ +[program:apache2] +command=pidproxy /var/run/apache2/apache2.pid /bin/bash -c "source /etc/apache2/envvars && apache2ctl -D FOREGROUND" +numprocs=1 +autostart=false +autorestart=true diff --git a/docker-contributor/supervisor/nginx.conf b/docker-contributor/supervisor/nginx.conf index 4ac205a1..efebb34c 100644 --- a/docker-contributor/supervisor/nginx.conf +++ b/docker-contributor/supervisor/nginx.conf @@ -1,5 +1,5 @@ [program:nginx] command=nginx -g "daemon off;" numprocs=1 -autostart=true +autostart=false autorestart=true diff --git a/docker-gitlabci/Dockerfile b/docker-gitlabci/Dockerfile index 6a07bb6e..53f44b14 100644 --- a/docker-gitlabci/Dockerfile +++ b/docker-gitlabci/Dockerfile @@ -1,65 +1,61 @@ -FROM ubuntu:20.04 +FROM ubuntu:24.04 ENV DEBIAN_FRONTEND=noninteractive -ENV PHPSUPPORTED="7.2 7.3 8.0 8.1 8.2" -ENV APTINSTALL="apt install -y -o Dpkg::Options::=--force-confdef -o Dpkg::Options::=--force-confold" -RUN apt update && apt install -y \ +ENV PHPSUPPORTED="7.4 8.0 8.1 8.2 8.4" +ENV APTINSTALL="apt-get install -y -o Dpkg::Options::=--force-confdef -o Dpkg::Options::=--force-confold" +RUN useradd -m domjudge +RUN useradd -d /nonexistent -g nogroup -s /bin/false domjudge-run-0 +RUN useradd -d /nonexistent -g nogroup -s /bin/false domjudge-run-1 +RUN groupadd domjudge-run + +RUN apt-get update && apt-get install -y \ acl make zip unzip apache2-utils bsdmainutils libcurl4-gnutls-dev \ libjsoncpp-dev libmagic-dev autoconf automake bats sudo debootstrap procps \ - gcc g++ default-jre-headless default-jdk ghc fp-compiler libcgroup-dev \ - devscripts shellcheck nginx libboost-regex-dev \ - php7.4 php7.4-cli php7.4-gd php7.4-curl php7.4-mysql php7.4-json php7.4-gmp php7.4-zip php7.4-xml php7.4-mbstring php7.4-fpm php7.4-intl php7.4-pcov \ - # W3c test \ - httrack \ - # Visual regression browser \ - cutycapt xvfb openimageio-tools imagemagick \ + gcc g++ default-jre-headless default-jdk-headless ghc fp-compiler libcgroup-dev \ + devscripts shellcheck nginx libboost-regex-dev composer codespell pv httpie \ + php8.3 php8.3-cli php8.3-gd php8.3-curl php8.3-mysql php8.3-gmp php8.3-zip php8.3-xml php8.3-mbstring php8.3-fpm php8.3-intl php8.3-pcov \ # Submit client \ python3-requests python3-magic \ # Docs \ python3-sphinx python3-sphinx-rtd-theme rst2pdf fontconfig python3-yaml \ - texlive-latex-recommended texlive-latex-extra \ - texlive-fonts-recommended texlive-lang-european latexmk \ + texlive-latex-recommended texlive-latex-extra texlive-lang-european latexmk \ # Misc gitlab things \ mariadb-client curl build-essential packaging-dev \ git python3-pip moreutils w3m python3-yaml \ # Things we'd have in the chroot \ - ca-certificates default-jre-headless pypy locales software-properties-common \ + ca-certificates default-jre-headless pypy3 locales software-properties-common \ # W3c WCAG \ - npm libnss3 libcups2 libxss1 libasound2 libatk1.0-0 libatk-bridge2.0-0 libpangocairo-1.0-0 libgtk-3-0 \ - # Code coverage for unit test + npm \ + # Code coverage for unit test \ php-pear php-dev \ - # Needed NPM packages \ - && npm install pa11y \ - # Needed python packages \ - && pip install codespell \ && rm -rf /var/lib/apt/lists/* -# Install composer -RUN apt update && \ - apt install --no-install-recommends --no-install-suggests -y ca-certificates \ - && rm -rf /var/lib/apt/lists/* \ - && php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" && php composer-setup.php \ - && mv /composer.phar /usr/local/bin/composer +# Install needed NPM packages and download chrome for the domjudge user +RUN su domjudge -c "cd /home/domjudge && \ + npm install pa11y puppeteer && \ + npx puppeteer browsers install chrome && \ + npm cache clean --force" # Install needed global PHP modules RUN composer -n require justinrainbow/json-schema # Install other PHP versions -RUN add-apt-repository ppa:ondrej/php -y && apt update && \ +RUN add-apt-repository ppa:ondrej/php -y && apt-get update && \ PACKAGES=$(dpkg-query -f '${binary:Package}\n' -W|grep "^php.*-") && \ for VERSION in $PHPSUPPORTED; do \ $APTINSTALL php${VERSION} && \ for PACKAGE in $PACKAGES; do \ $APTINSTALL php${VERSION}-${PACKAGE#php*-}; \ done; \ - done && update-alternatives --set php /usr/bin/php7.4 + done && update-alternatives --set php /usr/bin/php8.3 \ + && rm -rf /var/lib/apt/lists/* # Put the gitlab user in sudo RUN echo 'ALL ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers -RUN useradd -m domjudge -RUN useradd -d /nonexistent -g nogroup -s /bin/false domjudge-run-0 -RUN useradd -d /nonexistent -g nogroup -s /bin/false domjudge-run-1 -RUN groupadd domjudge-run +# Update dictionary to latest version +ENV GITHUBDICTIONARY="https://raw.githubusercontent.com/codespell-project/codespell/master/codespell_lib/data/dictionary.txt" +ENV CODESPELLDICTLOCATION="/usr/lib/python3/dist-packages/codespell_lib/data/dictionary.txt" +RUN wget $GITHUBDICTIONARY -O $CODESPELLDICTLOCATION # Do some extra setup RUN mkdir -p /run/php \ diff --git a/docker/README.md b/docker/README.md index 2232f6fc..9b46f867 100644 --- a/docker/README.md +++ b/docker/README.md @@ -33,12 +33,43 @@ These containers do not include MySQL / MariaDB; the [MariaDB](https://hub.docke These images are available on the [Docker Hub](https://hub.docker.com) as `domjudge/domserver` and `domjudge/judgehost`. +### DOMjudge network +For isolation, create a Docker network which will be used for the communication between DOMjudge-related containers. +```bash +docker network create dj +``` + +### Traefik container (Optional) +An easy way to get trusted certificates using ACME is running the Traefik reverse proxy in front of the DOMjudge stack. Create a Docker network which allows communication across compose stacks using: + +```bash +docker network create proxy_network +``` + +Now, you can deploy a Traefik reverse proxy. An example test deployment with **insecure** API access on port `8080` can be created using: + +```bash +docker run --name traefik --net proxy_network -p 80:80 -p 443:443 -p 8080:8080 -v /letsencrypt -v /var/run/docker.sock:/var/run/docker.sock:ro traefik:v2.10 \ + --api.insecure=true \ + --providers.docker=true \ + --providers.docker.exposedbydefault=false \ + --entrypoints.web.address=:80 \ + --entrypoints.websecure.address=:443 \ + --certificatesresolvers.myresolver.acme.email=your-email@example.com \ + --certificatesresolvers.myresolver.acme.httpchallenge.entrypoint=web \ + --certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json +``` + +This will start a Traefik container listening for http traffic on port `80`, https traffic on port `443`, and listening for Traefik dashboard traffic at port `8080`. +Traefik automatically listens to the Docker socket for running containers with labels defining reverse proxy routes. +It also defines an ACME resolver named `myresolver` which creates a Let's Encrypt ACME account using email address `your-email@example.com` used to create the TLS certificates for https traffic. + ### MariaDB container Before starting the containers, make sure you have a MySQL / MariaDB database somewhere. The easiest way to get one up and running is to use the [MariaDB](https://hub.docker.com/r/_/mariadb/) Docker container: ```bash -docker run -it --name dj-mariadb -e MYSQL_ROOT_PASSWORD=rootpw -e MYSQL_USER=domjudge -e MYSQL_PASSWORD=djpw -e MYSQL_DATABASE=domjudge -p 13306:3306 mariadb --max-connections=1000 +docker run -it --name dj-mariadb --net dj -e MYSQL_ROOT_PASSWORD=rootpw -e MYSQL_USER=domjudge -e MYSQL_PASSWORD=djpw -e MYSQL_DATABASE=domjudge -p 13306:3306 mariadb --max-connections=1000 ``` This will start a MariaDB container, set the root password to `rootpw`, create a MySQL user named `domjudge` with password `djpw` and create an empty database named `domjudge`. It will also expose the server on port `13306` on your local machine, so you can use your favorite MySQL GUI to connect to it. If you want to save the MySQL data after removing the container, please read the [MariaDB](https://hub.docker.com/r/_/mariadb/) Docker Hub page for more information. @@ -47,10 +78,10 @@ This will start a MariaDB container, set the root password to `rootpw`, create a Next, if you are on Linux make sure you have cgroups enabled. See the [DOMjudge documentation about setting up a judgehost](https://www.domjudge.org/docs/manual/master/install-judgehost.html#linux-control-groups) for information about how to do this. Docker on Windows and macOS actually use a small Linux VM which already has these options set. -Now you can run the domserver using the following command: +Without the optional Traefik reverse proxy, you can run the domserver using the following command: ```bash -docker run --link dj-mariadb:mariadb -it -e MYSQL_HOST=mariadb -e MYSQL_USER=domjudge -e MYSQL_DATABASE=domjudge -e MYSQL_PASSWORD=djpw -e MYSQL_ROOT_PASSWORD=rootpw -p 12345:80 --name domserver domjudge/domserver:latest +docker run -it --name domserver --net dj -e MYSQL_HOST=dj-mariadb -e MYSQL_USER=domjudge -e MYSQL_DATABASE=domjudge -e MYSQL_PASSWORD=djpw -e MYSQL_ROOT_PASSWORD=rootpw -p 12345:80 domjudge/domserver:latest ``` If you want a specific DOMjudge version instead of the latest, replace `latest` with the DOMjudge version (e.g. `5.3.0`). @@ -70,12 +101,32 @@ If you lose access to the admin user, see the [DOMjudge documentation on resetti Make a note of the password for the `judgehost` user, it will be used when the judgehost container is configured. The password can be changed from the web interface by editing the `judgehost` user. +For a deployment using the Traefik container with ACME on domain `domjudge.example.com`, run domserver using the following command: + +```bash +docker create -it --name domserver --net dj -e MYSQL_HOST=dj-mariadb -e MYSQL_USER=domjudge -e MYSQL_DATABASE=domjudge -e MYSQL_PASSWORD=djpw -e MYSQL_ROOT_PASSWORD=rootpw \ + -l "traefik.enable=true" \ + -l "traefik.http.services.domjudge.loadbalancer.server.port=80" \ + -l "traefik.http.routers.domjudge.rule=Host(\`domjudge.example.com\`)" \ + -l "traefik.http.routers.domjudge.entrypoints=web" \ + -l "traefik.http.routers.domjudgesecure.rule=Host(\`domjudge.example.com\`)" \ + -l "traefik.http.routers.domjudgesecure.entrypoints=websecure" \ + -l "traefik.http.routers.domjudgesecure.tls=true" \ + -l "traefik.http.routers.domjudgesecure.tls.certresolver=myresolver" \ + -l "traefik.docker.network=proxy_network" \ + domjudge/domserver:latest +docker network connect proxy_network domserver +docker start -a domserver +``` + +With DNS configured, you can now access the web interface on [http://domjudge.example.com/](http://domjudge.example.com/) or [https://domjudge.example.com/](https://domjudge.example.com/) and log in as admin. + #### Environment variables The following environment variables are supported by the `domserver` container: * `CONTAINER_TIMEZONE` (defaults to `Europe/Amsterdam`): allows you to change the timezone used inside the container. -* `MYSQL_HOST` (defaults to `mariadb`): set the host to connect to for MySQL. Can be hostname or IP. Docker will add hostnames for any containers you `--link`, so in the example above, the MariaDB container will be available under the hostname `mariadb`. +* `MYSQL_HOST` (defaults to `mariadb`): set the host to connect to for MySQL. Can be hostname or IP. * `MYSQL_USER` (defaults to `domjudge`): set the user to use for connecting to MySQL. * `MYSQL_PASSWORD` (defaults to `domjudge`): set the password to use for connecting to MySQL. * `MYSQL_ROOT_PASSWORD` (defaults to `domjudge`): set the root password to use for connecting to MySQL. @@ -130,13 +181,14 @@ where `[service]` is one of `nginx` or `php`. #### Docker-compose See https://github.com/DOMjudge/domjudge-packaging/blob/main/docker/docker-compose.yml for a docker-compose example which automates the steps above. +When using the optional Traefik reverse proxy, deploy the stack defined in https://github.com/DOMjudge/domjudge-packaging/blob/main/docker/docker-compose-traefik.yml first and uncomment the relevant lines in the `docker-compose.yml` file. ### Judgehost container To run a single judgehost, run the following command: ```bash -docker run -it --privileged -v /sys/fs/cgroup:/sys/fs/cgroup:ro --name judgehost-0 --link domserver:domserver --hostname judgedaemon-0 -e DAEMON_ID=0 domjudge/judgehost:latest +docker run -it --privileged -v /sys/fs/cgroup:/sys/fs/cgroup --name judgehost-0 --net dj --hostname judgedaemon-0 -e DAEMON_ID=0 domjudge/judgehost:latest ``` Again, replace `latest` with a specific version if desired. Make sure the version matches the version of the domserver. @@ -190,7 +242,7 @@ echo 127.0.0.1 $(hostname) | sudo tee -a /etc/hosts ################################################### # Fill in these (secret) variables yourself!! -sudo docker run -d --restart=on-failure --network host --privileged -v /sys/fs/cgroup:/sys/fs/cgroup:ro --name judgehost -e DOMSERVER_BASEURL=your_baseurl -e JUDGEDAEMON_USERNAME=your_username -e JUDGEDAEMON_PASSWORD=your_password domjudge/judgehost:7.0.3 +sudo docker run -d --restart=on-failure --network host --privileged -v /sys/fs/cgroup:/sys/fs/cgroup --name judgehost -e DOMSERVER_BASEURL=your_baseurl -e JUDGEDAEMON_USERNAME=your_username -e JUDGEDAEMON_PASSWORD=your_password domjudge/judgehost:7.0.3 ################################################### # Enable cgroup functionality that judgehost needs, this requires a reboot diff --git a/docker/build.sh b/docker/build.sh index 14c07432..c4ba8d12 100755 --- a/docker/build.sh +++ b/docker/build.sh @@ -1,50 +1,87 @@ #!/bin/sh -eu -if [ -n "${CI+}" ] +if [ "$#" -eq 0 ] || [ "$#" -gt 2 ] then - set -x - export PS4='(${0}:${LINENO}): - [$?] $ ' + echo "Usage: $0 domjudge-version " + echo " For example: $0 5.3.0" + echo " or: $0 5.3.0 otherNamespace" + exit 1 fi -if [ "$#" -ne 1 ] +# Placeholders for grouping log lines +# (the body is a nested function declaration so it won't appear in the trace when using `set -x`) +section_start() { _() { :; }; } +section_end() { _() { :; }; } + +if [ -n "${CI+x}" ] then - echo "Usage: $0 domjudge-version" - echo " For example: $0 5.3.0" - exit 1 + if [ -n "${GITHUB_ACTION+x}" ] + then + # Functions for grouping log lines on GitHub Actions + trace_on() { set -x; } + # trace_off is manually inlined so it won't appear in the trace + section_start() { + { set +x; } 2>/dev/null # trace_off + echo "::group::$1" + trace_on + } + section_end() { + { set +x; } 2>/dev/null # trace_off + echo "::endgroup::" + trace_on + } + # Redirect stderr to stdout as a workaround so they won't be out-of-order; see + # https://github.com/orgs/community/discussions/116552 + # https://web.archive.org/web/20220430214837/https://github.community/t/stdout-stderr-output-not-in-correct-order-in-logs/16335 + # (GitHub Actions displays stderr in the same style as stdout anyway, so + # there is no harm in us merging them.) + exec 2>&1 + fi + set -x fi +section_start "Variables" VERSION="$1" - +NAMESPACE="${2-domjudge}" URL=https://www.domjudge.org/releases/domjudge-${VERSION}.tar.gz FILE=domjudge.tar.gz +section_end +section_start "Download DOMjudge tarball" echo "[..] Downloading DOMjudge version ${VERSION}..." - if ! wget --quiet "${URL}" -O ${FILE} then echo "[!!] DOMjudge version ${VERSION} file not found on https://www.domjudge.org/releases" exit 1 fi - echo "[ok] DOMjudge version ${VERSION} downloaded as domjudge.tar.gz"; echo +section_end +section_start "Build domserver container" echo "[..] Building Docker image for domserver..." -./build-domjudge.sh "domjudge/domserver:${VERSION}" +./build-domjudge.sh "${NAMESPACE}/domserver:${VERSION}" echo "[ok] Done building Docker image for domserver" +section_end +section_start "Build judgehost container (with intermediate image)" echo "[..] Building Docker image for judgehost using intermediate build image..." -./build-judgehost.sh "domjudge/judgehost:${VERSION}" +./build-judgehost.sh "${NAMESPACE}/judgehost:${VERSION}" echo "[ok] Done building Docker image for judgehost" +section_end +section_start "Build judgehost container (judging chroot)" echo "[..] Building Docker image for judgehost chroot..." -docker build -t "domjudge/default-judgehost-chroot:${VERSION}" -f judgehost/Dockerfile.chroot . +docker build -t "${NAMESPACE}/default-judgehost-chroot:${VERSION}" -f judgehost/Dockerfile.chroot . echo "[ok] Done building Docker image for judgehost chroot" +section_end -echo "All done. Image domjudge/domserver:${VERSION} and domjudge/judgehost:${VERSION} created" +section_start "Push instructions" +echo "All done. Image ${NAMESPACE}/domserver:${VERSION} and ${NAMESPACE}/judgehost:${VERSION} created" echo "If you are a DOMjudge maintainer with access to the domjudge organization on Docker Hub, you can now run the following command to push them to Docker Hub:" -echo "$ docker push domjudge/domserver:${VERSION} && docker push domjudge/judgehost:${VERSION} && docker push domjudge/default-judgehost-chroot:${VERSION}" +echo "$ docker push ${NAMESPACE}/domserver:${VERSION} && docker push ${NAMESPACE}/judgehost:${VERSION} && docker push $NAMESPACE}/default-judgehost-chroot:${VERSION}" echo "If this is the latest release, also run the following command:" -echo "$ docker tag domjudge/domserver:${VERSION} domjudge/domserver:latest && \ -docker tag domjudge/judgehost:${VERSION} domjudge/judgehost:latest && \ -docker tag domjudge/default-judgehost-chroot:${VERSION} domjudge/default-judgehost-chroot:latest && \ -docker push domjudge/domserver:latest && docker push domjudge/judgehost:latest && docker push domjudge/default-judgehost-chroot:latest" +echo "$ docker tag ${NAMESPACE}/domserver:${VERSION} ${NAMESPACE}/domserver:latest && \ +docker tag ${NAMESPACE}/judgehost:${VERSION} ${NAMESPACE}/judgehost:latest && \ +docker tag ${NAMESPACE}/default-judgehost-chroot:${VERSION} ${NAMESPACE}/default-judgehost-chroot:latest && \ +docker push ${NAMESPACE}/domserver:latest && docker push ${NAMESPACE}/judgehost:latest && docker push ${NAMESPACE}/default-judgehost-chroot:latest" +section_end diff --git a/docker/docker-compose-traefik.yml b/docker/docker-compose-traefik.yml new file mode 100644 index 00000000..9327da47 --- /dev/null +++ b/docker/docker-compose-traefik.yml @@ -0,0 +1,28 @@ +version: '3' + +services: + traefik: + image: "traefik:v2.10" + container_name: "traefik" + command: + - --api.insecure=true + - --providers.docker=true + - --providers.docker.exposedbydefault=false + - --entrypoints.web.address=:80 + - --entrypoints.websecure.address=:443 + - --certificatesresolvers.myresolver.acme.email=your-email@example.com + - --certificatesresolvers.myresolver.acme.httpchallenge.entrypoint=web + - --certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json + ports: + - "80:80" + - "443:443" + - "8080:8080" + volumes: + - /letsencrypt + - /var/run/docker.sock:/var/run/docker.sock:ro + networks: + - proxy_network + +networks: + proxy_network: + external: true diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index db94888c..7ad67694 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -11,7 +11,7 @@ services: - MYSQL_DATABASE=domjudge ports: - 13306:3306 - command: --max-connections=1000 --max-allowed-packet=512M + command: --max-connections=1000 --max-allowed-packet=512M --innodb_snapshot_isolation=OFF volumes: - /var/lib/mysql domjudge: @@ -25,3 +25,20 @@ services: - MYSQL_HOST=mariadb ports: - 12345:80 +# When using the Traefik reverse proxy container, uncomment the lines below. +# labels: +# - traefik.enable=true +# - traefik.http.services.domjudge.loadbalancer.server.port=80 +# - traefik.http.routers.domjudge.rule=Host(`domjudge.example.com`) +# - traefik.http.routers.domjudge.entrypoints=web +# - traefik.http.routers.domjudgesecure.rule=Host(`domjudge.example.com`) +# - traefik.http.routers.domjudgesecure.entrypoints=websecure +# - traefik.http.routers.domjudgesecure.tls=true +# - traefik.http.routers.domjudgesecure.tls.certresolver=myresolver +# - traefik.docker.network=proxy_network +# networks: +# - default +# - proxy_network +# networks: +# proxy_network: +# external: true diff --git a/docker/domserver/Dockerfile b/docker/domserver/Dockerfile index ced93d97..aa28e298 100644 --- a/docker/domserver/Dockerfile +++ b/docker/domserver/Dockerfile @@ -4,9 +4,9 @@ LABEL org.opencontainers.image.authors="DOMjudge team " ENV DEBIAN_FRONTEND=noninteractive # Install required packages for build of domserver -RUN apt update \ - && apt install --no-install-recommends --no-install-suggests -y \ - autoconf automake git \ +RUN apt-get update \ + && apt-get install --no-install-recommends --no-install-suggests -y \ + autoconf automake git pkg-config \ gcc g++ make acl zip unzip \ php-cli php-zip \ php-gd php-curl php-mysql php-json php-intl \ @@ -56,9 +56,12 @@ ENV DEBIAN_FRONTEND=noninteractive \ FPM_MAX_CHILDREN=40 \ DJ_DB_INSTALL_BARE=0 +# Set up user +RUN useradd -m domjudge + # Install required packages for running of domserver -RUN apt update \ - && apt install --no-install-recommends --no-install-suggests -y \ +RUN apt-get update \ + && apt-get install --no-install-recommends --no-install-suggests -y \ acl curl zip unzip supervisor mariadb-client apache2-utils \ nginx php-cli php-fpm php-zip \ php-gd php-curl php-mysql php-json php-intl \ diff --git a/docker/domserver/configure.sh b/docker/domserver/configure.sh index 26c12412..a4a5b5ee 100644 --- a/docker/domserver/configure.sh +++ b/docker/domserver/configure.sh @@ -1,9 +1,7 @@ #!/bin/sh -eu -# Add user, create PHP FPM socket dir, change permissions for domjudge directory and fix scripts -useradd -m domjudge +# Create PHP FPM socket dir, change permissions for some domjudge directories and fix scripts mkdir -p /run/php -chown -R domjudge: /opt/domjudge chown -R www-data: /opt/domjudge/domserver/tmp chmod 755 /scripts/start.sh diff --git a/docker/domserver/scripts/patches.d/10-default-config.py b/docker/domserver/scripts/patches.d/10-default-config.py index cc582c07..bd7f5987 100755 --- a/docker/domserver/scripts/patches.d/10-default-config.py +++ b/docker/domserver/scripts/patches.d/10-default-config.py @@ -18,7 +18,7 @@ if category["category"] == "External systems": for item in category["items"]: if item["name"] == "print_command": - item["default_value"] = "/usr/bin/enscript --columns=2 --pages=-10 --landscape --pretty-print \"--header='[original]'; page $% of $=; time=$C; room='[location]'; team='[teamname]'\" [file]" + item["default_value"] = "/usr/bin/enscript --columns=2 --pages=-10 --landscape --pretty-print \"--header='[original]'; page $% of $=; time=$C; room='[location]'; team='[teamname]'; teamid='[teamid]'\" [file]" if item["name"] == "data_source": item["default_value"] = 1 diff --git a/docker/judgehost/Dockerfile b/docker/judgehost/Dockerfile index 4f6d6b2c..3a7e91bb 100644 --- a/docker/judgehost/Dockerfile +++ b/docker/judgehost/Dockerfile @@ -10,6 +10,9 @@ ENV DEBIAN_FRONTEND=noninteractive \ DOMJUDGE_CREATE_WRITABLE_TEMP_DIR=0 \ RUN_USER_UID_GID=62860 +# Set up user +RUN useradd -m domjudge + # Install required packages for running of judgehost RUN apt update \ && apt install --no-install-recommends --no-install-suggests -y \ @@ -17,7 +20,7 @@ RUN apt update \ acl zip unzip supervisor sudo procps libcgroup-dev \ php-cli php-zip php-gd php-curl php-mysql php-json \ php-gmp php-xml php-mbstring python3 \ - gcc g++ default-jre-headless default-jdk ghc fp-compiler \ + gcc g++ openjdk-21-jre-headless openjdk-21-jdk-headless ghc fp-compiler \ && rm -rf /var/lib/apt/lists/* # Install more languages @@ -39,7 +42,7 @@ COPY judgehost/scripts /scripts/ # Make the scripts available to the root user ENV PATH="$PATH:/opt/domjudge/judgehost/bin" -# Change start script permissions, add user and fix permissions +# Run customizations COPY judgehost/configure.sh /configure.sh RUN chmod 700 /configure.sh && /configure.sh && rm -f /configure.sh diff --git a/docker/judgehost/Dockerfile.build b/docker/judgehost/Dockerfile.build index e95e0aa6..2c7c48b5 100644 --- a/docker/judgehost/Dockerfile.build +++ b/docker/judgehost/Dockerfile.build @@ -6,9 +6,9 @@ ENV DEBIAN_FRONTEND=noninteractive COPY judgehost/add_repositories.sh /scripts/add_repositories.sh # Install required packages for build of judgehost -RUN apt update \ - && apt install --no-install-recommends --no-install-suggests -y \ - autoconf automake git \ +RUN apt-get update \ + && apt-get install --no-install-recommends --no-install-suggests -y \ + autoconf automake git pkg-config \ gcc g++ make zip unzip \ php-cli php-zip lsb-release debootstrap \ php-gd php-curl php-mysql php-json \ diff --git a/docker/judgehost/Dockerfile.chroot b/docker/judgehost/Dockerfile.chroot index 4bd240d7..d3bd840a 100644 --- a/docker/judgehost/Dockerfile.chroot +++ b/docker/judgehost/Dockerfile.chroot @@ -1,6 +1,6 @@ FROM ubuntu:24.04 ENV DEBIAN_FRONTEND=noninteractive -RUN apt update && apt -y install \ +RUN apt-get update && apt-get -y install \ ca-certificates default-jre-headless pypy3 locales \ && rm -rf /var/lib/apt/lists/* diff --git a/docker/judgehost/chroot-and-tar.sh b/docker/judgehost/chroot-and-tar.sh index 6d15acdc..a0250e78 100755 --- a/docker/judgehost/chroot-and-tar.sh +++ b/docker/judgehost/chroot-and-tar.sh @@ -1,9 +1,11 @@ #!/bin/bash +set -euo pipefail + sed -i.bak '/# Upgrade the system, and install\/remove packages as desired/i mkdir \"\$CHROOTDIR\/scripts\/" && cp \/scripts\/add_repositories.sh \"\$CHROOTDIR\/scripts\/" && chmod -R 755 \"\$CHROOTDIR\/scripts\/" && in_chroot \"\/scripts\/add_repositories.sh\"\n' /opt/domjudge/judgehost/bin/dj_make_chroot # Usage: https://github.com/DOMjudge/domjudge/blob/main/misc-tools/dj_make_chroot.in#L58-L87 -/opt/domjudge/judgehost/bin/dj_make_chroot -R jammy -i openjdk-17-jre-headless,openjdk-17-jdk-headless,pypy3,icpc-kotlinc +/opt/domjudge/judgehost/bin/dj_make_chroot -R noble -i openjdk-21-jre-headless,openjdk-21-jdk-headless,pypy3,icpc-kotlinc cd / echo "[..] Compressing chroot" diff --git a/docker/judgehost/configure.sh b/docker/judgehost/configure.sh index e6766a4e..013487f7 100644 --- a/docker/judgehost/configure.sh +++ b/docker/judgehost/configure.sh @@ -1,8 +1,5 @@ #!/bin/bash -e -useradd -m domjudge -chown -R domjudge: /opt/domjudge - chmod 755 /scripts/start.sh for script in /scripts/bin/* do