banner
libxcnya.so

libxcnya.so

Nothing...
telegram
twitter
github
email

docker 容器跟隨宿主機域名解析

前景需要#

自從朋友家裡網爆炸之後,你站的前端和 API 不得不搬到了同一台機器上
但是某一天在使用某人的神秘設備訪問的時候,報錯 "禁止訪問或 API 服務出現問題",我一想估計就是因為前端訪問後端帶的 User-Agent 是客戶端的,或者是說前端訪問後端的時候給 CDN 傳遞的 IP 出了問題,然後就完美的觸發了我抽象的 WAF 被攔截了
這樣前端訪問後端是需要先到 CDN,然後 CDN 再回來到後端,既然在一台伺服器上為什麼要兜這麼大一圈呢,於是就有了這篇文章

省流#

把宿主機的 /etc/hosts 檔案映射到 docker 容器中

問題分析#

由於 Mix-Space 的前後端目前都是可以用 docker 運行的,圖省事所以兩個我都是用 docker 跑的
前端的 API 是由 .env 中的 NEXT_PUBLIC_API_URL 提供的,這也就是最主要的
在 docker 容器中,127.0.0.1 指的是當前這個容器自己,當然前端容器裡面只跑了一個前端並沒有後端,所以不能設置為 127.0.0.1
那設置為後端容器的 IP 不就行了?在前端頁面的某些場景中需要明文用到這個 URL,所以不能直接設置在伺服器上的內網地址然後給用戶訪問顯然是不現實的,所以此方案行不通
有人說把兩個容器放在同一個網路裡,這樣確實是訪問更方便,但是回到上一個問題,所以行不通

IP 行不通只能走域名了,那麼我們可以給域名固定到目標容器的 IP
但容器每次重啟之後 IP 好像是會變的吧(?但是 docker bridge 網路的網關始終是指向宿主機的,所以我們可以把後端容器中 Web 服務的端口映射到宿主機,然後用 nginx 反代到 80 端口,然後域名在本機指向 bridge 的 IP,這樣就能一舉兩得了(確信

解決過程#

首先得獲取 docker 的 bridge 網卡的網關是哪個
伺服器終端輸入 ifconfig,然後找一找有個叫 docker0 的網卡,這個就是了
1
然後 inet 對應的值(也就是 172.17.0.1 就是他的網關了
可以 curl 測試一下,我宿主機跑了一個 nginx,curl 的結果是 nginx 的默認頁,也就是說這個地址確實是指向宿主機的(當然 curl 後端的 port 也是通的

然後我第一時間想到的是修改宿主機的 /etc/hosts 檔案,給後端的域名指定到這個地址
然後去容器裡測試一看,這玩意根本就不走宿主機的 hosts,,,
2
此時有兩個解決方案

1. 通過本地搭建 DNS 強行解析 IP#

其實用 ADGuard Home 中的自定義規則就可以
關於如何搭建可以詳情這篇文章

由於我本地不走這玩意的 DNS 所以直接看第二個

2. 將宿主機 hosts 檔案映射到 docker 容器中#

給前端容器的 docker-compose.yml 檔案裡面加一句

    volumes:
      - /etc/hosts:/etc/hosts:ro

防止容器亂改所以掛載為只讀
然後重啟容器
3
再回到容器裡試試
4
好已經完美解決了

後記#

本文有點繁瑣,意在記錄遇到的抽象問題
如果你認為我的思路對你有用的話,歡迎點贊轉發收藏最後再投食一下,謝謝喵

此文由 Mix Space 同步更新至 xLog
原始連結為 https://blog.nekorua.com/posts/maintain/121.html


載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。