为什么在 docker-compose.yml 中使用 blank/empty 卷允许持久性但使用相对路径失败(例如 jenkins gui 不可用)?
Why does using a blank/empty volume in docker-compose.yml allow persistence but using a relative path fails (eg jenkins gui unavailable)?
问题:
- 为什么相对主机卷路径(即
./jenkins_home:...
)阻止 jenkins 为其 GUI 提供服务,而空卷路径允许 jenkins 为其 GUI 提供服务?
- 主机上的别名主机卷(即
volumes: jenkins_home: <no value>
)存储在哪里?
上下文:
这种情况类似于 ,但我不确定该解决方案为何有效。
在 Windows 10 上使用 Docker 桌面 docker-compose
,主机卷位置的相对路径(即 ./jenkins_home:...
)正确地将数据保存到当前目录, & 端口 50000 可以访问,但是端口 8080(即 Jenkins GUI)不可用:
version: '3.9'
services:
jenkins:
image: 'jenkins/jenkins:lts'
restart: 'unless-stopped'
ports:
- '8080:8080'
- '50000:50000'
volumes:
- './jenkins_home:/var/jenkins_home' # Relative path (jenkins GUI doesn't work).
volumes:
jenkins_home:
ping http://localhost:50000 # Success.
ping http://localhost:8080 # Not found.
而使用空主机卷路径有效:
# ...
services:
jenkins:
# ...
volumes:
- 'jenkins_home:/var/jenkins_home' # Aliased empty path (jenkins GUI works).
volumes:
# NOTE: Empty path value used below.
jenkins_home:
ping http://localhost:8080 # Success.
为了比较,使用 docker run
和主机卷路径别名时可以访问 jenkins GUI,如下所示(尽管我不确定它在主机上的位置):
运行 jenkins 通过 docker run
成功使 jenkins GUI 可用:
docker run -p 8080:8080 -p 50000:50000 -d -v jenkins_home:/var/jenkins_home jenkins/jenkins:lts
相对卷路径使 jenkins GUI 无法访问,这似乎是因为持久性在这种情况下不起作用,这会阻止 jenkins 在 http://localhost:8080
上提供它的 GUI,并且不知何故使用空卷路径通过卷别名允许持久性和提供 GUI - 问题是为什么相对路径导致 GUI 不提供服务而空路径导致 GUI 提供服务?
由于 GUI 不可用是一个 application-specific 问题,因此不能仅从 docker
的角度来回答。但最有可能的原因是 docker
中的 volumes
and bind-mounts
之间的差异,即它们在创建时的初始化方式:
虽然对于 bind-mounts
主机上的指定目录将简单地挂载到容器 as-is 中,但新的 volumes
由 docker
创建,如果它们不这样做的话还存在 populated with the contents of the target directory from the image。这还包括为 volume
.
设置相同的权限
所以对于您的问题 1.:在容器的日志中查找有关 permission denied
/ access denied
或 /var/jenkins_home
中缺少 files/directories 的错误消息。如果是这样,您只需要为 ./jenkins_home
设置正确的权限或手动初始化预期内容(application-specific 问题到底是什么)。
关于问题 2.: where the contents of the volumes are stored on disk is managed by docker
and dependent on the configuration of the docker
daemon and host. Normally you should not need to care about this and only manage them via the docker volume
command.
有关详细信息,请参阅 the docker
documentation。
问题:
- 为什么相对主机卷路径(即
./jenkins_home:...
)阻止 jenkins 为其 GUI 提供服务,而空卷路径允许 jenkins 为其 GUI 提供服务? - 主机上的别名主机卷(即
volumes: jenkins_home: <no value>
)存储在哪里?
上下文:
这种情况类似于
在 Windows 10 上使用 Docker 桌面 docker-compose
,主机卷位置的相对路径(即 ./jenkins_home:...
)正确地将数据保存到当前目录, & 端口 50000 可以访问,但是端口 8080(即 Jenkins GUI)不可用:
version: '3.9'
services:
jenkins:
image: 'jenkins/jenkins:lts'
restart: 'unless-stopped'
ports:
- '8080:8080'
- '50000:50000'
volumes:
- './jenkins_home:/var/jenkins_home' # Relative path (jenkins GUI doesn't work).
volumes:
jenkins_home:
ping http://localhost:50000 # Success.
ping http://localhost:8080 # Not found.
而使用空主机卷路径有效:
# ...
services:
jenkins:
# ...
volumes:
- 'jenkins_home:/var/jenkins_home' # Aliased empty path (jenkins GUI works).
volumes:
# NOTE: Empty path value used below.
jenkins_home:
ping http://localhost:8080 # Success.
为了比较,使用 docker run
和主机卷路径别名时可以访问 jenkins GUI,如下所示(尽管我不确定它在主机上的位置):
运行 jenkins 通过 docker run
成功使 jenkins GUI 可用:
docker run -p 8080:8080 -p 50000:50000 -d -v jenkins_home:/var/jenkins_home jenkins/jenkins:lts
相对卷路径使 jenkins GUI 无法访问,这似乎是因为持久性在这种情况下不起作用,这会阻止 jenkins 在 http://localhost:8080
上提供它的 GUI,并且不知何故使用空卷路径通过卷别名允许持久性和提供 GUI - 问题是为什么相对路径导致 GUI 不提供服务而空路径导致 GUI 提供服务?
由于 GUI 不可用是一个 application-specific 问题,因此不能仅从 docker
的角度来回答。但最有可能的原因是 docker
中的 volumes
and bind-mounts
之间的差异,即它们在创建时的初始化方式:
虽然对于 bind-mounts
主机上的指定目录将简单地挂载到容器 as-is 中,但新的 volumes
由 docker
创建,如果它们不这样做的话还存在 populated with the contents of the target directory from the image。这还包括为 volume
.
所以对于您的问题 1.:在容器的日志中查找有关 permission denied
/ access denied
或 /var/jenkins_home
中缺少 files/directories 的错误消息。如果是这样,您只需要为 ./jenkins_home
设置正确的权限或手动初始化预期内容(application-specific 问题到底是什么)。
关于问题 2.: where the contents of the volumes are stored on disk is managed by docker
and dependent on the configuration of the docker
daemon and host. Normally you should not need to care about this and only manage them via the docker volume
command.
有关详细信息,请参阅 the docker
documentation。