This project helps you build reusable, versioned development images for Go and Node.js with common tools and a customized Zsh experience.
- Build the image:
make 1.23(or your preferred Go version) - Copy and customize
go/devcontainer.jsonfor your project - Start dependencies (if needed):
docker compose -f shared/utils/docker-compose.yml up -d - Open in VS Code and enjoy your fully configured Go environment!
- Build the image:
make node-20 - Copy and customize
node/devcontainer.jsonfor your project - Open in VS Code and start developing!
If you want to use your own zsh and Powerlevel10k settings, copy them into the shared/zsh-config/ directory:
cp ~/.zshrc shared/zsh-config/
cp ~/.p10k.zsh shared/zsh-config/The repo provides example versions of
.zshrcand.p10k.zsh, but feel free to replace them with your own.
You can also edit the files directly inside shared/zsh-config/.
No need to manually copy plugins — the following plugins are automatically cloned during image build:
zsh-autosuggestionszsh-syntax-highlightingpowerlevel10k
Use make to build the desired version image:
# Build specific versions
make 1.18 # Go 1.18 with gopls v0.14.2, mockery v2.20.0, mockgen v0.1.0
make 1.21 # Go 1.21 with gopls v0.16.1, mockery v2.32.4, mockgen v0.4.0
make 1.23 # Go 1.23 with gopls v0.20.0, mockery v2.47.0, mockgen v0.6.0
make 1.24 # Go 1.24 with gopls v0.20.0, mockery v2.53.6, mockgen v0.6.0
make 1.25 # Go 1.25 with gopls v0.21.1, mockery v2.53.6, mockgen v0.6.0
# Build all Go versions at once
make allEach Go version includes version-specific tooling optimized for that release.
make node-20 # Node.js 20 with pnpm
make node-22 # Node.js 22 with pnpmCopy go/devcontainer.json to your project and customize:
- Update the
"name"and"workspaceFolder"fields to match your project - Update the
"image"field to match your built version (e.g.,"devcontainer-go:1.23") - Customize ports, VS Code extensions, and environment variables as needed
Example customization:
{
"name": "my-go-project",
"image": "devcontainer-go:1.23",
"workspaceFolder": "/my-go-project",
"mounts": [
"source=${localWorkspaceFolder},target=/my-go-project,type=bind,consistency=cached"
]
}Copy node/devcontainer.json to your project and customize:
- Update the
"name"and"workspaceFolder"fields to match your project - Update the
"image"field (e.g.,"devcontainer-node:20") - Customize ports and VS Code extensions as needed
Example customization:
{
"name": "my-node-project",
"image": "devcontainer-node:20",
"workspaceFolder": "/my-node-project",
"mounts": [
"source=${localWorkspaceFolder},target=/my-node-project,type=bind,consistency=cached"
]
}If your project relies on services like MySQL or Redis, use the shared docker-compose.yml:
docker compose -f shared/utils/docker-compose.yml up -dExample:
# shared/utils/docker-compose.yml
services:
mysql:
ports:
- "4306:3306" # Expose MySQL container's port 3306 to host port 4306This setup uses socat to seamlessly forward container ports to host services, allowing your application to use standard connection strings (like 127.0.0.1:3306 for MySQL) while avoiding port conflicts.
How it works:
- Host services run on non-standard ports (MySQL: 4306, Redis: 7379, MongoDB: 37017)
- The
go/post-start-cmd.shscript forwards standard ports in the container to host ports:
# Forward MySQL (3306 in container -> 4306 on host)
nohup socat TCP-LISTEN:3306,fork,reuseaddr TCP:host.docker.internal:4306 > /tmp/socat-mysql.log 2>&1 &
# Forward Redis (6379 in container -> 7379 on host)
nohup socat TCP-LISTEN:6379,fork,reuseaddr TCP:host.docker.internal:7379 > /tmp/socat-redis.log 2>&1 &
# Forward MongoDB (27017 in container -> 37017 on host)
nohup socat TCP-LISTEN:27017,fork,reuseaddr TCP:host.docker.internal:37017 > /tmp/socat-mongo.log 2>&1 &- Your application connects to standard ports as if running locally
Required: Include
"--add-host=host.docker.internal:host-gateway"in yourdevcontainer.jsonunderrunArgsfor this to work.
devcontainer-go/
├── go/ # Go development container
│ ├── Dockerfile
│ ├── devcontainer.json
│ └── post-start-cmd.sh
├── node/ # Node.js development container
│ ├── Dockerfile
│ └── devcontainer.json
├── shared/ # Shared configurations
│ ├── zsh-config/
│ │ ├── .zshrc
│ │ └── .p10k.zsh
│ └── utils/
│ └── docker-compose.yml
├── Makefile
└── README.md
Result: Your DevContainer behaves exactly like a local development environment!