diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 00000000000..c4fce86f3ce --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,50 @@ +// For format details, see https://aka.ms/devcontainer.json. +{ + "name": "Kolibri Dev Container", + "build": { + "dockerfile": "../docker/base.dockerfile", + "context": ".." + }, + "features": { + "ghcr.io/devcontainers/features/common-utils:2": { + "username": "devuser", + "upgradePackages": true, + "installZsh": false, + "configureZshAsDefaultShell": false, + "installOhMyZsh": false, + "installOhMyZshConfig": false, + "nonFreePackages": false + } + }, + "workspaceMount": "source=${localWorkspaceFolder},target=/kolibri,type=bind", + "workspaceFolder": "/kolibri", + "forwardPorts": [ + 3000 + ], + "portsAttributes": { + "3000": { + "label": "Webpack port", + "onAutoForward": "silent" + } + }, + "containerEnv": { + "KOLIBRI_RUN_MODE": "docker_dev", + "KOLIBRI_HOME": "/kolibri/.devcontainer/persist_dir/.kolibri" + }, + "remoteEnv": { + "GIT_EDITOR": "nano" + }, + "customizations": { + "vscode": { + "extensions": [ + "ms-python.python", + "ms-python.vscode-pylance", + "octref.vetur", + "editorconfig.editorconfig" + ] + } + }, + "onCreateCommand": "yarn install --non-interactive --frozen-lockfile && pip install -e . && pre-commit install", + "containerUser": "devuser", + "remoteUser": "devuser" +} diff --git a/.devcontainer/persist_dir/README.md b/.devcontainer/persist_dir/README.md new file mode 100644 index 00000000000..ade44a26159 --- /dev/null +++ b/.devcontainer/persist_dir/README.md @@ -0,0 +1 @@ +This directory is used by the devcontainer to persist kolibri related directories. diff --git a/.gitignore b/.gitignore index 4e69e1b4121..fa00c34e6d5 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,9 @@ # can be used to pass in a pre-build pex file or fixtures for tests docker/mnt/ +.devcontainer/persist_dir/* +!.devcontainer/persist_dir/README.md + # other docker files docker-whl.cid docker-whl.iid diff --git a/docker/base.dockerfile b/docker/base.dockerfile index 61a2ca8ce89..3fc782ede86 100644 --- a/docker/base.dockerfile +++ b/docker/base.dockerfile @@ -1,43 +1,30 @@ -FROM ubuntu:jammy - -ENV NODE_VERSION=16.20.0 - -# install required packages -RUN apt-get update && \ - DEBIAN_FRONTEND=noninteractive apt-get install -y \ - curl \ - software-properties-common \ - gettext \ - git \ - git-lfs \ - psmisc \ - python3 \ - python3-pip \ - python3-sphinx - -# add yarn ppa -RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - -RUN echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list - -# install nodejs and yarn -RUN apt-get update && \ - ARCH=$(dpkg --print-architecture) && \ - curl -sSO https://deb.nodesource.com/node_16.x/pool/main/n/nodejs/nodejs_$NODE_VERSION-1nodesource1_$ARCH.deb && \ - dpkg -i ./nodejs_$NODE_VERSION-1nodesource1_$ARCH.deb && \ - rm nodejs_$NODE_VERSION-1nodesource1_$ARCH.deb && \ - apt-get install yarn - -RUN git lfs install - -# Check if symbolic links exist before creating them -RUN if [ ! -f /usr/bin/python ]; then ln -s /usr/bin/python3 /usr/bin/python; fi \ - && if [ ! -f /usr/bin/pip ]; then ln -s /usr/bin/pip3 /usr/bin/pip; fi - -# copy Kolibri source code into image -COPY . /kolibri - -# do the time-consuming base install commands -RUN cd /kolibri \ - && pip3 install -r requirements/dev.txt \ - && pip3 install -r requirements/test.txt \ - && yarn install --network-timeout 100000 +# This Dockerfile serves as a base image for Kolibri installations. It installs python, required OS packages, node, npm, yarn and python dependencies. + +# Declare python version argument. +ARG PYTHON_VARIANT="3.9-slim" +FROM python:${PYTHON_VARIANT} + +# Declare node major version argument. +ARG NODE_MAJOR_VERSION="16" + +# Install only the absolutely-required packages to run Kolibri -- Git, Git-LFS, ip, ps and Node (plus npm). +RUN DEBIAN_FRONTEND=noninteractive apt-get update && apt-get install -y ca-certificates curl gnupg git git-lfs procps iproute2 \ + && mkdir -p /etc/apt/keyrings \ + && curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg \ + && echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_MAJOR_VERSION.x nodistro main" | tee /etc/apt/sources.list.d/nodesource.list \ + && apt-get update && apt-get install -t nodistro -y nodejs + +# Install yarn. +RUN npm install --global yarn + +# Change working directory for the commands that follow. +WORKDIR /kolibri + +# Copy python dependency files and install them. +COPY requirements/ ./requirements +COPY requirements.txt ./ +RUN pip install --upgrade --root-user-action=ignore --default-timeout=150 pip \ + && pip install -r requirements.txt --upgrade --root-user-action=ignore --default-timeout=150 \ + && pip install -r requirements/dev.txt --upgrade --root-user-action=ignore --default-timeout=150 \ + && pip install -r requirements/test.txt --upgrade --root-user-action=ignore --default-timeout=150 \ + && pip install -r requirements/docs.txt --upgrade --root-user-action=ignore --default-timeout=150 diff --git a/docker/dev.dockerfile b/docker/dev.dockerfile index 1a6b87022e4..d32fe188b5c 100644 --- a/docker/dev.dockerfile +++ b/docker/dev.dockerfile @@ -13,6 +13,8 @@ COPY . /kolibri WORKDIR /kolibri +RUN yarn install --non-interactive --frozen-lockfile + ENTRYPOINT ["python", "/docker/entrypoint.py"] # Install kolibri from source diff --git a/docs/dev-container-loading.png b/docs/dev-container-loading.png new file mode 100644 index 00000000000..39c4a98d056 Binary files /dev/null and b/docs/dev-container-loading.png differ diff --git a/docs/getting_started.rst b/docs/getting_started.rst index f464bd42d0c..99c42e20714 100644 --- a/docs/getting_started.rst +++ b/docs/getting_started.rst @@ -56,6 +56,19 @@ Finally, add the Learning Equality repo as a remote called `upstream`. That way git fetch --all # Check if there are changes upstream git checkout -t upstream/develop # Checkout the development branch +Choose your development environment setup +------------------------------------------ + +The following are the options available for setting up the development environment. + +* :ref:`Host setup (Recommended) `: Use host setup if you are planning to contribute on a regular basis because host setup is a more efficient setup for long term code contributions. + +* :ref:`Docker Dev Container setup `: Use Dev Container setup if you want to quickly get started working on your task because this setup does not require installing Python and JavaScript runtime and their dependencies. + +.. _host-setup: + +Host setup +---------- Python and Pip ~~~~~~~~~~~~~~ @@ -186,6 +199,7 @@ To initialize the database run the following command: kolibri manage migrate +.. _running_server: Running the server ------------------ @@ -511,11 +525,71 @@ Go to Kolibri's `GitHub page `__, a Another member of the team will review your code, and either ask for updates on your part or merge your PR to Kolibri codebase. Until the PR is merged you can push new commits to your branch and add updates to it. -Learn more about our :ref:`dev_workflow` and :ref:`release_process` +Learn more about our :ref:`dev_workflow` and :ref:`release_process`. + +.. _dev-container-setup: + +Dev Container setup +------------------- + +Dev Containers lets you use a Docker container as a full-featured development environment. It allows you to open the Kolibri codebase inside a docker container and take advantage of your editor or IDE's full feature set including IntelliSense, Code Navigation, GUI Debugging and Extensions. A Dev Container eliminates the need to install runtimes and dependencies. + +Dev Container is well supported in VSCode, PyCharm and many other IDEs. We recommend using VSCode as your IDE for running the Kolibri Dev Container. + +The following guide covers how to setup the Kolibri Dev Container in VSCode. + +Installing Docker +~~~~~~~~~~~~~~~~~ + +Check whether Docker and Docker compose are installed in your system by running: + +.. code-block:: bash + + # Docker v18.06+ and Docker Compose v1.21+ is required for Dev Containers. + $ docker --version + Docker version 18.09.2, build 6247962 + $ docker-compose --version + docker-compose version 1.29.2, build 5becea4c + +If the above commands error out then that means you don't have Docker. You need to `install Docker `__ to proceed further. +Installing Dev Container Extension +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Development using Docker ------------------------- +Install the `Dev Containers extension in VSCode `__. + +Starting Dev Container +~~~~~~~~~~~~~~~~~~~~~~~ +Open the Kolibri folder that you cloned in VSCode. After opening, click on the "Open a Remote Window" icon present in the bottom left corner. + +.. image:: ./remote-window-open-vscode.png + +Then click on the "Reopen in Container" option from the list. + +.. image:: ./reopen-in-container-vscode.png + +Then you will see that Dev Container is getting set up. You can click on "show log" to see the logs. It usually takes around five minutes for Dev Container to set up. Once the initial setup is complete, the next time you open, it will take just a few seconds. + +.. image:: ./dev-container-loading.png + +Running Kolibri inside Dev Container +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Once the Dev Container setup is complete, you will start seeing all the files on the left side of VSCode. Then you can open a new bash terminal on VSCode by using the shortcut ``Ctrl+Shift+```. + +Any command you run on this terminal will work inside the Dev Container. Remember, all other commands mentioned in this documentation, including git related commands like ``git add``, ``git commit`` and so on, should be executed in this Dev Container terminal. + +Finally, you can follow the :ref:`guide to start running the Kolibri server `. + +.. note:: + + If you would like to learn more about Dev Containers in general, refer `Developing inside a Container `__. + +Development using Docker (Legacy) +--------------------------------- + +.. warning:: + The following documentation is for the legacy Docker setup and may be outdated. We recommend using :ref:`dev-container-setup` instead. Engineers who are familiar with Docker can start a Kolibri instance without setting up the full JavaScript and Python development environments on the host machine. diff --git a/docs/remote-window-open-vscode.png b/docs/remote-window-open-vscode.png new file mode 100644 index 00000000000..2e9ed90f4b0 Binary files /dev/null and b/docs/remote-window-open-vscode.png differ diff --git a/docs/reopen-in-container-vscode.png b/docs/reopen-in-container-vscode.png new file mode 100644 index 00000000000..7e404082d42 Binary files /dev/null and b/docs/reopen-in-container-vscode.png differ