8

I cannot seem to find a clear answer for this, I found https://stackoverflow.com/a/68864132/17183293 but it is not very clear and also might be outdated because "dockerComposeFile" is no longer a valid option.

I have a project with an existing docker-compose.yml file which spins up a MariaDB database, I added a generated devcontainer.json configuration file for Node which looks like

// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at:
// https://github.com/microsoft/vscode-dev-containers/tree/v0.202.3/containers/javascript-node
{
    "name": "Node.js",
    "runArgs": ["--init"],
    "build": {
        "dockerfile": "Dockerfile",
        // Update 'VARIANT' to pick a Node version: 16, 14, 12.
        // Append -bullseye or -buster to pin to an OS version.
        // Use -bullseye variants on local arm64/Apple Silicon.
        "args": { "VARIANT": "12" }
    },

    // Set *default* container specific settings.json values on container create.
    "settings": {},

    // Add the IDs of extensions you want installed when the container is created.
    "extensions": [
        "dbaeumer.vscode-eslint"
    ],

    // Use 'forwardPorts' to make a list of ports inside the container available locally.
    // "forwardPorts": [],

    // Use 'postCreateCommand' to run commands after the container is created.
    // "postCreateCommand": "yarn install",

    // Comment out connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root.
    "remoteUser": "node"
}

It also generated a Dockerfile

# See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.202.3/containers/javascript-node/.devcontainer/base.Dockerfile

# [Choice] Node.js version (use -bullseye variants on local arm64/Apple Silicon): 16, 14, 12, 16-bullseye, 14-bullseye, 12-bullseye, 16-buster, 14-buster, 12-buster
ARG VARIANT="16-bullseye"
FROM mcr.microsoft.com/vscode/devcontainers/javascript-node:0-${VARIANT}

# [Optional] Uncomment this section to install additional OS packages.
# RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
#     && apt-get -y install --no-install-recommends <your-package-list-here>

# [Optional] Uncomment if you want to install an additional version of node using nvm
# ARG EXTRA_NODE_VERSION=10
# RUN su node -c "source /usr/local/share/nvm/nvm.sh && nvm install ${EXTRA_NODE_VERSION}"

# [Optional] Uncomment if you want to install more global node modules
# RUN su node -c "npm install -g <your-package-list-here>"

These files are inside my .devcontainer folder, now in my project's docker-compose.yml file

version: '3.8'

services:
  mariadb:
    image: mariadb:10.1
    env_file: .env
    environment:
    ports:
      - 3306:3306
    volumes:
      - ./docker/mariadb.conf.d/:/etc/mysql/conf.d:z
      - ./docker/mariadb-init/:/docker-entrypoint-initdb.d:z

What I like to achieve is to be able to spin up this mariadb instance so my app inside my dev container can access it and ideally I'd also be able to access the database through my operating system, I'd like to use the existing docker-compose.yml file so that people without the dev containers extension can run docker-compose up manually, how could I achieve this?

David
  • 1,920
  • 25
  • 31
Dan
  • 81
  • 1
  • 2

1 Answers1

7

Full working example (combined from answers mentioned in question and other SO):

  • Linux as host
  • Go as example language
  • zsh, oh-my-zsh, .zsh_history from host Linux

.devcontainer/devcontainer.json:

// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at:
// https://github.com/microsoft/vscode-dev-containers/tree/v0.217.4/containers/go
{
    "name": "Go",
    "service": "workspace",
    "workspaceFolder": "/home/vscode/woskpaces/go-example/",
    "dockerComposeFile": [
        "docker-compose.yml",
        "docker-compose.workspace.yml"
    ],
    // Set *default* container specific settings.json values on container create.
    "settings": {
        "go.toolsManagement.checkForUpdates": "local",
        "go.useLanguageServer": true,
        "go.gopath": "/go",
        "go.goroot": "/usr/local/go"
    },
    // Add the IDs of extensions you want installed when the container is created.
    "extensions": [
        "golang.go"
    ],
    // Use 'forwardPorts' to make a list of ports inside the container available locally.
    // "forwardPorts": [],
    // Use 'postCreateCommand' to run commands after the container is created.
    // "postCreateCommand": "go version",
    // Comment out connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root.
    "remoteUser": "vscode"
}

.devcontainer/docker-compose.workspace.yml:

version: '3'
networks:
  myNetwork:
    name: myNetwork
