Categories
Software

Improve your local web app development with Docker

Setting up the initial container

The docker-compose file will initially just have a go image and mount our entire local directory. This will allow you to work within the container with all of the application’s source files.

docker-compose.yaml

version: '3'

services:
  app:
    working_dir: /app
    stdin_open: true
    image: golang:1.14-alpine
    volumes:
      - ./:/app

I’ve picked an alpine build for the go image because of how small the Alpine images are. It should make the initial builds faster than using larger Linux distributions (and often you won’t need the functionality in said distributions for development or deployment either).

stdin_open is set to true so that we can run

$ docker-compose exec app [command]

to execute commands into the container when it is running.

Run:

$ docker-compose up -d

to start the container in detached mode. You can then enter the go container with:

$ docker-compose run exec app sh
/app #

And you’re in there, capable of running all your Linux commands inside the container!

The app – "Hello, world" revisited

Let us create a simple app – it will just expose a root / HTTP endpoint which writes Hello, world! as a response.

main.go

package main

import (
    "net/http"
)

func main() {
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        w.Write([]byte("Hello, world!"))
    })

    panic(http.ListenAndServe(":8000", nil))
}

The service is exposed on port 8000 for now (we will change this later). We now want to make this exposed in our docker-compose configuration:

docker-compose.yaml

version: '3'

services:
  app:
    working_dir: /app
    stdin_open: true
    image: golang:1.14-alpine
    volumes:
      - ./:/app
    ports:
      - 8000:8000

Now run the following commands:

$ docker-compose up -d
$ docker-compose exec app go run main.go

and visit http://localhost:8000 to see the message Hello, world!. If you see it, congratulations: the app is now containerized! You can stop the container with:

$ docker-compose down

This is a good starting point, but it can be improved on. We want to make the ports configurable for both the host and the container: in a world of microservices development, developers could be running multiple docker containers and apps on various ports, and we want to make this as easy as possible to change.