Access Your Version Controlled Configuration from a Docker Container

For years now, I’ve stubbornly duplicated version-controlled configuration files into my running Docker containers. Meaning, instead of making the files accessible directly by the container, I’ve been maintaining both the version-controlled file and copies used by the containers. At last, I’ve found a solution to help avoid the duplication.

Visualization of Docker volumes and bind mounts
Image credit : Jaouadirabeb

The problem

Right now I keep my configuration files in a homelab repository. For example, /home/fletcher/homelab/gatus/config/config.yml has my configuration for my Gatus monitoring. But when I first started running services in 2019, I settled on keeping all service data jailed to /home/fletcher/service-data; for example, service-data/gatus for Gatus data, service-data/home-assistant for Home Assistant data, etc. Keeping all container data compartmentalized to service-data made sense in my brain.

The problem is, for service data that is human-managed configuration, like Gatus, how can I keep it version controlled? I could make it its own git repository, but then it would be decoupled from the rest of my homelab content. I could duplicate it, but who wants that? So I tried symlinks…and failed miserably. I tried symlinking service-data/gatus to homelab/gatus, but since path mappings are different in the container, the symlinks don’t work.

At this point I gave up and duplicated the content, which of course means they sometimes got out of sync.

The solution – duh

The solution was pretty obvious when I slept on it for a few years and took another look. Somehow in my head I got “keep all service data jailed to /home/fletcher/service-data.” But by simply bind mounting another directory, poof, now I can point directly at the source directory! Duh!!!!

An example

Here is what my compose configuration looks like for Gatus:


gatus:
    container_name: gatus
    image: twinproduction/gatus:v5.37.0
    restart: unless-stopped

    networks:
      - gatus
    ports:
      - 8080:8080
    volumes:
      - ${HOMELAB_DIR}/gatus/config/config.yaml:/config/config.yaml:ro
      - ${SERVICE_DATA_DIR}/gatus/data:/data

And then in my .env file I have:


HOMELAB_DIR=/home/fletcher/git/homelab
SERVICE_DATA_DIR=/home/fletcher/service-data

Super straightfoward. In the case of Gatus, there’s no reason for its configuration to be changed by the application, so we bind it read-only.

Conclusion

This is such a blindingly obvious solution I’m embarrassed to be writing about it seven years later. I think I got myself into this pickle because I was too fixated on “all Docker service data must be jailed to /home/fletcher/service-data!” And that constraint had me overlooking other solutions.

But, that said, we all have our blinders on sometimes. This is a good reminder to be patient and empathetic when others have their blinders on, as we’re all human and you’ll likely have yours on again next week.

Conversation

Join the conversation

Your email address will not be published. Required fields are marked *