假设我在脚本中运行以下命令:
#!/usr/bin/env bash
docker run --name mydb --rm -e POSTGRES_PASSWORD=kgalli -e POSTGRES_USER=kgalli -p "9999:5432" -v $PWD/db:/opt -d postgres
然后我运行以下命令来创建数据库时,它运行正常。
docker exec -e PGPASSWORD=kgalli mydb psql -U kgalli -d template1 -c "CREATE DATABASE kgalli_test WITH OWNER kgalli ENCODING 'UTF8' LC_COLLATE = 'en_US.utf8' LC_CTYPE = 'en_US.utf8';"
但是,当我将此行添加到上面的脚本中时,该脚本不仅启动了postgres服务器,还创建了失败的数据库。
我不太明白为什么会出现以下错误:
psql: could not connect to server: No such file or directory
Is the server running locally and accepting
connections on Unix domain socket "/var/run/postgresql/.s.PGSQL.5432"?
我知道我可以指示docker postgres映像在启动时创建数据库。但这实际上不是我想要实现的。我只是以此为例来理解问题。
答案 0 :(得分:1)
使用docker run
,您将启动一个新容器,使用docker exec
,您将在已经运行的容器中执行命令
答案 1 :(得分:1)
在脚本中运行它时,很可能发生得太快。 docker run …
命令立即返回,然后docker exec …
在数据库服务器仍在启动时尝试使用PostgreSQL。创建额外的数据库之前,您需要等待它准备就绪。
也就是说,postgres image在其入口点脚本中具有运行自定义初始化脚本的功能。您可以将CREATE DATABASE …
语句放入.sql
文件或配置中,并将其装入容器中的/docker-entrypoint-initdb.d
中。数据库服务器就绪后,postgres容器将自动运行它。
有关此文档的文档似乎已经消失了,但是you can see the implementation in docker-entrypoint.sh。
答案 2 :(得分:0)
docker run
命令首先在指定的图像上creates
一个可写的容器层,然后使用指定的命令starts
将其复制。
docker exec
命令在正在运行的容器中运行新命令。
如果容器已暂停,则docker exec
命令将失败并显示错误
$ docker pause test
test
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1ae3b36715d2 ubuntu:latest "bash" 17 seconds ago Up 16 seconds (Paused) test
$ docker exec test ls
FATA[0000] Error response from daemon: Container test is paused, unpause the container before exec
$ echo $?
1