Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: add .devcontainer configuration #719

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .devcontainer/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Ignore changes to customisation files as intended to be user modifiable without pushing changes to repo
customisation
4 changes: 4 additions & 0 deletions .devcontainer/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
FROM atomlearning/devcontainer-base:latest

### Reset user to ensure non-privileged user downstream
USER user
68 changes: 68 additions & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
{
"name": "components",
"build": {
"dockerfile": "Dockerfile",
"options": ["--pull"],
"args": {
"INSTALL_JS_STACK": "yes",
"JS_STACK_N_VERSION": "v9.2.0",
"JS_STACK_NODE_VERSION": "20.11"
}
},

"forwardPorts": [],
"portsAttributes": {},
"runArgs": ["--add-host=kubernetes:host-gateway"],

"remoteUser": "user",
"containerUser": "root",
"updateRemoteUserUID": false,
"userEnvProbe": "loginInteractiveShell",
"containerEnv": {},
"remoteEnv": {
"ATOM_REMOTE_DEV_IS_MK2": "yes",
// Make VS Code the default editor in terminals for convenience
"EDITOR": "code -w",
// Use our custom SSH Auth proxy for SSH key forwarding e.g. for commit signing
"SSH_AUTH_SOCK": "/home/user/.ssh/atom-ssh-auth-proxy/server.sock"
},

"workspaceMount": "source=${localWorkspaceFolder},target=${localWorkspaceFolder},type=bind",
"workspaceFolder": "${localWorkspaceFolder}",
"mounts": [
"source=/home/user/.devcontainer-state/${devcontainerId},target=/home/user/.state,type=bind",
"source=devcontainer-caches,target=/home/user/.cache,type=volume",
"source=/home/user/.config/git,target=/home/user/.config/git,type=bind,readonly",
"source=/etc/rancher/k3s/k3s.yaml,target=/run/secrets/rancher-k3s.yaml,type=bind,readonly",
"source=/home/user/.atom-env-info,target=/home/user/.atom-env-info,type=bind,readonly",
"source=/home/user/.ssh/atom-ssh-auth-proxy/server.sock,target=/home/user/.ssh/atom-ssh-auth-proxy/server.sock,type=bind",
"source=/home/user/.gnupg,target=/home/user/.gnupg,type=bind"
],
"initializeCommand": "bash '${localWorkspaceFolder}/.devcontainer/scripts/init.bash' '${devcontainerId}' '${localWorkspaceFolder}'",
"postStartCommand": "/usr/local/bin/container-hooks.bash postStart '${containerWorkspaceFolder}'",

"features": {},

"customizations": {
"vscode": {
"extensions": ["esbenp.prettier-vscode","EditorConfig.EditorConfig","dbaeumer.vscode-eslint",],
"settings": {
// General VS Code
"editor.formatOnSave": true,
"editor.formatOnPaste": false,
"editor.formatOnSaveMode": "file",
"dev.containers.copyGitConfig": false,

// Exclude big, generated directories from VS Code's filewatcher to avoid it hogging file watch handles
"files.watcherExclude": {
"**/__pycache__/**": true,
"**/.cache/**": true,
"**/.venv/**": true,
"**/.yarn/unplugged/**": true,
"**/dist/**": true,
"**/node_modules/**": true
}
}
}
}
}
11 changes: 11 additions & 0 deletions .devcontainer/files/customisation.template/custom-packages.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/bin/sh

# Use this script, which is run as root, to install any custom packages
# This should be done with extreme caution as it could easily break your environment in weird ways
# Packages should only be installed here if pretty much they only apply to you/one other user
# Other packages should be put into the main Dockerfile and under Git.
#
# Apt is the available package manager. `apt-get update` must be run before attempting any package installs
#
# Rebuild the container after making changes to this script for it to take effect

9 changes: 9 additions & 0 deletions .devcontainer/files/customisation.template/custom.zshrc.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Add any other .zshrc scripting (e.g. aliases)
#
# .zshrc construction:
# 1. files/user-before-omz.zshrc.sh (cannot be user edited)
# 2. customisation/oh-my-zsh-settings.zshrc.sh
# 3. files/user-omz-init.zshrc.sh (cannot be user edited)
# 4. customisation/custom.zshrc.sh (you are here)
#

Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# Edit Oh My ZSH settings here. Rebuild container after editing to take effect
#
# .zshrc construction:
# 1. files/user-before-omz.zshrc.sh (cannot be user edited)
# 2. customisation/oh-my-zsh-settings.zshrc.sh (you are here)
# 3. files/user-omz-init.zshrc.sh (cannot be user edited)
# 4. customisation/custom.zshrc.sh
#
# Based on default .zshrc from oh-my-zsh commit 9ba6daa1b5d0b60c89525d679eb30fe3ed9947de

