使用Docker和Nginx在一個VPS上託管多個網站

使用Docker和Nginx在一個VPS上託管多個網站

Posted by Docker on 2020-02-20 08:00:00

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.comapp.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.TLDnginx-proxyDOMAIN.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