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

2025-05-27 0 28

前言

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

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

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

– 应用隔离

– 降低耦合度

– …

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

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

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

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

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

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

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

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

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

一、统一网络

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

?

1

2

3

4
docker network create proxy-network

# 查看

docker network ls

二、代理服务容器

创建一个专门用来代理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 ,如果不正常,检查下配置是否有错误。

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

三、添加应用

添加一个站点 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

nginxDockerfile

这个文件可以把前面的那个直接拿来,然后加上关于 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 是一样的。

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

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

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

快网idc优惠网 行业资讯 Docker中使用Nginx代理多个应用站点的方法 https://www.kuaiidc.com/67442.html

相关文章

发表评论
暂无评论