dockerdocker-composereverse-proxy

Docker: multiple sites with common containers


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:

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: 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.


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.