Run multiple Docker Compose projects on the same port using nginx-proxy

Note

Clone the git repository if you haven’t done it yet.

See nginx-proxy

Go to Project 6 from the git repository root:

cd projects/p06

Project structure:

.
├── nginxproxy
│   └── docker-compose.yml
├── web1
│   ├── Dockerfile
│   ├── docker-compose.yml
│   └── www
│       └── index.php
└── web2
    ├── Dockerfile
    ├── docker-compose.yml
    └── www
        └── index.php

We will need a proxy network which will be used by all of the compose projects for the communication between NGinX and the webservers:

docker network create public_proxy

Check the networks:

docker network ls

Navigate to the nginxproxy folder

cd nginxproxy

The compose file is the following:

name: p06proxy

networks:
  default:
    external: true
    name: public_proxy

services:
  nginx-proxy:
    image: nginxproxy/nginx-proxy:1.2.0
    ports:
      - "80:80"
    volumes:
      - /var/run/docker.sock:/tmp/docker.sock:ro

Start the proxy:

docker compose up -d

Navigate to the web1 folder:

cd ../web1

Here you will have a compose file:

name: p06web1

volumes:
  www:

networks:
  proxy:
    external: true
    name: public_proxy

services:
  php:
    image: localhost/p06_php_web1
    build:
      context: .
      dockerfile: Dockerfile
    volumes:
      - www:/var/www/html
  httpd:
    image: itsziget/httpd24:2.0
    volumes:
      - www:/var/www/html
    environment:
      SRV_PHP: "true"
      SRV_DOCROOT: /var/www/html
      VIRTUAL_HOST: web1.$NIP
    networks:
      - default
      - proxy

a Dockerfile

FROM itsziget/php:7.4-fpm

LABEL hu.itsziget.ld.project=p06

COPY www /var/www/html

# The scripts interpreted by PHP-FPM executes on behalf of "www-data" user.
RUN chown www-data:www-data -R /var/www/html

and the PHP file

<?php

file_put_contents(__DIR__ . '/access.txt', date('Y.m.d. H:i:s') . "\n", FILE_APPEND);

echo 'P06WEB1: ' . getenv('HOSTNAME') . '<br/>';
echo nl2br(file_get_contents(__DIR__ . '/access.txt'));

At this point you need to have the NIP variable set as Welcome to Learn Docker’s documentation! refers to it. Alternative option: set the NIP variable in a “.env” file.

Start the containers:

docker-compose up -d

In case of working in the cloned repository of this tutorial, you can also run the below command to set the variable

NIP=$(../../../system/usr/local/bin/nip.sh) docker compose up -d

Navigate to the web2 folder:

cd ../web2

The compose file is similar to the previous one:

name: p06web2

volumes:
  www:

networks:
  proxy:
    external: true
    name: public_proxy

services:
  php:
    image: localhost/p06_php_web2
    build:
      context: .
      dockerfile: Dockerfile
    volumes:
      - www:/var/www/html
  httpd:
    image: itsziget/httpd24:2.0
    volumes:
      - www:/var/www/html
    environment:
      SRV_PHP: "true"
      SRV_DOCROOT: /var/www/html
      VIRTUAL_HOST: web2.$NIP
    networks:
      - default
      - proxy

we also have another Dockerfile

FROM itsziget/php:7.4-fpm

LABEL hu.itsziget.ld.project=p06

COPY www /var/www/html

# The scripts interpreted by PHP-FPM executes on behalf of "www-data" user.
RUN chown www-data:www-data -R /var/www/html

and a PHP file

<?php

file_put_contents(__DIR__ . '/access.txt', date('Y.m.d. H:i:s') . "\n", FILE_APPEND);

echo 'P06WEB2: ' . getenv('HOSTNAME') . '<br/>';
echo nl2br(file_get_contents(__DIR__ . '/access.txt'));

Start the containers:

docker compose up -d

Or you can use nip.sh as we did in web1.

Both of the services are available on port 80. Example:

http://web1.192.168.1.6.nip.io
http://web2.192.168.1.6.nip.io

This way you do not need to remove a container just because it is running on the same port you want to use for a new container.

Clean the project:

docker compose down --volumes
cd ../web1
docker compose down --volumes
cd ../nginxproxy
docker compose down --volumes