You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue3运行时设环境变量并以非Root用户启动Nginx容器问题

解决Vue3应用Docker部署:运行时环境变量注入+非root启动Nginx权限问题

我需要在启动Docker Nginx容器时,为Vue3开发的Web应用注入运行时环境变量,同时以非root用户启动容器,但目前遇到权限问题导致容器无法启动,且需要在main.js中获取这些变量。已准备了环境变量替换脚本、.env.production、nginx.conf和Dockerfile,但问题未解决。


核心问题分析

非root用户(nginx)没有权限修改/client目录下的静态文件,也没有权限访问Nginx启动所需的核心资源(如PID文件、日志目录),这是导致容器启动失败的根本原因。以下是修正后的完整配置:

1. 修正Dockerfile

调整目录权限,确保nginx用户拥有/client目录的读写权,并且在执行替换脚本前完成权限配置:

FROM node:16.11.1-alpine3.14 as builder
COPY --chown=node src /client/src
COPY --chown=node public /client/public
COPY --chown=node package.json /client/
COPY --chown=node vue.config.js /client/
COPY --chown=node babel.config.js /client/
COPY --chown=node node_modules /client/node_modules/
USER root
WORKDIR /client
COPY package.json /client/package.json
RUN npm install
COPY --chown=node . /client
RUN npm run build
USER node

FROM builder as tester
USER node
COPY --chown=node .eslintrc.json /client/
WORKDIR /client
ENTRYPOINT ["./node_modules/.bin/eslint", "."]

FROM nginx:1.23.4-alpine as publisher
# 创建/client目录并赋予nginx用户所有权
RUN mkdir -p /client && chown -R nginx:nginx /client

# 修复Nginx核心资源权限
RUN chown -R nginx:nginx /var/cache/nginx && \
    chown -R nginx:nginx /var/log/nginx && \
    chown -R nginx:nginx /etc/nginx/conf.d && \
    touch /var/run/nginx.pid && \
    chown -R nginx:nginx /var/run/nginx.pid

# 复制构建产物并继承nginx权限
COPY --from=builder --chown=nginx:nginx /client/dist /client
COPY nginx.conf /etc/nginx/nginx.conf
COPY ./substitute_environment_variables.sh /substitute_environment_variables.sh
RUN chmod +x /substitute_environment_variables.sh

# 切换到nginx用户执行后续操作
USER nginx
ENTRYPOINT ["/substitute_environment_variables.sh"]

2. 修改环境变量替换脚本

适配alpine系统的sed命令,避免权限冲突,确保nginx用户可正常修改静态文件:

#!/bin/sh

ROOT_DIR=/client

# 替换静态文件中的环境变量占位符
for file in $ROOT_DIR/js/*.js* $ROOT_DIR/index.html;
do
  # 使用临时备份文件模式避免sed权限报错
  sed --in-place=.bak 's|VUE_APP_URL_KEYCLOAK_PLACEHOLDER|'"${VUE_APP_URL_KEYCLOAK}"'|g' "$file"
  sed --in-place=.bak 's|VUE_APP_KEYCLOAK_REALM_PLACEHOLDER|'"${VUE_APP_KEYCLOAK_REALM}"'|g' "$file"
  sed --in-place=.bak 's|VUE_APP_KEYCLOAK_CLIENT_ID_PLACEHOLDER|'"${VUE_APP_KEYCLOAK_CLIENT_ID}"'|g' "$file"
  # 删除临时备份文件
  rm -f "${file}.bak"
done

# 以nginx用户启动Nginx
nginx -g 'daemon off;'

3. 保留原nginx.conf配置

确保配置中user nginx;项保留,无需额外修改:

user  nginx;
worker_processes  1;
error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;
events {
  worker_connections  1024;
}
http {
  include       /etc/nginx/mime.types;
  default_type  application/octet-stream;
  log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                    '$status $body_bytes_sent "$http_referer" '
                    '"$http_user_agent" "$http_x_forwarded_for"';
  access_log  /var/log/nginx/access.log  main;
  sendfile        on;
  keepalive_timeout  65;
  server {
    listen       3000;
    server_name  localhost;
    location / {
      root   /client;
      index  index.html;
      try_files $uri $uri/ /index.html;
    }
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
      root   /usr/share/nginx/html;
    }
  }
}

4. main.js中获取环境变量

替换后的静态文件已将占位符替换为实际环境变量,直接在main.js中读取即可:

// main.js
const urlKeycloak = process.env.VUE_APP_URL_KEYCLOAK;
const keycloakRealm = process.env.VUE_APP_KEYCLOAK_REALM;
const keycloakClientId = process.env.VUE_APP_KEYCLOAK_CLIENT_ID;

console.log('Keycloak URL:', urlKeycloak);
// 后续Keycloak初始化等业务逻辑

容器启动命令

启动容器时直接传入环境变量:

docker run -d \
  -p 3000:3000 \
  -e VUE_APP_URL_KEYCLOAK=https://your-keycloak-domain \
  -e VUE_APP_KEYCLOAK_REALM=your-realm-name \
  -e VUE_APP_KEYCLOAK_CLIENT_ID=your-client-id \
  your-image-tag

内容的提问来源于stack exchange,提问作者Tolga

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 03:30:00