The Method of Using Nginx to Proxy Multiple Application Sites in Docker

  • 2021-07-18 09:28:53
  • OfStack

Preface

What is the role of an agent?
-Multiple domain names resolved to the same server

-It is convenient for one server and multiple applications to open only one port

-Access the application without annoying ports, and access the domain name directly

-Application isolation

-Reduced coupling

- ...

Generally speaking, it is convenient to maintain, and when maintaining one application, it does not affect other applications.

How to proxy (how to communicate between containers)?

You can use the proxy function of nginx directly (see the related capabilities separately), and the trouble here is the communication between docker containers.

There are four main ways to communicate between Docker containers:

-Access through container IP: IP changes after the container is restarted.

-Access through the host ip: port: If the host IP changes, each application must be changed once, and the port must be bound, which is troublesome.

-Link through link: too tightly interdependent for maintenance.

-Custom network: Containers in the same bridged network can access each other.

Obviously, we will choose the way of customizing network to link related applications to the same network, so that there is no dependence between applications, agents and agents, which is not only convenient for maintenance, but also convenient for migration. Configuration is not troublesome, just replace the regular IP or domain name with the corresponding container name.

1. Unified 1 Network

Then, you first need to create a shared bridging network:


docker network create proxy-network

#  View 
docker network ls

2. Proxy service container

Create a proxy-specific nginx service container named proxy-nginx, built here using docker-compose, whose directory structure ends up as follows:


proxy-nginx
 --  docker-compose.yml
 --  logs #  Journal 
 The    Off-  error.log
 --  nginx
 The    --  Dockerfile
 The    --  nginx.conf
 The    Off-  startup.sh
 --  sites #  Configured by the proxy site 
 The    --  baipiaoquan.com.conf
 The    Off-  chaohuahui.com.conf
 Off-  ssl #  Certificate file 
   Off-  baipiaoquan.com.pem

Some files are generated in the subsequent running process. When configuring, you only need to create the necessary files and directories.

docker-compose.yml


version: "3"

networks:
 default:
  external:
   name: proxy-network

services:
 nginx:
  build:
   context: ./nginx
  volumes:
   - ./logs:/var/log/nginx
   - ./sites:/etc/nginx/sites-available
   - ./ssl:/etc/nginx/ssl
  ports:
   - "80:80"
   - "443:443"

Bind the external ports of 80,443 to the proxy server, and all applications can come in from here.

Dockerfile


FROM nginx:alpine

LABEL maintainer="chuoke"

COPY nginx.conf /etc/nginx/

RUN apk update
  && apk upgrade
  && apk add --no-cache openssl
  && apk add --no-cache bash

RUN set -x ;
  addgroup -g 82 -S www-data ;
  adduser -u 82 -D -S -G www-data www-data && exit 0 ; exit 1

ADD ./startup.sh /opt/startup.sh

RUN sed -i 's/.//g' /opt/startup.sh

CMD ["/bin/bash", "/opt/startup.sh"]

EXPOSE 80 443

The running user group and user www-data will be created here for easy configuration and control. This name will be used in the configuration of nginx.

nginx.conf


user www-data;
worker_processes 4;
pid /run/nginx.pid;
daemon off;

events {
 worker_connections 2048;
 multi_accept on;
 use epoll;
}

