gpt4 book ai didi

Docker中使用Nginx代理多个应用站点的方法

转载 作者:qq735679552 更新时间:2022-09-27 22:32:09 28 4
gpt4 key购买 nike

CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.

这篇CFSDN的博客文章Docker中使用Nginx代理多个应用站点的方法由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.

 前言 。

代理的作用是什么? - 多个域名解析到同一个服务器 。

- 方便一台服务器多个应用只对外开放一个端口 。

- 访问应用不需要带着烦人的端口,直接域名访问 。

- 应用隔离 。

- 降低耦合度 。

- ... 。

总的来说就是方便维护,并且在维护一个应用的时候,不影响其他应用.

如何代理 (容器间如何通信)?

直接使用 nginx 的代理功能即可 (相关能力另行查阅),这里麻烦的就是 docker 容器间的通信.

Docker 容器间通信的主要方式有以下 4 种:

- 通过容器 IP 访问:容器重启后,IP 会发生变化.

- 通过宿主机的 ip:port 的方式访问:如果宿主机 IP 改变,就得每个应用都得改一遍,并且还要绑定端口,麻烦.

- 通过 link 建立链接:相互依赖的太紧,不利于维护.

- 自定义 network: 在同一个桥接网络中的容器可以相互访问.

很明显,会选择 自定义 network 的方式,让相关应用链接到同一个网络,这样应用与应用、代理与被代理之间其实就没什么依赖,不仅维护方便,而且迁移也方便。配置也不麻烦,只需要将常规的 IP 或域名换成相应的容器名即可.

1、统一网络 。

那么,首先需要创建一个共用的桥接网络:

?
1
2
3
4
docker network create proxy-network
 
# 查看
docker network ls

 2、代理服务容器 。

创建一个专门用来代理的 nginx 服务容器,取名:proxy-nginx,这里使用 docker-compose 构建,其目录结构最终如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
proxy-nginx
├── docker-compose.yml
├── logs # 日志
│  └── error.log
├── nginx
│  ├── Dockerfile
│  ├── nginx.conf
│  └── startup.sh
├── sites # 被代理站点配置
│  ├── baipiaoquan.com.conf
│  └── chaohuahui.com.conf
└── ssl # 证书文件
   └── baipiaoquan.com.pem

有些文件是在后续的运行过程产生的,配置时,只需要把必要的文件和目录创建好就行.

 docker-compose.yml 。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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"

把对外的 80、443 的端口绑定到代理服务器,所有的应用都可以从这里进来.

 Dockerfile 。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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

这里将会创建运行用户组和用户 www-data,方便配置和控制,这个名字会用在 nginx 的配置中.

 nginx.conf 。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
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;
}

这个的内容拷贝 nginx 的默认就行,需要改的就是运行用户名,注意用户名要和前面的设置的保持一致.

 startup.sh 。

?
1
2
3
4
5
6
7
#!/bin/bash
 
# Start crond in background
crond -l 2 -b
 
# Start nginx in foreground
nginx

这个是用来启动 nginx 程序用的,内容目前比较少,主要是为以后扩充内容方便.

 启动代理服务容器 。

?
1
docker-compose up -d nginx

 查看启动是否正常 docker-compose ps ,如果不正常,检查下配置是否有错误.

这个就这样,先放着,去创建应用.

 3、添加应用 。

添加一个站点 https://baipiaoquan.com/.

 配置应用容器 。

同样使用 docker-compose 创建应用.

这是一个 php 项目,所以这个应用里至少需要 nginx 和 php-fpm 两个服务容器,项目目录结构如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
baipiaoquan/
├── docker-compose.yml
├── log
│  └── nginx
│    └── error.log
├── nginx
│  ├── Dockerfile
│  ├── log
│  ├── nginx.conf
│  ├── sites
│  │  └── baipiaoquan.com.conf
│  ├── ssl
│  │  ├── baipiaoquan.com.key
│  │  ├── baipiaoquan.com.pem
│  └── startup.sh
└── php-fpm
   ├── Dockerfile
   └── php.ini

docker-compose.yml 。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
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

为了方便调整,这里使用了环境变量.

注意 nginx 的容器名称 container_name: ${COMPOSE_PROJECT_NAME}_nginx,这个值很关键并且会在后续代理中用到.

.env 。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# 宿主机中代码的位置
APP_CODE_PATH_HOST=../
 
# 容器中代码的位置
APP_CODE_PATH_CONTAINER=/var/www
 
# 这个是抄的 laradock
APP_CODE_CONTAINER_FLAG=:cached
 
# 选择机器上的存储路径。适用于所有储存系统
DATA_PATH_HOST=~/.baipiaoquan/data
 
### Drivers ################################################
 
# All volumes driver
VOLUMES_DRIVER=local
 
# 网络驱动
NETWORKS_DRIVER=bridge
 
# 代理网络名称,这是前面创建的
PROXY_NETWORK_NAME=proxy-network
 
### Docker compose files ##################################
#
COMPOSE_FILE=docker-compose.yml
 
# Change the separator from : to ; on Windows
COMPOSE_PATH_SEPARATOR=:
 
# 项目名称
COMPOSE_PROJECT_NAME=baipiaoquan

使用的代理网络名称是:proxy-network,这是在前面创建的; nginx 的容器名称会是:baipiaoquan_nginx.

nginx 的 Dockerfile 。

这个文件可以把前面的那个直接拿来,然后加上关于 php 相关的就行了.

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
FROM nginx:alpine
 
COPY nginx.conf /etc/nginx/
 
RUN apk update
   && apk upgrade
   && apk --update add logrotate
   && 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
 
ARG PHP_UPSTREAM_CONTAINER=php-fpm
ARG PHP_UPSTREAM_PORT=9000
 
# Set upstream conf and remove the default conf
RUN echo "upstream php-upstream { server ${PHP_UPSTREAM_CONTAINER}:${PHP_UPSTREAM_PORT}; }" > /etc/nginx/conf .d /upstream .conf
   && rm /etc/nginx/conf .d /default .conf
 
ADD . /startup .sh /opt/startup .sh
RUN sed -i 's/.//g' /opt/startup .sh
 
CMD [ "/bin/bash" , "/opt/startup.sh" ]
 
EXPOSE 80 443

php-fpm 的 Dockerfile 。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
FROM php:7.3-fpm
 
ARG PUID=1000
 
ENV PUID ${PUID}
 
ARG PGID=1000
 
ENV PGID ${PGID}
 
RUN groupmod -o -g ${PGID} www-data &&
   usermod -o -u ${PUID} -g www-data www-data
 
EXPOSE 9000
 
WORKDIR /var/www
 
CMD [ "php-fpm" ]

别忘了 php.ini 文件,也可以使用它默认的,那就要把这个相关的配置删掉.

 服务 baipiaoquan.com.conf 的配置 。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
server {
 
   listen 80 default_server;
 
   # For https
   listen 443 ssl default_server;
   ssl_certificate /etc/nginx/ssl/3243258_baipiaoquan .com.pem;
   ssl_certificate_key /etc/nginx/ssl/3243258_baipiaoquan .com.key;
   ssl_session_timeout 5m;
   ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
   ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
   ssl_prefer_server_ciphers on;
 
   add_header X-Frame-Options "SAMEORIGIN" ;
   add_header X-XSS-Protection "1; mode=block" ;
   add_header X-Content-Type-Options "nosniff" ;
 
   # localhost 一定要
   server_name localhost baipiaoquan.com www.baipiaoquan.com;
   root /var/www/ ; # 这个和前面的配置保持一致
   index index.php index.html index.htm;
 
   location / {
      try_files $uri $uri/ /index .php$is_args$args;
   }
 
   location ~ .php$ {
     try_files $uri /index .php =404;
     fastcgi_pass php-upstream; # 这个是 nginx Dockerfile 里配置的
     fastcgi_index index.php;
     fastcgi_buffers 16 16k;
     fastcgi_buffer_size 32k;
     fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
     #fixes timeouts
     fastcgi_read_timeout 600;
     include fastcgi_params;
   }
 
   location ~ /.ht {
     deny all;
   }
 
   location /.well-known /acme-challenge/ {
     root /var/www/letsencrypt/ ;
     log_not_found off;
   }
}

