local & stage development with docker-compose & nginx-proxy to host multiple websites on a stage server
two environments: local & stage ( with multiple domains on stage using proxy network)
software needed: docker + docker-compose
ref: https://blog.ssdnodes.com/blog/host-multiple-websites-docker-nginx/
On local development we assume you enable/run only a single project at time.
typically with "docker-compose up -d" from project root.
This is why proxy-network is created only on stage server (but is up to you).
You can configure local and stage hostnames in your /etc/hosts
cat /etc/htdocs
127.0.0.1 project1.local
216.58.208.163 project1.stage (<-- if need fake hostname for stage server)
/home/localuser/html <-- local public html
/home/localuser/html/project1/
/home/localuser/html/project1/.env (<-- git-ignored env variables)
/home/localuser/html/project1/docker-compose.yml <-- common compose
/home/localuser/html/project1/docker-compose-local.yml <-- specific local directives
/home/localuser/html/project1/docker-compose-release.yml <-- specific stage directives
cat /home/localuser/html/project1/.env
VIRTUAL_HOST=project1.local,aliasproject1.local
APP_NAME=project_1
COMPOSE_PROJECT_NAME=project_1
COMPOSE_FILE=docker-compose.yml:docker-compose-local.yml
VIRTUAL_HOST contains hostnames (concatenated with comma)
APP_NAME is used to pass an unique identifier to your services
COMPOSE_PROJECT_NAME is the default name postponed to the containers i.e.: (database-project_1, webserver-project_1)
COMPOSE_FILE is the name/s of file loaded by "docker-compose up"
cat /home/localuser/html/project1/docker-compose.yml
version: '2'
volumes:
mysql_data:
driver: local
services:
php-fpm:
image: phpdockerio/php72-fpm:latest
container_name: "php-fpm-${APP_NAME}"
working_dir: /application
volumes:
- ./app:/application
- ./docker/phpinfo.php:/application/public/phpinfo.php
- ./docker/storage:/application/storage
nginx:
image: nginx
container_name: "nginx-${APP_NAME}"
working_dir: /application
volumes:
- ./docker/nginx.conf:/etc/nginx/conf.d/default.conf
- ./app/public:/application/public
- ./log/nginx:/var/log/nginx
database:
container_name: "mysql-${APP_NAME}"
image: mysql:5.7
environment:
- MYSQL_ROOT_PASSWORD=root
- MYSQL_DATABASE=${APP_NAME}_db
- MYSQL_USER=${APP_NAME}
- MYSQL_PASSWORD=${APP_NAME}
volumes:
- mysql_data:/var/lib/mysql
- ./initial_dump.sql:/docker-entrypoint-initdb.d/dump.sql
local .yml usually map ports and use default network
cat /home/localuser/html/project1/docker-compose-local.yml
version: '2'
services:
database:
ports:
- 3306:3306
webserver:
environment:
VIRTUAL_HOST: ${VIRTUAL_HOST}
ports:
- 80:80
networks:
default:
cat /etc/htdocs
127.0.0.1 project1.stage (<-- if need fake hostname)
/home/stageuser/html (<--- projects root)
/home/stageuser/html/nginx-proxy (<--- reverse proxy)
/home/stageuser/html/nginx-proxy/docker-compose.yml
reverse proxy configuration
$ cat /home/stageuser/html/nginx-proxy/docker-compose.yml
version: "3"
services:
nginx-proxy:
image: jwilder/nginx-proxy
container_name: nginx-proxy
ports:
- "80:80"
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
- /var/docker/proxy/htpasswd/:/etc/nginx/htpasswd
networks:
default:
network_mode: "host"
external:
name: nginx-proxy
optional basic auth for each project (filename must be the hostname)
cat /var/docker/proxy/htpasswd/project1.stage
project1:{SHA}opRrLDSuXrtXSDXmWmqA4EoKK6Q=
projects on stage server must have a different .env note also the difference of COMPOSE_FILE concatenation
/home/stageuser/html/project1
/home/stageuser/html/project1/.env
/home/stageuser/html/project1/docker-compose.yml
/home/stageuser/html/project1/docker-compose-release.yml
cat /home/stageuser/html/project1/.env
VIRTUAL_HOST=project1.stage
APP_NAME=project_1
COMPOSE_PROJECT_NAME=project_1
COMPOSE_FILE=docker-compose.yml:docker-compose-release.yml
the release .yml just expose port 80 on webserver and use nginx-proxy
cat /home/stageuser/html/project1/docker-compose-release.yml
version: '2'
services:
webserver:
environment:
VIRTUAL_HOST: ${VIRTUAL_HOST}
expose:
- 80
networks:
default:
external:
name: nginx-proxy