197 lines
6.7 KiB
Docker
197 lines
6.7 KiB
Docker
FROM ubuntu:focal as minimal-system
|
|
|
|
# Warning: This file is experimental.
|
|
#
|
|
# Short-term goals:
|
|
# * Be a suitable replacement for the `edxops/edxapp` image in devstack (in progress).
|
|
# * Take advantage of Docker caching layers: aim to put commands in order of
|
|
# increasing cache-busting frequency.
|
|
# * Related to ^, use no Ansible or Paver.
|
|
# Long-term goal:
|
|
# * Be a suitable base for production LMS and CMS images (THIS IS NOT YET THE CASE!).
|
|
|
|
ARG DEBIAN_FRONTEND=noninteractive
|
|
ARG SERVICE_VARIANT
|
|
ARG SERVICE_PORT
|
|
|
|
# Env vars: paver
|
|
# We intentionally don't use paver in this Dockerfile, but Devstack may invoke paver commands
|
|
# during provisioning. Enabling NO_PREREQ_INSTALL tells paver not to re-install Python
|
|
# requirements for every paver command, potentially saving a lot of developer time.
|
|
ARG NO_PREREQ_INSTALL='1'
|
|
|
|
# Env vars: locale
|
|
ENV LANG='en_US.UTF-8'
|
|
ENV LANGUAGE='en_US:en'
|
|
ENV LC_ALL='en_US.UTF-8'
|
|
|
|
# Env vars: configuration
|
|
ENV CONFIG_ROOT='/edx/etc'
|
|
ENV LMS_CFG="$CONFIG_ROOT/lms.yml"
|
|
ENV CMS_CFG="$CONFIG_ROOT/cms.yml"
|
|
|
|
# Env vars: path
|
|
ENV VIRTUAL_ENV="/edx/app/edxapp/venvs/edxapp"
|
|
ENV PATH="${VIRTUAL_ENV}/bin:${PATH}"
|
|
ENV PATH="/edx/app/edxapp/edx-platform/node_modules/.bin:${PATH}"
|
|
ENV PATH="/edx/app/edxapp/edx-platform/bin:${PATH}"
|
|
ENV PATH="/edx/app/edxapp/nodeenv/bin:${PATH}"
|
|
|
|
WORKDIR /edx/app/edxapp/edx-platform
|
|
|
|
# Create user before assigning any directory ownership to it.
|
|
RUN useradd -m --shell /bin/false app
|
|
|
|
# Use debconf to set locales to be generated when the locales apt package is installed later.
|
|
RUN echo "locales locales/default_environment_locale select en_US.UTF-8" | debconf-set-selections
|
|
RUN echo "locales locales/locales_to_be_generated multiselect en_US.UTF-8 UTF-8" | debconf-set-selections
|
|
|
|
# Install requirements that are absolutely necessary
|
|
RUN apt-get update && \
|
|
apt-get -y dist-upgrade && \
|
|
apt-get -y install --no-install-recommends \
|
|
python3 \
|
|
python3-venv \
|
|
python3.8 \
|
|
python3.8-minimal \
|
|
# python3-dev: required for building mysqlclient python package version 2.2.0
|
|
python3-dev \
|
|
libpython3.8 \
|
|
libpython3.8-stdlib \
|
|
libmysqlclient21 \
|
|
# libmysqlclient-dev: required for building mysqlclient python package version 2.2.0
|
|
libmysqlclient-dev \
|
|
pkg-config \
|
|
libssl1.1 \
|
|
libxmlsec1-openssl \
|
|
# lynx: Required by https://github.com/openedx/edx-platform/blob/b489a4ecb122/openedx/core/lib/html_to_text.py#L16
|
|
lynx \
|
|
ntp \
|
|
git \
|
|
build-essential \
|
|
gettext \
|
|
gfortran \
|
|
graphviz \
|
|
locales \
|
|
swig \
|
|
&& \
|
|
apt-get clean all && \
|
|
rm -rf /var/lib/apt/*
|
|
|
|
RUN mkdir -p /edx/var/edxapp
|
|
RUN mkdir -p /edx/etc
|
|
RUN chown app:app /edx/var/edxapp
|
|
|
|
# The builder-production stage is a temporary stage that installs required packages and builds the python virtualenv,
|
|
# installs nodejs and node_modules.
|
|
# The built artifacts from this stage are then copied to the base stage.
|
|
FROM minimal-system as builder-production
|
|
|
|
RUN apt-get update && \
|
|
apt-get -y install --no-install-recommends \
|
|
curl \
|
|
libssl-dev \
|
|
libffi-dev \
|
|
libfreetype6-dev \
|
|
libgeos-dev \
|
|
libgraphviz-dev \
|
|
libjpeg8-dev \
|
|
liblapack-dev \
|
|
libpng-dev \
|
|
libsqlite3-dev \
|
|
libxml2-dev \
|
|
libxmlsec1-dev \
|
|
libxslt1-dev
|
|
|
|
# Setup python virtual environment
|
|
# It is already 'activated' because $VIRTUAL_ENV/bin was put on $PATH
|
|
RUN python3.8 -m venv "${VIRTUAL_ENV}"
|
|
|
|
# Install python requirements
|
|
# Requires copying over requirements files, but not entire repository
|
|
COPY requirements requirements
|
|
RUN pip install -r requirements/pip.txt
|
|
RUN pip install -r requirements/edx/base.txt
|
|
|
|
# Install node and npm
|
|
RUN nodeenv /edx/app/edxapp/nodeenv --node=18.19.0 --prebuilt
|
|
RUN npm install -g npm@10.5.x
|
|
|
|
# This script is used by an npm post-install hook.
|
|
# We copy it into the image now so that it will be available when we run `npm install` in the next step.
|
|
# The script itself will copy certain modules into some uber-legacy parts of edx-platform which still use RequireJS.
|
|
COPY scripts/copy-node-modules.sh scripts/copy-node-modules.sh
|
|
|
|
# Install node modules
|
|
COPY package.json package.json
|
|
COPY package-lock.json package-lock.json
|
|
RUN npm set progress=false && npm ci
|
|
|
|
# The builder-development stage is a temporary stage that installs python modules required for development purposes
|
|
# The built artifacts from this stage are then copied to the development stage.
|
|
FROM builder-production as builder-development
|
|
|
|
RUN pip install -r requirements/edx/development.txt
|
|
|
|
# base stage
|
|
FROM minimal-system as base
|
|
|
|
# Copy python virtual environment, nodejs and node_modules
|
|
COPY --from=builder-production /edx/app/edxapp/venvs/edxapp /edx/app/edxapp/venvs/edxapp
|
|
COPY --from=builder-production /edx/app/edxapp/nodeenv /edx/app/edxapp/nodeenv
|
|
COPY --from=builder-production /edx/app/edxapp/edx-platform/node_modules /edx/app/edxapp/edx-platform/node_modules
|
|
|
|
# Copy over remaining parts of repository (including all code)
|
|
COPY . .
|
|
|
|
# Install Python requirements again in order to capture local projects
|
|
RUN pip install -e .
|
|
|
|
# Setting edx-platform directory as safe for git commands
|
|
RUN git config --global --add safe.directory /edx/app/edxapp/edx-platform
|
|
|
|
# Production target
|
|
FROM base as production
|
|
|
|
USER app
|
|
|
|
ENV EDX_PLATFORM_SETTINGS='docker-production'
|
|
ENV SERVICE_VARIANT="${SERVICE_VARIANT}"
|
|
ENV SERVICE_PORT="${SERVICE_PORT}"
|
|
ENV DJANGO_SETTINGS_MODULE="${SERVICE_VARIANT}.envs.$EDX_PLATFORM_SETTINGS"
|
|
EXPOSE ${SERVICE_PORT}
|
|
|
|
CMD gunicorn \
|
|
-c /edx/app/edxapp/edx-platform/${SERVICE_VARIANT}/docker_${SERVICE_VARIANT}_gunicorn.py \
|
|
--name ${SERVICE_VARIANT} \
|
|
--bind=0.0.0.0:${SERVICE_PORT} \
|
|
--max-requests=1000 \
|
|
--access-logfile \
|
|
- ${SERVICE_VARIANT}.wsgi:application
|
|
|
|
# Development target
|
|
FROM base as development
|
|
|
|
RUN apt-get update && \
|
|
apt-get -y install --no-install-recommends \
|
|
# wget is used in Makefile for common_constraints.txt
|
|
wget \
|
|
&& \
|
|
apt-get clean all && \
|
|
rm -rf /var/lib/apt/*
|
|
|
|
COPY --from=builder-development /edx/app/edxapp/venvs/edxapp /edx/app/edxapp/venvs/edxapp
|
|
|
|
RUN ln -s "$(pwd)/lms/envs/devstack-experimental.yml" "$LMS_CFG"
|
|
RUN ln -s "$(pwd)/cms/envs/devstack-experimental.yml" "$CMS_CFG"
|
|
# Temporary compatibility hack while devstack is supporting both the old `edxops/edxapp` image and this image.
|
|
# * Add in a dummy ../edxapp_env file
|
|
# * devstack sets /edx/etc/studio.yml as CMS_CFG.
|
|
RUN ln -s "$(pwd)/cms/envs/devstack-experimental.yml" "/edx/etc/studio.yml"
|
|
RUN touch ../edxapp_env
|
|
|
|
ENV EDX_PLATFORM_SETTINGS='devstack_docker'
|
|
ENV SERVICE_VARIANT="${SERVICE_VARIANT}"
|
|
EXPOSE ${SERVICE_PORT}
|
|
CMD ./manage.py ${SERVICE_VARIANT} runserver 0.0.0.0:${SERVICE_PORT}
|