Unified Docker development environment that automatically serves any project in the workspace — no per-project configuration needed.
Clone any project into your workspace folder and it's instantly accessible via http://<folder>.<repo-name>.test:81. Powered by wildcard nginx + dnsmasq.
| Service | Container | Port | Image |
|---|---|---|---|
| Nginx | dj_nginx | 81 → 80 | nginx:latest |
| PHP | dj_php | (internal) | php:8.4-fpm |
| MySQL | dj_mysql | 3307 → 3306 | mysql:8.0 |
| PostgreSQL | dj_postgres | 5432 | postgres:16-alpine |
| Redis | dj_redis | 6379 | redis:latest |
| Memcached | dj_memcached | 11211 | memcached:latest |
| RabbitMQ | dj_rabbitmq | 5672 / 15672 | rabbitmq:3-mgmt |
| phpMyAdmin | dj_phpmyadmin | 8080 → 80 | phpmyadmin:latest |
- Docker Desktop (or Docker Engine on Linux)
- DNS wildcard resolution for
*.test(see DNS Setup below)
# 1. Clone into your workspace
cd ~/Workspace
git clone https://github.com/jupaygon/docker.git
# 2. Configure DNS (one-time, see DNS Setup section)
./docker/scripts/setup-dnsmasq.sh # macOS
# 3. Start services
cd docker
cp .env.dist .env
docker compose up -d --buildAll *.test domains must resolve to 127.0.0.1. Choose your platform:
./scripts/setup-dnsmasq.shThis installs dnsmasq via Homebrew, adds address=/test/127.0.0.1, and creates /etc/resolver/test.
# Install dnsmasq
sudo apt install dnsmasq # Debian/Ubuntu
sudo dnf install dnsmasq # Fedora/RHEL
# Configure wildcard
echo "address=/test/127.0.0.1" | sudo tee /etc/dnsmasq.d/test.conf
# If systemd-resolved is running (Ubuntu 18+), configure it to delegate .test:
sudo mkdir -p /etc/systemd/resolved.conf.d
echo -e "[Resolve]\nDNS=127.0.0.1\nDomains=~test" | sudo tee /etc/systemd/resolved.conf.d/test.conf
sudo systemctl restart systemd-resolved
# Restart dnsmasq
sudo systemctl restart dnsmasqdnsmasq is not available on Windows. Use Acrylic DNS Proxy instead:
- Install Acrylic DNS Proxy
- Edit
AcrylicHosts.txt, add:127.0.0.1 *.test - Set your network adapter DNS to
127.0.0.1
Alternatively, use WSL2 and follow the Linux setup inside your WSL distribution.
- dnsmasq resolves all
*.testdomains to127.0.0.1 - Nginx captures the first subdomain segment as the folder name:
server_name ~^(?<folder>[^.]+)\.; root /var/www/html/$folder/public; - The entire workspace is mounted as a single volume
http://<folder>.<repo-name>.test:81
Only the first segment (<folder>) determines which folder is served. The second segment (<repo-name>) is for DNS routing.
For a regular clone, <folder> and <repo-name> are the same:
cd ~/Workspace
git clone https://github.com/org/my-project.git
# → http://my-project.my-project.test:81If you use git worktrees to work on multiple branches simultaneously, each worktree gets its own folder — and its own URL:
cd ~/Workspace/my-project
git worktree add ../wt-my-project-fix-login feature/fix-login
# → http://wt-my-project-fix-login.my-project.test:81No nginx config, no hosts file, no restart. It just works.
The PHP container includes everything you'd need for a modern Symfony/Laravel stack:
redis · amqp · imagick · zip · xml · mbstring · bcmath · soap · intl · gd · xsl · opcache · pdo_mysql · pdo_pgsql · memcached · xdebug
Plus Composer and Deployer pre-installed.
Add to your .zshrc:
export DJ_HOME="$HOME/Workspace"
# Login into containers
alias dj-docker-php="docker exec -ti dj_php bash"
alias dj-docker-mysql="docker exec -ti dj_mysql bash"
alias dj-docker-nginx="docker exec -ti dj_nginx bash"
alias dj-docker-redis="docker exec -ti dj_redis redis-cli"
# Docker compose shortcut
alias dj-docker="docker compose -f $DJ_HOME/docker/docker-compose.yml"
# Start / stop
alias dj-docker-up="$DJ_HOME/docker/scripts/docker-up.sh"
alias dj-docker-build="dj-docker up --build -d"
alias dj-docker-down="$DJ_HOME/docker/scripts/docker-down.sh"
# Service UIs
alias dj-docker-rabbit="open http://localhost:15672"
alias dj-docker-pma="open http://localhost:8080"
# Monitoring
alias dj-docker-ps="docker ps | grep dj_"
alias dj-docker-images="docker images | grep dj_"| Command | Description |
|---|---|
dj-docker-php |
Shell into PHP container |
dj-docker-mysql |
Shell into MySQL container |
dj-docker-redis |
Redis CLI |
dj-docker |
Docker compose shortcut |
dj-docker-up |
Start containers |
dj-docker-down |
Stop containers (backs up databases) |
dj-docker-build |
Rebuild and start containers |
dj-docker-rabbit |
Open RabbitMQ Management UI |
dj-docker-pma |
Open phpMyAdmin |
| Script | Description |
|---|---|
scripts/setup-dnsmasq.sh |
One-time DNS setup (installs and configures dnsmasq) |
scripts/docker-up.sh |
Start containers with credentials support |
scripts/docker-down.sh |
Stop containers with automatic database backup |
scripts/db-sync.sh |
Interactive database sync from remote servers |
# Verify dnsmasq
brew services list | grep dnsmasq
# Test resolution
dig test-project.test @127.0.0.1
# Re-run setup
./scripts/setup-dnsmasq.sh- Ensure the project has a
public/directory with anindex.phporindex.html - Check the folder name matches the first subdomain segment exactly
Host: dj_mysql
Port: 3306
User: root | dev
Password: password
Host: dj_postgres
Port: 5432
User: app
Password: password
Database: app
MIT