Reputation: 11818
I have this multi-container project comprised of 3 NestJS and 1 dotnet5.0 application. Besides the applications, the project depends on a RabbitMQ and an InfluxDB services (running as pure docker images)
The docker-compose
file looks like this:
version: '3.8'
services:
influxdb:
image: influxdb:2.0
container_name: influxdb
ports:
- '8086:8086'
expose:
- '8086'
volumes:
- ./data/influxdb2/data:/var/lib/influxdb2
- ./data/influxdb2/config:/etc/influxdb2
rabbitmq:
hostname: 'rabbitmq'
image: rabbitmq:3-management
container_name: rabbitmq
ports:
- '15672:15672'
- '5672:5672'
microservice1:
image: microservice1
container_name: microservice1
depends_on: [rabbitmq, influxdb]
build:
context: .
dockerfile: ./apps/microservice1/Dockerfile
microservice2:
image: microservice2
container_name: microservice2
depends_on: [rabbitmq, influxdb]
build:
context: .
dockerfile: ./apps/microservice2/Dockerfile
microservice3:
image: microservice3
container_name: microservice3
depends_on: [rabbitmq, influxdb]
build:
context: .
dockerfile: ./apps/microservice3/Dockerfile
microservice4:
image: microservice4
container_name: microservice4
depends_on: [rabbitmq, influxdb]
build:
context: .
dockerfile: ./apps/microservice4/Dockerfile
I want to move the whole dev. environment to the new VS Code devcontainers but I'm not quite getting how to work with dependencies (like rabbitmq and influxdb here).
Ideally, I'd open the repo in a devcontainer with both nodejs and dotnet SDKs to be able to run the microservices during development. But, I don't want to also install influxdb and rabbitmq into the devcontainer as I want to leverage the existing (and convenient) docker images.
Problem is, once I open the repo inside the devcontainer there's no way to interact with docker-compose from the inside (as docker/docker-compose is not available inside the devcontainer).
Is it possible to interact with Docker engine on the host from inside the container? So I can simply have a dev.sh
script that can simply up
the rabbitmq and influxdb dependencies and then launch whatever microservice I want to run?
Maybe I'm getting it all wrong but I couldn't find a clear explanation on how to mix VS Code devcontainers and docker-compose files (with image-based dependencies).
Upvotes: 28
Views: 37790
Reputation: 6812
You would need to add Docker as a feature to your devcontainer.json:
"features": { "ghcr.io/devcontainers/features/docker-outside-of-docker:1": {} }
This will allow access to the docker socket on the host.
Working example: devcontainer.json
Upvotes: 8
Reputation: 796
vscode can only use one service as "the workspace" where the IDE runs. Just like when working locally you are on the IDE and the other services run in other containers.
None of your current services seem "good" for being the IDE workspace, so you would have to add that one. That would be "just like" your host machine, but in the container.
You can use multiple compose files so you can avoid changing your current docker-compose.yml
while being able to add your new service.
So, part I:
docker-compose.yml
file (maybe: docker-compose.workspace.yml
).devcontainer.json
point to both files and define the workspace service:...
"dockerComposeFile": [
"docker-compose.yaml",
"docker-compose.workspace.yaml"
],
"service": "workspace",
...
Ok. So that gives you the workspace container and everything else on the side. That gets us to the other part of the question:
Is it possible to interact with Docker engine on the host from inside the container? So I can simply have a dev.sh script that can simply up the rabbitmq and influxdb dependencies and then launch whatever microservice I want to run?
First, if you want the docker & docker-compose commands you have to install the packages. Some images have them builtin, others not. You may use your own image, etc.
But that is not enough. You workspace container is ignorant of the host's docker. But it is easy enough to fix. Just add a volume mount:
/var/run/docker.sock:/var/run/docker.sock
On the workspace service. That way vscode will "see" your host's docker and operate with it.
Beware that it is still the host's docker, so you may get into trouble with paths, etc depending on what you do.
Upvotes: 24
Reputation: 1671
I recently started to muddle through this myself and will share what I have working. I am still futzing with the permissions, but running as root, everything is fine. So, as near as I can tell, you do not need to change anything in your working docker-compose.yml
file. Mine looks like this:
version: '3.9'
services:
app:
build:
context: ./
dockerfile: Dockerfile
command: sleep infinity
user: root
ports:
- 5001:5001
- [snip]
depends_on:
- mysql
mysql:
image: mysql:8
ports:
- 3306:3306
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: myRootpwd32
Taken from the standard Dockerfile
generated by VS Code (truncated for brevity):
# [Choice] .NET version: 5.0, 3.1, 2.1
ARG VARIANT="3.1"
FROM mcr.microsoft.com/vscode/devcontainers/dotnet:0-${VARIANT}
# [Option] Install Node.js
ARG INSTALL_NODE="true"
ARG NODE_VERSION="lts/*"
RUN if [ "${INSTALL_NODE}" = "true" ]; then su vscode -c "umask 0002 && . /usr/local/share/nvm/nvm.sh && nvm install ${NODE_VERSION} 2>&1"; fi
And finally the devcontainer.json
:
{
"name": "C# (.NET)",
"dockerComposeFile": "docker-compose.yml",
"service": "app",
"workspaceFolder": "/workspaces/MemberCore",
// Set *default* container specific settings.json values on container create.
"settings": {
"terminal.integrated.shell.linux": "/bin/bash"
},
// Add the IDs of extensions you want installed when the container is created.
"extensions": [
"ms-dotnettools.csharp",
"wakatime.vscode-wakatime",
"fernandoescolar.vscode-solution-explorer",
"adrianwilczynski.add-reference",
"kreativ-software.csharpextensions",
"k--kato.docomment",
"pranaygp.vscode-css-peek",
"dbaeumer.vscode-eslint",
"patcx.vscode-nuget-gallery",
"derivitec-ltd.vscode-dotnet-adapter"
],
}
The key is obviously in the dockerComposeFile
line, which lets you re-use what you've already written there.
A lot of my information came from this repo: https://github.com/0916dhkim/vscode-devcontainer-tutorial which has a full working example from scratch.
Upvotes: 6