|
| 1 | +# Dev Container CLI Examples |
| 2 | + |
| 3 | +This folder contains a set of basic examples that use the devcontainer CLI for different use cases. It includes example scripts to: |
| 4 | + |
| 5 | +1. [Use three different tools from a development container](#tool-examples) |
| 6 | +2. [Use a dev container as your CI build environment](#ci-build-environment-example) (even if your app is not deployed as a container) |
| 7 | +3. [Build a container image](#building-an-image-from-devcontainerjson) from a devcontainer.json file that includes [dev container features](https://containers.dev/implementors/features/#devcontainer-json-properties) |
| 8 | + |
| 9 | +Each should run on macOS or Linux. For Windows, you can use these scripts from WSL2. |
| 10 | + |
| 11 | +## Pre-requisites |
| 12 | + |
| 13 | +1. Install Node.js 16 (e.g., using [nvm](https://github.com/nvm-sh/nvm)) |
| 14 | +2. Install [node-gyp pre-requisites](https://github.com/nodejs/node-gyp): |
| 15 | + - **Linux:** Use your distro's package manager. E.g. on Ubuntu/Debian: `sudo apt-get update && sudo apt-get install python3-minimal gcc g++ make` |
| 16 | + - **macOS:** Install the XCode Command Line Tools ([more info](https://github.com/nodejs/node-gyp/blob/main/README.md#on-macos)) |
| 17 | +3. Make sure you have an OpenSSH compliant `ssh` command available and in your path if you plan to use the `Vim via SSH` example (it should already be there on macOS, and in Linux/WSL, you can install `openssh-client` using your distro's package manager if its missing) |
| 18 | +3. Install the latest dev container CLI: `npm install -g @devcontainers/cli` |
| 19 | + |
| 20 | +## Using the examples |
| 21 | + |
| 22 | +All examples use the contents of the `workspace` folder for their configuration, which is where you can make modifications if you'd like. The example scripts are then in different sub-folders. |
| 23 | + |
| 24 | +### Tool examples |
| 25 | + |
| 26 | +You can use these examples by opening a terminal and typing one of the following: |
| 27 | + |
| 28 | +- `tool-vscode-server/start.sh` - [VS Code Server](https://code.visualstudio.com/docs/remote/vscode-server) (official) |
| 29 | +- `tool-openvscode-server/start.sh` - [openvscode-server](https://github.com/gitpod-io/openvscode-server) |
| 30 | +- `tool-vim-via-ssh/start.sh` - Vim via an SSH connection. SSH is used primarily to demonstrate how this could be achieved from other SSH supporting client tools. |
| 31 | + |
| 32 | +When switching between examples, pass `true` in as an argument to get the container recreated to avoid port conflicts. e.g., `./start.sh true` |
| 33 | + |
| 34 | +In the first two examples, you'll be instructed to go to `http://localhost:8000` in a browser. |
| 35 | + |
| 36 | +This also adds a desktop to the container that can be accessed from a web browser at `http://localhost:6080` and you can connect using the password `vscode`. |
| 37 | + |
| 38 | +#### How the tool examples work |
| 39 | + |
| 40 | +These examples demonstrate the use of the dev container CLI to: |
| 41 | + |
| 42 | +1. Simplify setup using the "[dev container features](https://containers.dev/implementors/features/#devcontainer-json-properties)" concept. For example, SSH support is added just using a feature reference. See `workspace/.devcontainer/devcontainer.json` for more information. |
| 43 | + |
| 44 | +2. How the dev container CLI can be used to inject tools without building them into the base image: |
| 45 | + |
| 46 | + 1. Use `devcontainer up` to spin up the container and mount a `server` and `workspace` folder into the container. |
| 47 | + 2. Use `devcontainer exec` to run a script from this mounted folder to set up the appropriate server. |
| 48 | + 3. In the `vim` example, a temporary SSH key is set up and configured, and then SSH is used from the command line to connect to the container once it is up and running. See `tool-vim-via-ssh/start.sh` for details. |
| 49 | + |
| 50 | +Currently the `appPort` property is used in `devcontainer.json` instead of `forwardPorts` due to a gap in the current dev container CLI ([see here](https://github.com/devcontainers/cli/issues/22)). |
| 51 | + |
| 52 | +### CI build environment example |
| 53 | + |
| 54 | +This example illustrates how you can use the dev container CLI to build your application in any CI system. (Note there is also a [GitHub Action](https://github.com/marketplace/actions/devcontainers-ci) and [Azure DevOps task](https://marketplace.visualstudio.com/items?itemName=devcontainers.ci) if you are using those automation systems, but this example will focus on direct use of the CLI.) |
| 55 | + |
| 56 | +You can use the example by opening a terminal and typing the following: |
| 57 | + |
| 58 | +``` |
| 59 | +ci-app-build-script/build-app.sh |
| 60 | +``` |
| 61 | + |
| 62 | +After the build completes, you can find the built application in the `workspace/dist` folder. |
| 63 | + |
| 64 | +The initial build can take a bit since it is building the dev container image, which is an example of where [pre-building an image](#building-an-image-from-devcontainerjson) helps. |
| 65 | + |
| 66 | +#### How the CI example works |
| 67 | + |
| 68 | +This example demonstrates the use of the dev container CLI to: |
| 69 | + |
| 70 | +1. Simplify setup using the "[dev container features](https://containers.dev/implementors/features/#devcontainer-json-properties)" concept. For example, SSH support is added just using a feature reference. See `workspace/.devcontainer/devcontainer.json` for more information. |
| 71 | + |
| 72 | +2. Execute an application build script inside a dev container as follows: |
| 73 | + |
| 74 | + 1. Use `devcontainer up` to spin up the container and mount the the `workspace` folder into the container. |
| 75 | + 2. Use `devcontainer exec` to run a build script from the mounted folder inside the development container. |
| 76 | + 3. Delete the container when the build is finished. |
| 77 | + |
| 78 | +All environment variables are automatically available from `exec`, including those that are are set in the non-root user's `.bashrc` file. The dev container CLI also automatically adjusts to UID/GID differences for the user inside the container on Linux to ensure the workspace folder is writable. |
| 79 | + |
| 80 | +### Building an image from devcontainer.json |
| 81 | + |
| 82 | +You can use the example by opening a terminal and typing the following: |
| 83 | + |
| 84 | +``` |
| 85 | +image-build/build-image.sh |
| 86 | +``` |
| 87 | + |
| 88 | +The resulting image name defaults to `devcontainer-cli-test-image`, but you can change it with the first argument, and configure it to push to a registry by setting the second argument to true. The third argument allows you to build for multiple architectures. |
| 89 | + |
| 90 | +``` |
| 91 | +image-build/build-image.sh ghcr.io/my-org/my-image-name-here true "linux/amd64 linux/arm64" |
| 92 | +``` |
| 93 | + |
| 94 | +Ultimately, this script just calls the `devcontainer build` command to do all the work. Once built, you can refer to the specified image name directly in a devcontainer.json file using the `image` property. |
0 commit comments