For completeness, here is a working solution:
devcontainer.json
{
"dockerComposeFile": "docker-compose.yml",
"workspaceFolder": "/workspaces/plfantasy",
"service": "plfantasy",
"shutdownAction": "stopCompose",
"features": {
"ghcr.io/devcontainers/features/common-utils:2": {
"installZsh": "true",
"username": "vscode",
"userUid": "1000",
"userGid": "1000",
"upgradePackages": "true"
},
"ghcr.io/devcontainers/features/git:1": {
"version": "latest",
"ppa": "false"
}
},
// Configure tool-specific properties.
"customizations": {
// Configure properties specific to VS Code.
"vscode": {
// Set *default* container specific settings.json values on container create.
"settings": {
"emmet.includeLanguages": {
"phoenix-heex": "html"
},
"tailwindCSS.includeLanguages": {
"elixir": "html",
"phoenix-heex": "html"
}
},
"extensions": [
"jakebecker.elixir-ls",
"phoenixframework.phoenix",
"samuel-pordeus.elixir-test",
"bradlc.vscode-tailwindcss",
"ms-azuretools.vscode-docker",
"ms-vscode.azurecli",
"eamodio.gitlens"
]
}
},
// Use 'forwardPorts' to make a list of ports inside the container available locally.
"forwardPorts": [
4000,
4001,
5432
],
// Use 'postCreateCommand' to run commands after the container is created.
"postCreateCommand": "mix local.hex --force && mix local.rebar --force && mix archive.install --force hex phx_new",
// Set `remoteUser` to `root` to connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root.
"remoteUser": "vscode"
}
docker-compose.yml
version: '3'
services:
plfantasy:
build:
context: ..
dockerfile: .devcontainer/Dockerfile
volumes:
- ../..:/workspaces:cached
# Overrides default command so things don't shut down after the process ends.
command: sleep infinity
environment:
MIX_ENV: dev
# Runs app on the same network as the database container, allows "forwardPorts" in devcontainer.json function.
network_mode: service:db
# Use "forwardPorts" in **devcontainer.json** to forward an app port locally.
# (Adding the "ports" property to this file will not forward from a Codespace.)
db:
image: postgres:latest
restart: unless-stopped
environment:
POSTGRES_USER: postgres
POSTGRES_DB: postgres
POSTGRES_PASSWORD: postgres
volumes:
- postgres-data:/var/lib/postgresql/data
volumes:
postgres-data:
Dockerfile
FROM hexpm/elixir:1.15.7-erlang-26.1.2-debian-buster-20231009-slim AS elixir-build
RUN apt-get update && \
apt-get install -y git && \
apt-get install -y postgresql-client && \
apt-get install -y inotify-tools && \
apt-get install -y curl && \
apt-get install -y wget && \
apt-get install -y gnupg2 && \
apt-get install -y dirmngr && \
apt-get install -y gpg && \
apt-get install -y gawk
Note the use of network_mode in docker-compose.yml. I did not need to tweak the IP mapping in config/dev.exs


















