Run and Develop Hugo in a Docker Container

Published: 2024-06-05 | Updated: 2024-06-17

I like to keep my development machine as clean as possible, and for keeping my projects under development as separated as possible, Docker is a no-brainer.

With separate Docker containers for each project nothing in project A can ever interfere with something going on in project B. All projects effectively run on serarate machines. Not only that, but as many projects as necessary can be in active development at the same time.

My setup for each project lives in a .docker folder in the project root. It consists of 3 files: .env, compose.yml, and

What I love about this setup is all it takes to start up a new project is a quick modification to the .env file and I’m off to the races. Here’s what’s in mine for this site:

COMPOSE_PROJECT_NAME    = hugo_tdstg
HOST_MACHINE_PORT       = 2020
VIRTUAL_HOST            = tdstg.localhost

My Docker Compose file is pretty simple too:


      - .env
    image: hugomods/hugo:exts
    container_name: ${COMPOSE_PROJECT_NAME}
    restart: unless-stopped
      - ../:/src
      - $HOME/hugo_cache:/tmp/hugo_cache
    working_dir: /src
    stdin_open: true # docker run -i
    tty: true        # docker run -t
    command: /bin/sh -c ".docker/"

    name: local-network
    external: true

There is nothing in this compose file which ever needs to change when starting up a new development container.

And finally, my startup script, which Docker runs automatically


set -e  # quit on any error

echo Starting HUGO Development Server on port $HOST_MACHINE_PORT

# index the site
npx -y pagefind --site public && \
hugo server -p $HOST_MACHINE_PORT --disableFastRender --gc --ignoreCache --bind --appendPort=false

Like compose.yml, never needs to be modified. They get everything they need from the .env file. So all it takes is to pick a project name and a port on my host machine and I’m good to go. Simple and fast.