温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

怎么在Docker中使用Nginx代理多个应用站点

发布时间:2021-03-22 17:20:07 来源:亿速云 阅读:256 作者:Leah 栏目:服务器

这篇文章给大家介绍怎么在Docker中使用Nginx代理多个应用站点,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。

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

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

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

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

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

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

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

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

一、统一网络

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

docker network create proxy-network # 查看 docker network ls

 二、代理服务容器

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

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

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

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

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

#!/bin/bash # Start crond in background crond -l 2 -b # Start nginx in foreground nginx

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

 启动代理服务容器

docker-compose up -d nginx

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

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

 三、添加应用

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

 配置应用容器

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

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

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

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

# 宿主机中代码的位置 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 相关的就行了。

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

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 的配置

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 的目录下运行:

docker-compose up -d nginx

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

docker-compose exec nginx wget localhost

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

docker network inspect proxy-network

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

添加代理配置到 nginx-proxy

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

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

# 我这配的仅支持 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 目录下运行:

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

关于怎么在Docker中使用Nginx代理多个应用站点就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI