[英]Permission denied when running `mkdir` inside of a Docker container
I am using Docker Compose to run several containers, including one with a Postgres image. 我使用Docker Compose运行几个容器,包括一个带Postgres图像的容器。 I am attempting to add a volume to that container to persist my data across container builds. 我正在尝试向该容器添加一个卷,以便在容器构建中保留我的数据。 However, I am receiving an error when it tries to create a directory for this volume within the container. 但是,当它尝试在容器中为此卷创建目录时,我收到错误。
I run: 我跑:
docker-compose build
then 然后
docker-compose up
And I receive the following error: 我收到以下错误:
ERROR: for cxbenchmark_db_1 Cannot start service db: oci runtime error: container_linux.go:265: starting container process caused "process_linux.go:368: container init caused \\"rootfs_linux.go:57: mounting \\\\"/var/lib/docker/volumes/69845a017b4465e9122852a75ca194db473df95fa218658b8a60fb56eba9be9e/_data\\\\" to rootfs \\\\"/var/lib/docker/overlay2/627956d63fb0480448079577a83b0b54f83866fdf31136b7c669541c3f672355/merged\\\\" at \\\\"/var/lib/docker/overlay2/627956d63fb0480448079577a83b0b54f83866fdf31136b7c669541c3f672355/merged/var/lib/postgresql/data\\\\" caused \\\\"mkdir /var/lib/docker/overlay2/627956d63fb0480448079577a83b0b54f83866fdf31136b7c669541c3f672355/merged/var/lib/postgresql/data: permission denied\\\\"\\"" 错误:对于cxbenchmark_db_1无法启动服务db:oci运行时错误:container_linux.go:265:启动容器进程导致“process_linux.go:368:容器init导致”rootfs_linux.go:57:mount \\\\“/ var / lib /泊坞窗/卷/ 69845a017b4465e9122852a75ca194db473df95fa218658b8a60fb56eba9be9e / _data \\\\ “来根文件系统\\\\ ”的/ var / lib中/泊坞窗/ overlay2 / 627956d63fb0480448079577a83b0b54f83866fdf31136b7c669541c3f672355 /合并\\\\“ 在\\\\” 的/ var / lib中/泊坞窗/ overlay2 / 627956d63fb0480448079577a83b0b54f83866fdf31136b7c669541c3f672355 /合并的/ var / lib中/ postgresql / data \\\\“cause \\\\”mkdir / var / lib / docker / overlay2 / 627956d63fb0480448079577a83b0b54f83866fdf31136b7c669541c3f672355 / merged / var / lib / postgresql / data:permission denied \\\\“\\”“
My full docker-compose.yml
looks like this (note the service called db
where the volume is defined): 我的完整docker-compose.yml
看起来像这样(注意名为db
的服务,其中定义了卷):
version: '3'
services:
nginx:
image: nginx:latest
ports:
- 80:8000
volumes:
- ./src:/src
- ./config/nginx:/etc/nginx/conf.d
- ./src/static:/static
depends_on:
- web
web:
build: .
command: bash -c "python manage.py makemigrations && python manage.py migrate && gunicorn cx_benchmark.wsgi -b 0.0.0.0:8000"
depends_on:
- db
volumes:
- ./src:/src
- ./src/static:/static
expose:
- 8000
db:
image: postgres:latest
volumes:
- /private/var/lib/postgresql:/var/lib/postgresql
ports:
- 5432:5432
Any ideas for how to solve? 有关如何解决的任何想法?
The error you are seeing is not a problem (necessarily) with the explicit volume bind mount in your compose
file, but rather with the VOLUME
declaration in the main postgres
official Docker image Dockerfile
: 你看到的错误不一定是你的compose
文件中显式卷绑定挂载的问题,而是主postgres
官方Docker镜像Dockerfile
的VOLUME
声明:
VOLUME /var/lib/postgresql/data
Since you haven't provided a mount-point for this directory (but rather the parent), the docker engine is creating a local volume and then trying to mount that volume into your already bind-mounted location and getting a permissions error. 由于您尚未为此目录(而是父目录)提供挂载点,因此docker引擎正在创建本地卷,然后尝试将该卷装入已绑定装入的位置并获取权限错误。
For clarity, here is the volume the docker engine created for you: 为清楚起见,这是docker引擎为您创建的卷:
/var/lib/docker/volumes/69845a017b4465e9122852a75ca194db473df95fa218658b8a60fb56eba9be9e/_data
And here is the directory location at which it is trying to bind mount that dir; 这是目录位置,它尝试绑定mount dir; on top of your bind mount from /private/var/lib/postgresql
: 在/private/var/lib/postgresql
bind挂载之上:
mkdir /var/lib/docker/overlay2/627956d63fb0480448079577a83b0b54f83866fdf31136b7c669541c3f672355/merged/var/lib/postgresql/data: permission denied
Now, I think the reason this is failing is that you may have turned on user namespaces in your Docker engine (" userns-remap
" flag/setting) such that the container doesn't have permissions to create a directory in that root-owned location on your host. 现在,我认为失败的原因是你可能在Docker引擎中打开了用户命名空间(“ userns-remap
”标志/设置),这样容器就没有权限在root拥有的内创建一个目录在您的主机上的位置。 Barring that, the only other option is that the postgres
container is starting as a non-root user, but I don't see anything in your compose file or the official Dockerfile
for the latest release that uses the USER
directive. 除此之外,唯一的另一个选择是postgres
容器以非root用户身份启动,但我没有在compose文件或使用USER
指令的最新版本的官方Dockerfile
看到任何内容。
As an aside, since you are ending up with double-volumes because your bind mount doesn't match the VOLUME
specifier in the postgres Dockerfile
, you could change your compose file to mount to /var/lib/postgresql/data
and get around that extra volume being created. Dockerfile
,由于你的绑定挂载与postgres Dockerfile
中的VOLUME
说明符不匹配,因此你最终会出现双卷,你可以将你的compose文件更改为挂载到/var/lib/postgresql/data
并绕过那个正在创建额外的卷。 Especially if you expect your DB data to end up in /private/var/lib/postgresql
, as it may be surprising to find it isn't there, but rather in the /var/lib/docker/volumes/..
location. 特别是如果您希望您的数据库数据最终在/private/var/lib/postgresql
,因为它可能会令人惊讶地发现它不在那里,而是在/var/lib/docker/volumes/..
位置。
Based on https://github.com/docker/compose/issues/4039 , common fixes are: 基于https://github.com/docker/compose/issues/4039 ,常见的修复方法是:
I'm able to get this working: 我能够做到这一点:
sudo mkdir /private/lib/postgresql
docker-compose up
With the following docker-compose.yml: 使用以下docker-compose.yml:
version: '3'
services:
nginx:
image: nginx:latest
ports:
- 80:8000
db:
image: postgres:latest
volumes:
- /private/var/lib/postgresql:/var/lib/postgresql
ports:
- 5432:5432
I'm sorry I haven't been more help! 对不起,我没有得到更多的帮助!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.