webproject-xyz/docker-hostsfile-sync

A PHP docker API client with a cli tool to sync your hosts file with running docker containers to add hostnames for every network like '172.16.238.100 jwilder-proxy.docker jwilder-proxy.proxyNet jwilder.proxyNet proxy.local.proxyNet'

Installs: 0

Dependents: 0

Suggesters: 0

Security: 0

Stars: 1

Watchers: 1

Forks: 0

Open Issues: 4

pkg:composer/webproject-xyz/docker-hostsfile-sync

1.7.0 2026-01-13 19:15 UTC

README

Tests Docker Image License: MIT PHP Version

Automatically sync your /etc/hosts file with running Docker containers. Each container gets hostnames for every network it's connected to.

Inspired by docker-hostmanager

Features

  • Listens to Docker events in real-time (start, stop, restart)
  • Generates hostnames based on container name and network
  • Supports reverse proxy setups (nginx-proxy, Traefik, etc.)
  • Reads hostnames from DOMAIN_NAME and VIRTUAL_HOST environment variables
  • Works with Docker and Podman

Quick Start

Using Docker (Recommended)

docker run -d \
  --name docker-hostfile-sync \
  --restart=always \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v /etc/hosts:/app/hosts \
  ghcr.io/webproject-xyz/docker-hosts-file-sync:latest

Using Docker Compose

services:
  docker-hostfile-sync:
    image: ghcr.io/webproject-xyz/docker-hosts-file-sync:latest
    container_name: docker-hostfile-sync
    restart: always
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - /etc/hosts:/app/hosts
docker compose up -d

Configuration

Command Line Options

Option Short Description Default
--hosts_file -f Path to hosts file ./tmp-hosts
--tld -t TLD suffix for hostnames .docker
--reverse-proxy-host-ip -r IP address of your reverse proxy -

Environment Variables

You can also configure via environment variables:

Variable Description
HOSTS_FILE Path to hosts file
TLD TLD suffix for hostnames

Examples

Example 1: Basic Setup

A simple web application with a database:

# docker-compose.yml
services:
  docker-hostfile-sync:
    image: ghcr.io/webproject-xyz/docker-hosts-file-sync:latest
    restart: always
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - /etc/hosts:/app/hosts

  webapp:
    image: nginx:alpine
    container_name: webapp

  database:
    image: mysql:8
    container_name: database

Generated hosts entries:

## docker-hostsfile-sync
172.20.0.2 webapp.docker webapp.myproject_default
172.20.0.3 database.docker database.myproject_default
## docker-hostsfile-sync-end

Now you can access your services:

  • http://webapp.docker → nginx container
  • mysql -h database.docker → MySQL container

Example 2: Multiple Networks

When containers are connected to multiple networks, each network gets its own hostname:

# docker-compose.yml
services:
  docker-hostfile-sync:
    image: ghcr.io/webproject-xyz/docker-hosts-file-sync:latest
    restart: always
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - /etc/hosts:/app/hosts

  webapp:
    image: nginx:alpine
    container_name: webapp
    networks:
      - frontend
      - backend

  api:
    image: node:alpine
    container_name: api
    networks:
      - backend

  database:
    image: postgres:16
    container_name: database
    networks:
      - backend

networks:
  frontend:
  backend:

Generated hosts entries:

## docker-hostsfile-sync
172.21.0.2 webapp.docker webapp.frontend
172.22.0.2 webapp.backend
172.22.0.3 api.docker api.backend
172.22.0.4 database.docker database.backend
## docker-hostsfile-sync-end

This allows:

  • Frontend services reach webapp via webapp.frontend
  • Backend services communicate via *.backend hostnames
  • Your host machine can reach any container directly

Example 3: With Reverse Proxy (nginx-proxy)

For production-like setups with a reverse proxy, use the --reverse-proxy-host-ip option. This routes URL-like hostnames (containing dots) to your proxy:

