Dockerfile未生成宿主机initdb.sql,引发Apache Guacamole挂载报错
Apache Guacamole部署问题:PostgreSQL容器循环重启
问题现象
通过Docker Compose+Dockerfile部署Apache Guacamole时,未配置自动数据库初始化可正常运行。添加Dockerfile生成initdb.sql后,执行docker-compose up --build -d构建成功,但PostgreSQL容器进入循环重启状态,报错显示:挂载宿主机路径/scripts/Cherry-VM-Manager/docker/apache-guacamole/initdb.sql到容器内/initdb.sql时,该路径为目录而非文件。
相关配置文件与目录结构
docker-compose.yml
version: '3' services: guacd: restart: always image: guacamole/guacd guacamole-server: restart: always image: guacamole/guacamole build: context: . dockerfile: Dockerfile ports: - "8080:8080" environment: - GUACD_HOSTNAME=guacd - POSTGRESQL_HOSTNAME=database - POSTGRESQL_DATABASE=${GUACAMOLE_DATABASE} - POSTGRESQL_USER=${GUACAMOLE_USER} - POSTGRESQL_PASSWORD=${GUACAMOLE_PASSWORD} depends_on: - guacd - database volumes: - ./initdb.sql:/initdb.sql:ro database: restart: always image: postgres environment: - POSTGRES_USER=${GUACAMOLE_USER} - POSTGRES_DB=${GUACAMOLE_DATABASE} - POSTGRES_PASSWORD=${GUACAMOLE_PASSWORD} volumes: - ./db:/var/lib/postgresql/data:rw - ./initdb.sql:/initdb.sql:ro command: > sh -c "psql -U ${GUACAMOLE_USER} ${GUACAMOLE_DATABASE} -f /initdb.sql && tail -f /dev/null" volumes: db:
Dockerfile
# Dockerfile for guacamole/guacamole container FROM guacamole/guacamole:latest USER root # Generate the initdb.sql file for PostgreSQL RUN /opt/guacamole/bin/initdb.sh --postgresql > initdb.sql USER guacamole
当前目录结构
total 16 drwxr-xr-x 1 root root 112 Aug 3 18:18 . drwxr-xr-x 1 root root 74 Jul 25 12:58 .. -rw-r--r-- 1 root root 82 Aug 3 18:18 .env -rw-r--r-- 1 root root 217 Aug 3 18:18 Dockerfile drwxr-xr-x 1 root root 0 Aug 3 17:17 db -rw-r--r-- 1 root root 1048 Aug 3 18:18 docker-compose.yml -rw-r--r-- 1 root root 852 Aug 3 18:18 docker-compose.yml.bak
问题原因
- Dockerfile生成的
initdb.sql仅存在于镜像内部:Dockerfile中用RUN生成的initdb.sql是构建到guacamole-server镜像里的,并未输出到宿主机目录。 - 宿主机自动创建同名目录:由于宿主机当前目录无
initdb.sql文件,Docker挂载时会自动创建同名目录,导致挂载路径类型不匹配。 - 数据库启动命令执行无效路径:PostgreSQL容器的自定义命令试图读取目录路径的
/initdb.sql,触发报错退出,进而触发重启机制。
解决方案
方案一:提前生成initdb.sql到宿主机
- 执行命令生成初始化脚本到当前目录:
docker run --rm guacamole/guacamole /opt/guacamole/bin/initdb.sh --postgresql > initdb.sql
- 修改
docker-compose.yml中guacamole-server配置,移除build和./initdb.sql挂载(guacamole-server无需该文件):
guacamole-server: restart: always image: guacamole/guacamole ports: - "8080:8080" environment: - GUACD_HOSTNAME=guacd - POSTGRESQL_HOSTNAME=database - POSTGRESQL_DATABASE=${GUACAMOLE_DATABASE} - POSTGRESQL_USER=${GUACAMOLE_USER} - POSTGRESQL_PASSWORD=${GUACAMOLE_PASSWORD} depends_on: - guacd - database
- 重启服务:
docker-compose up -d
方案二:在数据库容器中直接生成并执行脚本
修改docker-compose.yml中database服务的command,无需提前生成文件:
command: > sh -c "docker run --rm --network container:database guacamole/guacamole /opt/guacamole/bin/initdb.sh --postgresql | psql -U ${GUACAMOLE_USER} ${GUACAMOLE_DATABASE} && tail -f /dev/null"
同时删除database和guacamole-server服务中关于./initdb.sql的挂载配置。
额外注意事项
- 确保
.env文件中的GUACAMOLE_DATABASE、GUACAMOLE_USER、GUACAMOLE_PASSWORD配置正确。 - 数据库首次初始化完成后,可移除自定义
command,恢复PostgreSQL默认启动逻辑,避免每次重启重复执行初始化。
内容的提问来源于stack exchange,提问作者Krzysztoff
相关产品推荐
相关产品推荐

