From 92adfdd479fb1964e7fd408c27052294ca6112d8 Mon Sep 17 00:00:00 2001 From: Nathan Wallach Date: Sun, 4 Aug 2019 02:08:30 +0300 Subject: [PATCH 01/16] Update Docker configuration to use Ubuntu 18.04 as the base image. Install more Perl packages from Ubuntu and less from CPAN. Include sample Apache and SSL configuration files, and include many details about possible local configuration in docker-compose.yml. Some of the run-time configuration is done by setting specific environment variables in docker-compose.yml. By default the OPL will be installed in a local named Docker volume when a container is first started, and the OPL-update will be run. Running OPL-update takes a very long time. An alternative approach is to modify docker-compose.yml to mount the OPL from an external directory, which allows for OPL maintenance to be handled outside of the Docker container/named storage volume. --- Dockerfile | 419 ++++++++++++------ docker-compose.yml | 171 ++++++- docker-compose.yml.nomb4.dist | 45 -- docker-compose.yml.utf8_mb4_storage.dist | 54 --- docker-config/apache/000-default.conf | 54 +++ docker-config/apache/apache2.conf | 234 ++++++++++ docker-config/apache/htaccess | 1 + docker-config/apache/index.html | 12 + docker-config/apache/mpm_prefork.conf | 19 + docker-config/db/mariadb.cnf | 10 + .../docker-entrypoint.sh | 91 +++- docker-config/ssl/default-ssl.conf | 45 ++ .../local/PutYourCertificate_and_key_here.txt | 8 + docker-config/ssl/local/my.crt | 0 docker-config/ssl/local/my.key | 0 docker-config/ssl/local/myCA_chain.crt | 0 docker-config/ssl/ssl.conf | 85 ++++ 17 files changed, 988 insertions(+), 260 deletions(-) delete mode 100644 docker-compose.yml.nomb4.dist delete mode 100644 docker-compose.yml.utf8_mb4_storage.dist create mode 100644 docker-config/apache/000-default.conf create mode 100644 docker-config/apache/apache2.conf create mode 100644 docker-config/apache/htaccess create mode 100644 docker-config/apache/index.html create mode 100644 docker-config/apache/mpm_prefork.conf rename docker-entrypoint.sh => docker-config/docker-entrypoint.sh (51%) create mode 100644 docker-config/ssl/default-ssl.conf create mode 100644 docker-config/ssl/local/PutYourCertificate_and_key_here.txt create mode 100644 docker-config/ssl/local/my.crt create mode 100644 docker-config/ssl/local/my.key create mode 100644 docker-config/ssl/local/myCA_chain.crt create mode 100644 docker-config/ssl/ssl.conf diff --git a/Dockerfile b/Dockerfile index 13c9de0813..2e21950479 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,9 +1,82 @@ -FROM ubuntu:16.04 +# Optional things to change/configure below: +# +# 1. Which branch of webwork2/ and pg/ to install. +# +# 2. Installing the OPL in the Docker image itself. +# (almost 850MB: 290+MB for the main OPL, 90+MB for Pending, 460+MB for Contrib) +# +# By default this is NOT done, and it will instead be installed in +# a named Docker storage volume when the container is first started. +# +# Note: For typical use, we recommend that the OPL be either mounted from +# a local directory on the source or from a separate named data volume. +# That approach precludes needing to download the OPL for each update to +# the Docker image, and allows it to be easily upgraded using git in its +# persistent location. +# +# 3. Some things should be handled by setting environment variables which +# take effect at container startup. They can usually be set in +# docker-compose.yml. +# +# SSL=1 +# will turn on SSL at startup +# ADD_LOCALES="locale1,locale2,locale3" +# will build these locales at startup +# PAPERSIZE=a4 +# will set the system papersize to A4 +# SYSTEM_TIMEZONE=zone/city +# will set the system timezone to zone/city +# Make sure to use a valid setting. +# "/usr/bin/timedatectl list-timezones" on Ubuntu will find valid values +# +# ================================================================== +# Phase 1 - download some Git repos for later use: +# as suggested by Nelson Moller in https://gist.github.com/nmoller/81bd8e149e6aa2a7cf051e0bf248b2e2 +FROM alpine/git AS base -ENV PG_BRANCH=develop \ - WEBWORK_URL=/webwork2 \ +WORKDIR /opt/base + +# Currently set to use the 2.15 branches or WeBWorK and PG + +# WeBWorK master branch: +#RUN git clone --single-branch --branch master --depth 1 https://github.com/openwebwork/webwork2.git \ +# && rm -rf webwork2/.git webwork2/{*ignore,Dockerfile,docker-compose.yml,docker-config} + +# WeBWorK 2.15 branch: +RUN git clone --single-branch --branch WeBWorK-2.15 --depth 1 https://github.com/openwebwork/webwork2.git \ + && rm -rf webwork2/.git webwork2/{*ignore,Dockerfile,docker-compose.yml,docker-config} + +# PG master branch: +#RUN git clone --single-branch --branch master --depth 1 https://github.com/openwebwork/pg.git \ +# && rm -rf pg/.git + +# PG 2.15 branch: +RUN git clone --single-branch --branch PG-2.15 --depth 1 https://github.com/openwebwork/pg.git \ + && rm -rf pg/.git + +RUN git clone --single-branch --branch master --depth 1 https://github.com/mathjax/MathJax \ + && rm -rf MathJax/.git + +# Optional - include OPL (also need to uncomment further below when an included OPL is desired): +#RUN git clone --single-branch --branch master --depth 1 https://github.com/openwebwork/webwork-open-problem-library.git \ +# && rm -rf webwork-open-problem-library/.git + +# ================================================================== + +# Phase 2 - set ENV variables + +# we need to change FROM before setting the ENV variables + +FROM ubuntu:18.04 + +# WARNING: The real value of WEBWORK_DB_PASSWORD is set in docker-compose.yml via the +# value of MYSQL_PASSWORD at the time the MariaDB container is first initialized. +# Thus the value of WEBWORK_DB_PASSWORD should usually also be set in docker-compose.yml. +# Several other environment values should usually be set via docker-compose.yml. + +ENV WEBWORK_URL=/webwork2 \ WEBWORK_ROOT_URL=http://localhost \ WEBWORK_DB_HOST=db \ WEBWORK_DB_PORT=3306 \ @@ -22,125 +95,197 @@ ENV PG_BRANCH=develop \ # Only /var/log/apache2 is handled by /etc/logrotate.d/apache2. APACHE_LOG_DIR=/var/log/apache2 \ APP_ROOT=/opt/webwork \ + DEBIAN_FRONTEND=noninteractive \ + DEBCONF_NONINTERACTIVE_SEEN=true \ DEV=0 +# Environment variables which depend on a prior environment variable must be set +# in an ENV call after the dependencies were defined. ENV WEBWORK_DB_DSN=DBI:mysql:${WEBWORK_DB_NAME}:${WEBWORK_DB_HOST}:${WEBWORK_DB_PORT} \ WEBWORK_ROOT=$APP_ROOT/webwork2 \ PG_ROOT=$APP_ROOT/pg \ PATH=$PATH:$APP_ROOT/webwork2/bin -# Ubuntu 18.04 should add libemail-address-xs-perl in the package list below. -# For Ubuntu 16.04 it is not packed in Ubuntu universe, so installed using CPANM below. +# ================================================================== + +# Phase 3 - Ubuntu 18.04 base image + required packages + +# Packages changes/added for ubuntu 18.04: + +# For ubuntu 18.04 libemail-address-xs-perl installed from Ubuntu, for 16.04 it would be installed using cpamn +# +# texlive-generic-recommended # For ubuntu 16.04 - contains path.sty +# texlive-plain-generic # For ubuntu 18.04 - contains path.sty + +# Do NOT include "apt-get -y upgrade" +# see: https://docs.docker.com/develop/develop-images/dockerfile_best-practices/ RUN apt-get update \ && apt-get install -y --no-install-recommends --no-install-suggests \ - apache2 \ - curl \ - dvipng \ - gcc \ - libapache2-request-perl \ - libcrypt-ssleay-perl \ - libdatetime-perl \ - libdancer-perl \ - libdancer-plugin-database-perl \ - libdbd-mysql-perl \ - libexception-class-perl \ - libextutils-xsbuilder-perl \ - libfile-find-rule-perl-perl \ - libgd-perl \ - libhtml-scrubber-perl \ - libjson-perl \ - liblocale-maketext-lexicon-perl \ - libmail-sender-perl \ - libmime-tools-perl \ - libnet-ip-perl \ - libnet-ldap-perl \ - libnet-oauth-perl \ - libossp-uuid-perl \ - libpadwalker-perl \ - libpath-class-perl \ - libphp-serialization-perl \ - libxml-simple-perl \ - libsoap-lite-perl \ - libsql-abstract-perl \ - libstring-shellquote-perl \ - libtemplate-perl \ - libtext-csv-perl \ - libtimedate-perl \ - libuuid-tiny-perl \ - libxml-parser-perl \ - libxml-writer-perl \ - libxmlrpc-lite-perl \ - libapache2-reload-perl \ - libxmlrpc-lite-perl \ - libxml-simple-perl \ - make \ - netpbm \ - preview-latex-style \ - texlive \ - texlive-latex-extra \ - libc6-dev \ - git \ - mysql-client \ - && rm -fr /var/lib/apt/lists/* - -# Warning - when I tried to include XML::Simple near the start of the first "cpanm install" line, there was an error: -# Building and testing XMLRPC-Lite-0.717 ... ! Installing XMLRPC::Lite failed. See /root/.cpanm/work/1551887935.125/build.log for details. Retry with --force to force install it. -# so it was put into a second "cpanm install" line. - -RUN curl -Lk https://cpanmin.us | perl - App::cpanminus \ - && cpanm install XML::Parser::EasyTree Iterator Iterator::Util Pod::WSDL Array::Utils HTML::Template Mail::Sender Email::Sender::Simple Data::Dump Statistics::R::IO Email::Address::XS - -##RUN cpanm install XML::Simple \ -# && rm -fr ./cpanm /root/.cpanm /tmp/* - - -RUN mkdir -p $APP_ROOT/courses $APP_ROOT/libraries $APP_ROOT/webwork2 - -# Block to include webwork2 in the container, when needed, instead of getting it from a bind mount. -# Uncomment when needed, and set the correct branch name on the following line. -#ENV WEBWORK_BRANCH=develop # need a valid branch name from https://github.com/openwebwork/webwork2 -#RUN curl -fSL https://github.com/openwebwork/webwork2/archive/${WEBWORK_BRANCH}.tar.gz -o /tmp/${WEBWORK_BRANCH}.tar.gz \ -# && cd /tmp \ -# && tar xzf /tmp/${WEBWORK_BRANCH}.tar.gz \ -# && mv webwork2-${WEBWORK_BRANCH} $APP_ROOT/webwork2 \ -# && rm -rf /tmp/${WEBWORK_BRANCH}.tar.gz /tmp/webwork2-${WEBWORK_BRANCH} - -RUN curl -fSL https://github.com/openwebwork/pg/archive/${PG_BRANCH}.tar.gz -o /tmp/${PG_BRANCH}.tar.gz \ - && tar xzf /tmp/${PG_BRANCH}.tar.gz \ - && mv pg-${PG_BRANCH} $APP_ROOT/pg \ - && rm /tmp/${PG_BRANCH}.tar.gz \ - && curl -fSL https://github.com/openwebwork/webwork-open-problem-library/archive/master.tar.gz -o /tmp/opl.tar.gz \ - && tar xzf /tmp/opl.tar.gz \ - && mv webwork-open-problem-library-master $APP_ROOT/libraries/webwork-open-problem-library \ - && rm /tmp/opl.tar.gz - -RUN curl -fSL https://github.com/mathjax/MathJax/archive/master.tar.gz -o /tmp/mathjax.tar.gz \ - && tar xzf /tmp/mathjax.tar.gz \ - && mv MathJax-master $APP_ROOT/MathJax \ - && rm /tmp/mathjax.tar.gz - #&& rm /tmp/VERSION - #curl -fSL https://github.com/openwebwork/webwork2/archive/WeBWorK-${WEBWORK_VERSION}.tar.gz -o /tmp/WeBWorK-${WEBWORK_VERSION}.tar.gz \ - #&& tar xzf /tmp/WeBWorK-${WEBWORK_VERSION}.tar.gz \ - #&& mv webwork2-WeBWorK-${WEBWORK_VERSION} $APP_ROOT/webwork2 \ - #&& rm /tmp/WeBWorK-${WEBWORK_VERSION}.tar.gz \ - - -RUN echo "PATH=$PATH:$APP_ROOT/webwork2/bin" >> /root/.bashrc - -COPY . $APP_ROOT/webwork2 - - -# Move these lines into docker-entrypoint.sh so the bind mount of courses -# will be available + apache2 \ + curl \ + dvipng \ + gcc \ + libapache2-request-perl \ + libcrypt-ssleay-perl \ + libdatetime-perl \ + libdancer-perl \ + libdancer-plugin-database-perl \ + libdbd-mysql-perl \ + libemail-address-xs-perl \ + libexception-class-perl \ + libextutils-xsbuilder-perl \ + libfile-find-rule-perl-perl \ + libgd-perl \ + libhtml-scrubber-perl \ + libjson-perl \ + liblocale-maketext-lexicon-perl \ + libmail-sender-perl \ + libmime-tools-perl \ + libnet-ip-perl \ + libnet-ldap-perl \ + libnet-oauth-perl \ + libossp-uuid-perl \ + libpadwalker-perl \ + libpath-class-perl \ + libphp-serialization-perl \ + libxml-simple-perl \ + libsoap-lite-perl \ + libsql-abstract-perl \ + libstring-shellquote-perl \ + libtemplate-perl \ + libtext-csv-perl \ + libtimedate-perl \ + libuuid-tiny-perl \ + libxml-parser-perl \ + libxml-writer-perl \ + libxmlrpc-lite-perl \ + libapache2-reload-perl \ + cpanminus \ + libxml-parser-easytree-perl \ + libiterator-perl \ + libiterator-util-perl \ + libpod-wsdl-perl \ + libtest-xml-perl \ + libmodule-build-perl \ + libxml-semanticdiff-perl \ + libxml-xpath-perl \ + libpath-tiny-perl \ + libarray-utils-perl \ + libhtml-template-perl \ + libtest-pod-perl \ + libemail-sender-perl \ + libmail-sender-perl \ + libmodule-pluggable-perl \ + libemail-date-format-perl \ + libcapture-tiny-perl \ + libthrowable-perl \ + libdata-dump-perl \ + libfile-sharedir-install-perl \ + libclass-tiny-perl \ + libtest-requires-perl \ + libtest-mockobject-perl \ + libtest-warn-perl \ + libsub-uplevel-perl \ + libtest-exception-perl \ + libuniversal-can-perl \ + libuniversal-isa-perl \ + libtest-fatal-perl \ + libjson-xs-perl \ + make \ + netpbm \ + preview-latex-style \ + texlive \ + texlive-latex-extra \ + texlive-plain-generic \ + texlive-xetex \ + texlive-latex-recommended \ + texlive-lang-other \ + texlive-lang-arabic \ + libc6-dev \ + git \ + mysql-client \ + tzdata \ + apt-utils \ + locales \ + debconf-utils \ + ssl-cert \ + ca-certificates \ + culmus \ + fonts-linuxlibertine \ + lmodern \ + && apt-get clean \ + && rm -fr /var/lib/apt/lists/* /tmp/* + +# Developers may want to add additional packages inside the image +# such as: telnet vimvim mc file + +# ================================================================== + +# Phase 4 - Install webwork2, pg, MathJaX which were downloaded to /opt/base/ in phase 1 +# Option: Install the OPL in the image also (about 850 MB) + +RUN mkdir -p $APP_ROOT/courses $APP_ROOT/libraries $APP_ROOT/libraries/webwork-open-problem-library $APP_ROOT/webwork2 /www/www/html + +COPY --from=base /opt/base/webwork2 $APP_ROOT/webwork2 +COPY --from=base /opt/base/pg $APP_ROOT/pg +COPY --from=base /opt/base/MathJax $APP_ROOT/MathJax + +# Optional - include OPL (also need to uncomment above to clone from GitHub when needed): +# ??? could/should this include the main OPL = /opt/base/webwork-open-problem-library/OpenProblemLibrary and not Contrib and Pending ??? +#COPY --from=base /opt/base/webwork-open-problem-library $APP_ROOT/libraries/webwork-open-problem-library + +# ================================================================== + +# Phase 5 - some configuration work + +# 1. Setup PATH. +# 2. Compiles color.c in the copy INSIDE the image, will also be done in docker-entrypoint.sh for externally mounted locations. +# 3. Some chown/chmod for material INSIDE the image. +# 4. Build some standard locales. +# 5. Set the default system timezone to be UTC. + +RUN echo "PATH=$PATH:$APP_ROOT/webwork2/bin" >> /root/.bashrc \ + && cd $APP_ROOT/pg/lib/chromatic && gcc color.c -o color \ + && cd $APP_ROOT/webwork2/ \ + && chown www-data DATA ../courses htdocs/applets logs tmp $APP_ROOT/pg/lib/chromatic \ + && chmod -R u+w DATA ../courses htdocs/applets logs tmp $APP_ROOT/pg/lib/chromatic \ + && echo "en_US ISO-8859-1\nen_US.UTF-8 UTF-8" > /etc/locale.gen \ + && /usr/sbin/locale-gen \ + && echo "locales locales/default_environment_locale select en_US.UTF-8\ndebconf debconf/frontend select Noninteractive" > /tmp/preseed.txt \ + && debconf-set-selections /tmp/preseed.txt \ + && rm /etc/localtime /etc/timezone && echo "Etc/UTC" > /etc/timezone \ + && dpkg-reconfigure -f noninteractive tzdata + +# These lines were moved into docker-entrypoint.sh so the bind mount of courses will be available #RUN cd $APP_ROOT/webwork2/courses.dist \ # && cp *.lst $APP_ROOT/courses/ \ # && cp -R modelCourse $APP_ROOT/courses/ -RUN cd $APP_ROOT/pg/lib/chromatic \ - && gcc color.c -o color +# ================================================================== + +# Phase 6 - install additional Perl modules from CPAN (not packaged for Ubuntu or outdated in Ubuntu) + +RUN cpanm install Statistics::R::IO \ + && rm -fr ./cpanm /root/.cpanm /tmp/* + +# Now installed from Ubuntu packages: +# XML::Parser::EasyTree Iterator Iterator::Util Pod::WSDL Array::Utils HTML::Template Mail::Sender Email::Sender::Simple Data::Dump +# For Ubuntu 16.04 would also need: +# Email::Address::XS + +# ================================================================== + +# Phase 7 - setup apache + +# Note we always create the /etc/ssl/local directory in case it will be needed, as +# the SSL config can also be done via a modified docker-entrypoint.sh script. + +# Always provide the dummy default-ssl.conf file: +COPY docker-config/ssl/default-ssl.conf /etc/apache2/sites-available/default-ssl.conf + +# However SSL will only be enabled at container startup via docker-entrypoint.sh. -# setup apache RUN cd $APP_ROOT/webwork2/conf \ && cp webwork.apache2.4-config.dist webwork.apache2.4-config \ && cp $APP_ROOT/webwork2/conf/webwork.apache2.4-config /etc/apache2/conf-enabled/webwork.conf \ @@ -148,30 +293,52 @@ RUN cd $APP_ROOT/webwork2/conf \ && a2enmod mpm_prefork \ && sed -i -e 's/Timeout 300/Timeout 1200/' /etc/apache2/apache2.conf \ && sed -i -e 's/MaxRequestWorkers 150/MaxRequestWorkers 20/' \ - -e 's/MaxConnectionsPerChild 0/MaxConnectionsPerChild 100/' \ - /etc/apache2/mods-available/mpm_prefork.conf \ + -e 's/MaxConnectionsPerChild 0/MaxConnectionsPerChild 100/' \ + /etc/apache2/mods-available/mpm_prefork.conf \ && cp $APP_ROOT/webwork2/htdocs/favicon.ico /var/www/html \ + && mkdir -p $APACHE_RUN_DIR $APACHE_LOCK_DIR $APACHE_LOG_DIR \ + && mkdir /etc/ssl/local \ + && a2enmod rewrite \ && sed -i -e 's/^$/\ - PerlPassEnv WEBWORK_URL\n\ - PerlPassEnv WEBWORK_ROOT_URL\n\ - PerlPassEnv WEBWORK_DB_DSN\n\ - PerlPassEnv WEBWORK_DB_USER\n\ - PerlPassEnv WEBWORK_DB_PASSWORD\n\ - PerlPassEnv WEBWORK_SMTP_SERVER\n\ - PerlPassEnv WEBWORK_SMTP_SENDER\n\ - PerlPassEnv WEBWORK_TIMEZONE\n\ - \n/' /etc/apache2/conf-enabled/webwork.conf - -RUN cd $APP_ROOT/webwork2/ \ - && chown www-data DATA ../courses htdocs/applets logs tmp $APP_ROOT/pg/lib/chromatic \ - && chmod -R u+w DATA ../courses htdocs/applets logs tmp $APP_ROOT/pg/lib/chromatic - -COPY docker-entrypoint.sh /usr/local/bin/ + PerlPassEnv WEBWORK_URL\n\ + PerlPassEnv WEBWORK_ROOT_URL\n\ + PerlPassEnv WEBWORK_DB_DSN\n\ + PerlPassEnv WEBWORK_DB_USER\n\ + PerlPassEnv WEBWORK_DB_PASSWORD\n\ + PerlPassEnv WEBWORK_SMTP_SERVER\n\ + PerlPassEnv WEBWORK_SMTP_SENDER\n\ + PerlPassEnv WEBWORK_TIMEZONE\n\ + \n/' /etc/apache2/conf-enabled/webwork.conf + +EXPOSE 80 +WORKDIR $APP_ROOT + +# Enabling SSL is NOT done here. +# Instead it is done by docker-entrypoint.sh at container startup when SSL=1 +# is set in the environment, for example by docker-compose.yml. +#RUN a2enmod ssl && a2ensite default-ssl +#EXPOSE 443 + +# ================================================================== + +# Phase 8 - prepare docker-entrypoint.sh +# Done near the end, so that an update to docker-entrypoint.sh can be +# done without rebuilding the earlier layers of the Docker image. + +COPY docker-config/docker-entrypoint.sh /usr/local/bin/ ENTRYPOINT ["docker-entrypoint.sh"] -EXPOSE 80 +# ================================================================== -WORKDIR $APP_ROOT +# Add enviroment variables to control some things during container startup + +ENV SSL=0 \ + PAPERSIZE=letter \ + SYSTEM_TIMEZONE=UTC \ + ADD_LOCALES=0 \ + ADD_PACKAGES=0 + +# ================================================ CMD ["apache2", "-DFOREGROUND"] diff --git a/docker-compose.yml b/docker-compose.yml index df1c97e7f1..5d0492925d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,45 +1,182 @@ -version: '2' +version: '3.5' services: db: - image: mariadb:10.1 + image: mariadb:10.4 volumes: - mysql:/var/lib/mysql + # When using "dbMB4" as the name of the Docker DB volume, comment out line above and uncomment the line below + #- mysqlMB4:/var/lib/mysql + # Set up UTF8MB4 in config file for the container. # Needs to be done BEFORE the database is created. - # - "./docker-config/db/mariadb.cnf:/etc/mysql/conf.d/mariadb.cnf" + - "./docker-config/db/mariadb.cnf:/etc/mysql/conf.d/mariadb.cnf" restart: always environment: - MYSQL_ROOT_PASSWORD: randomepassword + # When the MariaDB container is first started it will set the + # the MYSQL_ROOT_PASSWORD if there is no mysql database in the + # data volume. + MYSQL_ROOT_PASSWORD: sqlRootPasswordSetThisPasswordBEFOREfirstStartingTheDBcontainer + + # When the MariaDB container is first started it will create + # the WW database and WW DB user based on: MYSQL_DATABASE: webwork MYSQL_USER: webworkWrite - MYSQL_PASSWORD: passwordRW + MYSQL_PASSWORD: passwordRWsetItBeforeFirstStartingTheDBcontainer + # Old default: + #MYSQL_PASSWORD: passwordRW + app: - build: . image: webwork + + # Select the appropriate "build:" block: + + # For use/building when docker-compose.yml is in the webwork2 directory + build: . + + # For use/building when docker-compose.yml is OUTSIDE the webwork2 directory. + # For example, if multiple hosts use a NFS shared webwork2/ directory, and + # each one needs customized values in docker-compose.yml. + # Under typical use, the Dockerfile should not need to be customized per host, + # but may contain some changes/additions relative to the standard webwork image. + # + #build: + # context: /Path_To/webwork2/ + # dockerfile: /Path_To/Dockerfile + depends_on: - db - r + volumes: - - ".:/opt/webwork/webwork2" - # OLD approach put the courses tree under webwork2/.data/courses - #- "./.data/courses:/opt/webwork/courses" - # NEW appoach puts the courses tree in a separate tree outside of webwork2/ + # ====================================================================== + + # If you are using locally modified webwork2 files, then + # either mount them from the webwork2 tree from which you start Docker: + #- ".:/opt/webwork/webwork2" + # OR mount it from a fixed external location + #- "/path_to/webwork2:/opt/webwork/webwork2" + + # Shared main /pg repository - allows local PG development + #- "/path_to_shared/pg:/opt/webwork/pg" + # OR locally modified PG directory + #- "../pg:/opt/webwork/pg" + + # ====================================================================== + + # Sometimes it is helpful to mount certain webwork2/conf files from elsewhere + # so the main contents of webwork2 can be shared by several hosts (ex. NFS) + #- "/per_host_conf_path/conf/authen_LTI.conf:/opt/webwork/webwork2/conf/authen_LTI.conf" + #- "/per_host_conf_path/conf/localOverrides.conf:/opt/webwork/webwork2/conf/localOverrides.conf" + #- "/per_host_conf_path/conf/site.conf:/opt/webwork/webwork2/conf/site.conf" + + # webwork2 misc LOCAL files - mount live (per host) so NOT in the main webwork2 location + #- "/per_host_conf_path/htdocs/my_site_info.txt:/opt/webwork/webwork2/htdocs/my_site_info.txt" + + # webwork2 LOCAL logs and htdocs/tmp directories (per host) + #- "/per_host_data_path/webwork2/logs:/opt/webwork/webwork2/logs" + #- "/per_host_data_path/webwork2/htdocs/tmp:/opt/webwork/webwork2/htdocs/tmp" + + # By default the courses tree in a separate tree outside of webwork2/ as follows: - "../ww-docker-data/courses:/opt/webwork/courses" + # OR mount like (here we are assuming that the hosts have different courses on them) + #- "/per_host_data_path/courses/:/opt/webwork/courses/" + + # ====================================================================== + + # By default the OPL is stored in a named Docker storage volume: + - oplVolume:/opt/webwork/libraries/webwork-open-problem-library + # + # as an alternative, you can comment out the prior option and uncomment the line below to use a local directory containing the OPL + #- "/path_to/webwork-open-problem-library:/opt/webwork/libraries/webwork-open-problem-library" + + # ====================================================================== + + # The mounts from ./docker-config/ below are local samples. + # In production, there may be per-host versions of most + # of these files stored in an appropriate place. + # If not - the samples should be edited as needed. + + # Main index.html page with a redirect (you probably need to customize some of these files) + #- "./docker-config/apache/index.html:/var/www/html/index.html" + #- "./docker-config/apache/htaccess:/var/www/html/.htaccess" + + # Apache config (you probably need to customize some of these files) + - "./docker-config/apache/000-default.conf:/etc/apache2/sites-available/000-default.conf" + - "./docker-config/apache/apache2.conf:/etc/apache2/apache2.conf" + - "./docker-config/apache/mpm_prefork.conf:/etc/apache2/mods-enabled/mpm_prefork.conf" + + # Apache logs - to have them persistent (per host) mount directory from outside. + #- "/per_host_data_path/apache2_logs:/var/log/apache2" + + # ====================================================================== + + # SSL certificates (subdirectory with certificate and key) + # (you MUST replace/customize these files, or change the location they are mounded from) + - "./docker-config/ssl/local/:/etc/ssl/local" + + # Apache SSL config (you probably need to customize some of these files) + # (make sure default-ssl.conf points to the certificates where they will be in the container) + - "./docker-config/ssl/ssl.conf:/etc/apache2/mods-available/ssl.conf" + - "./docker-config/ssl/default-ssl.conf:/etc/apache2/sites-available/default-ssl.conf" + + # ====================================================================== + + hostname: myhost.mydomain.edu - # Uncomment the line below to use local OPL for development - #- "../opl:/opt/webwork/libraries/webwork-open-problem-library" - # Uncomment the line below to use local PG for development - - "../pg:/opt/webwork/pg" ports: + # For a personal machine - "8080:80" + + # For a production machine + #- "80:80" + #- "443:443" + + # For a production machine + #restart: always + environment: + DEV: 0 + + APACHE_RUN_GROUP: www-data + + WEBWORK_DB_PASSWORD: passwordRWsetItBeforeFirstStartingTheDBcontainer + # should be the same password as MYSQL_PASSWORD above. + # Old default: + #WEBWORK_DB_PASSWORD: passwordRW + + # To turn on SSL in the running container + #SSL: 1 + + # Change to A4 paper + #PAPERSIZE: a4 + + # Use to build additional locales in the running container at startup + #ADD_LOCALES: he_IL ISO-8859-8,he_IL.UTF-8 UTF-8 + + # Extra Ubuntu packages to install during startup + #ADD_PACKAGES: mc vim telnet + + # If you use https below, make sure to set up the certificate and SSL configuration +# WEBWORK_ROOT_URL: https://myhost.mydomain.edu + +# WEBWORK_SMTP_SERVER: smtp.mydomain.edu +# WEBWORK_SMTP_SENDER: support@mydomain.edu + +# WEBWORK_TIMEZONE: America/New_York + + # For when using "dbMB4" as the name of the Docker DB volume: + #WEBWORK_DB_HOST: dbMB4 + #WEBWORK_DB_DSN: DBI:mysql:webwork:dbMB4:3306 r: image: ubcctlt/rserve - ports: - - "6311:6311" +# # The R server need not be available from outside the local Docker network. +# ports: +# - "6311:6311" volumes: + oplVolume: mysql: - + # When using "dbMB4" as the name of the Docker DB volume, comment out line above and uncomment the line below + #mysqlMB4: diff --git a/docker-compose.yml.nomb4.dist b/docker-compose.yml.nomb4.dist deleted file mode 100644 index e7133f18d5..0000000000 --- a/docker-compose.yml.nomb4.dist +++ /dev/null @@ -1,45 +0,0 @@ -version: '2' -services: - db: - image: mariadb:10.1 - volumes: - - mysql:/var/lib/mysql - # Set up UTF8MB4 in config file for the container. - # Needs to be done BEFORE the database is created. - - "./docker-config/db/mariadb.cnf:/etc/mysql/conf.d/mariadb.cnf" - restart: always - environment: - MYSQL_ROOT_PASSWORD: randomepassword - MYSQL_DATABASE: webwork - MYSQL_USER: webworkWrite - MYSQL_PASSWORD: passwordRW - app: - build: . - image: webwork - depends_on: - - db - - r - volumes: - - ".:/opt/webwork/webwork2" - - # OLD approach put the courses tree under webwork2/.data/courses - #- "./.data/courses:/opt/webwork/courses" - # NEW appoach puts the courses tree in a separate tree outside of webwork2/ - - "../ww-docker-data/courses:/opt/webwork/courses" - - # Uncomment the line below to use local OPL for development - #- "../opl:/opt/webwork/libraries/webwork-open-problem-library" - # Uncomment the line below to use local PG for development - - "../pg:/opt/webwork/pg" - ports: - - "8080:80" - environment: - DEV: 0 - r: - image: ubcctlt/rserve - ports: - - "6311:6311" - -volumes: - mysql: - diff --git a/docker-compose.yml.utf8_mb4_storage.dist b/docker-compose.yml.utf8_mb4_storage.dist deleted file mode 100644 index 53dc498be0..0000000000 --- a/docker-compose.yml.utf8_mb4_storage.dist +++ /dev/null @@ -1,54 +0,0 @@ -version: '2' -services: - # We have renamed the database service from "db" to "dbMB4", - # changed the name of the data volume to "mysqlMB4" and set - # environment variables to use the "dbMB4" server. All this was needed - # ONLY to allow leaving a version of the "db" container which does not - # use utf8mb4 available until the UTF8MB4 changes become mainstream. - dbMB4: - image: mariadb:10.1 - volumes: - - mysqlMB4:/var/lib/mysql - # Set up UTF8MB4 in config file for the container. - # Needs to be done BEFORE the database is created. - - "./docker-config/db/mariadb.cnf:/etc/mysql/conf.d/mariadb.cnf" - restart: always - environment: - MYSQL_ROOT_PASSWORD: randomepassword - MYSQL_DATABASE: webwork - MYSQL_USER: webworkWrite - MYSQL_PASSWORD: passwordRW - app: - build: . - image: webwork - depends_on: - - dbMB4 - - r - volumes: - - ".:/opt/webwork/webwork2" - - # OLD approach put the courses tree under webwork2/.data/courses - #- "./.data/courses:/opt/webwork/courses" - # NEW appoach puts the courses tree in a separate tree outside of webwork2/ - - "../ww-docker-data/courses:/opt/webwork/courses" - - # Uncomment the line below to use local OPL for development - #- "../opl:/opt/webwork/libraries/webwork-open-problem-library" - # Uncomment the line below to use local PG for development - #- "../pg:/opt/webwork/pg" - ports: - - "8080:80" - environment: - - DEV=0 - - WEBWORK_DB_HOST=dbMB4 - # - WEBWORK_DB_PORT=3306 - # - WEBWORK_DB_NAME=webwork - - WEBWORK_DB_DSN=DBI:mysql:webwork:dbMB4:3306 - r: - image: ubcctlt/rserve - ports: - - "6311:6311" - -volumes: - mysqlMB4: - diff --git a/docker-config/apache/000-default.conf b/docker-config/apache/000-default.conf new file mode 100644 index 0000000000..ab9887a59a --- /dev/null +++ b/docker-config/apache/000-default.conf @@ -0,0 +1,54 @@ + + # This fake virtual host is intented to capture traffic which + # spoofs the "Host:" header value for security reasons. + # It will deny ALL such traffic. + ServerName fake + DocumentRoot "/www/www/html" + + Order deny,allow + deny from all + + + + + ServerName localhost + DocumentRoot /var/www/html + ErrorLog ${APACHE_LOG_DIR}/error.log + CustomLog ${APACHE_LOG_DIR}/access.log combined + + + + # The ServerName directive sets the request scheme, hostname and port that + # the server uses to identify itself. This is used when creating + # redirection URLs. In the context of virtual hosts, the ServerName + # specifies what hostname must appear in the request's Host: header to + # match this virtual host. For the default virtual host (this file) this + # value is not decisive as it is used as a last resort host regardless. + # However, you must set it for any further virtual host explicitly. + + ServerAdmin support@mydomain.edu + ServerName myserver.mydomain.edu + ServerAlias myserver.mydomain.edu + + DocumentRoot /var/www/html + + UseCanonicalName On + + # Available loglevels: trace8, ..., trace1, debug, info, notice, warn, + # error, crit, alert, emerg. + # It is also possible to configure the loglevel for particular + # modules, e.g. + #LogLevel info ssl:warn + + ErrorLog ${APACHE_LOG_DIR}/error.log + CustomLog ${APACHE_LOG_DIR}/access.log combined + + # For most configuration files from conf-available/, which are + # enabled or disabled at a global level, it is possible to + # include a line for only one particular virtual host. For example the + # following line enables the CGI configuration for this host only + # after it has been globally disabled with "a2disconf". + #Include conf-available/serve-cgi-bin.conf + + +# vim: syntax=apache ts=4 sw=4 sts=4 sr noet diff --git a/docker-config/apache/apache2.conf b/docker-config/apache/apache2.conf new file mode 100644 index 0000000000..e9de2b7880 --- /dev/null +++ b/docker-config/apache/apache2.conf @@ -0,0 +1,234 @@ +# This is the main Apache server configuration file. It contains the +# configuration directives that give the server its instructions. +# See http://httpd.apache.org/docs/2.4/ for detailed information about +# the directives and /usr/share/doc/apache2/README.Debian about Debian specific +# hints. +# +# +# Summary of how the Apache 2 configuration works in Debian: +# The Apache 2 web server configuration in Debian is quite different to +# upstream's suggested way to configure the web server. This is because Debian's +# default Apache2 installation attempts to make adding and removing modules, +# virtual hosts, and extra configuration directives as flexible as possible, in +# order to make automating the changes and administering the server as easy as +# possible. + +# It is split into several files forming the configuration hierarchy outlined +# below, all located in the /etc/apache2/ directory: +# +# /etc/apache2/ +# |-- apache2.conf +# | `-- ports.conf +# |-- mods-enabled +# | |-- *.load +# | `-- *.conf +# |-- conf-enabled +# | `-- *.conf +# `-- sites-enabled +# `-- *.conf +# +# +# * apache2.conf is the main configuration file (this file). It puts the pieces +# together by including all remaining configuration files when starting up the +# web server. +# +# * ports.conf is always included from the main configuration file. It is +# supposed to determine listening ports for incoming connections which can be +# customized anytime. +# +# * Configuration files in the mods-enabled/, conf-enabled/ and sites-enabled/ +# directories contain particular configuration snippets which manage modules, +# global configuration fragments, or virtual host configurations, +# respectively. +# +# They are activated by symlinking available configuration files from their +# respective *-available/ counterparts. These should be managed by using our +# helpers a2enmod/a2dismod, a2ensite/a2dissite and a2enconf/a2disconf. See +# their respective man pages for detailed information. +# +# * The binary is called apache2. Due to the use of environment variables, in +# the default configuration, apache2 needs to be started/stopped with +# /etc/init.d/apache2 or apache2ctl. Calling /usr/bin/apache2 directly will not +# work with the default configuration. + + +# Global configuration +# + +ServerName myserver.mydomain.edu +ServerAdmin support@mydomain.edu + +# +# ServerRoot: The top of the directory tree under which the server's +# configuration, error, and log files are kept. +# +# NOTE! If you intend to place this on an NFS (or otherwise network) +# mounted filesystem then please read the Mutex documentation (available +# at ); +# you will save yourself a lot of trouble. +# +# Do NOT add a slash at the end of the directory path. +# +#ServerRoot "/etc/apache2" + +# +# The accept serialization lock file MUST BE STORED ON A LOCAL DISK. +# +#Mutex file:${APACHE_LOCK_DIR} default + +# +# The directory where shm and other runtime files will be stored. +# + +DefaultRuntimeDir ${APACHE_RUN_DIR} + +# +# PidFile: The file in which the server should record its process +# identification number when it starts. +# This needs to be set in /etc/apache2/envvars +# +PidFile ${APACHE_PID_FILE} + +# +# Timeout: The number of seconds before receives and sends time out. +# +Timeout 1200 + +# +# KeepAlive: Whether or not to allow persistent connections (more than +# one request per connection). Set to "Off" to deactivate. +# +KeepAlive On + +# +# MaxKeepAliveRequests: The maximum number of requests to allow +# during a persistent connection. Set to 0 to allow an unlimited amount. +# We recommend you leave this number high, for maximum performance. +# +MaxKeepAliveRequests 100 + +# +# KeepAliveTimeout: Number of seconds to wait for the next request from the +# same client on the same connection. +# +KeepAliveTimeout 5 + + +# These need to be set in /etc/apache2/envvars +User ${APACHE_RUN_USER} +Group ${APACHE_RUN_GROUP} + +# +# HostnameLookups: Log the names of clients or just their IP addresses +# e.g., www.apache.org (on) or 204.62.129.132 (off). +# The default is off because it'd be overall better for the net if people +# had to knowingly turn this feature on, since enabling it means that +# each client request will result in AT LEAST one lookup request to the +# nameserver. +# +HostnameLookups Off + +# ErrorLog: The location of the error log file. +# If you do not specify an ErrorLog directive within a +# container, error messages relating to that virtual host will be +# logged here. If you *do* define an error logfile for a +# container, that host's errors will be logged there and not here. +# +ErrorLog ${APACHE_LOG_DIR}/error.log + +# +# LogLevel: Control the severity of messages logged to the error_log. +# Available values: trace8, ..., trace1, debug, info, notice, warn, +# error, crit, alert, emerg. +# It is also possible to configure the log level for particular modules, e.g. +# "LogLevel info ssl:warn" +# +LogLevel warn + +# Include module configuration: +IncludeOptional mods-enabled/*.load +IncludeOptional mods-enabled/*.conf + +# Include list of ports to listen on +Include ports.conf + + +# Sets the default security model of the Apache2 HTTPD server. It does +# not allow access to the root filesystem outside of /usr/share and /var/www. +# The former is used by web applications packaged in Debian, +# the latter may be used for local directories served by the web server. If +# your system is serving content from a sub-directory in /srv you must allow +# access here, or in any related virtual host. + + Options FollowSymLinks + AllowOverride None + Require all denied + + + + AllowOverride None + Require all granted + + + + Options Indexes FollowSymLinks + AllowOverride None + Require all granted + + + + Options Indexes FollowSymLinks + AllowOverride All + Require all granted + + +# +# Options Indexes FollowSymLinks +# AllowOverride None +# Require all granted +# + + +# AccessFileName: The name of the file to look for in each directory +# for additional configuration directives. See also the AllowOverride +# directive. +# +AccessFileName .htaccess + +# +# The following lines prevent .htaccess and .htpasswd files from being +# viewed by Web clients. +# + + Require all denied + + + +# +# The following directives define some format nicknames for use with +# a CustomLog directive. +# +# These deviate from the Common Log Format definitions in that they use %O +# (the actual bytes sent including headers) instead of %b (the size of the +# requested file), because the latter makes it impossible to detect partial +# requests. +# +# Note that the use of %{X-Forwarded-For}i instead of %h is not recommended. +# Use mod_remoteip instead. +# +LogFormat "%v:%p %h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" vhost_combined +LogFormat "%h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined +LogFormat "%h %l %u %t \"%r\" %>s %O" common +LogFormat "%{Referer}i -> %U" referer +LogFormat "%{User-agent}i" agent + +# Include of directories ignores editors' and dpkg's backup files, +# see README.Debian for details. + +# Include generic snippets of statements +IncludeOptional conf-enabled/*.conf + +# Include the virtual host configurations: +IncludeOptional sites-enabled/*.conf + +# vim: syntax=apache ts=4 sw=4 sts=4 sr noet diff --git a/docker-config/apache/htaccess b/docker-config/apache/htaccess new file mode 100644 index 0000000000..0003da531b --- /dev/null +++ b/docker-config/apache/htaccess @@ -0,0 +1 @@ +Redirect /index.html https://myserver.mydomain.edu/webwork2/ diff --git a/docker-config/apache/index.html b/docker-config/apache/index.html new file mode 100644 index 0000000000..dc2ebed7f7 --- /dev/null +++ b/docker-config/apache/index.html @@ -0,0 +1,12 @@ + + + + + WeBWorK site - redirects to main page + + + You probably want to use the + the WeBWorK list of courses page + + + diff --git a/docker-config/apache/mpm_prefork.conf b/docker-config/apache/mpm_prefork.conf new file mode 100644 index 0000000000..1ebb9aba57 --- /dev/null +++ b/docker-config/apache/mpm_prefork.conf @@ -0,0 +1,19 @@ +# prefork MPM +# StartServers: number of server processes to start +# MinSpareServers: minimum number of server processes which are kept spare +# MaxSpareServers: maximum number of server processes which are kept spare +# MaxRequestWorkers: maximum number of server processes allowed to start +# MaxConnectionsPerChild: maximum number of requests a server process serves + + + StartServers 5 + MinSpareServers 5 + MaxSpareServers 15 + MaxRequestWorkers 20 + MaxConnectionsPerChild 50 + + +# Was MaxRequestWorkers 30 +# Was MaxConnectionsPerChild 100 +# +# vim: syntax=apache ts=4 sw=4 sts=4 sr noet diff --git a/docker-config/db/mariadb.cnf b/docker-config/db/mariadb.cnf index 22c4abce0b..88245b35b9 100644 --- a/docker-config/db/mariadb.cnf +++ b/docker-config/db/mariadb.cnf @@ -32,3 +32,13 @@ character_set_server = utf8mb4 collation_server = utf8mb4_general_ci init-connect='SET NAMES utf8mb4' +# Increase max_connections +max_connections = 500 + +# Modify: +# wait_timeout (default usually 28800), +# interactive_timeout (default usually 28800), +# net_read_timeout (default usually 60) +wait_timeout = 28800 +interactive_timeout = 28800 +net_read_timeout = 3600 diff --git a/docker-entrypoint.sh b/docker-config/docker-entrypoint.sh similarity index 51% rename from docker-entrypoint.sh rename to docker-config/docker-entrypoint.sh index 7860cee2f5..29242f9a0c 100755 --- a/docker-entrypoint.sh +++ b/docker-config/docker-entrypoint.sh @@ -6,12 +6,57 @@ if [ "${1:0:1}" = '-' ]; then set -- apache2 "$@" fi +# Enable SSL when it is requested by the SSL environment variable +if [ $SSL -eq 1 ]; then + echo "Enabling SSL" + a2enmod ssl && a2ensite default-ssl +fi + +# Build more locales +if [ "$ADD_LOCALES" != "0" ]; then + echo "Rebulding locales - adding: $ADD_LOCALES" + cp -a /etc/locale.gen /etc/locale.gen.orig + /bin/echo -e "en_US ISO-8859-1\nen_US.UTF-8 UTF-8\n$ADD_LOCALES" > /etc/locale.gen.tmp + /usr/bin/tr "," "\n" < /etc/locale.gen.tmp > /etc/locale.gen + rm /etc/locale.gen.orig + /usr/sbin/locale-gen +fi + +# Set system timezone if not the default UTC +if [ "$SYSTEM_TIMEZONE" != "UTC" ]; then + echo "Setting system timezone to $SYSTEM_TIMEZONE" + rm /etc/localtime + rm /etc/timezone + echo "$SYSTEM_TIMEZONE" > /etc/timezone + dpkg-reconfigure -f noninteractive tzdata +fi + +# Modify default papersize based on environment variable PAPERSIZE +echo "Setting libpaper1 papersize to $PAPERSIZE" +echo "libpaper1 libpaper/defaultpaper select $PAPERSIZE\nlibpaper1:amd64 libpaper/defaultpaper select $PAPERSIZE\ndebconf debconf/frontend select Noninteractive" > /tmp/preseed.txt +debconf-set-selections /tmp/preseed.txt +dpkg-reconfigure -f noninteractive libpaper1 +# Install some extra packages +if [ "$ADD_PACKAGES" != "0" ]; then + apt-get update + apt-get install -y --no-install-recommends --no-install-suggests $ADD_PACKAGES +fi + +# If necessary, install the OPL in the running container, hopefully in persistent storage +if [ ! -d "$APP_ROOT/libraries/webwork-open-problem-library/OpenProblemLibrary" ]; then + echo "Installing the OPL - This takes time - please be patient." + cd $APP_ROOT/libraries/ + /usr/bin/git clone -v --progress --single-branch --branch master --depth 1 https://github.com/openwebwork/webwork-open-problem-library.git + # The next line forces the system to run OPL-update below, as we just installed it + rm $APP_ROOT/webwork2/htdocs/DATA/tagging-taxonomy.json +fi if [ "$1" = 'apache2' ]; then # generate conf files if not exist for i in site.conf localOverrides.conf; do if [ ! -f $APP_ROOT/webwork2/conf/$i ]; then + echo "Creating a new $APP_ROOT/webwork2/conf/$i" cp $APP_ROOT/webwork2/conf/$i.dist $APP_ROOT/webwork2/conf/$i if [ $i == 'site.conf' ]; then sed -i -e 's/webwork_url = '\''\/webwork2'\''/webwork_url = $ENV{"WEBWORK_URL"}/' \ @@ -22,7 +67,7 @@ if [ "$1" = 'apache2' ]; then -e 's/mail{smtpServer} = '\'''\''/mail{smtpServer} = $ENV{"WEBWORK_SMTP_SERVER"}/' \ -e 's/mail{smtpSender} = '\'''\''/mail{smtpSender} = $ENV{"WEBWORK_SMTP_SENDER"}/' \ -e 's/siteDefaults{timezone} = "America\/New_York"/siteDefaults{timezone} = $ENV{"WEBWORK_TIMEZONE"}/' \ - -e 's/$server_groupID = '\''wwdata'\''/$server_groupID = "root"/' \ + -e 's/$server_groupID = '\''wwdata'\''/$server_groupID = "www-data"/' \ $APP_ROOT/webwork2/conf/site.conf fi fi @@ -36,7 +81,7 @@ if [ "$1" = 'apache2' ]; then umask 2 cd $APP_ROOT/courses WEBWORK_ROOT=$APP_ROOT/webwork2 $APP_ROOT/webwork2/bin/addcourse admin --db-layout=sql_single --users=$APP_ROOT/webwork2/courses.dist/adminClasslist.lst --professors=admin - chown www-data:root -R $APP_ROOT/courses + chown www-data:www-data -R $APP_ROOT/courses echo "Admin course is created." fi # modelCourses link if not existing @@ -48,11 +93,12 @@ if [ "$1" = 'apache2' ]; then fi # create htdocs/tmp directory if not existing if [ ! -d "$APP_ROOT/webwork2/htdocs/tmp" ]; then + echo "Creating htdocs/tmp directory" mkdir $APP_ROOT/webwork2/htdocs/tmp + chown www-data:www-data -R $APP_ROOT/webwork2/htdocs/tmp echo "htdocs/tmp directory created" fi - chown www-data:root -R $APP_ROOT/webwork2/htdocs/tmp - + # defaultClasslist.lst and adminClasslist.lst files if not existing if [ ! -f "$APP_ROOT/courses/defaultClasslist.lst" ]; then echo "defaultClasslist.lst is being created" @@ -66,36 +112,45 @@ if [ "$1" = 'apache2' ]; then fi # run OPL-update if necessary if [ ! -f "$APP_ROOT/webwork2/htdocs/DATA/tagging-taxonomy.json" ]; then + echo "About to start OPL-update. This takes time - please be patient." cd $APP_ROOT/webwork2/bin ./OPL-update fi - + # Compile chromatic/color.c if necessary - may be needed for PG directory mounted from outside image + if [ ! -f "$APP_ROOT/pg/lib/chromatic/color" ]; then + cd $APP_ROOT/pg/lib/chromatic + gcc color.c -o color + fi # generate apache2 reload config if needed if [ $DEV -eq 1 ]; then - echo "PerlModule Apache2::Reload" > /etc/apache2/conf-enabled/apache2-reload.conf + echo "PerlModule Apache2::Reload" >> /etc/apache2/conf-enabled/apache2-reload.conf echo "PerlInitHandler Apache2::Reload" >> /etc/apache2/conf-enabled/apache2-reload.conf echo "Running in DEV mode..." else + if [ $SSL -eq 0 ]; then rm -f /etc/apache2/conf-enabled/apache2-reload.conf + fi fi # Fix possible permission issues echo "Fixing ownership and permissions (just in case it is needed)" cd $APP_ROOT/webwork2 - rm -rf htdocs/tmp/* # pointers which which have no target shut down the rebuild process. - # the tmp directory is rebuilt automatically at the cost of some speed. - chown -R www-data logs tmp DATA htdocs/tmp + # Symbolic links which have no target outside the Docker container + # cause problems duringt the rebuild process on some systems. + # So we delete them. They will be rebuilt automatically when needed again + # at the cost of some speed. + find htdocs/tmp -type l -exec rm -f {} \; + chown -R www-data:www-data logs tmp DATA htdocs/tmp chmod -R u+w logs tmp DATA ../courses htdocs/tmp cd $APP_ROOT - find courses -type f -exec chown www-data:root {} \; - find courses -type d -exec chown www-data:root {} \; - - # echo "start cpan install XML::Simple" - # cpan install XML::Simple - # echo "end fixing ownership and permissions" - # OLD: chown www-data -R $APP_ROOT/courses - # but that sometimes caused errors in Docker on Mac OS X when there was a broken symbolic link somewhere in the directory tree being processed + # The chown for files/directories under courses is done using find, as + # using a simple "chown -R www-data $APP_ROOT/courses" would sometimes + # cause errors in Docker on Mac OS X when there was a broken symbolic link + # somewhere in the directory tree being processed. + find courses -type f -exec chown www-data:www-data {} \; + find courses -type d -exec chown www-data:www-data {} \; + echo "end fixing ownership and permissions" fi - exec "$@" +exec "$@" diff --git a/docker-config/ssl/default-ssl.conf b/docker-config/ssl/default-ssl.conf new file mode 100644 index 0000000000..0bd30d4292 --- /dev/null +++ b/docker-config/ssl/default-ssl.conf @@ -0,0 +1,45 @@ + + + # This fake virtual host is intented to capture traffic which + # spoofs the "Host:" header value for security reasons. + # It will deny ALL such traffic. + ServerName fake + DocumentRoot "/var/www/html/" + SSLEngine on + SSLCertificateFile /etc/ssl/local/my.crt + SSLCertificateKeyFile /etc/ssl/local/my.key + SSLCertificateChainFile /etc/ssl/local/myCA_chain.crt + + Order deny,allow + deny from all + + + + + ServerAdmin support@mydomain.edu + DocumentRoot /var/www/html/ + ServerName myserver.mydomain.edu + ServerAlias myserver.mydomain.edu + + UseCanonicalName On + + ErrorLog ${APACHE_LOG_DIR}/error.log + CustomLog ${APACHE_LOG_DIR}/access.log combined + + SSLEngine on + + SSLCertificateFile /etc/ssl/local/my.crt + SSLCertificateKeyFile /etc/ssl/local/my.key + SSLCertificateChainFile /etc/ssl/local/myCA_chain.crt + + + SSLOptions +StdEnvVars + + + SSLOptions +StdEnvVars + + + + + +# vim: syntax=apache ts=4 sw=4 sts=4 sr noet diff --git a/docker-config/ssl/local/PutYourCertificate_and_key_here.txt b/docker-config/ssl/local/PutYourCertificate_and_key_here.txt new file mode 100644 index 0000000000..a1eb1a947d --- /dev/null +++ b/docker-config/ssl/local/PutYourCertificate_and_key_here.txt @@ -0,0 +1,8 @@ +This directory should have your real SSL key and certificate, and +the Certificate Authority's root certificate or certrificate chain. + +The file names should match those defined in default-ssl.conf, ex: + + SSLCertificateFile /etc/ssl/local/my.crt + SSLCertificateKeyFile /etc/ssl/local/my.key + SSLCertificateChainFile /etc/ssl/local/myCA_chain.crt diff --git a/docker-config/ssl/local/my.crt b/docker-config/ssl/local/my.crt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/docker-config/ssl/local/my.key b/docker-config/ssl/local/my.key new file mode 100644 index 0000000000..e69de29bb2 diff --git a/docker-config/ssl/local/myCA_chain.crt b/docker-config/ssl/local/myCA_chain.crt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/docker-config/ssl/ssl.conf b/docker-config/ssl/ssl.conf new file mode 100644 index 0000000000..7e364639e9 --- /dev/null +++ b/docker-config/ssl/ssl.conf @@ -0,0 +1,85 @@ + + + # Pseudo Random Number Generator (PRNG): + # Configure one or more sources to seed the PRNG of the SSL library. + # The seed data should be of good random quality. + # WARNING! On some platforms /dev/random blocks if not enough entropy + # is available. This means you then cannot use the /dev/random device + # because it would lead to very long connection times (as long as + # it requires to make more entropy available). But usually those + # platforms additionally provide a /dev/urandom device which doesn't + # block. So, if available, use this one instead. Read the mod_ssl User + # Manual for more details. + # + SSLRandomSeed startup builtin + SSLRandomSeed startup file:/dev/urandom 512 + SSLRandomSeed connect builtin + SSLRandomSeed connect file:/dev/urandom 512 + + ## + ## SSL Global Context + ## + ## All SSL configuration in this context applies both to + ## the main server and all SSL-enabled virtual hosts. + ## + + # + # Some MIME-types for downloading Certificates and CRLs + # + AddType application/x-x509-ca-cert .crt + AddType application/x-pkcs7-crl .crl + + # Pass Phrase Dialog: + # Configure the pass phrase gathering process. + # The filtering dialog program (`builtin' is a internal + # terminal dialog) has to provide the pass phrase on stdout. + SSLPassPhraseDialog exec:/usr/share/apache2/ask-for-passphrase + + # Inter-Process Session Cache: + # Configure the SSL Session Cache: First the mechanism + # to use and second the expiring timeout (in seconds). + # (The mechanism dbm has known memory leaks and should not be used). + #SSLSessionCache dbm:${APACHE_RUN_DIR}/ssl_scache + SSLSessionCache shmcb:${APACHE_RUN_DIR}/ssl_scache(512000) + SSLSessionCacheTimeout 300 + + # Semaphore: + # Configure the path to the mutual exclusion semaphore the + # SSL engine uses internally for inter-process synchronization. + # (Disabled by default, the global Mutex directive consolidates by default + # this) + #Mutex file:${APACHE_LOCK_DIR}/ssl_mutex ssl-cache + + + # SSL Cipher Suite: + # List the ciphers that the client is permitted to negotiate. See the + # ciphers(1) man page from the openssl package for list of all available + # options. + # Enable only secure ciphers: + SSLCipherSuite HIGH:!aNULL + + # SSL server cipher order preference: + # Use server priorities for cipher algorithm choice. + # Clients may prefer lower grade encryption. You should enable this + # option if you want to enforce stronger encryption, and can afford + # the CPU cost, and did not override SSLCipherSuite in a way that puts + # insecure ciphers first. + # Default: Off + #SSLHonorCipherOrder on + + # The protocols to enable. + # Available values: all, SSLv3, TLSv1, TLSv1.1, TLSv1.2 + # SSL v2 is no longer supported + SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1 + + # Allow insecure renegotiation with clients which do not yet support the + # secure renegotiation protocol. Default: Off + #SSLInsecureRenegotiation on + + # Whether to forbid non-SNI clients to access name based virtual hosts. + # Default: Off + #SSLStrictSNIVHostCheck On + + + +# vim: syntax=apache ts=4 sw=4 sts=4 sr noet From 850f008086a6bad0ee91365ca6c55326939c5b15 Mon Sep 17 00:00:00 2001 From: Nathan Wallach Date: Sun, 4 Aug 2019 02:43:48 +0300 Subject: [PATCH 02/16] Modify handling to trigger/run OPL-update. --- docker-config/docker-entrypoint.sh | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/docker-config/docker-entrypoint.sh b/docker-config/docker-entrypoint.sh index 29242f9a0c..56024bf41c 100755 --- a/docker-config/docker-entrypoint.sh +++ b/docker-config/docker-entrypoint.sh @@ -49,7 +49,7 @@ if [ ! -d "$APP_ROOT/libraries/webwork-open-problem-library/OpenProblemLibrary" cd $APP_ROOT/libraries/ /usr/bin/git clone -v --progress --single-branch --branch master --depth 1 https://github.com/openwebwork/webwork-open-problem-library.git # The next line forces the system to run OPL-update below, as we just installed it - rm $APP_ROOT/webwork2/htdocs/DATA/tagging-taxonomy.json + touch "$APP_ROOT/libraries/RunOPLupdate" fi if [ "$1" = 'apache2' ]; then @@ -112,9 +112,17 @@ if [ "$1" = 'apache2' ]; then fi # run OPL-update if necessary if [ ! -f "$APP_ROOT/webwork2/htdocs/DATA/tagging-taxonomy.json" ]; then - echo "About to start OPL-update. This takes time - please be patient." + # The next line forces the system to run OPL-update below, as the + # tagging-taxonomy.json file was found to be missing. + echo "We will run OPL-update as the tagging-taxonomy.json file is missing in webwork2/htdocs/DATA/." + echo "Check if you should be mounting webwork2/htdocs/DATA/ from outside the Docker image!" + touch "$APP_ROOT/libraries/RunOPLupdate" + fi + if [ -f "$APP_ROOT/libraries/RunOPLupdate" ]; then + echo "About to start OPL-update. This takes a long time - please be patient." cd $APP_ROOT/webwork2/bin ./OPL-update + rm $APP_ROOT/libraries/RunOPLupdate fi # Compile chromatic/color.c if necessary - may be needed for PG directory mounted from outside image if [ ! -f "$APP_ROOT/pg/lib/chromatic/color" ]; then From ef670ca75c514e2162fa73b4dd0688bb835abb02 Mon Sep 17 00:00:00 2001 From: Florian Heiderich Date: Fri, 16 Aug 2019 13:49:36 +0200 Subject: [PATCH 03/16] call update-OPL-statistics after restore-OPL-tables Author: Florian Heiderich --- docker-config/docker-entrypoint.sh | 36 +++++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/docker-config/docker-entrypoint.sh b/docker-config/docker-entrypoint.sh index 56024bf41c..7a172a8c7b 100755 --- a/docker-config/docker-entrypoint.sh +++ b/docker-config/docker-entrypoint.sh @@ -48,7 +48,7 @@ if [ ! -d "$APP_ROOT/libraries/webwork-open-problem-library/OpenProblemLibrary" echo "Installing the OPL - This takes time - please be patient." cd $APP_ROOT/libraries/ /usr/bin/git clone -v --progress --single-branch --branch master --depth 1 https://github.com/openwebwork/webwork-open-problem-library.git - # The next line forces the system to run OPL-update below, as we just installed it + # The next line forces the system to run OPL-update or load saved OPL tables below, as we just installed it touch "$APP_ROOT/libraries/RunOPLupdate" fi @@ -114,14 +114,40 @@ if [ "$1" = 'apache2' ]; then if [ ! -f "$APP_ROOT/webwork2/htdocs/DATA/tagging-taxonomy.json" ]; then # The next line forces the system to run OPL-update below, as the # tagging-taxonomy.json file was found to be missing. - echo "We will run OPL-update as the tagging-taxonomy.json file is missing in webwork2/htdocs/DATA/." - echo "Check if you should be mounting webwork2/htdocs/DATA/ from outside the Docker image!" + if [ -f "$APP_ROOT/libraries/webwork-open-problem-library/TABLE-DUMP/OPL-tables.sql" ]; then + echo "The tagging-taxonomy.json file is missing in webwork2/htdocs/DATA/." + echo "But the libraries/webwork-open-problem-library/TABLE-DUMP/OPL-tables.sql files was seen" + echo "so the OPL tables and the JSON files will (hopefully) be restored from save versions" + else + echo "We will run OPL-update as the tagging-taxonomy.json file is missing in webwork2/htdocs/DATA/." + echo "Check if you should be mounting webwork2/htdocs/DATA/ from outside the Docker image!" + fi touch "$APP_ROOT/libraries/RunOPLupdate" fi if [ -f "$APP_ROOT/libraries/RunOPLupdate" ]; then - echo "About to start OPL-update. This takes a long time - please be patient." cd $APP_ROOT/webwork2/bin - ./OPL-update + if [ -f "$APP_ROOT/libraries/webwork-open-problem-library/TABLE-DUMP/OPL-tables.sql" ]; then + echo "Restoring OPL tables from the TABLE-DUMP/OPL-tables.sql file" + ./restore-OPL-tables + ./update-OPL-statistics + if [ -d $APP_ROOT/libraries/webwork-open-problem-library/JSON-SAVED ]; then + # Restore saved JSON files + echo "Restoring JSON files from JSON-SAVED directory" + cp -a $APP_ROOT/libraries/webwork-open-problem-library/JSON-SAVED/*.json $APP_ROOT/webwork2/htdocs/DATA/ + else + echo "No webwork-open-problem-library/JSON-SAVED directory was found." + echo "You are missing some of the JSON files including tagging-taxonomy.json" + echo "Some of the library functions will not work properly" + fi + else + echo "About to start OPL-update. This takes a long time - please be patient." + ./OPL-update + # Dump the OPL tables, to allow a quick restore in the future + ./dump-OPL-tables + # Save a copy of the generated JSON files + mkdir -p $APP_ROOT/libraries/webwork-open-problem-library/JSON-SAVED + cp -a $APP_ROOT/webwork2/htdocs/DATA/*.json $APP_ROOT/libraries/webwork-open-problem-library/JSON-SAVED + fi rm $APP_ROOT/libraries/RunOPLupdate fi # Compile chromatic/color.c if necessary - may be needed for PG directory mounted from outside image From b2bcceddf5b716f2d8a494b0e527b38941459531 Mon Sep 17 00:00:00 2001 From: Florian Heiderich Date: Thu, 15 Aug 2019 13:57:32 +0200 Subject: [PATCH 04/16] add `wait_for_db` function and use it at several places --- docker-config/docker-entrypoint.sh | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/docker-config/docker-entrypoint.sh b/docker-config/docker-entrypoint.sh index 7a172a8c7b..4d09e74792 100755 --- a/docker-config/docker-entrypoint.sh +++ b/docker-config/docker-entrypoint.sh @@ -1,6 +1,13 @@ #!/bin/bash set -eo pipefail +function wait_for_db { + echo "Waiting for database to become available..." + while ! timeout 1 bash -c "(cat < /dev/null > /dev/tcp/$WEBWORK_DB_HOST/$WEBWORK_DB_PORT) >/dev/null 2>&1"; do \ + echo "waiting..." + sleep 0.5; \ + done +} # if command starts with an option, prepend apache2 if [ "${1:0:1}" = '-' ]; then set -- apache2 "$@" @@ -74,12 +81,10 @@ if [ "$1" = 'apache2' ]; then done # create admin course if not existing if [ ! -d "$APP_ROOT/courses/admin" ]; then - # wait for db to start up - echo "Waiting for database to start..." - while ! timeout 1 bash -c "(cat < /dev/null > /dev/tcp/$WEBWORK_DB_HOST/$WEBWORK_DB_PORT) >/dev/null 2>&1"; do sleep 0.5; done newgrp www-data umask 2 cd $APP_ROOT/courses + wait_for_db WEBWORK_ROOT=$APP_ROOT/webwork2 $APP_ROOT/webwork2/bin/addcourse admin --db-layout=sql_single --users=$APP_ROOT/webwork2/courses.dist/adminClasslist.lst --professors=admin chown www-data:www-data -R $APP_ROOT/courses echo "Admin course is created." @@ -128,6 +133,7 @@ if [ "$1" = 'apache2' ]; then cd $APP_ROOT/webwork2/bin if [ -f "$APP_ROOT/libraries/webwork-open-problem-library/TABLE-DUMP/OPL-tables.sql" ]; then echo "Restoring OPL tables from the TABLE-DUMP/OPL-tables.sql file" + wait_for_db ./restore-OPL-tables ./update-OPL-statistics if [ -d $APP_ROOT/libraries/webwork-open-problem-library/JSON-SAVED ]; then @@ -141,6 +147,7 @@ if [ "$1" = 'apache2' ]; then fi else echo "About to start OPL-update. This takes a long time - please be patient." + wait_for_db ./OPL-update # Dump the OPL tables, to allow a quick restore in the future ./dump-OPL-tables From 0e45bca7fb616b3d10e3f9353cb7e48e0eb7b16c Mon Sep 17 00:00:00 2001 From: Nathan Wallach Date: Fri, 16 Aug 2019 18:01:56 +0300 Subject: [PATCH 05/16] Small fixes - see GitHub discussion --- Dockerfile | 2 ++ docker-compose.yml | 13 ++++++++++++- docker-config/docker-entrypoint.sh | 15 ++++++++++----- 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/Dockerfile b/Dockerfile index 2e21950479..443af176d7 100644 --- a/Dockerfile +++ b/Dockerfile @@ -28,6 +28,8 @@ # will set the system timezone to zone/city # Make sure to use a valid setting. # "/usr/bin/timedatectl list-timezones" on Ubuntu will find valid values +# ADD_PACKAGES="package1 package2 package3" +# will have these additional Ubuntu packages installed at startup. # # ================================================================== diff --git a/docker-compose.yml b/docker-compose.yml index 5d0492925d..bd1a749dfe 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -146,18 +146,29 @@ services: # Old default: #WEBWORK_DB_PASSWORD: passwordRW + # ======================================================= + # Local configuration variables: + # To turn on SSL in the running container #SSL: 1 # Change to A4 paper #PAPERSIZE: a4 - # Use to build additional locales in the running container at startup + # Use to build additional locales in the running container at startup. Ex: #ADD_LOCALES: he_IL ISO-8859-8,he_IL.UTF-8 UTF-8 # Extra Ubuntu packages to install during startup #ADD_PACKAGES: mc vim telnet + # The system timezone for the container can be set using + #SYSTEM_TIMEZONE: zone/city + # where zone/city must be a valid setting. + # "/usr/bin/timedatectl list-timezones" on an Ubuntu system with + # that tool installed will find valid values. + + # ======================================================= + # If you use https below, make sure to set up the certificate and SSL configuration # WEBWORK_ROOT_URL: https://myhost.mydomain.edu diff --git a/docker-config/docker-entrypoint.sh b/docker-config/docker-entrypoint.sh index 4d09e74792..9f49e88849 100755 --- a/docker-config/docker-entrypoint.sh +++ b/docker-config/docker-entrypoint.sh @@ -55,8 +55,13 @@ if [ ! -d "$APP_ROOT/libraries/webwork-open-problem-library/OpenProblemLibrary" echo "Installing the OPL - This takes time - please be patient." cd $APP_ROOT/libraries/ /usr/bin/git clone -v --progress --single-branch --branch master --depth 1 https://github.com/openwebwork/webwork-open-problem-library.git + + # FIXME / TO-DO : Download a saved version of the OPL sql table data to be loaded and extract + # it in the appropriate location.This would avoid the need for a length run of OPL-update. + # At present, a distribution point has not been set up for such data. + # The next line forces the system to run OPL-update or load saved OPL tables below, as we just installed it - touch "$APP_ROOT/libraries/RunOPLupdate" + touch "$APP_ROOT/libraries/Restore_or_build_OPL_tables" fi if [ "$1" = 'apache2' ]; then @@ -127,15 +132,15 @@ if [ "$1" = 'apache2' ]; then echo "We will run OPL-update as the tagging-taxonomy.json file is missing in webwork2/htdocs/DATA/." echo "Check if you should be mounting webwork2/htdocs/DATA/ from outside the Docker image!" fi - touch "$APP_ROOT/libraries/RunOPLupdate" + touch "$APP_ROOT/libraries/Restore_or_build_OPL_tables" fi - if [ -f "$APP_ROOT/libraries/RunOPLupdate" ]; then + if [ -f "$APP_ROOT/libraries/Restore_or_build_OPL_tables" ]; then cd $APP_ROOT/webwork2/bin if [ -f "$APP_ROOT/libraries/webwork-open-problem-library/TABLE-DUMP/OPL-tables.sql" ]; then echo "Restoring OPL tables from the TABLE-DUMP/OPL-tables.sql file" wait_for_db ./restore-OPL-tables - ./update-OPL-statistics + ./load-OPL-global-statistics if [ -d $APP_ROOT/libraries/webwork-open-problem-library/JSON-SAVED ]; then # Restore saved JSON files echo "Restoring JSON files from JSON-SAVED directory" @@ -155,7 +160,7 @@ if [ "$1" = 'apache2' ]; then mkdir -p $APP_ROOT/libraries/webwork-open-problem-library/JSON-SAVED cp -a $APP_ROOT/webwork2/htdocs/DATA/*.json $APP_ROOT/libraries/webwork-open-problem-library/JSON-SAVED fi - rm $APP_ROOT/libraries/RunOPLupdate + rm $APP_ROOT/libraries/Restore_or_build_OPL_tables fi # Compile chromatic/color.c if necessary - may be needed for PG directory mounted from outside image if [ ! -f "$APP_ROOT/pg/lib/chromatic/color" ]; then From aea3413826497a706ff5a27914ddeb32f0f30180 Mon Sep 17 00:00:00 2001 From: Florian Heiderich Date: Mon, 19 Aug 2019 13:15:37 +0200 Subject: [PATCH 06/16] introduce build time arguments for the branches of webwork2 and pg --- Dockerfile | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/Dockerfile b/Dockerfile index 443af176d7..86e29ec5ee 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,3 +1,4 @@ + # Optional things to change/configure below: # # 1. Which branch of webwork2/ and pg/ to install. @@ -38,24 +39,27 @@ FROM alpine/git AS base -WORKDIR /opt/base +# build args specifying the branches for webwork2 and pg used to build the image -# Currently set to use the 2.15 branches or WeBWorK and PG +# To use the master branches of webwork2 and pg +#ARG WEBWORK2_BRANCH=master +#ARG PG_BRANCH=master +# To use the 2.15 branches or webwork2 and pg +ARG WEBWORK2_BRANCH=WeBWorK-2.15 +ARG PG_BRANCH=PG-2.15 -# WeBWorK master branch: -#RUN git clone --single-branch --branch master --depth 1 https://github.com/openwebwork/webwork2.git \ -# && rm -rf webwork2/.git webwork2/{*ignore,Dockerfile,docker-compose.yml,docker-config} +# assign the build args WEBWORK2_BRANCH and PG_BRANCH to the ENV WEBWORK2_BRANCH_ENV and PG_BRANCH_ENV, resp. +ENV WEBWORK2_BRANCH_ENV ${WEBWORK2_BRANCH} +ENV PG_BRANCH_ENV ${PG_BRANCH} -# WeBWorK 2.15 branch: -RUN git clone --single-branch --branch WeBWorK-2.15 --depth 1 https://github.com/openwebwork/webwork2.git \ - && rm -rf webwork2/.git webwork2/{*ignore,Dockerfile,docker-compose.yml,docker-config} +WORKDIR /opt/base -# PG master branch: -#RUN git clone --single-branch --branch master --depth 1 https://github.com/openwebwork/pg.git \ -# && rm -rf pg/.git +RUN echo Cloning branch $WEBWORK2_BRANCH_ENV from https://github.com/openwebwork/webwork2.git \ + && git clone --single-branch --branch ${WEBWORK2_BRANCH_ENV} --depth 1 https://github.com/openwebwork/webwork2.git \ + && rm -rf webwork2/.git webwork2/{*ignore,Dockerfile,docker-compose.yml,docker-config} -# PG 2.15 branch: -RUN git clone --single-branch --branch PG-2.15 --depth 1 https://github.com/openwebwork/pg.git \ +RUN echo Cloning branch $PG_BRANCH_ENV branch from https://github.com/openwebwork/pg.git \ + && git clone --single-branch --branch ${PG_BRANCH_ENV} --depth 1 https://github.com/openwebwork/pg.git \ && rm -rf pg/.git RUN git clone --single-branch --branch master --depth 1 https://github.com/mathjax/MathJax \ From 07dc83484aba074be926ac37bc26d6ba3980ac15 Mon Sep 17 00:00:00 2001 From: Florian Heiderich Date: Mon, 19 Aug 2019 15:45:11 +0200 Subject: [PATCH 07/16] define the environment variable COURSES_DIRECTORY_ON_HOST in .env and use it instead of the hard-coded string "../ww-docker-data/courses" in docker-compose.yml --- .env | 1 + docker-compose.yml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 .env diff --git a/.env b/.env new file mode 100644 index 0000000000..e853c16e18 --- /dev/null +++ b/.env @@ -0,0 +1 @@ +COURSES_DIRECTORY_ON_HOST=../ww-docker-data/courses diff --git a/docker-compose.yml b/docker-compose.yml index bd1a749dfe..d384564be6 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -78,7 +78,7 @@ services: #- "/per_host_data_path/webwork2/htdocs/tmp:/opt/webwork/webwork2/htdocs/tmp" # By default the courses tree in a separate tree outside of webwork2/ as follows: - - "../ww-docker-data/courses:/opt/webwork/courses" + - "${COURSES_DIRECTORY_ON_HOST}:/opt/webwork/courses" # OR mount like (here we are assuming that the hosts have different courses on them) #- "/per_host_data_path/courses/:/opt/webwork/courses/" From f4d3573f77e5ed21082a3ad998d3f890a9f8a528 Mon Sep 17 00:00:00 2001 From: Florian Heiderich Date: Tue, 20 Aug 2019 11:19:23 +0200 Subject: [PATCH 08/16] introduce environment variable WEBWORK2_HTTP_PORT_ON_HOST --- .env | 1 + docker-compose.yml | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.env b/.env index e853c16e18..e939abfe73 100644 --- a/.env +++ b/.env @@ -1 +1,2 @@ COURSES_DIRECTORY_ON_HOST=../ww-docker-data/courses +WEBWORK2_HTTP_PORT_ON_HOST=8080 diff --git a/docker-compose.yml b/docker-compose.yml index d384564be6..8c664e2629 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -125,8 +125,7 @@ services: hostname: myhost.mydomain.edu ports: - # For a personal machine - - "8080:80" + - "${WEBWORK2_HTTP_PORT_ON_HOST}:80" # For a production machine #- "80:80" From cf7e0f84dfa88c7970e40f0bbd864c931b32d2c4 Mon Sep 17 00:00:00 2001 From: Florian Heiderich Date: Tue, 20 Aug 2019 12:13:43 +0200 Subject: [PATCH 09/16] introduce environment variables WEBWORK_DB_USER and WEBWORK_DB_PASSWORD and remove comments on old default --- .env | 2 ++ docker-compose.yml | 11 +++-------- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/.env b/.env index e939abfe73..0b99a88cb5 100644 --- a/.env +++ b/.env @@ -1,2 +1,4 @@ COURSES_DIRECTORY_ON_HOST=../ww-docker-data/courses WEBWORK2_HTTP_PORT_ON_HOST=8080 +WEBWORK_DB_USER=webworkWrite +WEBWORK_DB_PASSWORD=passwordRWsetItBeforeFirstStartingTheDBcontainer diff --git a/docker-compose.yml b/docker-compose.yml index 8c664e2629..a69c3dcbf1 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -20,10 +20,8 @@ services: # When the MariaDB container is first started it will create # the WW database and WW DB user based on: MYSQL_DATABASE: webwork - MYSQL_USER: webworkWrite - MYSQL_PASSWORD: passwordRWsetItBeforeFirstStartingTheDBcontainer - # Old default: - #MYSQL_PASSWORD: passwordRW + MYSQL_USER: ${WEBWORK_DB_USER} + MYSQL_PASSWORD: ${WEBWORK_DB_PASSWORD} app: image: webwork @@ -140,10 +138,7 @@ services: APACHE_RUN_GROUP: www-data - WEBWORK_DB_PASSWORD: passwordRWsetItBeforeFirstStartingTheDBcontainer - # should be the same password as MYSQL_PASSWORD above. - # Old default: - #WEBWORK_DB_PASSWORD: passwordRW + WEBWORK_DB_PASSWORD: ${WEBWORK_DB_PASSWORD} # ======================================================= # Local configuration variables: From 28c0fb49f06e9fc2b768cc399609159f51534d77 Mon Sep 17 00:00:00 2001 From: Nathan Wallach Date: Tue, 20 Aug 2019 15:58:40 +0300 Subject: [PATCH 10/16] Remove the old lines which refered to a special container/data volume for utf8mb4 - dbMB4 --- docker-compose.yml | 7 ------- 1 file changed, 7 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index a69c3dcbf1..982658e1d4 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -4,8 +4,6 @@ services: image: mariadb:10.4 volumes: - mysql:/var/lib/mysql - # When using "dbMB4" as the name of the Docker DB volume, comment out line above and uncomment the line below - #- mysqlMB4:/var/lib/mysql # Set up UTF8MB4 in config file for the container. # Needs to be done BEFORE the database is created. @@ -171,9 +169,6 @@ services: # WEBWORK_TIMEZONE: America/New_York - # For when using "dbMB4" as the name of the Docker DB volume: - #WEBWORK_DB_HOST: dbMB4 - #WEBWORK_DB_DSN: DBI:mysql:webwork:dbMB4:3306 r: image: ubcctlt/rserve # # The R server need not be available from outside the local Docker network. @@ -183,5 +178,3 @@ services: volumes: oplVolume: mysql: - # When using "dbMB4" as the name of the Docker DB volume, comment out line above and uncomment the line below - #mysqlMB4: From 87da69dc87fb4270fab2d676d4a62470c0363e19 Mon Sep 17 00:00:00 2001 From: Nathan Wallach Date: Tue, 20 Aug 2019 16:29:01 +0300 Subject: [PATCH 11/16] Remove all the WEBWORK_DB_* environment variables from Dockerfile. Set them all in docker-compose.yml, where some depend on the .env file. --- Dockerfile | 13 +------------ docker-compose.yml | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/Dockerfile b/Dockerfile index 86e29ec5ee..e69b77f81d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -77,18 +77,8 @@ RUN git clone --single-branch --branch master --depth 1 https://github.com/mathj FROM ubuntu:18.04 -# WARNING: The real value of WEBWORK_DB_PASSWORD is set in docker-compose.yml via the -# value of MYSQL_PASSWORD at the time the MariaDB container is first initialized. -# Thus the value of WEBWORK_DB_PASSWORD should usually also be set in docker-compose.yml. -# Several other environment values should usually be set via docker-compose.yml. - ENV WEBWORK_URL=/webwork2 \ WEBWORK_ROOT_URL=http://localhost \ - WEBWORK_DB_HOST=db \ - WEBWORK_DB_PORT=3306 \ - WEBWORK_DB_NAME=webwork \ - WEBWORK_DB_USER=webworkWrite \ - WEBWORK_DB_PASSWORD=passwordRW \ WEBWORK_SMTP_SERVER=localhost \ WEBWORK_SMTP_SENDER=webwork@example.com \ WEBWORK_TIMEZONE=America/New_York \ @@ -107,8 +97,7 @@ ENV WEBWORK_URL=/webwork2 \ # Environment variables which depend on a prior environment variable must be set # in an ENV call after the dependencies were defined. -ENV WEBWORK_DB_DSN=DBI:mysql:${WEBWORK_DB_NAME}:${WEBWORK_DB_HOST}:${WEBWORK_DB_PORT} \ - WEBWORK_ROOT=$APP_ROOT/webwork2 \ +ENV WEBWORK_ROOT=$APP_ROOT/webwork2 \ PG_ROOT=$APP_ROOT/pg \ PATH=$PATH:$APP_ROOT/webwork2/bin diff --git a/docker-compose.yml b/docker-compose.yml index 982658e1d4..a22c3a3453 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -121,6 +121,7 @@ services: hostname: myhost.mydomain.edu ports: + # For a personal machine - "${WEBWORK2_HTTP_PORT_ON_HOST}:80" # For a production machine @@ -136,7 +137,20 @@ services: APACHE_RUN_GROUP: www-data + # Standard database environment variables needed by WeBWorK: + WEBWORK_DB_HOST: db + WEBWORK_DB_PORT: 3306 + WEBWORK_DB_NAME: webwork + WEBWORK_DB_DSN: DBI:mysql:webwork:db:3306 + # We currently need to put the same data in the WEBWORK_DB_DSN line above + # as we cannot use the following form, as it would be done before the values + # needed are available. + # NO GOOD # WEBWORK_DB_DSN: DBI:mysql${WEBWORK_DB_NAME}:${WEBWORK_DB_HOST}:${WEBWORK_DB_PORT} + + + # These are set in the .env file and import values from there WEBWORK_DB_PASSWORD: ${WEBWORK_DB_PASSWORD} + WEBWORK_DB_USER: ${WEBWORK_DB_USER} # ======================================================= # Local configuration variables: From 36b21830b4c61b0610fa0dd529083940468ce90c Mon Sep 17 00:00:00 2001 From: Florian Heiderich Date: Wed, 21 Aug 2019 09:52:19 +0200 Subject: [PATCH 12/16] replace `$APP_ROOT/webwork2` by `$WEBWORK_ROOT` --- docker-config/docker-entrypoint.sh | 32 +++++++++++++++--------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/docker-config/docker-entrypoint.sh b/docker-config/docker-entrypoint.sh index 9f49e88849..12eb63cd81 100755 --- a/docker-config/docker-entrypoint.sh +++ b/docker-config/docker-entrypoint.sh @@ -67,9 +67,9 @@ fi if [ "$1" = 'apache2' ]; then # generate conf files if not exist for i in site.conf localOverrides.conf; do - if [ ! -f $APP_ROOT/webwork2/conf/$i ]; then - echo "Creating a new $APP_ROOT/webwork2/conf/$i" - cp $APP_ROOT/webwork2/conf/$i.dist $APP_ROOT/webwork2/conf/$i + if [ ! -f $WEBWORK_ROOT/conf/$i ]; then + echo "Creating a new $WEBWORK_ROOT/conf/$i" + cp $WEBWORK_ROOT/conf/$i.dist $WEBWORK_ROOT/conf/$i if [ $i == 'site.conf' ]; then sed -i -e 's/webwork_url = '\''\/webwork2'\''/webwork_url = $ENV{"WEBWORK_URL"}/' \ -e 's/server_root_url = '\'''\''/server_root_url = $ENV{"WEBWORK_ROOT_URL"}/' \ @@ -80,7 +80,7 @@ if [ "$1" = 'apache2' ]; then -e 's/mail{smtpSender} = '\'''\''/mail{smtpSender} = $ENV{"WEBWORK_SMTP_SENDER"}/' \ -e 's/siteDefaults{timezone} = "America\/New_York"/siteDefaults{timezone} = $ENV{"WEBWORK_TIMEZONE"}/' \ -e 's/$server_groupID = '\''wwdata'\''/$server_groupID = "www-data"/' \ - $APP_ROOT/webwork2/conf/site.conf + $WEBWORK_ROOT/conf/site.conf fi fi done @@ -90,7 +90,7 @@ if [ "$1" = 'apache2' ]; then umask 2 cd $APP_ROOT/courses wait_for_db - WEBWORK_ROOT=$APP_ROOT/webwork2 $APP_ROOT/webwork2/bin/addcourse admin --db-layout=sql_single --users=$APP_ROOT/webwork2/courses.dist/adminClasslist.lst --professors=admin + $WEBWORK_ROOT/bin/addcourse admin --db-layout=sql_single --users=$WEBWORK_ROOT/courses.dist/adminClasslist.lst --professors=admin chown www-data:www-data -R $APP_ROOT/courses echo "Admin course is created." fi @@ -98,30 +98,30 @@ if [ "$1" = 'apache2' ]; then if [ ! -d "$APP_ROOT/courses/modelCourse" ]; then echo "create modelCourse subdirectory" rm -rf $APP_ROOT/courses/modelCourse - cd $APP_ROOT/webwork2/courses.dist + cd $WEBWORK_ROOT/courses.dist cp -R modelCourse $APP_ROOT/courses/ fi # create htdocs/tmp directory if not existing - if [ ! -d "$APP_ROOT/webwork2/htdocs/tmp" ]; then + if [ ! -d "$WEBWORK_ROOT/htdocs/tmp" ]; then echo "Creating htdocs/tmp directory" - mkdir $APP_ROOT/webwork2/htdocs/tmp - chown www-data:www-data -R $APP_ROOT/webwork2/htdocs/tmp + mkdir $WEBWORK_ROOT/htdocs/tmp + chown www-data:www-data -R $WEBWORK_ROOT/htdocs/tmp echo "htdocs/tmp directory created" fi # defaultClasslist.lst and adminClasslist.lst files if not existing if [ ! -f "$APP_ROOT/courses/defaultClasslist.lst" ]; then echo "defaultClasslist.lst is being created" - cd $APP_ROOT/webwork2/courses.dist + cd $WEBWORK_ROOT/courses.dist cp *.lst $APP_ROOT/courses/ fi if [ ! -f "$APP_ROOT/courses/adminClasslist.lst" ]; then echo "adminClasslist.lst is being created" - cd $APP_ROOT/webwork2/courses.dist + cd $WEBWORK_ROOT/courses.dist cp *.lst $APP_ROOT/courses/ fi # run OPL-update if necessary - if [ ! -f "$APP_ROOT/webwork2/htdocs/DATA/tagging-taxonomy.json" ]; then + if [ ! -f "$WEBWORK_ROOT/htdocs/DATA/tagging-taxonomy.json" ]; then # The next line forces the system to run OPL-update below, as the # tagging-taxonomy.json file was found to be missing. if [ -f "$APP_ROOT/libraries/webwork-open-problem-library/TABLE-DUMP/OPL-tables.sql" ]; then @@ -135,7 +135,7 @@ if [ "$1" = 'apache2' ]; then touch "$APP_ROOT/libraries/Restore_or_build_OPL_tables" fi if [ -f "$APP_ROOT/libraries/Restore_or_build_OPL_tables" ]; then - cd $APP_ROOT/webwork2/bin + cd $WEBWORK_ROOT/bin if [ -f "$APP_ROOT/libraries/webwork-open-problem-library/TABLE-DUMP/OPL-tables.sql" ]; then echo "Restoring OPL tables from the TABLE-DUMP/OPL-tables.sql file" wait_for_db @@ -144,7 +144,7 @@ if [ "$1" = 'apache2' ]; then if [ -d $APP_ROOT/libraries/webwork-open-problem-library/JSON-SAVED ]; then # Restore saved JSON files echo "Restoring JSON files from JSON-SAVED directory" - cp -a $APP_ROOT/libraries/webwork-open-problem-library/JSON-SAVED/*.json $APP_ROOT/webwork2/htdocs/DATA/ + cp -a $APP_ROOT/libraries/webwork-open-problem-library/JSON-SAVED/*.json $WEBWORK_ROOT/htdocs/DATA/ else echo "No webwork-open-problem-library/JSON-SAVED directory was found." echo "You are missing some of the JSON files including tagging-taxonomy.json" @@ -158,7 +158,7 @@ if [ "$1" = 'apache2' ]; then ./dump-OPL-tables # Save a copy of the generated JSON files mkdir -p $APP_ROOT/libraries/webwork-open-problem-library/JSON-SAVED - cp -a $APP_ROOT/webwork2/htdocs/DATA/*.json $APP_ROOT/libraries/webwork-open-problem-library/JSON-SAVED + cp -a $WEBWORK_ROOT/htdocs/DATA/*.json $APP_ROOT/libraries/webwork-open-problem-library/JSON-SAVED fi rm $APP_ROOT/libraries/Restore_or_build_OPL_tables fi @@ -180,7 +180,7 @@ if [ "$1" = 'apache2' ]; then # Fix possible permission issues echo "Fixing ownership and permissions (just in case it is needed)" - cd $APP_ROOT/webwork2 + cd $WEBWORK_ROOT # Symbolic links which have no target outside the Docker container # cause problems duringt the rebuild process on some systems. # So we delete them. They will be rebuilt automatically when needed again From 129ae22def251970358166cd8e6eedbcd3efae4f Mon Sep 17 00:00:00 2001 From: Florian Heiderich Date: Wed, 21 Aug 2019 10:39:54 +0200 Subject: [PATCH 13/16] use absolute paths; spaces --- docker-config/docker-entrypoint.sh | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/docker-config/docker-entrypoint.sh b/docker-config/docker-entrypoint.sh index 12eb63cd81..53a5d692b8 100755 --- a/docker-config/docker-entrypoint.sh +++ b/docker-config/docker-entrypoint.sh @@ -89,7 +89,7 @@ if [ "$1" = 'apache2' ]; then newgrp www-data umask 2 cd $APP_ROOT/courses - wait_for_db + wait_for_db $WEBWORK_ROOT/bin/addcourse admin --db-layout=sql_single --users=$WEBWORK_ROOT/courses.dist/adminClasslist.lst --professors=admin chown www-data:www-data -R $APP_ROOT/courses echo "Admin course is created." @@ -135,12 +135,11 @@ if [ "$1" = 'apache2' ]; then touch "$APP_ROOT/libraries/Restore_or_build_OPL_tables" fi if [ -f "$APP_ROOT/libraries/Restore_or_build_OPL_tables" ]; then - cd $WEBWORK_ROOT/bin if [ -f "$APP_ROOT/libraries/webwork-open-problem-library/TABLE-DUMP/OPL-tables.sql" ]; then echo "Restoring OPL tables from the TABLE-DUMP/OPL-tables.sql file" - wait_for_db - ./restore-OPL-tables - ./load-OPL-global-statistics + wait_for_db + $WEBWORK_ROOT/bin/restore-OPL-tables + $WEBWORK_ROOT/bin/load-OPL-global-statistics if [ -d $APP_ROOT/libraries/webwork-open-problem-library/JSON-SAVED ]; then # Restore saved JSON files echo "Restoring JSON files from JSON-SAVED directory" @@ -152,10 +151,10 @@ if [ "$1" = 'apache2' ]; then fi else echo "About to start OPL-update. This takes a long time - please be patient." - wait_for_db - ./OPL-update - # Dump the OPL tables, to allow a quick restore in the future - ./dump-OPL-tables + wait_for_db + $WEBWORK_ROOT/bin/OPL-update + # Dump the OPL tables, to allow a quick restore in the future + $WEBWORK_ROOT/bin/dump-OPL-tables # Save a copy of the generated JSON files mkdir -p $APP_ROOT/libraries/webwork-open-problem-library/JSON-SAVED cp -a $WEBWORK_ROOT/htdocs/DATA/*.json $APP_ROOT/libraries/webwork-open-problem-library/JSON-SAVED From aab2c400e5493b11cb8df0bf9ef87327fe73ce72 Mon Sep 17 00:00:00 2001 From: Florian Heiderich Date: Wed, 21 Aug 2019 14:55:24 +0200 Subject: [PATCH 14/16] fix typo in Dockerfile --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index e69b77f81d..773277dc63 100644 --- a/Dockerfile +++ b/Dockerfile @@ -44,7 +44,7 @@ FROM alpine/git AS base # To use the master branches of webwork2 and pg #ARG WEBWORK2_BRANCH=master #ARG PG_BRANCH=master -# To use the 2.15 branches or webwork2 and pg +# To use the 2.15 branches of webwork2 and pg ARG WEBWORK2_BRANCH=WeBWorK-2.15 ARG PG_BRANCH=PG-2.15 From f3ae7bd98f84596a451bb31ac938ad57ba66f98a Mon Sep 17 00:00:00 2001 From: Florian Heiderich Date: Wed, 21 Aug 2019 15:29:10 +0200 Subject: [PATCH 15/16] remove option "--depth 1" --- docker-config/docker-entrypoint.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-config/docker-entrypoint.sh b/docker-config/docker-entrypoint.sh index 9f49e88849..546f63adb1 100755 --- a/docker-config/docker-entrypoint.sh +++ b/docker-config/docker-entrypoint.sh @@ -54,7 +54,7 @@ fi if [ ! -d "$APP_ROOT/libraries/webwork-open-problem-library/OpenProblemLibrary" ]; then echo "Installing the OPL - This takes time - please be patient." cd $APP_ROOT/libraries/ - /usr/bin/git clone -v --progress --single-branch --branch master --depth 1 https://github.com/openwebwork/webwork-open-problem-library.git + /usr/bin/git clone -v --progress --single-branch --branch master https://github.com/openwebwork/webwork-open-problem-library.git # FIXME / TO-DO : Download a saved version of the OPL sql table data to be loaded and extract # it in the appropriate location.This would avoid the need for a length run of OPL-update. From 967eba9934844595bcc46697b49e504be4c4a7d5 Mon Sep 17 00:00:00 2001 From: Nathan Wallach Date: Wed, 21 Aug 2019 21:59:40 +0300 Subject: [PATCH 16/16] Modified to use the script names ending in .pl after the name changes in PR 985 --- docker-config/docker-entrypoint.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docker-config/docker-entrypoint.sh b/docker-config/docker-entrypoint.sh index 97ddef0ecf..31d944aad9 100755 --- a/docker-config/docker-entrypoint.sh +++ b/docker-config/docker-entrypoint.sh @@ -138,8 +138,8 @@ if [ "$1" = 'apache2' ]; then if [ -f "$APP_ROOT/libraries/webwork-open-problem-library/TABLE-DUMP/OPL-tables.sql" ]; then echo "Restoring OPL tables from the TABLE-DUMP/OPL-tables.sql file" wait_for_db - $WEBWORK_ROOT/bin/restore-OPL-tables - $WEBWORK_ROOT/bin/load-OPL-global-statistics + $WEBWORK_ROOT/bin/restore-OPL-tables.pl + $WEBWORK_ROOT/bin/load-OPL-global-statistics.pl if [ -d $APP_ROOT/libraries/webwork-open-problem-library/JSON-SAVED ]; then # Restore saved JSON files echo "Restoring JSON files from JSON-SAVED directory" @@ -154,7 +154,7 @@ if [ "$1" = 'apache2' ]; then wait_for_db $WEBWORK_ROOT/bin/OPL-update # Dump the OPL tables, to allow a quick restore in the future - $WEBWORK_ROOT/bin/dump-OPL-tables + $WEBWORK_ROOT/bin/dump-OPL-tables.pl # Save a copy of the generated JSON files mkdir -p $APP_ROOT/libraries/webwork-open-problem-library/JSON-SAVED cp -a $WEBWORK_ROOT/htdocs/DATA/*.json $APP_ROOT/libraries/webwork-open-problem-library/JSON-SAVED