Setting Up a VSCode Devcontainer Using Docker Compose
Setting up a development environment can sometimes be challenging, especially when multiple services are involved. Fortunately, with Docker Compose and VSCode Devcontainers, you can create a streamlined setup that includes all necessary dependencies and services for your project.
This tutorial will guide you through setting up a VSCode Devcontainer for a Go project using Docker Compose. With this setup, you can run multiple services like PostgreSQL and pgAdmin alongside your application.
Step 1: Create a .env
File
First, create a .env
file to store your database credentials and other environment-specific configurations:
DB_USER=dev
DB_PASSWORD=secret
DB_NAME=dev_db
DB_HOST=db
PGADMIN_DEFAULT_EMAIL=anonymous@example.com
PGADMIN_DEFAULT_PASSWORD=secret
This file centralizes environment variables, making them easier to manage and preventing hardcoding sensitive information into your codebase.
Step 2: Create a docker-compose.yaml
File
Next, define your services in a docker-compose.yaml
file. Here is an example configuration:
services:
app:
image: mcr.microsoft.com/vscode/devcontainers/go:1.23-bookworm
ports:
- "${APP_PORT:-8080}:8080"
volumes:
- .:/workspace:cached
command: sleep infinity
db:
image: postgres:17
volumes:
- db-data:/var/lib/postgresql/data
environment:
POSTGRES_USER: ${DB_USER}
POSTGRES_PASSWORD: ${DB_PASSWORD}
POSTGRES_DB: ${DB_NAME}
pgadmin:
image: dpage/pgadmin4
ports:
- "${PGADMIN_PORT:-5050}:80"
environment:
PGADMIN_DEFAULT_EMAIL: ${PGADMIN_DEFAULT_EMAIL}
PGADMIN_DEFAULT_PASSWORD: ${PGADMIN_DEFAULT_PASSWORD}
volumes:
db-data:
Explanation:
- app: The Go development container. You can use any Go image here; this example uses the Microsoft-based image because it comes pre-packaged with tools and configurations that work well in a Devcontainer environment. The
command: sleep infinity
ensures the container stays alive while developing. - db: A PostgreSQL service with a mounted volume for persistent storage.
- pgadmin: A pgAdmin service for managing your PostgreSQL database via a web interface.
- volumes: Shared volume for the database to persist data.
Step 3: Create a devcontainer.json
File
Configure the Devcontainer settings by creating a .devcontainer/devcontainer.json
file:
{
"name": "Go Development Container",
"dockerComposeFile": "../docker-compose.yaml",
"service": "app",
"workspaceFolder": "/workspace",
"customizations": {
"vscode": {
"extensions": ["golang.Go", "EditorConfig.EditorConfig"],
"settings": {
"terminal.integrated.defaultProfile.linux": "zsh",
"terminal.integrated.profiles.linux": { "zsh": { "path": "/bin/zsh" } }
}
}
},
"remoteUser": "vscode",
"shutdownAction": "stopCompose"
}
Key Configuration:
- dockerComposeFile: Links to your
docker-compose.yaml
file. - service: Specifies the primary container (the Go development container).
- workspaceFolder: Sets the folder inside the container to map your project files.
- customizations: Installs VSCode extensions for Go development and configures the terminal to use Zsh.
- remoteUser: Ensures all operations inside the container run as the
vscode
user.
Step 4: Create a Go Application to Test Database Connection
To ensure your setup works, create a main.go
file that tests the connection to the PostgreSQL database:
package main
import (
"database/sql"
"fmt"
"log"
"os"
_ "github.com/joho/godotenv/autoload"
_ "github.com/lib/pq"
)
func main() {
dbUser := os.Getenv("DB_USER")
dbName := os.Getenv("DB_NAME")
dbPass := os.Getenv("DB_PASSWORD")
dbHost := os.Getenv("DB_HOST")
connStr := fmt.Sprintf(
"host=%s user=%s password=%s dbname=%s sslmode=disable",
dbHost, dbUser, dbPass, dbName,
)
// Open a connection to the database
db, err := sql.Open("postgres", connStr)
if err != nil {
log.Fatalf("Failed to open database: %v", err)
}
defer db.Close()
// Ping the database to verify the connection
if err := db.Ping(); err != nil {
log.Fatalf("Failed to ping database: %v", err)
}
fmt.Println("Successfully connected to the database!")
}
Key Points:
- This code uses environment variables to configure the database connection.
- It connects to the PostgreSQL database and verifies the connection using
db.Ping()
.
Step 5: Open Project in VSCode Devcontainer
Open the project in VSCode Devcontainer. Once the container is running, execute the following command to test the database connection:
go run main.go
You should see the output:
Successfully connected to the database!
Accessing pgAdmin
After starting the containers, you can access pgAdmin at http://localhost:5050. Use the credentials you specified in the environment variables to log in.
Source Code and Documentation
- Source Code: The complete setup can be found on GitHub.
- VSCode Devcontainer Documentation: For more information on configuring Devcontainers, visit the official VSCode documentation.
Conclusion
Using Docker Compose with VSCode Devcontainers provides a powerful and efficient way to manage a development environment with multiple services. This tutorial showed how to set up a Go project with PostgreSQL and pgAdmin, enabling seamless integration and testing. Feel free to expand this setup with additional services as needed for your projects!