Jericho Rivera
Jericho Rivera

Developing with Golang + FerretDB + PostgreSQL using Dev Containers

Recently, I have been working on ways to improve my testing environment and I stumbled upon Dev Containers. This article will provide a brief introduction on how to use Dev Containers in Visual Studio Code with FerretDB and PostgreSQL with Go.

What are Dev Containers?

The Visual Studio Code Dev Containers is an extension that lets you use a container as a full-featured development environment. It seamlessly integrates with Docker to launch a single container or with Docker Compose to launch multiple containers.

What are the minimum requirements?

You will need to install Docker Desktop, Visual Studio Code, and the Dev Containers extension.

The Setup

Ensure that Docker is installed and running, please refer to the Docker documentation for this part.

Open Visual Studio Code and install the Dev Containers extension.

Create the root directory:

 mkdir goferret // you may choose any other name here

Create the .devcontainer folder and inside the new directory then create the devcontainer.json and docker-compose.yml files. Your folder structure would be similar to this:

tree -a goferret/
goferret/
├── .devcontainer
│   ├── devcontainer.json
│   └── docker-compose.yml
└── src

3 directories, 2 files

Add the following in the devcontainer.json file:

{
    "name": "Go FerretDB",
    "dockerComposeFile": "docker-compose.yml",
    "service": "goferret",
    "workspaceFolder": "/workspace/src"
}

In the docker-compose.yml file, add the following lines:

services:
  goferret:
    container_name: goferret
    image: mcr.microsoft.com/devcontainers/go:1.22-bullseye
    restart: on-failure
    volumes:
      - ../:/workspace:cached
    links:
      - ferretdb
    command: ["sleep", "infinity"]
  
  ferretdb:
    container_name: ferretdb
    image: ghcr.io/ferretdb/ferretdb
    restart: on-failure
    environment:
      - FERRETDB_POSTGRESQL_URL=postgres://goferret:goferret101@postgresqldb:5432/ferretdb
  
  postgresqldb:
    container_name: postgresqldb
    image: postgres
    restart: on-failure
    environment:
      - POSTGRES_USER=goferret
      - POSTGRES_PASSWORD=goferret101
      - POSTGRES_DB=ferretdb
    command: [ "postgres", "-c", "wal_level=logical" ]
    volumes:
      - pgdata:/var/lib/postgresql/data

volumes:
  pgdata:

At this point you can start using dev containers, open the Command Palette (ctrl-shift-p), and then type Reopen in Container at the prompt.

Initialize the app from the VSCode terminal with

go mod init goferret

Create the main.go file and add the sample code from the MongoDB official manual.

// Connects to MongoDB and sets a Stable API version
package main

import (
	"context"
	"fmt"

	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
)

// Replace the placeholder with your Atlas connection string
const uri = "mongodb://goferret:goferret101@ferretdb:27017/ferretdb?authMechanism=PLAIN"

func main() {

	// Use the SetServerAPIOptions() method to set the Stable API version to 1
	serverAPI := options.ServerAPI(options.ServerAPIVersion1)
	opts := options.Client().ApplyURI(uri).SetServerAPIOptions(serverAPI)

	// Create a new client and connect to the server
	client, err := mongo.Connect(context.TODO(), opts)

	if err != nil {
		panic(err)
	}
	defer func() {
		if err = client.Disconnect(context.TODO()); err != nil {
			panic(err)
		}
	}()

	// Send a ping to confirm a successful connection
	var result bson.M
	if err := client.Database("admin").RunCommand(context.TODO(), bson.D{{Key: "ping", Value: 1}}).Decode(&result); err != nil {
		panic(err)
	}
	fmt.Println("Pinged your deployment. You successfully connected to MongoDB!")
}

From here you can either execute

go get .
go run .

to download the packages and execute the program.

vscode ➜ /workspace/src $ go run .
go: downloading github.com/klauspost/compress v1.13.6
Pinged your deployment. You successfully connected to MongoDB!

That's it, we completed setting up a Go + FerretDB + PostgreSQL development environment using Dev Containers and Docker with Visual Studio Code.

Send Jericho Rivera a reply about this page
More from Jericho Rivera
Back to profile