# Dev Environment Setup

Code for Life (CFL) has set up their development environment within [dev containers for VS Code](https://code.visualstudio.com/docs/devcontainers/containers). In short, dev containers are containerised virtual machines that come preinstalled with all the software and tools necessary for you to develop.

{% hint style="info" %}
A git submodule is synonymous with a git repository; a submodule is a repo that's nested within the workspace.
{% endhint %}

VS Code's dev containers allow us to setup your dev environment for you so you don't have to worry about doing it yourself. Furthermore, anytime we make a change to our dev environment, we will git-push the latest dev container to the workspace repo. Then, you can just simply git-pull the latest dev container and rebuild it.

Follow the below steps to setup the CFL workspace in a dev container.

***

## 1. Create a GitHub account

If you don't already have a GitHub account, [sign up for GitHub](https://github.com/signup).

***

## 2. Install and set up Git

Git is required to sync your local code changes with our online Git repos.

Follow Git's [installation instructions](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) and set up your Git user.

{% hint style="success" %}
We recommend you use the same username and email you used to create your GitHub account.
{% endhint %}

```bash
git config --global user.name "John Doe"
```

```bash
git config --global user.email "john.doe@example.com"
```

{% hint style="info" %}
For further guidance and how to set up Git, follow Git's [first-time setup instructions](https://git-scm.com/book/en/v2/Getting-Started-First-Time-Git-Setup).
{% endhint %}

***

## 3. Install Docker Engine

Docker Engine is required to build and run dev containers.

Note that Docker Desktop is an app built around Docker Engine that provides a user interface and additional tools. You only need Docker Engine.

{% hint style="danger" %}
If you're using an Ocado-issued laptop, **DO NOT install Docker Desktop** - it's licensed software requiring a paid subscription.
{% endhint %}

Follow the steps to install Docker Engine depending on your computer's operating system.

### Windows

{% hint style="success" %}
For an easier setup experience, we recommend you create a Linux environment using [WSL 2](https://learn.microsoft.com/en-us/windows/wsl/about#what-is-wsl-2) and [install the Ubuntu distro](https://documentation.ubuntu.com/wsl/stable/howto/install-ubuntu-wsl2/#install-ubuntu-wsl). You can then follow the simpler [Linux steps](#linux) instead.
{% endhint %}

[Follow the steps](https://docs.docker.com/engine/install/binaries/#install-server-and-client-binaries-on-windows) to download and install Docker Engine's server and client binaries.

### macOS

We recommend running the following commands. Alternatively, you can install [Docker Engine's client binaries](https://docs.docker.com/engine/install/binaries/#install-client-binaries-on-macos).

Install Docker Engine and Colima.

```bash
brew install docker colima
```

Start Colima and use it as Docker's context.

```bash
colima start && docker context use colima
```

Test Docker is working.

```bash
sudo docker run hello-world
```

### Linux

Check the [supported platforms](https://docs.docker.com/engine/install/#supported-platforms) to find your Linux distro. If you're using Ubuntu, follow [these steps](https://docs.docker.com/engine/install/ubuntu/).&#x20;

***

## 4. Install the Docker Compose plugin

The Docker Compose plugin is required as [our dev container runs multiple containers for different tools](https://github.com/ocadotechnology/codeforlife-workspace/blob/main/.devcontainer/docker-compose.yml).

Follow the steps to install the plugin depending on your computer's operating system.

### Windows

{% hint style="danger" %}
There's no way to install the plugin unless you install Docker Desktop. If you're using an Ocado-issued laptop, **DO NOT install Docker Desktop** - it's licensed software requiring a paid subscription.
{% endhint %}

{% hint style="success" %}
We recommend you create a Linux environment using [WSL 2](https://learn.microsoft.com/en-us/windows/wsl/about#what-is-wsl-2) and [install the Ubuntu distro](https://documentation.ubuntu.com/wsl/stable/howto/install-ubuntu-wsl2/#install-ubuntu-wsl). You can then follow the [Linux steps](#linux) instead.
{% endhint %}

### macOS

We recommend installing the plugin [via Homebrew](https://formulae.brew.sh/formula/docker-compose).

```bash
brew install docker-compose
```

Alternatively, you can [install the plugin manually](https://docs.docker.com/compose/install/linux/#install-the-plugin-manually).

### Linux

[Follow these steps](https://docs.docker.com/compose/install/linux/#install-using-the-repository) to install the plugin using the repository. Alternatively, you can [install it manually](https://docs.docker.com/compose/install/linux/#install-the-plugin-manually).

***

## 5. Install VS Code

Our dev containers are specifically defined to work within the VS Code IDE.

[Install VS Code](https://code.visualstudio.com/).

***

## 6. Install the Dev Containers extension in VS Code

Open the Extensions tab (Ctrl+Shift+X) in VS Code.

Search for the **"Dev Containers"** extension and install it.

<figure><img src="https://2662351606-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M_6UDUiGoJDhr_OXetO%2Fuploads%2FrE0hWPELwGTjibjo5Du6%2Fimage.png?alt=media&#x26;token=dcb58aa9-3106-40e3-987d-5e09160037fb" alt=""><figcaption></figcaption></figure>

***

## 7. Fork and clone the CFL workspace

You'll need to clone our [workspace](https://github.com/ocadotechnology/codeforlife-workspace) in a folder of your choosing on your local machine. How you do so will depend on whether you're an external or internal contributor

### External Contributor

{% hint style="success" %}
This option is for you if you're NOT a CFL team member.
{% endhint %}

Fork ([see how](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/fork-a-repo#forking-a-repository)) our [workspace](https://github.com/ocadotechnology/codeforlife-workspace) on GitHub (only the **main** branch) into your personal GitHub account and then clone your fork:

```bash
# Replace {username} with your GitHub username!
git clone https://github.com/{username}/codeforlife-workspace.git
```

### Internal Contributor

{% hint style="danger" %}
This option is for you ONLY if you're a CFL team member.
{% endhint %}

Clone the workspace and recursively clone each repo/submodule within the workspace:

```bash
git clone --recurse-submodules https://github.com/ocadotechnology/codeforlife-workspace.git
```

***

## 8. Change line endings (Windows only)

If you're using Windows as your OS, then you'll need to change the line endings in your cloned workspace before opening the dev container.

{% hint style="info" %}
[Inside the dev container the OS is Ubuntu](https://github.com/ocadotechnology/codeforlife-workspace/blob/main/.devcontainer/Dockerfile#L2) and Unix-like OS's (like Linux and macOS) use different *end of line* (EOL) [control characters](https://en.wikipedia.org/wiki/Control_character) to Windows. Linux distributions (like Ubuntu) use *line feed* (LF), which is control character "\n", while Windows uses *carriage return and line feed* (CRLF), which is control characters "\r\n". [See EOL table](https://en.wikipedia.org/wiki/Newline#Representation).
{% endhint %}

Open a Git Bash terminal in the directory of your cloned workspace.

<figure><img src="https://2662351606-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M_6UDUiGoJDhr_OXetO%2Fuploads%2FcOuy2GmaBGMZGlurw0yV%2Fimage.png?alt=media&#x26;token=1ae057ec-fb13-4330-8ffe-711c422e28ff" alt=""><figcaption><p>example terminal that's open in the "codeforlife-workspace" directory</p></figcaption></figure>

Configure the workspace to use LF as the EOL control character.

```bash
git config core.eol lf
```

Remove all the files tracked by Git in the workspace.

```bash
git rm -rf --cached .
```

Re-download the files. They should now have LF endings.

```bash
git reset --hard HEAD
```

To confirm that the files have LF endings, open any file in the workspace in VS Code and look at the bottom right (in the toolbar). You should see "LF" (not "CRLF").

<figure><img src="https://2662351606-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M_6UDUiGoJDhr_OXetO%2Fuploads%2FMKuDRK1wCmLiLE9Lg0gU%2Fimage.png?alt=media&#x26;token=0738fcd0-1032-4c0a-b5a9-29b3186cd13f" alt=""><figcaption></figcaption></figure>

***

## 9. Open the CFL workspace in a Dev Container

In VS Code, open the command palette (Ctrl+Shift+P or go to `View > Command Palette...`).

Search for the command: **">Dev Containers: Open Workspace in Container..."** and select it.

<figure><img src="https://2662351606-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M_6UDUiGoJDhr_OXetO%2Fuploads%2FOSpg2J33KHLbk9ataKP0%2Fimage.png?alt=media&#x26;token=8a28faab-7207-4b48-8718-16c5acfcaf8f" alt=""><figcaption></figcaption></figure>

{% hint style="warning" %}
Make sure Docker Engine is running before working with dev containers.
{% endhint %}

Select the **codeforlife.code-workspace** file in your local **codeforlife-workspace** folder.

```
path/to/codeforlife-workspace/codeforlife.code-workspace
```

VS Code will now begin building your dev container. If you wish to see the output of the build as it is happening, click the following prompt in the bottom-right:

<figure><img src="https://2662351606-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M_6UDUiGoJDhr_OXetO%2Fuploads%2FVJG4pPJFSjIciI987oSX%2Fimage.png?alt=media&#x26;token=c36d1a90-6955-4c70-9e4a-b865a04e1640" alt=""><figcaption></figcaption></figure>

At some point, VS Code will reload the window so that it may re-open the code-workspace within the dev container.&#x20;

{% hint style="info" %}
The first time the container is built takes some time, as it needs to download its OS and the various software, tools and extensions required for development. The duration of the build will also depend on your internet speed and processing power.

First-time builds have been known to take around 10-15 minutes.

Luckily, this is a one-off; the build is cached and rebuilds will be significantly faster!
{% endhint %}

### Known issues

#### Fails to pull [docker/dockerfile](https://hub.docker.com/r/docker/dockerfile)

If the build fails with an error message similar to:

<pre><code><strong>=> ERROR resolve image config for docker.io/docker/dockerfile:1.4        31.5s
</strong><strong>=> [auth] docker/dockerfile:pull token for registry-1.docker.io           0.0s
</strong><strong>------
</strong><strong>> resolve image config for docker.io/docker/dockerfile:1.4:
</strong><strong>------
</strong></code></pre>

Run this command *before* opening/building the dev container.

<pre class="language-bash"><code class="lang-bash"><strong>docker pull docker.io/docker/dockerfile:1.4
</strong></code></pre>

#### Images or dependencies fail to install

If you get build errors stating that some images or dependencies failed to install, it could be due to any VPN / DDoS mitigation software you might have running on your machine or network. Try disabling those temporarily to see if it helps.

***

## 10. Set up your CFL workspace

{% hint style="success" %}
If you cloned the workspace as an [internal contributor](#internal-contributor), you should skip this step by entering "n" (no) when the setup script asks if you would like to run the optional steps:

<img src="https://2662351606-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M_6UDUiGoJDhr_OXetO%2Fuploads%2FVm9Cq7vMZ3yv1qV951Jv%2Fimage.png?alt=media&#x26;token=96fb6a02-5bc9-492c-9bda-9b3fa7e1fdfc" alt="" data-size="line">
{% endhint %}

While the workspace is open in VS Code you'll notice there are a few empty folders. These are the repos contained within the workspace, each of which will also need to be forked and cloned ([like how you forked and cloned the workspace](#id-5.-fork-and-clone-the-cfl-workspace)).

To help you quickly fork and clone the many repos contained within our workspace, we've created a script that runs automatically when you start the workspace's dev container. You'll be prompted to sign into GitHub in VS Code's terminal window.

<figure><img src="https://2662351606-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M_6UDUiGoJDhr_OXetO%2Fuploads%2F9Lh0vHotfkNkbNxqNVkz%2Fimage.png?alt=media&#x26;token=fb63ce05-bc24-456f-b792-2655c34741f6" alt=""><figcaption><p>Use the arrows on your keyboard and Enter to select an option</p></figcaption></figure>

Follow the on-screen instructions in the terminal. Once you've successfully authenticated with GitHub, each repo within the workspace should be forked and cloned; the once empty folders should now be populated.

<figure><img src="https://2662351606-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M_6UDUiGoJDhr_OXetO%2Fuploads%2F4cDiJuDilN6IV68tkAYd%2Fimage.png?alt=media&#x26;token=72d7f483-18d2-4f45-a473-1742d23265f2" alt=""><figcaption></figcaption></figure>

***

## 11. Enable source control

{% hint style="info" %}
You many not need to do this step. If VS Code has disabled source control for the CFL repos you wish to develop for, you'll need to trust the repos within VS Code to enable source-control features like:

* checking out branches
* pulling, committing and pushing code changes.
  {% endhint %}

With the workspace folder open in VS Code, open the Source Control tab (Ctrl+Shift+G).

Click "**Manage Unsafe Repositories**". Then, select the one or more CFL repos shown in the drop-down.

<figure><img src="https://2662351606-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M_6UDUiGoJDhr_OXetO%2Fuploads%2FsV0ie55Kj1fhcHBJKUuO%2Fimage.png?alt=media&#x26;token=b747d7e9-f238-4eff-a84d-8cd736afd42e" alt=""><figcaption></figcaption></figure>

***

## 12. Set up the repo's virtual environment

{% hint style="info" %}
This step is only needed if you are working on either the `rapid-router` or `codeforlife-portal` repo.
{% endhint %}

In a new terminal in VS Code, run the following command:

```bash
pipenv install --dev
```

This will install all the dependencies the repo requires for the code to run. Then, activate the virtual environment by running:

```bash
pipenv shell
```

Finally, to start working on the project locally, run:

```bash
./run
```

This script will:

* run the project's database migrations,
* collect the static files,
* and start a Django server.

Once the script has finished running, you'll be able to run and view the project locally in your browser by going to `localhost:8000`.

{% hint style="info" %}
Any backend changes you make to the code should automatically reload the Django server (a.k.a. hot reloading). HTML changes will also be visible instantly.

However, any JS or CSS changes will require you to manually close the server using `Ctrl/Cmd + C` and relaunch the `run` script so that the static files are re-collected.
{% endhint %}

Enjoy working on the project!

***

## 13. Exiting the Dev Container

There are a few different ways you can stop running your VS Code window in a dev container and run it on your local machine instead.

* Close the VS Code window and open a new window.
* Open a local folder in the existing VS Code window (\[Ctrl+K Ctrl+O] or go to `File > Open Folder...`).
* Reopen the current folder locally by either:
  1. Opening the command palette (Ctrl+Shift+P or go to `View > Command Palette...`) and typing **">Dev Containers: Reopen Folder Locally"**.
  2. Clicking the Dev Container toolbox in the bottom-left of your VS Code window and selecting `Reopen Folder Locally`.
* Close the connection to the dev container by either:
  1. Opening the command palette (Ctrl+Shift+P or go to `View > Command Palette...`) and typing **">Remote: Close Remote Connection"**.
  2. Clicking the Dev Container toolbox in the bottom-left of your VS Code window and selecting `Close Remote Connection`.

<div data-full-width="true"><figure><img src="https://2662351606-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M_6UDUiGoJDhr_OXetO%2Fuploads%2FWx3ku0HohZwSlxW7N4Mp%2FScreenshot%20from%202024-01-22%2018-38-31.png?alt=media&#x26;token=94d6cfcd-138b-4c83-86f8-1871f9710b6c" alt=""><figcaption><p>Dev Container: toolbox</p></figcaption></figure></div>