# docker-compose.yml
services:
  docker-hostfile-sync:
    image: ghcr.io/webproject-xyz/docker-hosts-file-sync:latest
    restart: always
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - /etc/hosts:/app/hosts
    command: --reverse-proxy-host-ip=172.16.238.100

  nginx-proxy:
    image: nginxproxy/nginx-proxy
    container_name: nginx-proxy
    ports:
      - "80:80"
    volumes:
      - /var/run/docker.sock:/tmp/docker.sock:ro
    networks:
      proxy:
        ipv4_address: 172.16.238.100

  webapp:
    image: nginx:alpine
    container_name: webapp
    environment:
      - VIRTUAL_HOST=webapp.local,www.webapp.local
    networks:
      - proxy
      - default

  api:
    image: node:alpine
    container_name: api
    environment:
      - DOMAIN_NAME=api.local
    networks:
      proxy:
        aliases:
          - api.dev.local
      default:

networks:
  proxy:
    ipam:
      config:
        - subnet: 172.16.238.0/24

Generated hosts entries:

## docker-hostsfile-sync
# nginx-proxy container
172.16.238.100 nginx-proxy.docker nginx-proxy.proxy

# webapp container - direct access via container IP
172.20.0.2 webapp.docker webapp.myproject_default
172.16.238.2 webapp.proxy

# webapp container - reverse proxy routes (from VIRTUAL_HOST env var)
172.16.238.100 webapp.local www.webapp.local

# api container - direct access
172.20.0.3 api.docker api.myproject_default
172.16.238.3 api.proxy

# api container - reverse proxy routes (from DOMAIN_NAME env var and network alias)
172.16.238.100 api.dev.local api.local
## docker-hostsfile-sync-end

Now you can:

  • Access http://webapp.local → routed through nginx-proxy to webapp
  • Access http://api.local → routed through nginx-proxy to api
  • Access http://webapp.proxy → direct to webapp container (bypassing proxy)
  • Debug with http://api.docker → direct container access

Example 4: Network Aliases

Network aliases let you give containers additional hostnames. Aliases containing a dot (.) are treated as URLs and routed to the reverse proxy:

services:
  docker-hostfile-sync:
    image: ghcr.io/webproject-xyz/docker-hosts-file-sync:latest
    restart: always
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - /etc/hosts:/app/hosts
    command: --reverse-proxy-host-ip=172.16.238.100

  webapp:
    image: nginx:alpine
    container_name: webapp
    networks:
      default:
        aliases:
          - frontend          # Simple alias → webapp IP
          - app.example.com   # URL-like alias → reverse proxy IP

Generated hosts entries:

## docker-hostsfile-sync
172.20.0.2 webapp.docker frontend.default webapp.default
172.16.238.100 app.example.com
## docker-hostsfile-sync-end

How It Works

The tool manages a section in your hosts file between these markers:

## docker-hostsfile-sync
...entries managed automatically...
## docker-hostsfile-sync-end

Everything outside these markers is left untouched.

Hostname Generation Rules

Source Example Generated Hostname Target IP
Container name webapp webapp.networkname Container IP
Simple network alias frontend frontend.networkname Container IP
URL-like network alias app.example.com app.example.com Reverse proxy IP
DOMAIN_NAME env var api.local api.local Reverse proxy IP
VIRTUAL_HOST env var www.app.local www.app.local Reverse proxy IP

URL-like aliases (containing a .) are assumed to be real domain names that should route through your reverse proxy. Simple aliases (no .) are combined with the network name.

Running Locally (Development)

# Install dependencies
composer install

# Run (outputs to ./tmp-hosts for testing)
php bin/docker-api synchronize-hosts -v

# Run with reverse proxy support
php bin/docker-api synchronize-hosts -v --reverse-proxy-host-ip=172.16.238.100

# Run targeting /etc/hosts (requires sudo)
sudo php bin/docker-api synchronize-hosts --hosts_file=/etc/hosts -v

# View logs
docker compose logs -f docker-hostfile-sync

Troubleshooting

Hosts file not updating

  1. Check the container has write access to the hosts file:

    docker exec docker-hostfile-sync ls -la /app/hosts
  2. Check logs for errors:

    docker logs docker-hostfile-sync

Container not appearing in hosts file

Containers must be "exposed" (have at least one network with an IP address). Check your container:

docker inspect <container_name> --format '{{json .NetworkSettings.Networks}}'

License

MIT