DevContainers
7 minute read
Overview
DevContainers is a local tool to create a self-contained, reproducible and containerized development environment that you can setup to encapsulate your project with all its libraries and dependencies.
In this guide, you will learn how to use DevContainers with LocalStack. You can use the following two approaches to set up LocalStack with DevContainers:
LocalStack Templates
LocalStack provides two different approaches for Templates which can be used via supporting tools.
Type | Advantages | Disadvantages |
---|---|---|
Docker-in-Docker | • Strict separation from host Docker service • Control LocalStack with LocalStack CLI • All-in-one container | • Resources are limited as all resources spawned by LocalStack are encapsulated within the container • LocalStack volume directory must exist beforehand • Larger container size • Cannot use existing images on host system |
Docker-outside-of-Docker | • Easy addition of external services managed by Docker Compose • DNS service for custom domains | • Host’s Docker socket mounted into containers, raising security concerns • Limited LocalStack CLI usage • LocalStack volume directory must exist beforehand |
Docker-in-Docker
Dev Container CLI
You can use the DevContainer CLI to create a devcontainer.json
file from the LocalStack template.
Before you start, ensure that you have the DevContainer CLI installed.
Create a JSON file called options.json
with the desired options in it.
{
"imageVariant": "bullseye",
"awslocal": "true",
"logLevel": "debug",
"debug": "true",
"startup": "true"
}
Use the command below to generate your devcontainer.json
from the template.
Include additional features with the --features
option if needed.
$ devcontainer templates apply \
--template-id ghcr.io/localstack/devcontainer-template/localstack-dind \
--template-args "$(cat ./options.json)" \
--features '[{"id":"ghcr.io/devcontainers/features/aws-cli:1"}]'
Start your container using the following command.
$ devcontainer up --id-label project=localstack --workspace-folder .
Connect to it using the id-label
.
$ devcontainer exec --id-label project=localstack /bin/bash
Check that the LocalStack CLI is installed by executing:
vscode ➜ ~ $ localstack --version
3.6.0
vscode ➜ ~ $
To remove the container, run this cleanup script since the Dev Container CLI cannot currently do it.
$ for container in $(docker ps -q); do \
[[ "$(docker inspect --format '{{ index .Config.Labels "project"}}' $container)" = "localstack" ]] && \
docker rm -f $container; \
done
VSCode
Note
The DevContainer extension is currently reporting issues & bugs. Follow the issue for details.To get started with LocalStack and DevContainers in VS Code, follow these steps:
Open VS Code with the DevContainers extension installed.
From the Command Palette, select Dev Containers: Add Dev Container configuration file.
Choose Add configuration to workspace; alternatively, select Add configuration to user data folder for general usage.
Select Show All Definitions… to view community templates.
Filter by typing “localstack” in the search bar and select the LocalStack Docker-in-Docker template.
Proceed through the configuration by selecting or entering values. Pressing Enter through the options will apply default settings, which include:
- Select the image variant (only Debian-based images are supported).
- Select the log level.
- Select the LocalStack version.
- Select the image variant (only Debian-based images are supported).
Relative paths are acceptable for the volume path, but the specified mount folder must be created prior to building the container.
Select various tools and configuration options from the checklist. For local tools, either select the appropriate SDK or tool feature, or install it manually. The template and LocalStack CLI feature do not manage these installations.
You can also add additional features.
This results in the following folder structure in your workspace.
Reference file
The devcontainer.json
will look similar to the following:
{
"name": "LocalStack DinD setup",
"image": "mcr.microsoft.com/devcontainers/base:bullseye",
"remoteEnv": {
// Activate LocalStack Pro: https://docs.localstack.cloud/getting-started/auth-token/
"LOCALSTACK_AUTH_TOKEN": "${localEnv:LOCALSTACK_AUTH_TOKEN}", // required for Pro, not processed via template due to security reasons
"LOCALSTACK_API_KEY": "${localEnv:LOCALSTACK_API_KEY}",
// LocalStack configuration: https://docs.localstack.cloud/references/configuration/
"ACTIVATE_PRO": false,
"DEBUG": true,
"LS_LOG": "debug",
"PERSISTENCE": false,
"AWS_ENDPOINT_URL": "http://localhost.localstack.cloud:4566",
"AUTO_LOAD_POD": " ",
"ENFORCE_IAM": false,
"AWS_REGION": "us-east-1",
"AWS_DEFAULT_REGION": "us-east-1",
"IMAGE_NAME": "localstack/localstack-pro:latest",
"LOCALSTACK_VOLUME_DIR": "/data"
},
// 👇 Features to add to the Dev Container.
// More info: https://containers.dev/implementors/features.
"features": {
"ghcr.io/devcontainers/features/docker-in-docker:2": {},
"ghcr.io/localstack/devcontainer-feature/localstack-cli:latest": {
"version": "latest",
"awslocal": true, // if true, add in features manually: ghcr.io/devcontainers/features/aws-cli
"cdklocal": false, // if true, add in features manually: ghcr.io/devcontainers-contrib/features/aws-cdk
"pulumilocal": false, // if true, add in features manually: ghcr.io/devcontainers-contrib/features/pulumi
"samlocal": false, // if true, add in features manually: ghcr.io/customink/codespaces-features/sam-cli
"tflocal": false // if true, add in features manually: ghcr.io/devcontainers-contrib/features/terraform-asdf
},
"ghcr.io/devcontainers/features/aws-cli:1": {}
},
// 👇 Use 'postCreateCommand' to run commands after the container is created.
"postCreateCommand": "type localstack; true && localstack start -d || true",
"mounts": [
{
// to persist build data and images
"source": "dind-var-lib-docker",
"target": "/var/lib/docker",
"type": "volume"
},
{
"source": "./.volume",
"target": "/data",
"type": "bind",
"consistency": "cached"
}
]
}
Docker-outside-of-Docker
Dev Container CLI
You can use the DevContainer CLI to create a devcontainer.json
file from the LocalStack template.
Before you start, ensure that you have the DevContainer CLI installed.
Create a JSON file called options.json
with the desired options in it.
{
"imageVariant": "bookworm",
"awslocal": "true",
"logLevel": "debug",
"debug": "true",
"networkName": "localstack-network",
"networkCidr": "192.168.9.0/24",
"ipAddress": "192.168.9.13"
}
Use the command below to generate your devcontainer.json
from the template.
Include additional features with the --features
option if needed.
$ devcontainer templates apply \
--template-id ghcr.io/localstack/devcontainer-template/localstack-dood \
--template-args "$(cat ./options.json)" \
--features '[{"id":"ghcr.io/devcontainers/features/aws-cli:1"}]'
Start your container using the following command.
$ devcontainer up --id-label project=localstack --workspace-folder .
Connect to it using the id-label
.
$ devcontainer exec --id-label project=localstack /bin/bash
Check that the LocalStack CLI is installed by executing:
vscode ➜ ~ $ localstack --version
3.6.0
vscode ➜ ~ $
To remove the container, run this cleanup script since the Dev Container CLI cannot currently do it.
$ docker compose \
--project-name "$(basename $PWD)_devcontainer" \
-f ./.devcontainer/docker-compose.yml down
VSCode
Note
The DevContainer extension is currently reporting issues & bugs. Follow the issue for details.To get started with LocalStack and DevContainers in VS Code, follow these steps:
Open VSCode with the DevContainers extension installed.
From the Command Palette, choose Dev Containers: Add Dev Container configuration file.
Choose the Add configuration to workspace option; alternatively, select Add configuration to user data folder for general usage.
Select Show All Definitions… to view community templates.
Start typing “localstack” in the search bar to filter the official LocalStack templates and choose LocalStack Docker-outside-of-Docker.
Navigate through the configuration inputs by either selecting or typing in values. The defaults provided in the template are sufficient; navigating through the options by hitting Enter will result in a valid configuration. These options include:
- The image variant (currently only Debian-based images are supported).
- The log level.
- The LocalStack version.
- The image variant (currently only Debian-based images are supported).
Note that LocalStack’s IP address must be within the defined CIDR range. The network CIDR defaults to
10.0.2.0/24
, with the container IP set to10.0.2.20
.For the volume path, relative paths are accepted, but you must create the specified mount’s folder before successfully building the container. The default is
./.volume
.Select multiple tools and configuration options from the checklist. For local tools, you must select the appropriate SDK or tool feature, or install it manually. The template and the underlying LocalStack CLI Feature do not manage these installations.
You can also add additional features.
As a result, you will end up with the folder structure shown below.
Reference files
{
"name": "LocalStack DooD setup",
"dockerComposeFile": "docker-compose.yml",
"service": "app",
"workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}",
// 👇 Features to add to the Dev Container.
// More info: https://containers.dev/implementors/features.
"features": {
"ghcr.io/devcontainers/features/docker-outside-of-docker:1": {},
"ghcr.io/localstack/devcontainer-feature/localstack-cli:latest": {
"version": "latest",
"awslocal": true, // if true, add in features manually: ghcr.io/devcontainers/features/aws-cli
"cdklocal": false, // if true, add in features manually: ghcr.io/devcontainers-contrib/features/aws-cdk
"pulumilocal": false, // if true, add in features manually: ghcr.io/devcontainers-contrib/features/pulumi
"samlocal": false, // if true, add in features manually: ghcr.io/customink/codespaces-features/sam-cli
"tflocal": false // if true, add in features manually: ghcr.io/devcontainers-contrib/features/terraform-asdf
},
"ghcr.io/devcontainers/features/aws-cli:1": {}
}
}
version: "3.8"
services:
localstack:
container_name: "localstack-main"
image: localstack/localstack-pro:latest # required for Pro
ports:
- "127.0.0.1:4566:4566" # LocalStack Gateway
- "127.0.0.1:4510-4559:4510-4559" # external services port range
- "127.0.0.1:443:443" # LocalStack HTTPS Gateway (Pro)
env_file:
- .env
volumes:
- "/var/run/docker.sock:/var/run/docker.sock"
- "./.volume:/var/lib/localstack"
networks:
ls:
# Set the container IP address in the 10.0.2.0/24 subnet
ipv4_address: 10.0.2.20
app:
build:
context: .
dockerfile: Dockerfile
volumes:
- ../..:/workspaces:cached
# Overrides default command so things don't shut down after the process ends.
command: sleep infinity
init: true
env_file:
- .env
dns:
# Set the DNS server to be the LocalStack container
- 10.0.2.20
networks:
- ls
networks:
ls:
ipam:
config:
# Specify the subnet range for IP address allocation
- subnet: 10.0.2.0/24
FROM mcr.microsoft.com/devcontainers/base:bookworm
# Activate LocalStack Pro: https://docs.localstack.cloud/getting-started/auth-token/
LOCALSTACK_AUTH_TOKEN=${LOCALSTACK_AUTH_TOKEN:-} # required for Pro, not processed via template due to security reasons
LOCALSTACK_API_KEY=${LOCALSTACK_API_KEY:-}
# LocalStack configuration: https://docs.localstack.cloud/references/configuration/
ACTIVATE_PRO=false
DEBUG=true
LS_LOG=debug
PERSISTENCE=false
AWS_ENDPOINT_URL=http://localhost.localstack.cloud:4566
LOCALSTACK_HOST=localhost.localstack.cloud:4566
AUTO_LOAD_POD=
ENFORCE_IAM=false
AWS_REGION=us-east-1
AWS_DEFAULT_REGION=us-east-1
IMAGE_NAME=localstack/localstack-pro:latest
LocalStack Feature
Add the following minimal Feature snippet to your DevContainer config.
...
"features": {
"ghcr.io/localstack/devcontainer-feature/localstack-cli:latest": {}
}
...
That’s it.
By building your container the LocalStack CLI and any of the enabled local-tools (currently these are awslocal
, cdklocal
, pulumilocal
, samlocal
and tflocal
) will be installed.