Skip to Content

Developing With Docker

Just in case you’ve been living under a rock for the last 5 years or so, here’s a quick primer. Docker is a virtualisation/containerisation platform. It uses a description file (that you create) to build and apply layers to a base image. This allows containers to remain small, and only the layer needs to be updated when there’s a change. The image you build is a portable package, your application and complete dependencies.

This saves you from building entire VMs, maintaining the core system on top of just your application.

I’ve been using Docker for web/server development for a little over a year now. It is an indispensable tool for discrete project setup. I never have to install specific dependencies, or pieces of a stack to my host. In development, you may run into a few host->container mysteries – notoriously, fs updates. Most packages have a slower poll mode to make up for this. Inconvenience for sure, hopefully that’ll be a relic soon enough.

Quick nodemon example setup

  1. Create a Dockerfile – this is your application

    • pick a suitable base

      FROM node
      WORKDIR /var/app
      EXPOSE 3000
      ENTRYPOINT ["/var/app/dev-entrypoint.sh"]
      
    • here’s an example development entrypoint, this makes sure that dependencies are installed after the container is started.

      #!/bin/sh
      yarn install
      yarn dev
      
  2. Create a docker-compose.yml – compose connects containers

    • typically I don’t need to do anything special to base database images

      • initial migrations, schema/config, etc.

        FROM postgres
        COPY ./docker-entrypoint-initdb.d/* /docker-entrypoint-initdb.d
        
    • add a volumes section to persist dev/test data, and to connect your application code (for nodemon)

      version: '3'
      
      services:
          server:
              build: ./server
              env_file: ./server/dev.env
              volumes:
              - ./server:/var/app
              ports:
              - "3000:3000"
              depends_on:
              - db
      
          db:
              build: ./db
              ports:
              - "5432:5432"
              volumes:
              - pgdata:/var/lib/postgresql/data
              environment:
              POSTGRES_PASSWORD: secret
      
      volumes:
          pgdata:
      
    • compose sets up hostnames (by service name) for containers that need to connect between each other.

      • e.g., to connect to the db from server use db:5432
  3. > docker-compose up

Simple, easy to extend. A practical addition might be a container for front-end development.