Docker是在單個VPS上運行多種服務而又不會相互干擾的出色工具,例如,一個基於WordPress的網站和另一個基於Ghost或其他平面文件CMS的網站。
但是,容器化軟件會導致另一個問題:如何從一個VPS託管多個網站,每個網站都在單獨的Docker容器中?幸運的是,通過一些預見和配置,您可以使用Docker和Nginx從單個VPS託管多個網站。
默認情況下,Docker服務都在端口80上偵聽,這會為傳入流量造成衝突。當然,您可以更改偵聽端口,但是沒人願意輸入 coolwebsite.com:34567
以訪問他們喜歡的站點。
相反,如果可以用來 nginx
將到達的流量路由 coolwebsite.com
到偵聽該34567
端口的容器的唯一 路徑,並將到達的流量路由到anothercoolwebsite.net
偵聽的第二個容器的 路徑 45678
呢?
這就是 nginx-proxy
它的作用:它偵聽端口80(標準HTTP端口)並將傳入的請求轉發到適當的容器。這通常稱為 反向代理,它利用了Docker的 VIRTUAL_HOST
變量。
在本教程中,我們將設置 nginx-proxy
並學習如何使用Docker和Nginx將流量路由到不同的容器,從而使您可以從一個網站託管位於不同域的多個網站。
April 17, 2019: Updated with clearer instructions and updated examples!
先決條件
-
- 安裝了Docker的Ubuntu / Debian / CentOS服務器-要開始使用,請查看我們的 Docker入門教程。
- 具有
sudo
特權的非root用戶 。 - 來自域名註冊商的全限定域名。
- 通過您的域名註冊商更改DNS設置的能力。
在一台VPS上以16GB RAM託管多個站點,價格為$ 7.99 / mo!
使用Docker,Nginx和SSD節點負擔得起地託管多個站點!我們的Intel和SSD支持的服務器以及Tier-1網絡連接可為您提供所需的性能,而成本卻更低。立即部署您的新服務器並保存!
步驟1.啟動nginx-proxy將Docker和Nginx掛鉤
首先,讓我們啟動 nginx-proxy
容器。這可以通過單個 docker
命令或使用完成 docker-compose
。讓我們同時介紹一下。
但是在此之前,讓我們創建一個Docker網絡。該網絡將使我們的容器相互之間“對話”。
$ docker network create nginx-proxy
從現在開始,我們需要向該nginx-proxy
Docker網絡添加新容器。
使用Docker安裝Nginx-proxy
$ docker run -d -p 80:80 --name nginx-proxy --net nginx-proxy -v /var/run/docker.sock:/tmp/docker.sock jwilder/nginx-proxy
使用docker-compose安裝Nginx-proxy
首先,docker-compose.yml
在您選擇的目錄中創建一個新 文件(命名nginx-proxy
為一個好主意),然後復制以下文本:
version: "3"
services:
nginx-proxy:
image: jwilder/nginx-proxy
container_name: nginx-proxy
ports:
- "80:80"
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
networks:
default:
external:
name: nginx-proxy
然後運行以下 docker-compose
命令開始。
$ docker-compose up -d
nginx-proxy如何使用Docker和Nginx在一個VPS上託管多個網站
首先,nginx-proxy
容器在端口80上偵聽。在端口80上進入VPS的所有流量都將通過nginx-proxy
。這是很好的第一步。但是如何知道是否將人A發送blog.example.com
給人B app.example.com
?
這就是/var/run/docker.sock:/tmp/docker.sock
生產線所要完成的。本質上,這使任何容器都可以訪問主機的Docker套接字,該套接字包含有關各種Docker事件的信息,例如創建新容器或關閉一個容器。
每次將新的Docker容器添加到網絡時,nginx-proxy
都會通過套接字查看事件,自動創建路由流量所需的配置文件,然後重新啟動 nginx
以使更改立即可用。
代理查找VIRTUAL_HOST
啟用了變量的容器 。在該變量中,指定目的地,例如blog.example.com
或app.example.com
。代理將看到人A的請求blog.example.com
,並將他們的請求路由(或代理!)到正確的容器。也是一樣app.example.com
,或者你想運行其他任何容器。
還要注意--net nginx-proxy
Docker命令中的這一 行以及文件中的 networks: default: external: name: nginx-proxy
塊 docker-compose.yml
。這就是您指定希望新容器使用的Docker網絡的方式。
步驟2.將您的第一個Docker容器添加到Nginx代理中
現在我們已經 nginx-proxy
運行,我們可以開始添加新的容器,將自動為其進行配置。因為我們在上一期Docker教程中介紹了它,並且由於它是易於嘗試的實現,所以我們以WordPress為例。
使用Docker
使用基本配置啟動WordPress容器非常容易。
$ docker run -d --name blog --expose 80 --net nginx-proxy -e VIRTUAL_HOST=blog.DOMAIN.TLD wordpress
在這裡註意一些元素。 --expose 80
將允許流量流入端口80上的容器。 --net nginx-proxy
確保我們使用的是我們之前創建的Docker網絡。最後, 標記 用於創建代理,並將請求該域的所有流量定向到該新Docker容器。用您選擇的域替換。-e VIRTUAL_HOST=blog.DOMAIN.TLD
nginx-proxy
DOMAIN.TLD
使用docker-compose
首先在一個空目錄中創建一個“ docker-compose.yml”文件,然後復制以下內容。
version: "3"
services:
db_node_domain:
image: mysql:5.7
volumes:
- db_data:/var/lib/mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: PASSWORD
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: PASSWORD
container_name: wordpress_db
wordpress:
depends_on:
- db_node_domain
image: wordpress:latest
expose:
- 80
restart: always
environment:
VIRTUAL_HOST: blog.DOMAIN.TLD
WORDPRESS_DB_HOST: db_node_domain:3306
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: PASSWORD
container_name: wordpress
volumes:
db_data:
networks:
default:
external:
name: nginx-proxy
再次注意 文件中的 expose
和 environment: VIRTUAL_HOST
選項。另外,networks
底部的 選項對於使此容器與說“是必須的” nginx-proxy
。
您還將需要更改MySQL數據庫本身以及訪問該數據庫的WordPress用戶的密碼。WordPress將在設置過程中自動為您的WordPress管理員帳戶創建一個新密碼。
完成配置文件後,即可運行docker-compose up -d
命令。
第3步。訪問您的新WordPress網站並添加更多內容
At this point, you need to configure your domain’s DNS settings to point toward the IP address of your VPS. If you set up your blog on blog.DOMAIN.TLD
, create an A record for that subdomain and point it to the same IP address.
With your DNS set up correctly, you should be able to visit blog.DOMAIN.TLD
and see the famous 5-minute WordPress installation! Congratulations!
You can now boot up any other Docker containers, such as another WordPress site or any other type of app/service, and nginx-proxy
will take care of the rest.
One caveat for multiple WordPress installations
If you are going to host multiple WordPress blogs using this method, you need to create a unique database name for each instance. By doing so you that WordPress A connects to MySQL A, WordPress B connects to MySQL B, and so on.
See the line just under services
? The one that reads db_node_domain
? That’s the name of your container. You can pick any naming scheme you’d like, but each instance needs to have a different name.
Once you’ve chosen a name, you need to update two other fields. First:
depends_on:
- db_node_domain
And second:
WORDPRESS_DB_HOST: db_node_domain:3306