我这里算是配全了,其实可以精简,只需要配置需要的即可.

 启动应用 。

此时,已经可以启动 baipiaoquan.com 的服务了,在 baipiaoquan 的目录下运行:

?
1
docker-compose up -d nginx

如果没有意外,应用应该启动并可以接收服务。亦可以测试下,进入容器访问下 localhost,看看结果是不是想要的。我是这样测试的:

?
1
docker-compose exec nginx wget localhost

然后产看返回的数据大小,根据情况判断是不是成功了。 可以通过下面的命令查看该应用是否成功连接到 proxy-network:

?
1
docker network inspect proxy-network

接下来要让全世界的人都能访问到这个应用.

添加代理配置到 nginx-proxy 。

注意:要先启动应用,然后再开始代理,不然会出现 nginx 找不到 upstream 报错.

存放位置:proxy-nginx/sites/baipiaoquan.com.conf,只需要把上面的配置拷贝下来,改几个地方就行,最终配置如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# 我这配的仅支持 https,如果没要求,这个就不需要
 
server {
   listen 80;
   server_name baipiaoquan.com www.baipiaoquan.com;
   return 301 https: // $host$request_uri;
}
 
server {
 
   # 如果是 http 就配置这个
   # listen 80 default_server;
 
   # 如果是 https 就配置这个
   listen 443 ssl;
   ssl_certificate      /etc/nginx/ssl/3243258_baipiaoquan .com.pem;
   ssl_certificate_key    /etc/nginx/ssl/3243258_baipiaoquan .com.key;
   ssl_session_timeout    5m;
   ssl_protocols       TLSv1 TLSv1.1 TLSv1.2;
   ssl_ciphers        ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
   ssl_prefer_server_ciphers on;
 
   server_name baipiaoquan.com www.baipiaoquan.com;
 
   add_header X-Frame-Options "SAMEORIGIN" ;
   add_header X-XSS-Protection "1; mode=block" ;
   add_header X-Content-Type-Options "nosniff" ;
 
   location / {
     proxy_set_header Host        $host;
     proxy_set_header X-Real-IP      $remote_addr;
     proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;
     proxy_set_header X-Forwarded-Proto  $scheme;
     proxy_set_header X-Forwarded-Host  $host;
     proxy_set_header X-Forwarded-Port  $server_port;
     proxy_pass http: //baipiaoquan_nginx/ ; # 这个值就是应用 nginx 的容器名称
   }
}

重新加载代理服务器的配置,在 nginx-proxy 目录下运行:

?
1
2
3
4
5
# 先测试下配置文件,这步一定要执行成功
docker-compose exec nginx nginx -t
 
# 如果提示成功,则重新加载,否则就按提示检查修改配置文件
docker-compose exec nginx nginx -s reload

稍等片刻,如果一切顺利,那么现在全世界的人应该能访问到这个 https://baipiaoquan.com/ 网站了。  。

如果还需要添加其他应用,是一样的逻辑,流程照搬。例如我又加了一个应用:https://chaohuahui.com/ ,可以 ping 一下他们的 IP 是一样的.

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我.

原文链接:https://learnku.com/articles/38470 。

最后此篇关于Docker中使用Nginx代理多个应用站点的方法的文章就讲到这里了,如果你想了解更多关于Docker中使用Nginx代理多个应用站点的方法的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com