一般來說,咱們在使用docker build Nodejs容器時,代碼中就有預設一些參數,做爲各個環境的環境變量,例如數據庫的URL等前端
但做爲前端應用react,在編譯了代碼後,生成的代碼使用Nginx代理在瀏覽器中運行,那麼注意,在瀏覽器中沒有環境變量這個東西,因此本來在後臺Nodejs服務器中的獲取環境變量的方案,在前端React項目中不可用react
實際上,process在瀏覽器環境都不存在,它是特定於Nodejs的,在轉換過程當中,webpack進程會使用process.env給定的字符串值替換全部出現的內容,這就說明,前端React項目想要獲取參數只能在docker build期間進行配置。webpack
找到一個解決方案,當咱們啓動容器時,是能夠注入環境變量的特定時刻,而後咱們能夠從容器內部讀取環境變量。咱們能夠將它寫入一個文件,該文件能夠經過Nginx(或者是React應用程序)提供服務,它使用<script>標籤導入至index.htmlnginx
因此在那一刻,咱們能夠運行一個bash腳本,建立一個JavaScript文件,將環境變量被指定爲全局Window對應的屬性,將它注入至瀏覽器,以方便咱們的應用在全局可用git
建立項目,並建立有內容的.env文件github
# Generate React App create-react-app react-nginx-variable cd react-nginx-variable # Create default environment variables that we want to use touch .env echo "API_URL=https//default.dev.api.com" >> .env
建立腳本env.shweb
#!/bin/bash # Recreate config file rm -rf ./env-config.js touch ./env-config.js # Add assignment echo "window._env_ = {" >> ./env-config.js # Read each line in .env file # Each line represents key=value pairs while read -r line || [[ -n "$line" ]]; do # Split env variables by character `=` if printf '%s\n' "$line" | grep -q -e '='; then varname=$(printf '%s\n' "$line" | sed -e 's/=.*//') varvalue=$(printf '%s\n' "$line" | sed -e 's/^[^=]*=//') fi # Read value of current variable if exists as Environment variable value=$(printf '%s\n' "${!varname}") # Otherwise use value from .env file [[ -z $value ]] && value=${varvalue} # Append configuration property to JS file echo " $varname: \"$value\"," >> ./env-config.js done < .env echo "}" >> ./env-config.js
處理的流程docker
(1)刪除舊文件,並建立一個新文件。
(2)編寫JS代碼,打開對象文字並將其分配給全局窗口對象。
(3)讀取.env文件的每一行並分紅鍵/值對。
(4)查找環境變量,若是設置,則使用其值,不然,使用.env文件中的默認值。
(5)將它附加到咱們分配給全局窗口對象的對象
(6)關閉對象文字數據庫
而後咱們在index.html中<head>中添加如下腳本
<script src="%PUBLIC_URL%/env-config.js"></script>
且在首頁代碼App.js中寫一行代碼
<p>API_URL: {window._env_.API_URL}</p>
而後react項目的package.json中
"scripts": { "dev": "chmod +x ./env.sh && ./env.sh && cp env-config.js ./public/ && react-scripts start", "test": "react-scripts test", "eject": "react-scripts eject", "build": "react-scripts build'" },
而後在本機可使用yarn dev來運行項目,應該能夠看到界面上已經成功獲取到.env文件中的變量
固然,咱們也能夠修改React項目中的.env文件中的內容,從而在本地來運行看到結果
但當成到SIT/UAT/PROD環境時,使用docker-compose方式運行項目時
version: "3.2" services: web: image: weschen/workbench:20190627.2 ports: - "5000:80" environment: - "API_URL=weschen.production.example.com"
頁面中顯示的,便是weschen.production.example.com