如何解决在使用docker的生产应用程序中的生产环境中使用不同的API URL的最佳方法是什么?
好的,所以我整天都在努力,但仍然找不到解决方案。我创建了一个React应用,该应用在后端对Django服务器进行了一些API调用。 我创建了一个settings.js文件,该文件根据应用程序是在开发中还是在生产中运行来更改API URL。 settings.js文件如下所示:
let API_SERVER_VAL = '';
let MEDIA_SERVER_VAL = '';
let FRONTEND_SERVER_VAL = '';
switch (process.env.NODE_ENV) {
case 'development':
API_SERVER_VAL = 'http://localhost:8000';
MEDIA_SERVER_VAL = 'http://localhost:8000';
FRONTEND_SERVER_VAL = 'http://localhost:3000';
break;
case 'production':
API_SERVER_VAL = process.env.API_SERVER;
MEDIA_SERVER_VAL = process.env.API_SERVER;
FRONTEND_SERVER_VAL = process.env.API_SERVER;
break;
default:
API_SERVER_VAL = 'http://localhost:8000';
MEDIA_SERVER_VAL = 'http://localhost:8000';
FRONTEND_SERVER_VAL = 'http://localhost:3000';
break;
}
export const API_SERVER = API_SERVER_VAL;
export const MEDIA_SERVER = MEDIA_SERVER_VAL;
export const FRONTEND_SERVER = FRONTEND_SERVER_VAL;
export const SESSION_DURATION = 5*3600*1000;
基于上述示例的API如下所示:
import * as settings from '../../settings';
....
axios.post(`${settings.API_SERVER}/api/auth/logout/`,...)
Dockerfile如下所示。我正在执行图像的两阶段构建。
###########
# BUILDER #
###########
# pull official base image
FROM node:12.18.3-alpine3.9 as builder
# set work directory
WORKDIR /usr/src/app
# install dependencies and avoid `node-gyp rebuild` errors
COPY package.json .
RUN apk add --no-cache --virtual .gyp \
python \
make \
g++ \
&& npm install \
&& apk del .gyp
# copy our react project
COPY . .
# perform npm build
ARG API_SERVER
ENV API_SERVER=${API_SERVER}
RUN API_SERVER=${API_SERVER} \
npm run build
#########
# FINAL #
#########
# pull official base image
FROM node:12.18.3-alpine3.9
# set work directory
WORKDIR /usr/src/app
# install serve - deployment static server suggested by official create-react-app
RUN npm install -g serve
# copy our build files from our builder stage
COPY --from=builder /usr/src/app/build ./build
docker-compose文件如下所示(react服务)。基本上,docker-compose react服务将名为API_SERVER = 127.0.0.1的参数传递给Dockerfile的builder阶段。
version: "3.7"
services:
django:
build:
context: ./backend/app
dockerfile: Dockerfile.prod
command: gunicorn mainapp.wsgi:application --bind 0.0.0.0:8000
volumes:
- django_static_volume:/usr/src/app/files_static
- app_media_volume:/usr/src/app/files_media
expose:
- 8000
# ports:
# - 8000:8000
env_file:
- ./backend/.env.prod
depends_on:
- db
db:
image: postgres:12.0-alpine
volumes:
- postgres_data:/var/lib/postgresql/data/
env_file:
- ./backend/.env.prod.db
react:
build:
context: ./frontend/app
dockerfile: Dockerfile.prod
args:
- API_SERVER=127.0.0.1
volumes:
- react_static_volume:/usr/src/app/build/static
expose:
- 3000
command: serve -s build -l 3000
depends_on:
- django
nginx:
restart: always
build: ./nginx
volumes:
- django_static_volume:/usr/src/app/django_files/static
- app_media_volume:/usr/src/app/media
- react_static_volume:/usr/src/app/react_files/static
ports:
- 80:80
# - 8000:80
depends_on:
- react
volumes:
postgres_data:
django_static_volume:
app_media_volume:
react_static_volume:
我还通过在主页的控制台中打印此设置来检查是否已正确从docker传递此设置。因此,在Home.js中,我具有以下内容:
console.log(`The environment is ${process.env.NODE_ENV}`);
console.log(`The API server is ${process.env.API_SERVER}`);
console.log(`The settings API server is ${settings.API_SERVER}`);
console.log(`The PUBLIC URL is ${process.env.PUBLIC_URL}`);
因此仅正确显示了process.env.NODE_ENV !!我认为这是因为这是在显示图像第二阶段而不是构建器阶段的环境变量。
我在做什么错?不需要其他npm-packages的最优雅的方法是什么?
解决方法
我实际上在create-react-app的官方页面上找到了答案。问题在于,除非create-react-app以REACT_APP_
开头,否则它将不会使用该环境变量。 here就是这样的:
注意:您必须创建以以下内容开头的自定义环境变量
REACT_APP_
。除NODE_ENV
以外的任何其他变量将被忽略为 避免意外地在机器上公开私钥,这可能会 具有相同的名称。更改任何环境变量将需要 您可以重新启动开发服务器(如果正在运行)。
这正是我能够在控制台中打印出process.env.NODE_ENV
而不打印其他变量的原因,因为它们不是以REACT_APP_
开头。
所以我用以下方法更改了Dockerfile:
# perform npm build
ARG API_SERVER
ENV REACT_APP_API_SERVER=${API_SERVER}
RUN REACT_APP_API_SERVER=${API_SERVER} \
npm run build
,还有settings.js,其中包含:
case 'production':
API_SERVER_VAL = process.env.REACT_APP_API_SERVER;
MEDIA_SERVER_VAL = process.env.REACT_APP_API_SERVER;
FRONTEND_SERVER_VAL = process.env.REACT_APP_API_SERVER;
break;
现在控制台将打印出我从docker-compose.yaml文件中传递的所有内容!
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。