Docker中使用Nginx代理多个应用站点的方法
前言
代理的作用是什么?
-多个域名解析到同一个服务器
-方便一台服务器多个应用只对外开放一个端口
-访问应用不需要带着烦人的端口,直接域名访问
-应用隔离
-降低耦合度
-...
总的来说就是方便维护,并且在维护一个应用的时候,不影响其他应用。
如何代理(容器间如何通信)?
直接使用nginx的代理功能即可(相关能力另行查阅),这里麻烦的就是docker容器间的通信。
Docker容器间通信的主要方式有以下4种:
-通过容器IP访问:容器重启后,IP会发生变化。
-通过宿主机的ip:port的方式访问:如果宿主机IP改变,就得每个应用都得改一遍,并且还要绑定端口,麻烦。
-通过link建立链接:相互依赖的太紧,不利于维护。
-自定义network:在同一个桥接网络中的容器可以相互访问。
很明显,会选择自定义network的方式,让相关应用链接到同一个网络,这样应用与应用、代理与被代理之间其实就没什么依赖,不仅维护方便,而且迁移也方便。配置也不麻烦,只需要将常规的IP或域名换成相应的容器名即可。
一、统一网络
那么,首先需要创建一个共用的桥接网络:
dockernetworkcreateproxy-network #查看 dockernetworkls
二、代理服务容器
创建一个专门用来代理的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
FROMnginx:alpine LABELmaintainer="chuoke" COPYnginx.conf/etc/nginx/ RUNapkupdate &&apkupgrade &&apkadd--no-cacheopenssl &&apkadd--no-cachebash RUNset-x; addgroup-g82-Swww-data; adduser-u82-D-S-Gwww-datawww-data&&exit0;exit1 ADD./startup.sh/opt/startup.sh RUNsed-i's/.//g'/opt/startup.sh CMD["/bin/bash","/opt/startup.sh"] EXPOSE80443
这里将会创建运行用户组和用户www-data,方便配置和控制,这个名字会用在nginx的配置中。
nginx.conf
userwww-data; worker_processes4; pid/run/nginx.pid; daemonoff; events{ worker_connections2048; multi_accepton; useepoll; } http{ server_tokensoff; sendfileon; tcp_nopushon; tcp_nodelayon; keepalive_timeout15; types_hash_max_size2048; client_max_body_size20M; include/etc/nginx/mime.types; default_typeapplication/octet-stream; access_log/dev/stdout; error_log/dev/stderr; gzipon; gzip_disable"msie6"; ssl_protocolsTLSv1TLSv1.1TLSv1.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_cacheoff;#Disabledforissue619 charsetUTF-8; }
这个的内容拷贝nginx的默认就行,需要改的就是运行用户名,注意用户名要和前面的设置的保持一致。
startup.sh
#!/bin/bash #Startcrondinbackground crond-l2-b #Startnginxinforeground nginx
这个是用来启动nginx程序用的,内容目前比较少,主要是为以后扩充内容方便。
启动代理服务容器
docker-composeup-dnginx
查看启动是否正常docker-composeps,如果不正常,检查下配置是否有错误。
这个就这样,先放着,去创建应用。
三、添加应用
添加一个站点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################################################ #Allvolumesdriver VOLUMES_DRIVER=local #网络驱动 NETWORKS_DRIVER=bridge #代理网络名称,这是前面创建的 PROXY_NETWORK_NAME=proxy-network ###Dockercomposefiles################################## # COMPOSE_FILE=docker-compose.yml #Changetheseparatorfrom:to;onWindows COMPOSE_PATH_SEPARATOR=: #项目名称 COMPOSE_PROJECT_NAME=baipiaoquan
使用的代理网络名称是:proxy-network,这是在前面创建的;
nginx的容器名称会是:baipiaoquan_nginx。
nginx的Dockerfile
这个文件可以把前面的那个直接拿来,然后加上关于php相关的就行了。
FROMnginx:alpine COPYnginx.conf/etc/nginx/ RUNapkupdate &&apkupgrade &&apk--updateaddlogrotate &&apkadd--no-cacheopenssl &&apkadd--no-cachebash RUNset-x; addgroup-g82-Swww-data; adduser-u82-D-S-Gwww-datawww-data&&exit0;exit1 ARGPHP_UPSTREAM_CONTAINER=php-fpm ARGPHP_UPSTREAM_PORT=9000 #Setupstreamconfandremovethedefaultconf RUNecho"upstreamphp-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 RUNsed-i's/.//g'/opt/startup.sh CMD["/bin/bash","/opt/startup.sh"] EXPOSE80443
php-fpm的Dockerfile
FROMphp:7.3-fpm ARGPUID=1000 ENVPUID${PUID} ARGPGID=1000 ENVPGID${PGID} RUNgroupmod-o-g${PGID}www-data&& usermod-o-u${PUID}-gwww-datawww-data EXPOSE9000 WORKDIR/var/www CMD["php-fpm"]
别忘了php.ini文件,也可以使用它默认的,那就要把这个相关的配置删掉。
服务baipiaoquan.com.conf的配置
server{ listen80default_server; #Forhttps listen443ssldefault_server; ssl_certificate/etc/nginx/ssl/3243258_baipiaoquan.com.pem; ssl_certificate_key/etc/nginx/ssl/3243258_baipiaoquan.com.key; ssl_session_timeout5m; ssl_protocolsTLSv1TLSv1.1TLSv1.2; ssl_ciphersECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE; ssl_prefer_server_cipherson; add_headerX-Frame-Options"SAMEORIGIN"; add_headerX-XSS-Protection"1;mode=block"; add_headerX-Content-Type-Options"nosniff"; #localhost一定要 server_namelocalhostbaipiaoquan.comwww.baipiaoquan.com; root/var/www/;#这个和前面的配置保持一致 indexindex.phpindex.htmlindex.htm; location/{ try_files$uri$uri//index.php$is_args$args; } location~.php${ try_files$uri/index.php=404; fastcgi_passphp-upstream;#这个是nginxDockerfile里配置的 fastcgi_indexindex.php; fastcgi_buffers1616k; fastcgi_buffer_size32k; fastcgi_paramSCRIPT_FILENAME$document_root$fastcgi_script_name; #fixestimeouts fastcgi_read_timeout600; includefastcgi_params; } location~/.ht{ denyall; } location/.well-known/acme-challenge/{ root/var/www/letsencrypt/; log_not_foundoff; } }
我这里算是配全了,其实可以精简,只需要配置需要的即可。
启动应用
此时,已经可以启动baipiaoquan.com的服务了,在baipiaoquan的目录下运行:
docker-composeup-dnginx
如果没有意外,应用应该启动并可以接收服务。亦可以测试下,进入容器访问下localhost,看看结果是不是想要的。我是这样测试的:
docker-composeexecnginxwgetlocalhost
然后产看返回的数据大小,根据情况判断是不是成功了。
可以通过下面的命令查看该应用是否成功连接到proxy-network:
dockernetworkinspectproxy-network
接下来要让全世界的人都能访问到这个应用。
添加代理配置到nginx-proxy
注意:要先启动应用,然后再开始代理,不然会出现nginx找不到upstream报错。
存放位置:proxy-nginx/sites/baipiaoquan.com.conf,只需要把上面的配置拷贝下来,改几个地方就行,最终配置如下:
#我这配的仅支持https,如果没要求,这个就不需要 server{ listen80; server_namebaipiaoquan.comwww.baipiaoquan.com; return301https://$host$request_uri; } server{ #如果是http就配置这个 #listen80default_server; #如果是https就配置这个 listen443ssl; ssl_certificate/etc/nginx/ssl/3243258_baipiaoquan.com.pem; ssl_certificate_key/etc/nginx/ssl/3243258_baipiaoquan.com.key; ssl_session_timeout5m; ssl_protocolsTLSv1TLSv1.1TLSv1.2; ssl_ciphersECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4; ssl_prefer_server_cipherson; server_namebaipiaoquan.comwww.baipiaoquan.com; add_headerX-Frame-Options"SAMEORIGIN"; add_headerX-XSS-Protection"1;mode=block"; add_headerX-Content-Type-Options"nosniff"; location/{ proxy_set_headerHost$host; proxy_set_headerX-Real-IP$remote_addr; proxy_set_headerX-Forwarded-For$proxy_add_x_forwarded_for; proxy_set_headerX-Forwarded-Proto$scheme; proxy_set_headerX-Forwarded-Host$host; proxy_set_headerX-Forwarded-Port$server_port; proxy_passhttp://baipiaoquan_nginx/;#这个值就是应用nginx的容器名称 } }
重新加载代理服务器的配置,在nginx-proxy目录下运行:
#先测试下配置文件,这步一定要执行成功 docker-composeexecnginxnginx-t #如果提示成功,则重新加载,否则就按提示检查修改配置文件 docker-composeexecnginxnginx-sreload
稍等片刻,如果一切顺利,那么现在全世界的人应该能访问到这个https://baipiaoquan.com/网站了。
如果还需要添加其他应用,是一样的逻辑,流程照搬。例如我又加了一个应用:https://chaohuahui.com/,可以ping一下他们的IP是一样的。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。