http {
 server_tokens off;
 sendfile on;
 tcp_nopush on;
 tcp_nodelay on;
 keepalive_timeout 15;
 types_hash_max_size 2048;
 client_max_body_size 20M;
 include /etc/nginx/mime.types;
 default_type application/octet-stream;
 access_log /dev/stdout;
 error_log /dev/stderr;

 gzip on;
 gzip_disable "msie6";

 ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
 ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS';

 include /etc/nginx/conf.d/*.conf;
 include /etc/nginx/sites-available/*.conf;

 open_file_cache off; # Disabled for issue 619
 charset UTF-8;
}

This copy of the content of nginx default line, need to change is to run the user name, note that the user name and the previous settings to maintain 1.

startup.sh


#!/bin/bash

# Start crond in background
crond -l 2 -b

# Start nginx in foreground
nginx

This is used to start the nginx program, the content is relatively small, mainly for the future expansion of content convenience.

Start the agent service container


docker-compose up -d nginx

Check whether the startup is normal docker-compose ps. If not, check whether there are errors in the configuration.

That's it. Let's put it first and create the application.

Step 3 Add an application

Add a site https://baipiaoquan.com/.

Configure Application Container

Also use docker-compose to create applications.

This is an php project, so this application needs at least two service containers, nginx and php-fpm. The project directory structure is as follows:


baipiaoquan/
 --  docker-compose.yml
 --  log
 The    Off-  nginx
 The      Off-  error.log
 --  nginx
 The    --  Dockerfile
 The    --  log
 The    --  nginx.conf
 The    --  sites
 The    The    Off-  baipiaoquan.com.conf
 The    --  ssl
 The    The    --  baipiaoquan.com.key
 The    The    --  baipiaoquan.com.pem
 The    Off-  startup.sh
 Off-  php-fpm
   --  Dockerfile
   Off-  php.ini

docker-compose.yml


version: '3'

networks:
 proxy:
  external:
    name: ${PROXY_NETWORK_NAME}
 backend:
  driver: ${NETWORKS_DRIVER}

services:
 php-fpm:
   build:
    context: ./php-fpm
   volumes:
    - ./php-fpm/php.ini:/usr/local/etc/php/php.ini
    - ${APP_CODE_PATH_HOST}:${APP_CODE_PATH_CONTAINER}${APP_CODE_CONTAINER_FLAG}
   networks:
    - backend

 nginx:
   build:
    context: ./nginx
    args:
     - PHP_UPSTREAM_CONTAINER=${NGINX_PHP_UPSTREAM_CONTAINER}
     - PHP_UPSTREAM_PORT=${NGINX_PHP_UPSTREAM_PORT}
   volumes:
    - ${APP_CODE_PATH_HOST}:${APP_CODE_PATH_CONTAINER}${APP_CODE_CONTAINER_FLAG}
    - ./log:/var/log/nginx
    - ./sites:/etc/nginx/sites-available
    - ./ssl:/etc/nginx/ssl
   container_name: ${COMPOSE_PROJECT_NAME}_nginx
   depends_on:
    - php-fpm
   networks:
    - proxy
    - backend

For the convenience of adjustment, environment variables are used here.

Note the container name container_name for nginx: ${COMPOSE_PROJECT_NAME} _nginx, which is critical and will be used in subsequent agents.

.env


#  Location of code in host machine 
APP_CODE_PATH_HOST=../

#  Location of code in container 
APP_CODE_PATH_CONTAINER=/var/www

#  This is copied  laradock
APP_CODE_CONTAINER_FLAG=:cached

#  Select the storage path on the machine. Applicable to all storage systems 
DATA_PATH_HOST=~/.baipiaoquan/data

### Drivers ################################################

# All volumes driver 
VOLUMES_DRIVER=local 

#  Network driver  
NETWORKS_DRIVER=bridge 

#  The proxy network name, which is created earlier  
PROXY_NETWORK_NAME=proxy-network

### Docker compose files ##################################
# 
COMPOSE_FILE=docker-compose.yml

# Change the separator from : to ; on Windows
COMPOSE_PATH_SEPARATOR=:

#  Project name 
COMPOSE_PROJECT_NAME=baipiaoquan

The proxy network name used is: proxy-network, which was created earlier;
The container name for nginx will be: baipiaoquan_nginx.

Dockerfile of nginx

This file can take the previous one directly, and then add something related to php.


proxy-nginx
 --  docker-compose.yml
 --  logs #  Journal 
 The    Off-  error.log
 --  nginx
 The    --  Dockerfile
 The    --  nginx.conf
 The    Off-  startup.sh
 --  sites #  Configured by the proxy site 
 The    --  baipiaoquan.com.conf
 The    Off-  chaohuahui.com.conf
 Off-  ssl #  Certificate file 
   Off-  baipiaoquan.com.pem
0

Dockerfile for php-fpm


proxy-nginx
 --  docker-compose.yml
 --  logs #  Journal 
 The    Off-  error.log
 --  nginx
 The    --  Dockerfile
 The    --  nginx.conf
 The    Off-  startup.sh
 --  sites #  Configured by the proxy site 
 The    --  baipiaoquan.com.conf
 The    Off-  chaohuahui.com.conf
 Off-  ssl #  Certificate file 
   Off-  baipiaoquan.com.pem
1

Don't forget the php. ini file. You can also use its default, so delete this related configuration.

Configuration of service baipiaoquan. com. conf


proxy-nginx
 --  docker-compose.yml
 --  logs #  Journal 
 The    Off-  error.log
 --  nginx
 The    --  Dockerfile
 The    --  nginx.conf
 The    Off-  startup.sh
 --  sites #  Configured by the proxy site 
 The    --  baipiaoquan.com.conf
 The    Off-  chaohuahui.com.conf
 Off-  ssl #  Certificate file 
   Off-  baipiaoquan.com.pem
2

I have it all here. In fact, it can be streamlined. I only need to configure what I need.

Start the application

At this point, you can start the service of baipiaoquan. com and run it in the directory of baipiaoquan:


docker-compose up -d nginx

If there is no accident, the application should be started and can receive services. You can also test, enter the container under localhost to see if the results are desired. Here's how I tested it:


proxy-nginx
 --  docker-compose.yml
 --  logs #  Journal 
 The    Off-  error.log
 --  nginx
 The    --  Dockerfile
 The    --  nginx.conf
 The    Off-  startup.sh
 --  sites #  Configured by the proxy site 
 The    --  baipiaoquan.com.conf
 The    Off-  chaohuahui.com.conf
 Off-  ssl #  Certificate file 
   Off-  baipiaoquan.com.pem
4

Then look at the size of the returned data and judge whether it is successful according to the situation.
You can see if the application successfully connected to proxy-network by using the following command:


proxy-nginx
 --  docker-compose.yml
 --  logs #  Journal 
 The    Off-  error.log
 --  nginx
 The    --  Dockerfile
 The    --  nginx.conf
 The    Off-  startup.sh
 --  sites #  Configured by the proxy site 
 The    --  baipiaoquan.com.conf
 The    Off-  chaohuahui.com.conf
 Off-  ssl #  Certificate file 
   Off-  baipiaoquan.com.pem
5

The next step is to make this application accessible to people all over the world.

Add Agent Configuration to nginx-proxy

Note: Start the application first, and then start the agent, otherwise nginx can not find upstream error.

Storage location: proxy-nginx/sites/baipiaoquan. com. conf, just copy the above configuration and change it to several places. The final configuration is as follows:


proxy-nginx
 --  docker-compose.yml
 --  logs #  Journal 
 The    Off-  error.log
 --  nginx
 The    --  Dockerfile
 The    --  nginx.conf
 The    Off-  startup.sh
 --  sites #  Configured by the proxy site 
 The    --  baipiaoquan.com.conf
 The    Off-  chaohuahui.com.conf
 Off-  ssl #  Certificate file 
   Off-  baipiaoquan.com.pem
6

Reload the proxy server configuration and run it in the nginx-proxy directory:


proxy-nginx
 --  docker-compose.yml
 --  logs #  Journal 
 The    Off-  error.log
 --  nginx
 The    --  Dockerfile
 The    --  nginx.conf
 The    Off-  startup.sh
 --  sites #  Configured by the proxy site 
 The    --  baipiaoquan.com.conf
 The    Off-  chaohuahui.com.conf
 Off-  ssl #  Certificate file 
   Off-  baipiaoquan.com.pem
7

Hold on for a moment, and if the cut goes well, people all over the world should be able to access this website https://baipiaoquan.com/ by now.

If you need to add other applications, it is a kind of logic and process copy. For example, I added another application: https://chaohuahui.com/, so that their IP is one kind under ping 1.


Related articles: