###?前言
#####?代理的作用是什么淹辞?
-?多個(gè)域名解析到同一個(gè)服務(wù)器
-?方便一臺(tái)服務(wù)器多個(gè)應(yīng)用只對(duì)外開放一個(gè)端口
-?訪問應(yīng)用不需要帶著煩人的端口洼哎,直接域名訪問
-?應(yīng)用隔離
-?降低耦合度
-?...
總的來說就是方便維護(hù)边败,并且在維護(hù)一個(gè)應(yīng)用的時(shí)候业扒,不影響其他應(yīng)用减途。
#####?如何代理(容器間如何通信)酣藻?
直接使用?nginx?的代理功能即可(相關(guān)能力另行查閱),這里麻煩的就是?docker?容器間的通信鳍置。
__Docker__?容器間通信的主要方式有以下?4?種:
-?__通過容器?IP?訪問__:容器重啟后辽剧,IP?會(huì)發(fā)生變化。
-?__通過宿主機(jī)的?ip:port?的方式訪問__:如果宿主機(jī)?IP?改變墓捻,就得每個(gè)應(yīng)用都得改一遍抖仅,并且還要綁定端口,麻煩砖第。
-?__通過?link?建立鏈接__:相互依賴的太緊撤卢,不利于維護(hù)。
-?__自定義?network__:?在同一個(gè)橋接網(wǎng)絡(luò)中的容器可以相互訪問梧兼。?
很明顯放吩,會(huì)選擇?__自定義?network__?的方式,讓相關(guān)應(yīng)用鏈接到同一個(gè)網(wǎng)絡(luò)羽杰,這樣應(yīng)用與應(yīng)用渡紫、代理與被代理之間其實(shí)就沒什么依賴,不僅維護(hù)方便考赛,而且遷移也方便惕澎。配置也不麻煩,只需要將常規(guī)的?IP?或域名換成相應(yīng)的容器名即可颜骤。
####?
-----
####?一唧喉、統(tǒng)一網(wǎng)絡(luò)
那么,首先需要?jiǎng)?chuàng)建一個(gè)共用的橋接網(wǎng)絡(luò):
```bash
docker?network?create?proxy-network
#?查看
docker?network?ls
```
------
###?二、代理服務(wù)容器
創(chuàng)建一個(gè)專門用來代理的?`nginx`?服務(wù)容器八孝,取名:__proxy-nginx__董朝,這里使用?`docker-compose`?構(gòu)建,其目錄結(jié)構(gòu)最終如下:
```bash
proxy-nginx
├──?docker-compose.yml
├──?logs?#?日志
│???└──?error.log
├──?nginx
│???├──?Dockerfile
│???├──?nginx.conf
│???└──?startup.sh
├──?sites?#?被代理站點(diǎn)配置
│???├──?baipiaoquan.com.conf
│???└──?chaohuahui.com.conf
└──?ssl?#?證書文件
????└──?baipiaoquan.com.pem
```
有些文件是在后續(xù)的運(yùn)行過程產(chǎn)生的干跛,配置時(shí)子姜,只需要把必要的文件和目錄創(chuàng)建好就行。
#####?docker-compose.yml
```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"
```
把對(duì)外的?80楼入、443?的端口綁定到代理服務(wù)器哥捕,所有的應(yīng)用都可以從這里進(jìn)來。
#####?Dockerfile
```bash
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/\r//g'?/opt/startup.sh
CMD?["/bin/bash",?"/opt/startup.sh"]
EXPOSE?80?443
```
這里將會(huì)創(chuàng)建運(yùn)行用戶組和用戶?`www-data`浅辙,方便配置和控制扭弧,這個(gè)名字會(huì)用在?nginx?的配置中。
#####?nginx.conf
```bash
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;
}
```
這個(gè)的內(nèi)容拷貝?nginx?的默認(rèn)就行记舆,需要改的就是運(yùn)行用戶名,注意用戶名要和前面的設(shè)置的保持一致呼巴。
#####?startup.sh
```bash
#!/bin/bash
#?Start?crond?in?background
crond?-l?2?-b
#?Start?nginx?in?foreground
nginx
```
這個(gè)是用來啟動(dòng)?nginx?程序用的泽腮,內(nèi)容目前比較少,主要是為以后擴(kuò)充內(nèi)容方便衣赶。
#####?啟動(dòng)代理服務(wù)容器
```bash
docker-compose?up?-d?nginx
```
?查看啟動(dòng)是否正常?`docker-compose?ps`?诊赊,如果不正常,檢查下配置是否有錯(cuò)誤府瞄。
這個(gè)就這樣碧磅,先放著,去創(chuàng)建應(yīng)用。
-----
###?三、添加應(yīng)用
添加一個(gè)站點(diǎn)?[https://baipiaoquan.com/](https://baipiaoquan.com/)糙捺。?
#####?配置應(yīng)用容器
同樣使用?docker-compose?創(chuàng)建應(yīng)用圃酵。
這是一個(gè)?php?項(xiàng)目,所以這個(gè)應(yīng)用里至少需要?`nginx`?和?`php-fpm`?兩個(gè)服務(wù)容器收壕,項(xiàng)目目錄結(jié)構(gòu)如下:
```bash
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__?
```bash
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
```
為了方便調(diào)整,這里使用了環(huán)境變量。
注意?nginx?的容器名稱?`container_name:?${COMPOSE_PROJECT_NAME}_nginx`职辨,這個(gè)值很關(guān)鍵并且會(huì)在后續(xù)代理中用到。
__.env__
```bash
#?宿主機(jī)中代碼的位置
APP_CODE_PATH_HOST=../
#?容器中代碼的位置
APP_CODE_PATH_CONTAINER=/var/www
#?這個(gè)是抄的?laradock
APP_CODE_CONTAINER_FLAG=:cached
#?選擇機(jī)器上的存儲(chǔ)路徑戈二。適用于所有儲(chǔ)存系統(tǒng)
DATA_PATH_HOST=~/.baipiaoquan/data
###?Drivers?################################################
#?All?volumes?driver??
VOLUMES_DRIVER=local??
#?網(wǎng)絡(luò)驅(qū)動(dòng)??
NETWORKS_DRIVER=bridge??
#?代理網(wǎng)絡(luò)名稱舒裤,這是前面創(chuàng)建的??
PROXY_NETWORK_NAME=proxy-network
###?Docker?compose?files?##################################
#?
COMPOSE_FILE=docker-compose.yml
#?Change?the?separator?from?:?to?;?on?Windows
COMPOSE_PATH_SEPARATOR=:
#?項(xiàng)目名稱
COMPOSE_PROJECT_NAME=baipiaoquan
```
使用的代理網(wǎng)絡(luò)名稱是:proxy-network,這是在前面創(chuàng)建的觉吭;
nginx?的容器名稱會(huì)是:baipiaoquan_nginx腾供。
__nginx?的?Dockerfile__?
這個(gè)文件可以把前面的那個(gè)直接拿來,然后加上關(guān)于?php?相關(guān)的就行了。
```bash
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/\r//g'?/opt/startup.sh
CMD?["/bin/bash",?"/opt/startup.sh"]
EXPOSE?80?443
```
#####?php-fpm?的?Dockerfile
```bash
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`?文件台腥,也可以使用它默認(rèn)的宏赘,那就要把這個(gè)相關(guān)的配置刪掉。
#####?服務(wù)?baipiaoquan.com.conf?的配置
```bash
server?{
????listen?80?default_server;
????listen?[::]:80?default_server?ipv6only=on;
????#?For?https
????listen?443?ssl?default_server;
????listen?[::]:443?ssl?default_server?ipv6only=on;
????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/;??#?這個(gè)和前面的配置保持一致
????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;?#?這個(gè)是?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;
????}
}
```
我這里算是配全了黎侈,其實(shí)可以精簡(jiǎn)察署,只需要配置需要的即可。
#####?啟動(dòng)應(yīng)用
此時(shí)峻汉,已經(jīng)可以啟動(dòng)?baipiaoquan.com?的服務(wù)了贴汪,在?baipiaoquan?的目錄下運(yùn)行:
```bash
docker-compose?up?-d?nginx
```
如果沒有意外,應(yīng)用應(yīng)該啟動(dòng)并可以接收服務(wù)休吠。亦可以測(cè)試下扳埂,進(jìn)入容器訪問下?localhost,看看結(jié)果是不是想要的瘤礁。我是這樣測(cè)試的:
```bash
docker-compose?exec?nginx?wget?localhost
```
然后產(chǎn)看返回的數(shù)據(jù)大小阳懂,根據(jù)情況判斷是不是成功了。
可以通過下面的命令查看該應(yīng)用是否成功連接到?proxy-network:
```bash
docker?network?inspect?proxy-network
```
接下來要讓全世界的人都能訪問到這個(gè)應(yīng)用柜思。
#####?
#####?添加代理配置到?nginx-proxy
注意:要先啟動(dòng)應(yīng)用岩调,然后再開始代理,不然會(huì)出現(xiàn)?nginx?找不到?upstream?報(bào)錯(cuò)赡盘。
存放位置:`proxy-nginx/sites/baipiaoquan.com.conf`号枕,只需要把上面的配置拷貝下來,改幾個(gè)地方就行陨享,最終配置如下:
```bash
#?我這配的僅支持?https葱淳,如果沒要求,這個(gè)就不需要?
server?{
????listen?80;
????server_name?baipiaoquan.com?www.baipiaoquan.com;
????return?301?https://$host$request_uri;?
}
server?{
????#?如果是?http?就配置這個(gè)
????#?listen?80?default_server;
????#?如果是?https?就配置這個(gè)
????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/;??#?這個(gè)值就是應(yīng)用?nginx?的容器名稱
????}
}
```
重新加載代理服務(wù)器的配置抛姑,在?nginx-proxy?目錄下運(yùn)行:
```bash
#?先測(cè)試下配置文件赞厕,這步一定要執(zhí)行成功
docker-compose?exec?nginx?nginx?-t
#?如果提示成功,則重新加載途戒,否則就按提示檢查修改配置文件
docker-compose?exec?nginx?nginx?-s?reload
```
稍等片刻坑傅,如果一切順利,那么現(xiàn)在全世界的人應(yīng)該能訪問到這個(gè)?[https://baipiaoquan.com/](https://baipiaoquan.com/)?網(wǎng)站了喷斋。??
如果還需要添加其他應(yīng)用唁毒,是一樣的邏輯,流程照搬星爪。例如我又加了一個(gè)應(yīng)用:[https://chaohuahui.com/](https://chaohuahui.com/)?浆西,可以?ping?一下他們的?IP?是一樣的。
>?大量參考?[https://laradock.io/](https://laradock.io/)?