forked from openwebwork/webwork2
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Dockerfile
342 lines (299 loc) · 11.7 KB
/
Dockerfile
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
# 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
# ADD_APT_PACKAGES="package1 package2 package3"
# will have these additional Ubuntu packages installed at startup.
# ==================================================================
# 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
# build args specifying the branches for webwork2 and pg used to build the image
ARG WEBWORK2_GIT_URL
ARG WEBWORK2_BRANCH
ARG PG_GIT_URL
ARG PG_BRANCH
WORKDIR /opt/base
RUN echo Cloning branch $WEBWORK2_BRANCH from $WEBWORK2_GIT_URL \
&& echo git clone --single-branch --branch ${WEBWORK2_BRANCH} --depth 1 $WEBWORK2_GIT_URL \
&& git clone --single-branch --branch ${WEBWORK2_BRANCH} --depth 1 $WEBWORK2_GIT_URL \
&& rm -rf webwork2/.git webwork2/{*ignore,Dockerfile,docker-compose.yml,docker-config}
RUN echo Cloning branch $PG_BRANCH branch from $PG_GIT_URL \
&& echo git clone --single-branch --branch ${PG_BRANCH} --depth 1 $PG_GIT_URL \
&& git clone --single-branch --branch ${PG_BRANCH} --depth 1 $PG_GIT_URL \
&& rm -rf pg/.git
# Optional - include OPL (also need to uncomment further below when an included OPL is desired):
#RUN git clone --single-branch --branch main --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:20.04
ENV WEBWORK_URL=/webwork2 \
WEBWORK_ROOT_URL=http://localhost \
WEBWORK_SMTP_SERVER=localhost \
WEBWORK_TIMEZONE=America/New_York \
APACHE_RUN_USER=www-data \
APACHE_RUN_GROUP=www-data \
# temporary state file location. This might be changed to /run in Wheezy+1 \
APACHE_PID_FILE=/var/run/apache2/apache2.pid \
APACHE_RUN_DIR=/var/run/apache2 \
APACHE_LOCK_DIR=/var/lock/apache2 \
# 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
ARG ADDITIONAL_BASE_IMAGE_PACKAGES
# Environment variables which depend on a prior environment variable must be set
# in an ENV call after the dependencies were defined.
ENV WEBWORK_ROOT=$APP_ROOT/webwork2 \
PG_ROOT=$APP_ROOT/pg \
PATH=$PATH:$APP_ROOT/webwork2/bin
# ==================================================================
# Phase 3 - Ubuntu 20.04 base image + required packages
# 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 \
dvisvgm \
gcc \
libapache2-request-perl \
libarchive-zip-perl \
libcgi-pm-perl \
libcrypt-ssleay-perl \
libdatetime-perl \
libdbd-mysql-perl \
libdbd-mariadb-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 \
libnet-https-nb-perl \
libhttp-async-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 \
libjson-maybexs-perl \
libcpanel-json-xs-perl \
libyaml-libyaml-perl \
libemail-stuffer-perl \
make \
netpbm \
patch \
pdf2svg \
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 \
zip \
iputils-ping \
imagemagick \
jq $ADDITIONAL_BASE_IMAGE_PACKAGES \
&& curl -fsSL https://deb.nodesource.com/setup_16.x | bash - \
&& apt-get install -y --no-install-recommends --no-install-suggests nodejs \
&& apt-get clean \
&& rm -fr /var/lib/apt/lists/* /tmp/*
# Developers may want to add additional packages inside the image
# such as: telnet vim mc file
# ==================================================================
# Phase 4 - Install webwork2 and pg 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
# 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.
# 6. Install third party javascript files.
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 logs tmp $APP_ROOT/pg/lib/chromatic \
&& chmod -R u+w DATA ../courses 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 \
&& cd $WEBWORK_ROOT/htdocs \
&& npm install \
&& cd $PG_ROOT/htdocs \
&& npm install
# 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/
# ==================================================================
# 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/*
# ==================================================================
# 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
# Patch files that are applied below
COPY docker-config/xmlrpc-lite-utf8-fix.patch /tmp
COPY docker-config/imagemagick-allow-pdf-read.patch /tmp
# However SSL will only be enabled at container startup via docker-entrypoint.sh.
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 \
&& a2dismod mpm_event \
&& a2enmod mpm_prefork rewrite \
&& 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 \
&& 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 \
&& sed -i -e 's/^<Perl>$/\
PerlPassEnv WEBWORK_URL\n\
PerlPassEnv WEBWORK_ROOT_URL\n\
PerlPassEnv WEBWORK_DB_DRIVER\n\
PerlPassEnv WEBWORK_DB_NAME\n\
PerlPassEnv WEBWORK_DB_HOST\n\
PerlPassEnv WEBWORK_DB_PORT\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<Perl>/' /etc/apache2/conf-enabled/webwork.conf \
&& patch -p1 -d / < /tmp/xmlrpc-lite-utf8-fix.patch \
&& rm /tmp/xmlrpc-lite-utf8-fix.patch \
&& patch -p1 -d / < /tmp/imagemagick-allow-pdf-read.patch \
&& rm /tmp/imagemagick-allow-pdf-read.patch
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"]
# ==================================================================
# Add enviroment variables to control some things during container startup
ENV SSL=0 \
PAPERSIZE=letter \
SYSTEM_TIMEZONE=UTC \
ADD_LOCALES=0 \
ADD_APT_PACKAGES=0
# ================================================
CMD ["apache2", "-DFOREGROUND"]