DevContainers

Use DevContainers with LocalStack

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.

TypeAdvantagesDisadvantages
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

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.

    Add Dev Container configuration file

  • Choose Add configuration to workspace; alternatively, select Add configuration to user data folder for general usage.

    Add configuration to workspace

  • Select Show All Definitions… to view community templates.

    Show all Template definitions

  • Filter by typing “localstack” in the search bar and select the LocalStack Docker-in-Docker template.

    Select official LocalStack Template (DinD)

  • 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).

      Image variant option

    • Select the log level.

      Log level option

    • Select the LocalStack version.

      LocalStack version option

  • Relative paths are acceptable for the volume path, but the specified mount folder must be created prior to building the container.

    Volume path option

    Volume folder exists

  • 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.

    List of options (DinD)

  • You can also add additional features.

    Additional Features

  • This results in the following folder structure in your workspace.

    Generated folder structure (DinD)

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

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.

    Add Dev Container configuration file

  • Choose the Add configuration to workspace option; alternatively, select Add configuration to user data folder for general usage.

    Add configuration to workspace

  • Select Show All Definitions… to view community templates.

    Show all Template definitions

  • Start typing “localstack” in the search bar to filter the official LocalStack templates and choose LocalStack Docker-outside-of-Docker.

    Select official LocalStack Template (DooD)

  • 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).

      Image variant option

    • The log level.

      Log level option

    • The LocalStack version.

      LocalStack version option

  • 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 to 10.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.

    Volume path option

    Volume folder exists

  • 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.

    List of options (DooD)

  • You can also add additional features.

    Additional Features

  • As a result, you will end up with the folder structure shown below.

    Folder structure (DooD)

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.