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
相关产品推荐
相关产品推荐