services:
  workspace:
    build:
      context: ./
      dockerfile: Dockerfile
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - ..:/home/vscode/woskpaces/go-example/
      - ~/.zshrc:/home/vscode/.zshrc
      - ~/.oh-my-zsh/:/home/vscode/.oh-my-zsh/
      - ~/.zsh_history:/home/vscode/.zsh_history
    depends_on:
      - kafka
    tty: true           # <- keeps container running
    networks:
      - myNetwork

.devcontainer/docker-compose.yml:

version: '3'
networks:
  myNetwork:
    name: myNetwork
services:
  zookeeper:
    image: confluentinc/cp-zookeeper:latest
    environment:
      ZOOKEEPER_CLIENT_PORT: 2181
      ZOOKEEPER_TICK_TIME: 2000
    ports:
      - 22181:2181
    networks:
      - myNetwork
    tmpfs: "/datalog"
  
  kafka:
    image: confluentinc/cp-kafka:latest
    depends_on:
      - zookeeper
    ports:
      - 29092:29092
    environment:
      KAFKA_BROKER_ID: 1
      KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka:9092,PLAINTEXT_HOST://localhost:29092
      KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT
      KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT
      KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
    networks:
      - myNetwork
    depends_on:
      - zookeeper

.devcontainer/Dockerfile:

# See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.209.6/containers/go/.devcontainer/base.Dockerfile

# [Choice] Go version (use -bullseye variants on local arm64/Apple Silicon): 1, 1.16, 1.17, 1-bullseye, 1.16-bullseye, 1.17-bullseye, 1-buster, 1.16-buster, 1.17-buster
ARG VARIANT="1.17-bullseye"
FROM mcr.microsoft.com/vscode/devcontainers/go:0-${VARIANT}

# [Choice] Node.js version: none, lts/*, 16, 14, 12, 10
ARG NODE_VERSION="none"
RUN if [ "${NODE_VERSION}" != "none" ]; then su vscode -c "umask 0002 && . /usr/local/share/nvm/nvm.sh && nvm install ${NODE_VERSION} 2>&1"; fi

# [Optional] Uncomment this section to install additional OS packages.
# RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
#     && apt-get -y install --no-install-recommends <your-package-list-here>

# [Optional] Uncomment the next lines to use go get to install anything else you need
# USER vscode
# RUN go get -x <your-dependency-or-tool>

# [Optional] Uncomment this line to install global node packages.
# RUN su vscode -c "source /usr/local/share/nvm/nvm.sh && npm install -g <your-package-here>" 2>&1
David
  • 1,920
  • 25
  • 31
  • 1
    The fact that things are this complicated make me question why anyone would use this feature in the first place. – AlxVallejo Mar 09 '23 at 17:46
  • will docker-compose.workspace.yml override common properties of docker-compose.yml? what ive both had a common service with volumes that are exclusive to each other? are they merged then? – mike01010 Apr 13 '23 at 02:01
  • @AlxVallejo When you have multiple computers, when you have to jump from one programming stack to another or want to conserve/freeze environment setup so when you come back, everything is working as before. Also, when you want to share setup with your team using Git. You may use same setup on remote computers also, so large teams may share setup, and improve it from time to time for benefit of all developers (it is sometimes called "Zero configuration" as new developers don't need to spend time to setup programming stack few hours/days called sometimes "Onboarding" in corporate) – David May 05 '23 at 10:22
  • @David Or you can just open a port up in your container and debug it remotely as necessary without having to run through this crazy configuration. New developers shouldn't struggle for getting docker containers up and running locally and being able to debug them without these dependencies. – AlxVallejo May 05 '23 at 12:59
  • @AlxVallejo There is need to compile code locally for remote debugging. Problem is on client (host) side to have full language stack installed on host environment to be able to compile and follow step by step code on guest (container) env. If working on multiple programming stacks, all of them should be installed on host environment following probably long procedure of docs (in README.md files from source code repos). VSCode devcontainers simplifies and automates it - there is no need for manual tedious installation process. – David May 05 '23 at 15:10
  • @David The entire point of docker-compose is to remove the "manual tedious installation process". It should be as simple as `docker compose up` – AlxVallejo May 05 '23 at 15:13
  • @AlxVallejo It is simple as creating `docker-compose.yml` file. It is simpler, if there is no need for additional "third-party services" (Kafka, Db, Redis...). In that case, VSCode creates devcontainer environment in "one click" automatically - simpler than `docker compose up`. I was talking about setup and configuration. If there is already `.devcontainer/` folder (prepared with all setup), it same same as starting up VSCode or any other IDE. – David May 05 '23 at 15:29