請教一下,我的 CI/CD 流程在 Docker build image 時,一般會傳變數進 dockerfile,以讓 npm build 時,依環境變數使用不同 env 設定檔 build 成靜態檔,在下個 stage COPY 到 nginx image,最終產出 2 個正式環境的 image 以 Deploy 在不同環境上。
但這樣 2 個環境就得 build 2次 image,以後環境更多要 build 更多次,寫更多 build job,但只是差在打的後端 API 網址不同
想問有沒什麼方法可以 build 一次,但可套到所有環境?
目前只有想到從前端邏輯改,當抓到 URL 是 A 網址就打 X 網址的 API,URL 是 B 就打 Y 網址 API
但當網址異動了就得改邏輯,不知有無更好作法,在 Deploy 時決定打的後端網址
謝謝前輩
可以透過給容器運行時的環境變數的方式,
在運行時給定不同的後端 API 網址,而不必在 build 階段。
Dockerfile:
# 基礎映像檔
FROM node:14-alpine
# 建立工作目錄
WORKDIR /app
# 複製應用程式到工作目錄
COPY . .
# 安裝 npm 套件
RUN npm install
# 定義環境變數,用於運行時給定 API 網址
ENV API_URL=""
# 運行應用程式
CMD ["npm", "start", "--", "--apiUrl=$API_URL"]
我們透過 -e 參數給定 API_URL 環境變數,並在運行應用程式時使用該變數,以達到不同環境使用不同後端 API 網址的目的。
運行容器範例:
docker run -e API_URL=http://api-server-A.com my-image-name
你好,我是使用 nginx 容器裡面的 envsubst 工具在容器啟動時替換,您可以參考看看。
參考 https://blog.miniasp.com/post/2018/08/22/Angular-nginx-reverse-proxy-and-Docker
FROM nginx:${NGINX_VERSION}-alpine as prd
COPY --from=build /app/dist /usr/share/nginx/html
# 把 Nginx 模版複製到 Nginx 的設定檔目錄
COPY .docker/nginx.template /etc/nginx/conf.d/
# 利用 envsubst 將特定字串替換成指定文字
CMD envsubst '${BACKEND_URI}${FAB8F_URI}${WEATHER_8T_URI}' < /etc/nginx/conf.d/nginx.template > /etc/nginx/conf.d/default.conf && \
exec nginx -g 'daemon off;'
server {
listen 80;
root /usr/share/nginx/html;
proxy_set_header Host $proxy_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header x-forwarded-for $remote_addr;
proxy_set_header X-Forwarded-Host $server_name;
# 這裡要指定 log,Nginx 才會寫入
# 預設的 access.log 是空的
access_log /var/log/nginx/frontend-access.log custom;
error_log /var/log/nginx/frontend-error.log;
# The dog.ceo domain is very slow that will lead nginx resolver not working.
resolver 172.28.0.1 valid=30s ipv6=off;
location ~/backend(.+)$ {
proxy_pass ${BACKEND_URI}$1?$args;
proxy_redirect off;
proxy_set_header Host $proxy_host;
}
location ~/8f-amas(.+)$ {
proxy_pass ${FAB8F_URI}$1?$args;
proxy_redirect off;
proxy_set_header Host $proxy_host;
proxy_connect_timeout 10s;
proxy_send_timeout 10s;
proxy_read_timeout 10s;
}
location ~/8t-weather(.+)$ {
proxy_pass ${WEATHER_8T_URI}$1?$args;
proxy_redirect off;
proxy_set_header Host $proxy_host;
proxy_connect_timeout 90s;
proxy_send_timeout 90s;
proxy_read_timeout 90s;
proxy_ignore_client_abort on;
}
}
service:
frontend:
build:
context: ./frontend
target: prd
networks:
net:
ipv4_address: 172.28.0.2
ports:
- 80:80
volumes:
- nginx_log:/var/log/nginx
environment:
BACKEND_URI: http://172.28.0.3:3003
FAB8F_URI: http://172.28.0.4:3050
WEATHER_8T_URI: http://172.28.0.5:3090
TZ: Asia/Taipei
restart: on-failure:5