Skip to content
This repository was archived by the owner on Aug 1, 2024. It is now read-only.

Commit 1b0b65c

Browse files
committed
feat: mount src/ into /edx/app/src of frontend containers (#803)
Allows installation of local versions of NPM packages via module.config.js, allowing frontend devs to test out frontend library changes within devstack. The mounts follow nearly the same pattern that micro-services do, which allows devs to develop local versions of Python packages alongside devstack micro-services. See included ADR #5 for details and rationale. TNL-8407
1 parent 54fb57f commit 1b0b65c

2 files changed

Lines changed: 121 additions & 0 deletions

File tree

docker-compose-host.yml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,34 +50,44 @@ services:
5050
- edxapp_tox:/edx/app/edxapp/edx-platform/.tox
5151
- edxapp_uploads:/edx/var/edxapp/uploads
5252
- ${DEVSTACK_WORKSPACE}/src:/edx/src:cached
53+
54+
# Note that frontends mount `src` to /edx/app/src instead of /edx/src.
55+
# See ADR #5 for rationale.
5356
frontend-app-course-authoring:
5457
volumes:
5558
- ${DEVSTACK_WORKSPACE}/frontend-app-course-authoring:/edx/app/frontend-app-course-authoring:cached
5659
- frontend_app_course_authoring_node_modules:/edx/app/frontend-app-course-authoring/node_modules
60+
- ${DEVSTACK_WORKSPACE}/src:/edx/app/src:cached
5761
frontend-app-gradebook:
5862
volumes:
5963
- ${DEVSTACK_WORKSPACE}/frontend-app-gradebook:/edx/app/frontend-app-gradebook:cached
6064
- frontend_app_gradebook_node_modules:/edx/app/frontend-app-gradebook/node_modules
65+
- ${DEVSTACK_WORKSPACE}/src:/edx/app/src:cached
6166
frontend-app-learning:
6267
volumes:
6368
- ${DEVSTACK_WORKSPACE}/frontend-app-learning:/edx/app/frontend-app-learning:cached
6469
- frontend_app_learning_node_modules:/edx/app/frontend-app-learning/node_modules
70+
- ${DEVSTACK_WORKSPACE}/src:/edx/app/src:cached
6571
frontend-app-library-authoring:
6672
volumes:
6773
- ${DEVSTACK_WORKSPACE}/frontend-app-library-authoring:/edx/app/frontend-app-library-authoring:cached
6874
- frontend_app_library_authoring_node_modules:/edx/app/frontend-app-library-authoring/node_modules
75+
- ${DEVSTACK_WORKSPACE}/src:/edx/app/src:cached
6976
frontend-app-payment:
7077
volumes:
7178
- ${DEVSTACK_WORKSPACE}/frontend-app-payment:/edx/app/frontend-app-payment:cached
7279
- frontend_app_payment_node_modules:/edx/app/frontend-app-payment/node_modules
80+
- ${DEVSTACK_WORKSPACE}/src:/edx/app/src:cached
7381
frontend-app-program-console:
7482
volumes:
7583
- ${DEVSTACK_WORKSPACE}/frontend-app-program-console:/edx/app/frontend-app-program-console:cached
7684
- frontend_app_program_console_node_modules:/edx/app/frontend-app-program-console/node_modules
85+
- ${DEVSTACK_WORKSPACE}/src:/edx/app/src:cached
7786
frontend-app-publisher:
7887
volumes:
7988
- ${DEVSTACK_WORKSPACE}/frontend-app-publisher:/edx/app/frontend-app-publisher:cached
8089
- frontend_app_publisher_node_modules:/edx/app/frontend-app-publisher/node_modules
90+
- ${DEVSTACK_WORKSPACE}/src:/edx/app/src:cached
8191

8292
volumes:
8393
credentials_node_modules:
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
5. Mounting frontend packages from src directory
2+
------------------------------------------------
3+
4+
Synopsis
5+
========
6+
7+
``${DEVSTACK_WORKSPACE}/src`` will be mounted at ``/edx/app/src`` within frontend containers, allowing locally-modified NPM packages to be tested via devstack. This will result in workflow changes for some frontend developers, which we will communicate via email.
8+
9+
Status
10+
======
11+
12+
Approved
13+
14+
15+
Context
16+
=======
17+
18+
Current SOA: Local packages for backend services
19+
************************************************
20+
21+
Backend devstack services currently mount the host folder ``${DEVSTACK_WORKSPACE}/src`` into their respective Docker containers at ``/edx/src``, making the contents of ``src`` available within the container. This enables developers to install local versions of Python packages into backend devstack services, as long as the package is placed within the host ``src`` folder. As a concrete user story:
22+
23+
* A dev runs their devstack with ``~`` (home folder) as their ``${DEVSTACK_WORKSPACE}``.
24+
* They would like to run edx-platform with a modified version of the ``completion`` Python package.
25+
* So, they place their modified ``completion`` repository in ``~/src``.
26+
* The dev's modified ``completion`` repository is now available to backend containers at ``/edx/src/completion``.
27+
* Within ``make lms-shell``, they can now run ``pip install -e /edx/src/completion`` in order to install the modified package.
28+
29+
This workflow is made possible via the ``${DEVSTACK_WORKSPACE}/src:/edx/src:cached`` volume declarations for each service that exist in docker-compose-host.yml. This line simply tells docker-compose to mount the ``src`` directory within the host devstack workspace to the ``/edx/src`` directory within a service's Docker container.
30+
31+
32+
Current SOA: Local packages for frontends
33+
*****************************************
34+
35+
Unfortunately, this flow is currently *not* an option for frontend services (i.e., micro-frontends) when they're run via devstack. This was probably not an intentional omission; frontend services were added to devstack in a somewhat ad-hoc way, and the local-package workflow was probably overlooked.
36+
37+
There is, however, an established strategy for using local packages when running frontends *outside* of devstack. This stategy is described in the `frontend-build documentation <https://github.com/edx/frontend-build#local-module-configuration-for-webpack>`_. Essentially, frontend package respositories can be placed anywhere in the host system, and each frontend's ``module.config.js`` can be pointed at those local respositories using a path relative to the frontend itself. For example:
38+
39+
* A frontend dev has ``frontend-app-profile`` within their home folder (``~``).
40+
* They would like to run a modified version of Paragon, located at ``~/paragon``.
41+
* They create a ``module.config.js``, as recommended by the frontend-build docs, specifying ``../paragon`` as the path.
42+
* They can now ``npm run build`` Paragon, and then install and start ``frontend-app-profile``, which will use their modified Paragon repository.
43+
44+
45+
The issue: Making the frontend strategy work with devstack
46+
**********************************************************
47+
48+
With the acceptance of `ADR 4: Backend services now depend on frontend apps <./0004-backends-depend-on-frontends.rst>`_, it is more important than ever that devstack has a local package workflow for frontends.
49+
50+
Unfortunately, the current backend and frontend strategies are incompatible in two ways:
51+
52+
* The current frontend strategy allows package repositories to be placed anywhere in the filesystem, with the docs recommending them to be siblings of the ``frontend-app-...`` repositories. The backend strategy, on the other hand, requires packages to be placed within ``${DEVSTACK_WORKSPACE}/src``.
53+
* The frontend strategy occurs entirely within the host system; directory mounting is not required. In the backend strategy, though, packages get mounted at ``/edx/src``.
54+
55+
The implication of this is that local frontend package strategy for devstack will have to either:
56+
57+
#. be slightly different than the current non-devstack local frontend package strategy, or
58+
#. be implemented differently than devstack's current local backend package strategy.
59+
60+
61+
Decision
62+
========
63+
64+
We will introduce a local frontend package strategy to devstack that is (a) as similar in mechanism as possible to devstack's local backend package strategy, while (b) differing just enough to make it compatible with non-devstack frontend development. See **Consequences** for specifics.
65+
66+
This is in observance of the `worse-is-better <https://www.jwz.org/doc/worse-is-better.html>`_ design philosophy, which prioritizes simplicity of implementation over simplicity of interface. We hope that maintaining consistency with devstack's local package strategy will be worth the short-term frontend workflow confusion that this change may cause.
67+
68+
69+
Consequences
70+
============
71+
72+
In docker-compose-host.yml, each frontend service will be given a new volume declaration::
73+
74+
services:
75+
76+
...
77+
78+
frontend-app-XX:
79+
volumes:
80+
- ${DEVSTACK_WORKSPACE}/frontend-app-XX:/edx/app/frontend-app-XX:cached
81+
- frontend_app_XX_node_modules:/edx/app/frontend-app-XX/node_modules
82+
- ${DEVSTACK_WORKSPACE}/src:/edx/app/src:cached # <--- This line is new!
83+
84+
This will cause the ``${DEVSTACK_WORKSPACE}/src`` folder to mounted at ``/edx/app/src`` of each frontend service, similar to how that folder is mounted at ``/edx/src`` of each backend service. Via ``module.config.js``, frontend developers will then be able to specify ``../src/PACKAGE`` as the path of any local frontend package. This scheme has the benefit of:
85+
86+
* working within a frontend Devstack container, since ``../src/PACKAGE`` resolves to ``/edx/app/src/PACKAGE``, and
87+
* working oustide of Devstack, since ``../src/PACKAGE`` points to ``PACKAGE`` when ``src`` is a sibling of the frontend application repository.
88+
89+
Developers will be informed of this scheme via a frontend-build documentation update and an email.
90+
91+
92+
Rejected alternatives
93+
=====================
94+
95+
96+
Mount frontend packages at ``/edx/src``
97+
***************************************
98+
99+
One alternative would be to mount packages at ``/edx/src`` within frontend containers instead of ``/edx/app/src``. This approach would have been maximally consistent with the existing local backend package strategy. However, it would make it impossible for frontend developers to maintain a single ``module.config.js`` for both with-devstack and sans-devstack development.
100+
101+
Concretely: Within a devstack container, in order to reference, say, ``/edx/src/paragon`` from an app running within ``/edx/app/frontend-app-profile``, one would need to specify the path ``../../src/paragon`` within ``module.config.js``. In order to reference the same package *outside* of devstack, the proper path would be ``../src/paragon`` (recall that ``src`` and ``frontend-app-profile`` are expected to be sibling directories, both within the devstack workspace).
102+
103+
104+
Explicit frontend mounts in devstack workspace
105+
**********************************************
106+
107+
A more radical alternative would be to explicitly mount certain local frontend packages from the devstack workspace into each frontend container. For example, ``${DEVSTACK_WORKSPACE}/frontend-platform`` would be mounted into every frontend container (if it existed) at ``/edx/app/frontend-platform``. This would be done for a handful of other commonly-developed frontend packages, including Paragon and the branding packages.
108+
109+
This approach would have been the most compatible with the existing local frontend package strategy, but it would sharply differ from devstack's backend package strategy.
110+
111+
For reference, here is a draft implementation of this rejected approach: https://github.com/edx/devstack/pull/795.

0 commit comments

Comments
 (0)