Skip to content

Instantly share code, notes, and snippets.

@zofe
Last active February 11, 2020 09:32
Show Gist options
  • Save zofe/50917c22d72e4fe9d5118779a65d02a8 to your computer and use it in GitHub Desktop.
Save zofe/50917c22d72e4fe9d5118779a65d02a8 to your computer and use it in GitHub Desktop.
Host multiple websites with docker-compose & nginx reverse proxy

docker-compose + nginx reverse proxy

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/

local development

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:


stage server

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


Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment