我想在主机和Docker的容器之间正确共享目录
在两个系统上都使用相同的UID
和GID
。
为此,我想将它们作为变量MY_UID=$(id -u)
传递给docker。
我们正在考虑以下情况:.env
引用了某些变量,例如MY_UID=$(id -u)
,
不是行值,例如MY_UID=1000
正确声明变量,将其导出为环境变量
并且它可以在docker-compose.yml
级别上运行,但是docker-compose不会将它们进一步传递给Dockerfile。
到目前为止,我已经在docker-compose.yml中尝试过:
与bash一起使用:
或docker-compose -e
的选项。
给定变量的整个路径为export> docker-compose> dockerfile。
出于测试目的,Dockerfile很简单,例如: (在此级别上,变量不起作用!)
FROM heroku/heroku:18 AS production
RUN useradd -ms /usr/bin/fish -p $(openssl passwd -1 django) --uid "$MY_UID" --gid "$MY_GID" -r
和$ MY_UID在使用docker-compose
时为空。
docker-compose.yml (在此级别上变量有效!)
version: '3.7'
networks: {}
services:
django:
build:
context: ${MY_DIR}
dockerfile: ${COMPOSE_DIR}/django/Dockerfile
env_file:
- .env
environment:
- MY_UID: ${MY_UID}
volumes:
- ${MY_DIR}:/app:rw
docker-compose config返回:
MY_GID: $$(id -u)
对于.env:MY_GID=$(id -u)
我想避免这种解决方法:
source .env && cat template_Dockerfile | envsubst > Dockerfile
或
source .env && cat .env | envsubst > .env_for_dockercompose
答案 0 :(得分:1)
关于将值从docker-compose
(或仅从CLI)传递到Dockerfile
的正确方法,我想您需要添加一些ARG
指令,例如:
FROM heroku/heroku:18 AS production
ARG MY_UID="...default UID..."
ARG MY_GID="...default GID..."
RUN useradd -ms /usr/bin/fish -p $(openssl passwd -1 django) --uid "$MY_UID" --gid "$MY_GID" -r
然后对其进行测试:
$ docker build --build-arg=MY_UID="1000" --build-arg=MY_GID="1000" -t test .
我使用类似的方法in the Dockerfile of coqorg/base(基于Debian)。
但是,如果您对传递变量以确保UID / GID匹配特别感兴趣,请注意,可以采用另一种方法,该方法具有额外的好处,即可以使映像与使用不同UID / GID的多个主机兼容。 this SO answer by @BMitch中对此进行了描述,该提案建议在启动时修复容器目录的权限,例如:
答案 1 :(得分:0)
您可以使用2张图片来处理UID/GID
(第一张=主图片和公开图片,第二张=小图片和私人图片)
这样,大部分环境都会被缓存,并由称为base_image
的预先配置的第一张映像提供给其他人。
然后,最终图像的说明很简单:
FROM base_image
RUN groupadd -r django -g ${UFG_GID} ...
base_image
被赋予所有人,
但最终映像是一个延续,每个主机都打算构建每个主机上不同UID/GID
部分的内容。但这没问题,因为这样的操作非常便宜。
这样,不需要额外的脚本,但是其他人无法使用最终图像来避免使用不同的UID/GID
问题。
如果您希望每个人都可以使用一个图像,则需要用于修复用户权限的其他脚本-请参见ErikiMD answer
说明:
Dockerfile_template
docker-compose.yml_template
这样,通过下面的模板,您可以完全控制将在每个级别(主机,容器)上替换哪个变量
...
ENV PATH="/pyenv/bin:${DOLLAR}PATH"
...
RUN ... ${MY_VAR}...
...
注意:
使用DOLLAR='$'
,并用${DOLLAR}PATH
转义$ PATH,以避免用错误的主机中的值替换$ PATH。
含义:
以这种方式呈现docker文件:
source .env && \
cat $COMPOSE_DIR/django/Dockerfile_template | DOLLAR='$' envsubst > $COMPOSE_DIR/django/Dockerfile \
docker-compose up -d --build
生成预配置的Dockerfile-在其中替换一些变量为值。
.env
保留所有变量 docker-compose.yml_template
也是如此(如果需要)。