這一系列文章,是我自己完成 Docker Server 建立的經歷以及過程,包含以下章節內容:
- 新手自建 Docker 伺服器 - (0) 簡介與架構說明
- 新手自建 Docker 伺服器 - (1) Ubuntu 主機建立 docker 服務
- 新手自建 Docker 伺服器 - (2) 建立 Nginx 代理伺服器
- 新手自建 Docker 伺服器 - (3) 建立應用,以靜態網頁為例
- 新手自建 Docker 伺服器 - (4) 建立 Joplin 筆記軟體
- 新手自建 Docker 伺服器 - (5) 建立自己的音樂串流服務 Navidrome
自建 Docker 伺服器 - (2) 建立 Nginx 代理伺服器
這篇算是開始進入最重要的部分,在我們把 infra 環境建立起來後,而在建立服務之前,我們必須要搭建反向代理,讓每個 request 進來時,由 nginx 來判斷要去到哪一個 docker 服務,而將服務內容返回給使用者。
因此我們再來看一次系統架構圖,這張圖我是用 Plantuml 畫出來的,這次我們的幾個重點如下:
@startuml left to right direction skinparam actorStyle awesome rectangle "Ubuntu" as ub { package Docker { usecase "Nginx" as ng note top of ng listen XXX Reverse to XXX.domain docker end note usecase "DockerA" as dka usecase "DockerB" as dkb } } note left of ub Create on Linode IP: 1.1.1.1 end note "User" as u u --> (Cloudflare) : XXX.domain note top of (Cloudflare) A Record: XXX.domain -> 1.1.1.1 end note (Cloudflare) --> ng ng --> dka : AAA.domain ng --> dkb : BBB.domain @enduml
- 使用者從 clent 端都是打 xxx.domain 進入服務器,而在 Cloudflare 上都是設定我們這台 ubuntu IP(1.1.1.1)。
- 因此使用者其實都是透過 1.1.1.1:443 或 1.1.1.1:80 訪問我的 Nginx。
- Nginx 透過反向代理的方式來判斷要去到哪一個 docker 服務,這會在每一個 docker compose 內定義。
步驟一:建立 docker 網路
最重要卻也最簡單的一步,我們要優先建立 docker 內部使用的網路,來確保後續我們的 docker 服務是可以互相通訊的
sudo docker network create net #建立一個名為'net'的網路
步驟二:建立 docker 資料夾與 nginx 資料夾
在主機建立一個 Nginx 的資料夾,接著進去後建立存放資料的資料夾(也可以不設定…但我就習慣想要資料放本機而不是在 docker 裡面)
mkdir nginx-proxy && cd nginx-proxy #建立 docker 專案資料夾
mkdir nginx-data && cd nginx-data #nginx 存放資料的位置
mkdir {conf.d,html,dhparam,vhost,certs} #建立要保存的幾個資料夾
cd .. #回到nginx-proxy資料夾
chmod -R 777 nginx-data #給 nginx-data 權限
步驟三:撰寫 docker compose
在 nginx-proxy 資料夾,透過指令建立 docker compose 檔案
nano docker-compose.yml
貼上以下 docker compose 內容,這裡的幾個部分可以稍微理解下
- 除了 nginx-proxy,還另外安裝了一個 letsencrypt 服務來自動申請 SSL 憑證,這樣假如要做多個不同 domain 服務時也可以使用
- 掛載的資料夾要對應上一部生成的資料夾位置
- network 要對應第一步驟建立的 docker 網路名稱
- Email 填入自己的
version: '3.7'
services:
nginx-proxy:
image: jwilder/nginx-proxy
container_name: nginx-proxy
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx-data/conf.d:/etc/nginx/conf.d
- ./nginx-data/html:/usr/share/nginx/html
- ./nginx-data/dhparam:/etc/nginx/dhparam
- ./nginx-data/vhost:/etc/nginx/vhost.d
- ./nginx-data/certs:/etc/nginx/certs
- /var/run/docker.sock:/tmp/docker.sock:ro
labels:
- "com.github.jrcs.letsencrypt_nginx_proxy_companion.nginx_proxy"
restart: always
networks:
- net
letsencrypt:
image: jrcs/letsencrypt-nginx-proxy-companion
container_name: lets-encrypt-proxy-companion
depends_on:
- "nginx-proxy"
volumes:
- ./nginx-data/certs:/etc/nginx/certs
- ./nginx-data/vhost:/etc/nginx/vhost.d
- ./nginx-data/html:/usr/share/nginx/html
- ./var/run/docker.sock:/var/run/docker.sock:ro
environment:
DEFAULT_EMAIL: YOUR_EMAIL
restart: always
networks:
- net
networks:
net:
external: true
步驟四:部署,檢查 nginx 是否生效
完成 docker compose 後,接著透過指令部署
docker compose up -d
部署之後,可以在 broswer 打開 http://1.1.1.1 來檢查 nginx 是否正常運作,另外這邊記得要把防火牆的 80 與 443 開啟,理論上看到 Nginx 503,就代表成功啦
完成了!代表什麼意思
到這一步,我們已經順利的把所有底層 docker 環境、以及代理伺服器建立起來,等於是我們已經 建立好一條從外部連進Server 的通道 ,因此接下來我們就能夠專注在 Server 上部署各種 Docker 應用程式了。
而之後要注意的是,如果你的 docker 要對外連線的話,在 docker compose 內的 environment 中的變數要加上 VIRTUAL_HOST ,如果要 SSL 憑證則要再加上 LETSENCRYPT_HOST
environment:
- VIRTUAL_HOST=domain.com #你自己擁有或要管理的 domain
- LETSENCRYPT_HOST=domain.com #可以自己決定要不要使用,有的話可以 https 連線
如果你有碰到什麼困難,歡迎寫 email 給我來討論喔