Skip to content

Commit

Permalink
Add dev container config
Browse files Browse the repository at this point in the history
  • Loading branch information
KevinMind committed Feb 5, 2025
1 parent 7489e89 commit 9dc78f2
Show file tree
Hide file tree
Showing 7 changed files with 131 additions and 2 deletions.
25 changes: 25 additions & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"name": "Addons-Server Devcontainer",
"image": "mcr.microsoft.com/devcontainers/base:bullseye",
"workspaceFolder": "/workspaces/addons-server",
"workspaceMount": "source=${localWorkspaceFolder},target=/workspaces/addons-server,type=bind",
"features": {
"ghcr.io/devcontainers/features/docker-in-docker": {
"version": "latest",
"enableNonRootDocker": "true",
"moby": "true"
}
},
"forwardPorts": [80],
"appPort": [80],
"portsAttributes": {
"80": {
"label": "Addons-Server",
"onAutoForward": "notify",
"protocol": "http",
"requireLocalPort": true,
"elevateIfNeeded": true
}
},
"postStartCommand": "make up"
}
10 changes: 10 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for more information:
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
# https://containers.dev/guide/dependabot

version: 2
updates:
- package-ecosystem: "devcontainers"
directory: "/"
schedule:
interval: weekly
- package-ecosystem: "npm"
directory: "/"
schedule:
Expand Down
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
*.css.tmp
.devcontainer/*
*.egg-info
*.js.tmp
*.less.css
Expand Down Expand Up @@ -53,5 +54,9 @@ tmp/*
# End of .gitignore. Please keep this in sync with the top section of .dockerignore

# do not ignore the following files
!.devcontainer/devcontainer.json
!.devcontainer/docker-compose.yml
!.devcontainer/Dockerfile
!deps/.gitkeep
!docker-compose.private.yml
!private/README.md
2 changes: 1 addition & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ x-env-mapping: &env
- MEMCACHE_LOCATION=memcached:11211
- MYSQL_DATABASE=olympia
- MYSQL_ROOT_PASSWORD=docker
- OLYMPIA_SITE_URL=http://olympia.test
- PYTHONDONTWRITEBYTECODE=1
- PYTHONUNBUFFERED=1
- PYTHONBREAKPOINT=ipdb.set_trace
Expand All @@ -21,6 +20,7 @@ x-env-mapping: &env
- HISTCONTROL=erasedups
- CIRCLECI
- DATA_BACKUP_SKIP
- OLYMPIA_SITE_URL

x-olympia: &olympia
<<: *env
Expand Down
63 changes: 63 additions & 0 deletions docs/topics/development/devcontainer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# Devcontainer Setup Guide

This document describes how to set up development via a [devcontainer](https://containers.dev),
either locally or in GitHub Codespaces.

**Using Docker Compose:**

If you prefer using Docker Compose, you can refer to the
[Setup and Configuration](./setup_and_configuration.md) document for more information
on how to configure an environment using Docker Compose.

## 1. Using Visual Studio Code (VS Code)

The Remote - Containers extension in VS Code makes it seamless to work with devcontainers.

**Prerequisites:**

- Install [VS Code](https://code.visualstudio.com/).
- Install the **Remote - Containers** extension.

**Steps:**

1. Open the repository folder in VS Code.
2. When prompted, click **"Reopen in Container"**.
3. VS Code will:
- Use the configuration from `.devcontainer/devcontainer.json` (including proper volume mounts and port mapping, such as forwarding port 80).
- Run post-start commands (e.g. `make up` that triggers [`scripts/setup.py`](scripts/setup.py)) to set up required environment variables and directories.

This process abstracts away the need to manually configure port mappings or run lengthy Docker commands.

## 2. GitHub Codespaces

GitHub Codespaces automatically leverages the devcontainer setup defined in your repository.

**Steps:**

1. In your repository on GitHub, click the **"Code"** button and select **"Open with Codespaces"****"New codespace"**.
2. Codespaces will:
- Use the same `.devcontainer/devcontainer.json` to build your container.
- Mount the repository and forward the ports (with port 80 mapping as required).
- Execute post-start routines (running `make up` to invoke [`scripts/setup.py`](scripts/setup.py)).

> [!IMPORTANT]
> Within Codespaces, the function `get_olympia_site_url()` in [`scripts/setup.py`](scripts/setup.py) detects the `CODESPACE_NAME` environment variable and sets `OLYMPIA_SITE_URL` to a Codespaces-compatible URL (e.g., `https://<codespace-name>-80.githubpreview.dev`). This automatic adjustment ensures that the nginx service is accessible without any extra configuration on your part.
## 3. Running a Devcontainer Locally (Command Line & Other IDEs)

> [!IMPORTANT]
> We do not currently support running a devcontainer directly and sshing into it, but we should.
> This would enable development via other IDEs like JetBrains, VIM, Atom, etc.
Please look at the [Dev Container CLI](https://code.visualstudio.com/docs/devcontainers/cli)
and open a PR to add support for your favorite IDE.

## Summary

Devcontainers can be very useful for local development by isolating the entire development environment from
the host machine. Instead of running containers directly on the hosst and mounting file changes into the
containers, you can inject your IDE directly into the container.

Devcontainers are also particularly useful for testing. You can deploy a branch to a codespace and enable
verifying a PR from a publically available URL. This allows much faster iteration and testing of PRs
without the need of independently setting up a local development environment.
11 changes: 11 additions & 0 deletions scripts/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,15 @@ def get_docker_image_meta():
return tag, target, version, digest


def get_olympia_site_url():
# In codespaces, we set the site URL to the codespace name port 80
# this will map to the nginx service in the devcontainer.
if os.environ.get('CODESPACE_NAME'):
return f'https://{os.environ.get("CODESPACE_NAME")}-80.githubpreview.dev'
# On local hosts, we set the site URL to olympia.test
return 'http://olympia.test'


# Env file should contain values that are referenced in docker-compose*.yml files
# so running docker compose commands produce consistent results in terminal and make.
# These values should not be referenced directly in the make file.
Expand All @@ -104,6 +113,7 @@ def main():
# use a value derived from other stable values.
debug = os.environ.get('DEBUG', str(docker_target != 'production'))
olympia_deps = os.environ.get('OLYMPIA_DEPS', docker_target)
olympia_site_url = get_olympia_site_url()

set_env_file(
{
Expand All @@ -117,6 +127,7 @@ def main():
'HOST_UID': olympia_uid,
'DEBUG': debug,
'OLYMPIA_DEPS': olympia_deps,
'OLYMPIA_SITE_URL': olympia_site_url,
}
)

Expand Down
17 changes: 16 additions & 1 deletion tests/make/test_setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@
'DOCKER_TAG',
'DOCKER_TARGET',
'HOST_UID',
'OLYMPIA_DEPS',
'DEBUG',
'OLYMPIA_DEPS',
'OLYMPIA_SITE_URL',
]


Expand Down Expand Up @@ -211,6 +212,20 @@ def test_olympia_deps_override(self):
self.assert_set_env_file_called_with(OLYMPIA_DEPS='test')


@override_env()
class TestOlympiaSiteUrl(BaseTestClass):
def test_default_olympia_site_url(self):
main()
self.assert_set_env_file_called_with(OLYMPIA_SITE_URL='http://olympia.test')

@override_env(CODESPACE_NAME='test')
def test_codespace_olympia_site_url(self):
main()
self.assert_set_env_file_called_with(
OLYMPIA_SITE_URL='https://test-80.githubpreview.dev'
)


@override_env()
@mock.patch('scripts.setup.os.makedirs')
def test_make_dirs(mock_makedirs):
Expand Down

0 comments on commit 9dc78f2

Please sign in to comment.