Docker: multiple sites with common containers

docker, docker-compose, reverse-proxy

Solution

Finally I managed to do it with `jwilder/nginx-proxy`. You can get full code from my repository.

docker-compose.yml:

version: '2'
services:
  # Reverse proxy
  nginx-proxy:
    image: jwilder/nginx-proxy
    container_name: nginx-proxy
    ports:
      - 80:80
    volumes:
      - /var/run/docker.sock:/tmp/docker.sock:ro

  # Services
  redis:
    image: redis:3.0.7
    ports:
      - 6379
  mysql:
    image: mysql:5.7
    ports:
      - 3306
    volumes:
      - /var/lib/mysql
    environment:
      - MYSQL_ROOT_PASSWORD=secretpass
  php5.6:
    build: ./php5.6
    ports:
      - 8001:80
    volumes:
      - ./php5.6/src:/var/www/html
    environment:
      - VIRTUAL_HOST=site1.dev
  php7.1:
    build: ./php7.1
    ports:
      - 8002:80
    volumes:
      - ./php7.1/src:/var/www/html
    environment:
      - VIRTUAL_HOST=site2.dev,site3.dev

  # Sites
  site1:
    image: tianon/true #minimal image
    depends_on:
      - nginx-proxy
      - php5.6
      - mysql
  site2:
    image: tianon/true #minimal image
    depends_on:
      - nginx-proxy
      - php7.1
      - mysql
  site3:
    image: tianon/true #minimal image
    depends_on:
      - nginx-proxy
      - php7.1
      - redis

Also I added following lines to `/etc/hosts/`:

 127.0.0.1   site1.dev
 127.0.0.1   site2.dev
 127.0.0.1   site3.dev

Now I can access sites with friendly-urls.

Problem

I am creating portfolio and I want to run all my sites on DigitalOcean droplet. I am using PHP7 in new projects, but some old ones are working only with PHP5. When I was looking how to run multiple versions I found Docker platform. Let's consider few sites: - Site 1 -> PHP5, MySQL - Site 2 -> PHP7, MySQL - Site 3 -> PHP7, Redis In typical approach with creating separated containers there will be two MySQL and two PHP7 instances, but with my small server I can't afford this. Sites doesn't have to be isolated, so they should use common containers to consume less memory. This is the target architecture: Currently I came up with this: ``` php5.6/ src/ site1/ #site1 files ... sites-available/ #virtual hosts for php5.6 site1.conf a2ensites.sh #script enabling all sites Dockerfile php7.1/ src/ site2/ #site2 files ... site3/ #site3 files ... sites-available/ #virtual hosts for php7.1 site2.conf site3.conf a2ensites.sh #script enabling all sites Dockerfile docker-compose.yml ``` docker-compose.yml: ``` version: '2' services: redis: image: redis:3.0.7 ports: - 6379 mysql: image: mysql:5.7 ports: - 3306 volumes: - /var/lib/mysql environment: - MYSQL_ROOT_PASSWORD=secretpass php5.6: build: ./php5.6 ports: - 8001:80 volumes: - ./php5.6/src:/var/www/html php7.1: build: ./php7.1 ports: - 8002:80 volumes: - ./php7.1/src:/var/www/html site1: image: tianon/true #minimal image depends_on: - php5.6 - mysql site2: image: tianon/true #minimal image depends_on: - php7.1 - mysql site3: image: tianon/true #minimal image depends_on: - php7.1 - redis ``` php5.6/Dockerfile: ``` FROM php:5.6-apache RUN a2enmod rewrite \ && docker-php-ext-install pdo pdo_mysql mysql EXPOSE 80 ADD ./sites-available /etc/apache2/sites-available/ COPY a2ensites.sh /a2ensites.sh RUN /a2ensites.sh && rm /a2ensites.sh ``` php5.6/sites-available/site1.conf: ``` <VirtualHost *:80> ServerName site1.dev DocumentRoot /var/www/html/site1 <Directory "/var/www/html/site1"> Options -Indexes AllowOverride All </Directory> </VirtualHost> ``` You can get all files from my repo and test it yourself. Now I can access all three sites with localhost:8001/site, localhost:8001/site2 and localhost:8002/site3, but I want it to work on site1.dev, site2.dev and site3.dev. How can I do this? Edit: I think I should create reverse-proxy container on port 80, but currently I don't know exactly how to do it.

Original source