# Set name of the theme to load --- if set to "random", it will
# load a random theme each time Oh My Zsh is loaded, in which case,
# to know which specific one was loaded, run: echo $RANDOM_THEME
# See https://github.com/ohmyzsh/ohmyzsh/wiki/Themes
ZSH_THEME="robbyrussell"

# Set list of themes to pick from when loading at random
# Setting this variable when ZSH_THEME=random will cause zsh to load
# a theme from this variable instead of looking in $ZSH/themes/
# If set to an empty array, this variable will have no effect.
# ZSH_THEME_RANDOM_CANDIDATES=( "robbyrussell" "agnoster" )

# Uncomment the following line to use case-sensitive completion.
# CASE_SENSITIVE="true"

# Uncomment the following line to use hyphen-insensitive completion.
# Case-sensitive completion must be off. _ and - will be interchangeable.
# HYPHEN_INSENSITIVE="true"

# Uncomment the following line if pasting URLs and other text is messed up.
# DISABLE_MAGIC_FUNCTIONS="true"

# Uncomment the following line to disable colors in ls.
# DISABLE_LS_COLORS="true"

# Uncomment the following line to disable auto-setting terminal title.
# DISABLE_AUTO_TITLE="true"

# Uncomment the following line to enable command auto-correction.
# ENABLE_CORRECTION="true"

# Uncomment the following line to display red dots whilst waiting for completion.
# You can also set it to another string to have that shown instead of the default red dots.
# e.g. COMPLETION_WAITING_DOTS="%F{yellow}waiting...%f"
# Caution: this setting can cause issues with multiline prompts in zsh < 5.7.1 (see #5765)
# COMPLETION_WAITING_DOTS="true"

# Uncomment the following line if you want to disable marking untracked files
# under VCS as dirty. This makes repository status check for large repositories
# much, much faster.
# DISABLE_UNTRACKED_FILES_DIRTY="true"

# Uncomment the following line if you want to change the command execution time
# stamp shown in the history command output.
# You can set one of the optional three formats:
# "mm/dd/yyyy"|"dd.mm.yyyy"|"yyyy-mm-dd"
# or set a custom format using the strftime function format specifications,
# see 'man strftime' for details.
# HIST_STAMPS="mm/dd/yyyy"

# Which plugins would you like to load?
# Standard plugins can be found in $ZSH/plugins/
# Custom plugins may be added to $ZSH_CUSTOM/plugins/
# Example format: plugins=(rails git textmate ruby lighthouse)
# Add wisely, as too many plugins slow down shell startup.
plugins=(git jump)

13 changes: 13 additions & 0 deletions .devcontainer/scripts/init.bash
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#!/usr/bin/env bash

ID="${1}"
LOCAL_WORKSPACE="${2}"

# This is a hack that does two things: creates the backing directory for ~/.state; and copy the customisation template into place to be available for the user to edit

mkdir -p "/home/user/.devcontainer-state/${ID}"

cd "${LOCAL_WORKSPACE}/.devcontainer"
if [ ! -d customisation ]; then
cp -r files/customisation.template customisation
fi
54 changes: 54 additions & 0 deletions devcontainer-template/README.md
andoulla marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
devcontainer-template
=====================
Dev Container template for Atom repositories.

To get started, just copy the `.devcontainer` directory into the root of your repository.

Customising the template
------------------------
Once you've added the .devcontainer template to your repository, you'll want to customise it for the languages, tools, etc. needed for working in that repo.
Below if the things you should customise before starting to use the Dev Container and how to make various customisations.

### Required
* In `devcontainer.json`, edit `name` as the name of the Dev Container displayed on the UI. Usually this is the name of the repository e.g. `atom-core`
* If you want to install the Atom JS and/or Python stacks, add the appropriate variables such as `INSTALL_JS_STACK` and `INSTALL_PYTHON_STACK` to `build.arg` in `devcontainer.json`. See the ONBUILD section of [devcontainer-base/README.md](../devcontainer-base/README.md) for details on these variables.
* Add any VS Code extensions that everyone using the repository should have installed (e.g. relevant language extensions) to `customisations.vscode.extensions` in `devcontainer.json`. These should be the extension IDs, which can be copied from the extension's page within VS Code
* Similarly add any VS Code settings that should be set a particular way (e.g. formatter settigs) to `customizations.vscode.settings` in `devcontainer.json`. Easiest way to get the correct format is to set the setting in your env via the VS Code settings UI and then click the cog next to the setting and choose "Copy Setting as JSON". The existing VS Code settings within the template are recommended but not required to be kept.

Once you've made your desire changes, you can then enter the Dev Container for everything to be setup (lower-left green bar in VS Code -> Reopen in container)

### Do not edit
Typically you should not, and not need to, edit the files under `file` and `scripts`. Discuss with @Atom-Learning/Devops before doing so

Additionally:
* In `devcontainer.json`:
* As a general rule, don't want single value settings (strings) and only append to map/list settings
* Only add new environment variables in `remoteEnv`, don't remove any existing ones. By convention, leave an empty line between the template ones and any new variables.
* Don't change `workspaceMount` or `workspaceFolder`. If you want to add new bind mounts, don't remove any of the existing ones.
* Don't change the `initializeCommand` or the `postStartCommand`. If you want to run a shell script as a postStart hook (useful for running setup commands that need access to the repository itself), see below.

### Adding additional software
If you only need the Atom JS and/or Python stack, these can be installed via the `INSTALL_JS_STACK` and `INSTALL_PYTHON_STACK` Docker build arguments. See above and [devcontainer-base/README.md](../devcontainer-base/README.md).
For other tools etc, this requires editing the Dockerfile.

Add the needed `RUN`, `COPY`, `ARG`, etc. instructions to install the software you desire. Make sure the final instruction in the file is always the included `USER user`.

Tips:
* Most software should be available in the Ubuntu repositories. You can run `apt search <term>` to search what is available under what name. You can then install it in the Dockerfile with `apt-get install <package name>`
* When installing with `apt-get`, it is recommended to always do an `apt-get update` in the same `RUN` instruction and to use `-y --no-install-recommends` in the `apt-get install` command. E.g. `RUN apt-get update && apt-get install -y --no-install-recommends <package name`
* If you are installing a specific version of software, it is a good idea to extract this version to a Docker build argument. Then the version being installed can be changed in `devcontainer.json` without having to edit the Dockerfile. To do so, add an `ARG <var name>` (usually `TOOLNAME_VERSION`) before the `RUN` instruction, replace the version in the `RUN` instruction with `${<var name>}`, and then specify the version in `devcontainer.json` `build.args`.

### Dev Container Features
Dev Containers have a mechanism called "features" for installing pre-made bundles of software. These can be installed by adding the feature name and config to `features` in `devcontainer.json`. The list of available features can be found at https://containers.dev/features. Generally speaking, features are only worth installing for very complex pieces of software or those that run services in the background like `desktop-lite`. Directly installing via the Dockerfile is preferable in most cases as it gives us much more control and oversight into what/how things are being installed and setup, which is important for future maintainability.

### Advanced - Adding a Dev Container postStart hook
If you want to add a postStart hook to the Dev Container to run a shell script, this process is slightly different for our setup to allow the base container to define it's own postStart hook. A postStart hook can be useful for running a shell script once the Dev Container has started to do setup steps that require access to the repository itself. For example, installing a tool who's code live within the repo itself.

Steps:
1. Add the shell script inside `files`, usually called `postStart-hook.bash`. This script will be sourced so don't include a `#!` at the top.
2. Add a `COPY` instruction in the Dockerfile to copy this file to `/opt/atom-devcontainer/hooks/postStart.d/` within the container. Number it with an index greater than 1. For example: `COPY files/postStart-hook.bash /opt/atom-devcontainer/hooks/postStart.d/2-<repo name>.bash`

This file when then be sourced by the built-in postStart hook after it's done it's postStart setup.

### Useful references
* https://containers.dev/implementors/json_reference/ - very useful for editing devcontainer.json
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,5 +58,6 @@
"packageManager": "[email protected]",
"engines": {
"node": "20.x"
}
},
"version": "4.3.1"
}