2023年10月26日 星期四

docker,或者說docker-compoes踩的小坑,nginx host name指向問題

先附上我寫的docker-compose

情境說明
我在構思前後端架構時,後端用nodejs,然後前端用nginx,這沒什麼問題,然後因為要走ssl,我懶得把ssl key也copy到後端專案,打算直接在nginx用proxy的方式做掉,OK事情就是這樣發生了,先附上docker-compose跟nginx設定

# docker-compose.yml
version: "3.6"

services:
node-api:
build:
context: .
dockerfile: Dockerfile
container_name: stemi_node_api
volumes:
- ./tmp:/app/tmp
working_dir: /app
command: sh -c "yarn dev"
ports:
- 8000:3333
depends_on:
- python-api
environment:
- PYTHON_API_HOST=python-api

nginx:
build:
context: web
dockerfile: Dockerfile
ports:
- "443:443"
- "3333:3333"
container_name: nginx
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
- ./nginx:/etc/nginx/conf.d
- ../ssl/:/ssl
depends_on:
- node-api

# nginx/default.conf
# ...前端設定省略,因為這不是今天踩坑的主題
server {
listen 3333 ssl;
server_name localhost;
ssl_certificate /ssl/certificate.crt;
ssl_certificate_key /ssl/private.key;

# 根目錄
location / {
proxy_pass http://node-api:8000;
}
}

這一切乍看之下都很完美,但實際在打https://127.0.0.1:3333卻會報502,意思就是打不到東西,我一開始是想是不是node-api讀不到的關係,查了很多關於links, depends_on, networks的文件,最後進到nginx container裡面實際下指令nslookup node-api也確實有,ping也ping得到

/app # nslookup node-api
Server:         127.0.0.11
Address:        127.0.0.11:53
Non-authoritative answer:
Non-authoritative answer:
Name:   node-api
Address: 172.23.0.2

/app # ping node-api
PING node-api (172.23.0.2): 56 data bytes
64 bytes from 172.23.0.2: seq=0 ttl=64 time=0.465 ms
64 bytes from 172.23.0.2: seq=1 ttl=64 time=0.387 ms
^C

後來我發現,我啟動的container也只有兩個,但ip卻有三個
172.23.0.1
172.23.0.2 <= node-api
172.23.0.3 <= nginx
ok問題來了,照上面指令2應該就是node-api,3應該是nginx,那1是什麼呢?我繼續下指令curl -G http://172.23.0.1:8000

/app # curl -G http://172.23.0.1:8000 {"code":0,"data":"ok"}/app #

矮油這下問題嚴重了,我一度以為docker出問題,把host name指向錯誤的主機,想上網找但關鍵字也不知道怎麼下

後來在苦無對策之際,最後試著下一個指令

/app # curl -G http://node-api:3333
{"code":0,"data":"ok"}/app #

一切都真相大白了,我一直以為container是在各自的容器(我不知道這專有名詞是啥,只是講container會搞混,在我想像中他形式比較像沙箱跟區網的概念,將箱子也不好聽,所以就叫中文的容器吧),藉由expose把port開出來讓外界使用,事實上如果用docker-compose那大家就會在同一個容器內,所以網內互打是打原本的port不是export的port,所以1應該就是最後所有container的集合....吧,所以最終只要這樣修改就好。

# nginx/default.conf
  location / {
proxy_pass http://node-api:3333; # 把port改掉
}

因此最終node-api的ports設定也可以拿掉。


我也不是專業的devpos,就是專案需要所以簡單地摸了一下,踩了坑就記錄一下,歡迎不大家吝嗇指教,只是希望可以噴得小力一點!