Skip to content

Instantly share code, notes, and snippets.

@crissilvaeng
Created July 10, 2025 23:37
Show Gist options
  • Save crissilvaeng/ab6a555e81ebde6fffa3eb2f41c361a1 to your computer and use it in GitHub Desktop.
Save crissilvaeng/ab6a555e81ebde6fffa3eb2f41c361a1 to your computer and use it in GitHub Desktop.
A ready-to-code Elixir/Phoenix/Erlang dev environment using VS Code Dev Containers, Docker Compose, and PostgreSQL. Includes automatic setup, common utilities, and recommended extensions for a seamless onboarding and development experience.
{
"name": "boilerplate-dev",
"dockerComposeFile": "docker-compose.yml",
"service": "elixir",
"workspaceFolder": "/workspace",
"features": {
"ghcr.io/devcontainers/features/common-utils:2": {
"installZsh": "true",
"configureZshAsDefaultShell": "true",
"installOhMyZsh": "true",
"username": "vscode",
"userUid": "1000",
"userGid": "1000",
"upgradePackages": "true"
},
"ghcr.io/devcontainers-extra/features/apt-packages:1": {
"packages": "curl, git, inotify-tools, watchman"
},
"ghcr.io/devcontainers/features/github-cli": {}
},
"forwardPorts": [
4000,
5432
],
"portsAttributes": {
"4000": {
"onAutoForward": "openBrowser"
},
"5432": {
"onAutoForward": "notify"
}
},
"remoteUser": "vscode",
"remoteEnv": {
"PHOENIX_VERSION": "1.8.0-rc.3"
},
"onCreateCommand": {
"loca.hex": [
"/bin/sh",
"-c",
"mix local.hex --force"
],
"local.rebar": [
"/bin/sh",
"-c",
"mix local.rebar --force"
],
"archive.install": [
"/bin/sh",
"-c",
"mix archive.install hex phx_new $PHOENIX_VERSION --force"
]
},
"postCreateCommand": [
"/bin/sh",
"-c",
"mix deps.get && mix ecto.setup"
],
"customizations": {
"vscode": {
"extensions": [
"JakeBecker.elixir-ls",
"phoenixframework.phoenix",
"bradlc.vscode-tailwindcss",
"mtxr.sqltools",
"mtxr.sqltools-driver-pg"
]
}
}
}
services:
elixir:
image: elixir:1.18
command: sleep infinity
network_mode: service:postgres
volumes:
- ..:/workspace:cached
depends_on:
postgres:
condition: service_healthy
postgres:
image: postgres:17.5
restart: unless-stopped
environment:
POSTGRES_PASSWORD: postgres
POSTGRES_USER: postgres
POSTGRES_DB: boilerplate_dev
volumes:
- postgres-data:/var/lib/postgresql/data
healthcheck:
test: [ "CMD-SHELL", "pg_isready -U postgres" ]
interval: 2s
timeout: 5s
retries: 5
volumes:
postgres-data:
{
"version": "0.2.0",
"configurations": [
{
"type": "mix_task",
"name": "mix phx.server",
"request": "launch",
"task": "phx.server",
"projectDir": "${workspaceRoot}",
"exitAfterTaskReturns": false
},
{
"type": "mix_task",
"name": "mix test",
"request": "launch",
"task": "test",
"projectDir": "${workspaceRoot}"
}
]
}
{
"files.exclude": {
"**/_build": true,
"**/deps": true,
"**/.elixir_ls": true,
},
"emmet.includeLanguages": {
"phoenix-heex": "html",
"html-eex": "html"
},
"sqltools.connections": [
{
"previewLimit": 50,
"server": "localhost",
"port": 5432,
"driver": "PostgreSQL",
"name": "boilerplate_dev",
"database": "boilerplate_dev",
"username": "postgres",
"password": "postgres"
}
],
"sqltools.autoConnectTo": [
"boilerplate_dev"
],
}

Boilerplate Dev Environment

This project is set up for Elixir, Phoenix, and Erlang development using a Dev Container for a fully reproducible and isolated environment. Below you'll find details on the setup, utilities, and how to get started.

Dev Container Overview

The development environment is defined using VS Code Dev Containers, leveraging Docker Compose for service orchestration. This ensures all contributors have a consistent setup, regardless of their local OS.

Key Features

  • Elixir 1.18 and Erlang pre-installed
  • Phoenix installed via mix archive.install
  • PostgreSQL 17.5 as the default database
  • Zsh with Oh My Zsh for a modern shell experience
  • Common utilities: curl, git, inotify-tools, watchman, and gh (GitHub CLI)
  • Automatic dependency installation and database setup on first run
  • Recommended VS Code extensions for Elixir, Phoenix, TailwindCSS, and SQL

Getting Started

  1. Open in VS Code

    • Use "Open Folder in Container" or the green "><" button in the bottom-left of VS Code.
    • VS Code will build the container and set up the environment automatically.
  2. Services

    • elixir: Main development container, runs Elixir, Phoenix, and your code.
    • postgres: Database service, automatically initialized and health-checked.
  3. Ports

    • 4000: Phoenix web server (auto-opens in browser)
    • 5432: PostgreSQL (auto-notifies)
  4. First-Time Setup

    • On first container start, the following commands run automatically:
      • mix local.hex --force
      • mix local.rebar --force
      • mix archive.install hex phx_new $PHOENIX_VERSION --force
      • mix deps.get && mix ecto.setup
  5. Database

    • Default credentials: postgres/postgres, database: boilerplate_dev
    • Data is persisted in a Docker volume (postgres-data)
  6. VS Code Extensions

    • ElixirLS (language server)
    • Phoenix Framework tools
    • TailwindCSS IntelliSense
    • SQLTools and PostgreSQL driver
  7. .vscode/settings.json

    • Excludes build and dependency folders from the file explorer
    • Enables Emmet for Phoenix templates
    • Pre-configures SQLTools for local database access
  8. .vscode/launch.json

    • Debug and run tasks for mix phx.server and mix test

Useful Commands

  • Start Phoenix server:
    mix phx.server
  • Run tests:
    mix test
  • Install dependencies:
    mix deps.get
  • Setup database:
    mix ecto.setup

Troubleshooting

  • If you encounter issues with dependencies or the database, try rebuilding the container from the VS Code command palette ("Dev Containers: Rebuild and Reopen in Container").
  • Ensure Docker Desktop is running and has enough resources allocated.

Additional Notes

  • The Dev Container is configured for the vscode user with UID/GID 1000.
  • Environment variable PHOENIX_VERSION is set to 1.8.0-rc.3.
  • All code and data are mounted into /workspace inside the container.

For more details, see the following files:

  • .devcontainer/devcontainer.json
  • .devcontainer/docker-compose.yml
  • .vscode/settings.json
  • .vscode/launch.json

Happy coding!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment