首頁 > 運維 > Nginx > 主體

Docker中如何使用Nginx代理多個應用站點

WBOY
發布: 2023-05-13 15:55:17
轉載
1970 人瀏覽過

如何代理程式 (容器間如何通訊)?

直接使用 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
登入後複製

稍等片刻,如果一切順利,那麼現在全世界的人應該能訪問到這個https://baipiaoquan.com/ 網站了。 

如果還需要增加其他應用,是一樣的邏輯,流程複製。例如我又加了一個應用程式:https://chaohuahui.com/ ,可以 ping 一下他們的 ip 是一樣的。

以上是Docker中如何使用Nginx代理多個應用站點的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:yisu.com
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!