From 49ce8b849902124fcf28e0df0151c39b9f39645b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9gis=20Behmo?= Date: Mon, 3 Oct 2022 12:00:11 +0200 Subject: [PATCH 1/2] fix: installation of local requirements The `compilejsi18n` command was failing during image building because the Open-edX package was not installed properly. The reason for that was an earlier change where we got rid of the `pip install -r requirements/edx/local.in` command. Installing the Open-edX package was part of this requirement file. The local.in requirements file no longer exists, but we still need to `pip install -e .` the edx-platform repo. To run this command we need both the edx-platform repo and the virtualenv. The good news is that there are no more local requirements in the base.txt requirements file. This means that we no longer have to COPY the edx-platform repo in the requirements installation step. Thus, changes in edx-platform will no longer trigger a rebuild of the pip requirements; this means that re-builds will be much faster when making changes to edx-platform. Note that plugins that implemented the "openedx-dockerfile-post-python-requirements" patch and that needed access to the edx-platform repo will no longer work. Instead, these plugins should implement the "openedx-dockerfile-pre-assets" patch. This scenario should be very rare, though. Close #726 --- CHANGELOG-nightly.md | 1 + tutor/templates/build/openedx/Dockerfile | 15 ++++++--------- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/CHANGELOG-nightly.md b/CHANGELOG-nightly.md index bf85f74697..5f89eb7d4c 100644 --- a/CHANGELOG-nightly.md +++ b/CHANGELOG-nightly.md @@ -8,6 +8,7 @@ will be backported to the master branch at every major release. When backporting changes to master, we should keep only the entries that correspond to user- facing changes. --> +- 💥[Bugfix] Fix local installation requirements. Plugins that implemented the "openedx-dockerfile-post-python-requirements" patch and that needed access to the edx-platform repo will no longer work. Instead, these plugins should implement the "openedx-dockerfile-pre-assets" patch. This scenario should be very rare, though. (by @regisb) - 💥[Improvement] Rename the implementation of tutor quickstart to tutor launch. (by @Carlos-Muniz) - 💥[Improvement] Remove the implementation of tutor dev runserver. (by @Carlos-Muniz) - [Bugfix] Fix MongoDB replica set connection error resulting from edx-platform's pymongo (3.10.1 -> 3.12.3) upgrade ([edx-platform#30569](https://github.com/openedx/edx-platform/pull/30569)). (by @ormsbee) diff --git a/tutor/templates/build/openedx/Dockerfile b/tutor/templates/build/openedx/Dockerfile index 0a5ccbd227..4e8dd8becc 100644 --- a/tutor/templates/build/openedx/Dockerfile +++ b/tutor/templates/build/openedx/Dockerfile @@ -69,13 +69,6 @@ ENV VIRTUAL_ENV /openedx/venv/ RUN apt update && apt install -y software-properties-common libmysqlclient-dev libxmlsec1-dev libgeos-dev -# Note that this means that we need to reinstall all requirements whenever there is a -# change in edx-platform, which sucks. Yet, we must do it, because edx-platform installs some -# Python projects from within the edx-platform repo itself. This is being fixed upstream. -# TODO: https://github.com/overhangio/2u-tutor-adoption/issues/86 -COPY --from=code /openedx/edx-platform /openedx/edx-platform -WORKDIR /openedx/edx-platform - # Install the right version of pip/setuptools # https://pypi.org/project/setuptools/ # https://pypi.org/project/pip/ @@ -83,8 +76,8 @@ WORKDIR /openedx/edx-platform RUN pip install setuptools==62.1.0 pip==22.0.4 wheel==0.37.1 # Install base requirements -RUN pip install -r ./requirements/edx/base.txt -RUN pip install -e . +COPY --from=code /openedx/edx-platform/requirements/edx/base.txt /tmp/base.txt +RUN pip install -r /tmp/base.txt # Install django-redis for using redis as a django cache # https://pypi.org/project/django-redis/ @@ -148,6 +141,10 @@ ENV PATH /openedx/venv/bin:./node_modules/.bin:/openedx/nodeenv/bin:${PATH} ENV VIRTUAL_ENV /openedx/venv/ WORKDIR /openedx/edx-platform +# We install edx-platform here because it creates an egg-info folder in the current +# repo. We need both the source code and the virtualenv to run this command. +RUN pip install -e . + # Create folder that will store lms/cms.env.yml files, as well as # the tutor-specific settings files. RUN mkdir -p /openedx/config ./lms/envs/tutor ./cms/envs/tutor From 63ed3b1965a9678714ee553ff436fd0eb7556064 Mon Sep 17 00:00:00 2001 From: Kyle McCormick Date: Tue, 13 Sep 2022 17:14:10 -0400 Subject: [PATCH 2/2] feat: overhaul Dockerfile for improved developer workflow WIP --- tutor/templates/build/openedx/Dockerfile | 157 ++++++++++++++---- tutor/templates/build/openedx/bin/npm | 14 ++ .../build/openedx/bin/openedx-assets | 93 ++++++++++- .../edx-platform-overrides/overrides-test.txt | 1 + .../openedx/dev/mounted-requirements.txt | 0 tutor/templates/dev/docker-compose.yml | 2 - 6 files changed, 233 insertions(+), 34 deletions(-) create mode 100755 tutor/templates/build/openedx/bin/npm create mode 100644 tutor/templates/build/openedx/dev/edx-platform-overrides/overrides-test.txt create mode 100644 tutor/templates/build/openedx/dev/mounted-requirements.txt diff --git a/tutor/templates/build/openedx/Dockerfile b/tutor/templates/build/openedx/Dockerfile index 4e8dd8becc..4a34f034f9 100644 --- a/tutor/templates/build/openedx/Dockerfile +++ b/tutor/templates/build/openedx/Dockerfile @@ -1,27 +1,58 @@ +############################################################################# ###### Minimal image with base system requirements for most stages + FROM docker.io/ubuntu:20.04 as minimal LABEL maintainer="Overhang.io " ENV DEBIAN_FRONTEND=noninteractive +# TODO: Safe/effective to rm var/lib/apt/lists in all these places? RUN apt update && \ - apt install -y build-essential curl git language-pack-en + apt install -y \ + build-essential \ + curl \ + language-pack-en \ + git \ + && \ + rm -rf /var/lib/apt/lists/* ENV LC_ALL en_US.UTF-8 + {{ patch("openedx-dockerfile-minimal") }} -###### Install python with pyenv in /opt/pyenv and create virtualenv in /openedx/venv +############################################################################# +###### Python with pyenv in /opt/pyenv and create virtualenv in /openedx/venv + FROM minimal as python + # https://github.com/pyenv/pyenv/wiki/Common-build-problems#prerequisites RUN apt update && \ - apt install -y libssl-dev zlib1g-dev libbz2-dev \ - libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev libncursesw5-dev \ - xz-utils tk-dev libffi-dev liblzma-dev python-openssl git + apt install -y \ + curl \ + git \ + libbz2-dev \ + libffi-dev \ + liblzma-dev \ + libncurses5-dev \ + libncursesw5-dev \ + libreadline-dev \ + libsqlite3-dev \ + libssl-dev \ + llvm \ + python-openssl \ + tk-dev \ + wget \ + xz-utils \ + zlib1g-dev \ + && \ + rm -rf /var/lib/apt/lists/* ARG PYTHON_VERSION=3.8.12 ENV PYENV_ROOT /opt/pyenv RUN git clone https://github.com/pyenv/pyenv $PYENV_ROOT --branch v2.2.2 --depth 1 RUN $PYENV_ROOT/bin/pyenv install $PYTHON_VERSION RUN $PYENV_ROOT/versions/$PYTHON_VERSION/bin/python -m venv /openedx/venv -###### Install Dockerize to wait for mysql DB availability +############################################################################# +###### Dockerize stage to wait for mysql DB availability + FROM minimal as dockerize # https://github.com/powerman/dockerize/releases ARG DOCKERIZE_VERSION=v0.16.0 @@ -30,10 +61,13 @@ RUN dockerize_url="https://github.com/powerman/dockerize/releases/download/$DOCK && curl --fail --location --output /usr/local/bin/dockerize $dockerize_url \ && chmod a+x /usr/local/bin/dockerize -###### Checkout edx-platform code +############################################################################# +###### Clone edx-platform in an intermediate stage + FROM minimal as code ARG EDX_PLATFORM_REPOSITORY={{ EDX_PLATFORM_REPOSITORY }} ARG EDX_PLATFORM_VERSION={{ EDX_PLATFORM_VERSION }} +RUN echo BREAK CACHE 1 RUN mkdir -p /openedx/edx-platform && \ git clone $EDX_PLATFORM_REPOSITORY --branch $EDX_PLATFORM_VERSION --depth 1 /openedx/edx-platform WORKDIR /openedx/edx-platform @@ -52,7 +86,9 @@ RUN git config --global user.email "tutor@overhang.io" \ {# Example: RUN curl -fsSL https://github.com/openedx/edx-platform/commit/ | git am #} {{ patch("openedx-dockerfile-post-git-checkout") }} +############################################################################# ###### Download extra locales to /openedx/locale/contrib/locale + FROM minimal as locales ARG OPENEDX_I18N_VERSION={{ OPENEDX_COMMON_VERSION }} RUN cd /tmp \ @@ -62,12 +98,22 @@ RUN cd /tmp \ && mv openedx-i18n-*/edx-platform/locale /openedx/locale/contrib \ && rm -rf openedx-i18n* +############################################################################# ###### Install python requirements in virtualenv + FROM python as python-requirements ENV PATH /openedx/venv/bin:${PATH} ENV VIRTUAL_ENV /openedx/venv/ -RUN apt update && apt install -y software-properties-common libmysqlclient-dev libxmlsec1-dev libgeos-dev +# TODO: Why are these here instead of an earlier stage? +RUN apt update && \ + apt install -y \ + software-properties-common \ + libmysqlclient-dev \ + libxmlsec1-dev \ + libgeos-dev \ + && \ + rm -rf /var/lib/apt/lists/* # Install the right version of pip/setuptools # https://pypi.org/project/setuptools/ @@ -75,9 +121,6 @@ RUN apt update && apt install -y software-properties-common libmysqlclient-dev l # https://pypi.org/project/wheel/ RUN pip install setuptools==62.1.0 pip==22.0.4 wheel==0.37.1 -# Install base requirements -COPY --from=code /openedx/edx-platform/requirements/edx/base.txt /tmp/base.txt -RUN pip install -r /tmp/base.txt # Install django-redis for using redis as a django cache # https://pypi.org/project/django-redis/ @@ -87,6 +130,11 @@ RUN pip install django-redis==5.2.0 # https://pypi.org/project/uWSGI/ RUN pip install uwsgi==2.0.20 +# Install base requirements +COPY --from=code /openedx/edx-platform/requirements/edx/base.txt /openedx/edx-platform/requirements/edx/base.txt +WORKDIR /openedx/edx-platform +RUN pip install -r ./requirements/edx/base.txt + {{ patch("openedx-dockerfile-post-python-requirements") }} # Install private requirements: this is useful for installing custom xblocks. @@ -98,7 +146,9 @@ RUN cd /openedx/requirements/ \ {% for extra_requirements in OPENEDX_EXTRA_PIP_REQUIREMENTS %}RUN pip install '{{ extra_requirements }}' {% endfor %} +############################################################################# ###### Install nodejs with nodeenv in /openedx/nodeenv + FROM python as nodejs-requirements ENV PATH /openedx/nodeenv/bin:/openedx/venv/bin:${PATH} @@ -113,38 +163,67 @@ COPY --from=code /openedx/edx-platform/package-lock.json /openedx/edx-platform/p WORKDIR /openedx/edx-platform RUN npm install --verbose --registry=$NPM_REGISTRY +############################################################################# ###### Production image with system and python requirements + FROM minimal as production # Install system requirements RUN apt update && \ - apt install -y gettext gfortran graphviz graphviz-dev libffi-dev libfreetype6-dev libgeos-dev libjpeg8-dev liblapack-dev libmysqlclient-dev libpng-dev libsqlite3-dev libxmlsec1-dev lynx ntp pkg-config rdfind && \ + apt install -y \ + gettext \ + gfortran \ + graphviz \ + graphviz-dev \ + libffi-dev \ + libfreetype6-dev \ + libgeos-dev \ + libjpeg8-dev \ + liblapack-dev \ + libmysqlclient-dev \ + libpng-dev \ + libsqlite3-dev \ + libxmlsec1-dev \ + lynx \ + ntp \ + pkg-config \ + rdfind \ + && \ rm -rf /var/lib/apt/lists/* -# From then on, run as unprivileged "app" user +# From here on, run as unprivileged "app" user # Note that this must always be different from root (APP_USER_ID=0) ARG APP_USER_ID=1000 RUN if [ "$APP_USER_ID" = 0 ]; then echo "app user may not be root" && false; fi RUN useradd --home-dir /openedx --create-home --shell /bin/bash --uid ${APP_USER_ID} app USER ${APP_USER_ID} -COPY --from=dockerize /usr/local/bin/dockerize /usr/local/bin/dockerize +# Copy in everything we need from the intermediate build stages +COPY --from=dockerize /usr/local/bin/dockerize /usr/local/bin/dockerize COPY --chown=app:app --from=code /openedx/edx-platform /openedx/edx-platform COPY --chown=app:app --from=locales /openedx/locale /openedx/locale COPY --chown=app:app --from=python /opt/pyenv /opt/pyenv COPY --chown=app:app --from=python-requirements /openedx/venv /openedx/venv COPY --chown=app:app --from=python-requirements /openedx/requirements /openedx/requirements COPY --chown=app:app --from=nodejs-requirements /openedx/nodeenv /openedx/nodeenv -COPY --chown=app:app --from=nodejs-requirements /openedx/edx-platform/node_modules /openedx/edx-platform/node_modules +COPY --chown=app:app --from=nodejs-requirements /openedx/edx-platform/node_modules /openedx/node_modules +RUN mv /openedx/node_modules/.bin /openedx/node_modules/bin -ENV PATH /openedx/venv/bin:./node_modules/.bin:/openedx/nodeenv/bin:${PATH} +# Enable venv & nodeenv +ENV PATH /openedx/venv/bin:/openedx/node_modules/bin:/openedx/nodeenv/bin:${PATH} ENV VIRTUAL_ENV /openedx/venv/ WORKDIR /openedx/edx-platform # We install edx-platform here because it creates an egg-info folder in the current # repo. We need both the source code and the virtualenv to run this command. +# TODO: Is it worth fixing up setup.py so that we can just run `pip install .` ? RUN pip install -e . +# Copy scripts and put them on the path. +COPY --chown=app:app ./bin /openedx/bin +RUN chmod a+x /openedx/bin/* +ENV PATH /openedx/bin:${PATH} + # Create folder that will store lms/cms.env.yml files, as well as # the tutor-specific settings files. RUN mkdir -p /openedx/config ./lms/envs/tutor ./cms/envs/tutor @@ -167,11 +246,6 @@ RUN cd /openedx/locale/user && \ RUN ./manage.py lms --settings=tutor.i18n compilejsi18n RUN ./manage.py cms --settings=tutor.i18n compilejsi18n -# Copy scripts -COPY --chown=app:app ./bin /openedx/bin -RUN chmod a+x /openedx/bin/* -ENV PATH /openedx/bin:${PATH} - {{ patch("openedx-dockerfile-pre-assets") }} # Collect production assets. By default, only assets from the default theme @@ -183,13 +257,19 @@ ENV PATH /openedx/bin:${PATH} # /openedx/staticfiles. ENV NO_PYTHON_UNINSTALL 1 ENV NO_PREREQ_INSTALL 1 + +# TODO: This is necessary for _compile_sass currently but should be removed +RUN ln -s /openedx/node_modules +RUN cd node_modules && ln -s bin .bin + # We need to rely on a separate openedx-assets command to accelerate asset processing. # For instance, we don't want to run all steps of asset collection every time the theme # is modified. +# TODO: Can we remove the pavelib dependency? RUN openedx-assets xmodule \ - && openedx-assets npm \ - && openedx-assets webpack --env=prod \ - && openedx-assets common + && openedx-assets npm \ + && openedx-assets webpack --env=prod \ + && openedx-assets common COPY --chown=app:app ./themes/ /openedx/themes/ RUN openedx-assets themes \ && openedx-assets collect --settings=tutor.assets \ @@ -207,23 +287,38 @@ ENV DJANGO_SETTINGS_MODULE lms.envs.tutor.production EXPOSE 8000 +############################################################################# ###### Intermediate image with dev/test dependencies + FROM production as development # Install useful system requirements (as root) USER root RUN apt update && \ - apt install -y vim iputils-ping dnsutils telnet \ - && rm -rf /var/lib/apt/lists/* + apt install -y \ + dnsutils \ + iputils-ping \ + telnet \ + vim \ + && \ + rm -rf /var/lib/apt/lists/* USER app -# Install dev python requirements -RUN pip install -r requirements/edx/development.txt -RUN pip install ipdb==0.13.4 ipython==7.27.0 - # Add ipdb as default PYTHONBREAKPOINT +RUN pip install ipdb==0.13.4 ipython==7.27.0 ENV PYTHONBREAKPOINT=ipdb.set_trace +# Override any edx-platform files, as supplied by build context. +# Primarily, this allows Tutor to override /openedx/edx-platform/requirements +# when edx-platform is mounted in order to force a requirements re-install +# and static asset re-compilation below. +COPY ./dev/edx-platform-overrides /openedx/edx-platform + +# Install dev requirements +RUN pip install -r requirements/edx/development.txt +RUN npm install --dev +RUN pip install -r requirements/edx/mounted.txt + # Recompile static assets: in development mode all static assets are stored in edx-platform, # and the location of these files is stored in webpack-stats.json. If we don't recompile # static assets, then production assets will be served instead. @@ -236,8 +331,10 @@ RUN rm -r /openedx/staticfiles && \ # Default django settings ENV DJANGO_SETTINGS_MODULE lms.envs.tutor.development +COPY ./dev/mounted-requirements.txt /openedx/mounted-requirements.txt CMD ./manage.py $SERVICE_VARIANT runserver 0.0.0.0:8000 +############################################################################# ###### Final image with production cmd FROM production as final diff --git a/tutor/templates/build/openedx/bin/npm b/tutor/templates/build/openedx/bin/npm new file mode 100755 index 0000000000..bb2ceb9448 --- /dev/null +++ b/tutor/templates/build/openedx/bin/npm @@ -0,0 +1,14 @@ +#!/bin/sh +# +# Wrapper around 'npm' for openedx image. +# Ensures that npm always operates in the 'global' /openedx/node_modules directory, +# not in the 'local' /openedx/edx-platform/node_modules directory. +# +# Rationale: We want node_modules to exist outside of the edx-platform repository. +# That way, when a developer mounts a fork of edx-platform, they don't need to +# re-run `npm install` themselves, because the pre-built node_modules folder will +# still be available on the image. + +set -ue # Fail loudly. +set -x # Print next command. +/openedx/nodeenv/bin/npm --global --prefix=/openedx/node_modules "$@" diff --git a/tutor/templates/build/openedx/bin/openedx-assets b/tutor/templates/build/openedx/bin/openedx-assets index 1b89434d67..b2b5d0969b 100755 --- a/tutor/templates/build/openedx/bin/openedx-assets +++ b/tutor/templates/build/openedx/bin/openedx-assets @@ -2,6 +2,7 @@ from __future__ import print_function import argparse import os +import shlex import subprocess import sys import traceback @@ -98,6 +99,8 @@ def run_build(args): def run_xmodule(_args): + print(f"{sys.argv[0]}: Collecting xmodule assets") + # Collecting xmodule assets is incompatible with setting the django path, because # of an unfortunate call to settings.configure() django_settings_module = os.environ.get("DJANGO_SETTINGS_MODULE") @@ -114,14 +117,93 @@ def run_xmodule(_args): def run_npm(_args): - assets.process_npm_assets() + """ + Post-process npm assets. + + Reimplementation of edx-platform's pavelib/assets.py:process_npm_assets() + """ + print(f"{sys.argv[0]}: Post-processing npm assets") + + # Create JS and CSS vendor directories. + _sh( + [ + "mkdir", + "-p", + "common/static/common/js/vendor", + "common/static/common/css/vendor", + ] + ) + + # Copy studio-frontend CSS and JS into vendor directory. + copy_css = """\ +find /openedx/node_modules/@edx/studio-frontend/dist \ +-type f \( -name \*.css -o -name \*.css.map \) | \ +xargs cp --target-directory=common/static/common/css/vendor\ +""" + copy_js = """\ +find /openedx/node_modules/@edx/studio-frontend/dist \ +-type f \! -name \*.css \! -name \*.css.map | \ +xargs cp --target-directory=common/static/common/js/vendor\ +""" + _sh(["bash", "-c", copy_css]) + _sh(["bash", "-c", copy_js]) +# css_find_query = "-type f '(' -name '*.css' -o -name '*.css.map' ')'".split(" ") +# js_find_query = "-type f '!' -name '*.css' '!' -name '*.css.map'".split(" ") +# _sh( +# [ +# "find", +# "/openedx/node_modules/@edx/studio-frontend/dist", +# *css_find_query, +# "|", +# "xargs", +# "cp", +# "--target-directory=common/static/common/css/vender", +# ] +# ) +# _sh( +# [ +# "find", +# "/openedx/node_modules/@edx/studio-frontend/dist", +# *js_find_query, +# "|", +# "xargs", +# "cp", +# "--target-directory=common/static/common/js/vender", +# ] +# ) + + # Copy certain node_modules into vendor directory. + _sh( + [ + "cp", + "-f", + "--target-directory=common/static/common/js/vendor", + "/openedx/node_modules/backbone.paginator/lib/backbone.paginator.js", + "/openedx/node_modules/backbone/backbone.js", + "/openedx/node_modules/bootstrap/dist/js/bootstrap.bundle.js", + "/openedx/node_modules/hls.js/dist/hls.js", + "/openedx/node_modules/jquery-migrate/dist/jquery-migrate.js", + "/openedx/node_modules/jquery.scrollto/jquery.scrollTo.js", + "/openedx/node_modules/jquery/dist/jquery.js", + "/openedx/node_modules/moment-timezone/builds/moment-timezone-with-data.js", + "/openedx/node_modules/moment/min/moment-with-locales.js", + "/openedx/node_modules/picturefill/dist/picturefill.js", + "/openedx/node_modules/requirejs/require.js", + "/openedx/node_modules/underscore.string/dist/underscore.string.js", + "/openedx/node_modules/underscore/underscore.js", + "/openedx/node_modules/which-country/index.js", + "/openedx/node_modules/sinon/pkg/sinon.js", + "/openedx/node_modules/squirejs/src/Squire.js", + ] + ) def run_webpack(args): + print(f"{sys.argv[0]}: Executing webpack") os.environ["STATIC_ROOT_LMS"] = args.static_root os.environ["STATIC_ROOT_CMS"] = os.path.join(args.static_root, "studio") os.environ["NODE_ENV"] = {"prod": "production", "dev": "development"}[args.env] - subprocess.check_call( + _sh( [ "webpack", "--progress", @@ -131,12 +213,14 @@ def run_webpack(args): def run_common(args): + print(f"{sys.argv[0]}: Compiling sass assets from common theme") for system in args.systems: print("Compiling {} sass assets from common theme...".format(system)) assets._compile_sass(system, None, False, False, []) def run_themes(args): + print(f"{sys.argv[0]}: Compiling sass assets for custom themes") for theme_dir in args.theme_dirs: local_themes = ( list_subdirectories(theme_dir) if "all" in args.themes else args.themes @@ -154,6 +238,7 @@ def run_themes(args): def run_collect(args): + print(f"{sys.argv[0]}: Collecting assets") assets.collect_assets(args.systems, args.settings) @@ -214,5 +299,9 @@ class ThemeWatcher(assets.SassWatcher): traceback.print_exc() +def _sh(args): + print(f"+{shlex.join(args)}") + return subprocess.check_call(args) + if __name__ == "__main__": main() diff --git a/tutor/templates/build/openedx/dev/edx-platform-overrides/overrides-test.txt b/tutor/templates/build/openedx/dev/edx-platform-overrides/overrides-test.txt new file mode 100644 index 0000000000..3d9880a12c --- /dev/null +++ b/tutor/templates/build/openedx/dev/edx-platform-overrides/overrides-test.txt @@ -0,0 +1 @@ +edx-platform-overrides test file diff --git a/tutor/templates/build/openedx/dev/mounted-requirements.txt b/tutor/templates/build/openedx/dev/mounted-requirements.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tutor/templates/dev/docker-compose.yml b/tutor/templates/dev/docker-compose.yml index 58b27aa832..57d8d4bfeb 100644 --- a/tutor/templates/dev/docker-compose.yml +++ b/tutor/templates/dev/docker-compose.yml @@ -30,7 +30,6 @@ services: lms: <<: *openedx-service - command: ./manage.py lms runserver 0.0.0.0:8000 environment: DJANGO_SETTINGS_MODULE: lms.envs.tutor.development ports: @@ -42,7 +41,6 @@ services: cms: <<: *openedx-service - command: ./manage.py cms runserver 0.0.0.0:8000 environment: DJANGO_SETTINGS_MODULE: cms.envs.tutor.development ports: