WSL下Docker部署Phoenix项目:生成文件无法在VSCode保存
解决Docker中Phoenix生成器文件权限问题(WSL环境)
核心问题
容器内以root身份创建的文件,主机用户无编辑权限;手动创建匹配主机UID/GID的用户后,mix又因权限不足无法访问_build等目录。
分步解决方案
1. 修改Dockerfile,保留构建阶段root权限
构建阶段仍用root执行依赖安装,避免权限问题,同时添加shadow工具用于后续创建用户:
FROM hexpm/elixir:1.16.2-erlang-26.2.2-alpine-3.19.1 RUN apk add --no-cache git shadow RUN mkdir /app COPY . /app WORKDIR /app # 以root完成依赖安装,确保文件可被后续用户访问 RUN mix local.hex --force RUN mix deps.get && mix deps.compile CMD /app/entrypoint.sh
2. 更新entrypoint.sh,动态创建匹配主机的用户
容器启动时根据主机传递的UID/GID创建用户,切换用户后再执行Phoenix命令:
#!/bin/sh set -e # 默认使用WSL普通用户的UID/GID(1000),可通过环境变量覆盖 HOST_UID=${HOST_UID:-1000} HOST_GID=${HOST_GID:-1000} # 创建用户组和用户 groupadd -g $HOST_GID appgroup useradd -u $HOST_UID -g appgroup -m appuser # 修正/app目录权限,让新用户能正常访问 chown -R appuser:appgroup /app # 切换用户执行Phoenix初始化和启动命令 su appuser -c "mix ecto.create && mix ecto.migrate && mix phx.server"
给脚本添加执行权限:
chmod +x entrypoint.sh
3. 修改docker-compose.yml,传递主机UID/GID
通过环境变量将主机用户的UID/GID传入容器:
services: phoenix: build: context: . volumes: - ./:/app environment: DB_USER: user DB_PASSWORD: secret DB_DATABASE: vrn DB_PORT: 3306 DB_HOST: db # 传递主机用户的UID和GID HOST_UID: ${HOST_UID:-1000} HOST_GID: ${HOST_GID:-1000} ports: - 4000:4000 depends_on: - db db: image: mysql:8.3 environment: MYSQL_ROOT_PASSWORD: rootsecret MYSQL_DATABASE: vrn MYSQL_USER: user MYSQL_PASSWORD: secret restart: always volumes: - mysql:/var/lib/mysql volumes: mysql:
4. 清理旧容器并重新构建(可选)
避免旧镜像缓存导致的权限问题:
docker-compose down --rmi all docker-compose build --no-cache docker-compose up
方案说明
- 构建阶段用root处理依赖,确保
_build、deps等目录的基础权限正确; - 启动时动态创建匹配主机的用户,保证容器内生成的文件权限与主机用户一致,VSCode可正常编辑;
- 通过环境变量适配不同主机的用户配置,无需硬编码UID/GID。
内容的提问来源于stack exchange,提问作者Daanooo
相关产品推荐
相关产品推荐

