不少开发者在开始一个新项目的时候,一般会使用 JSON,CSV 或者其余 Flat File 来模拟真实存放在数据库中的数据。这是由于他们老是在没有真实的数据库环境限制和是否须要本身建立模拟数据库之间左右为难。既然这样,为何不使用 Docker Compose 定义一个能够在几秒钟内建立、销毁和从新建立的 PostgreSQL 数据库和监视工具?html
正确建立配置两个容器的 Docker 命令过于冗长。而使用 Docker Compose,你只须要记住 up
命令和 down
命令!前端
Up
命令将建立指定版本的 PostgreSQL 数据库和一个 GUI 管理工具。Down
命令会将其关闭并删除。android
下面所展现的这份 docker-compose.yml
文件定义了一个运行特定版本 PostgreSQL 和 pgAdmin 4(Postgres 最经常使用的管理工具)的 PostgreSQL 容器。该文件的内容值得咱们详细的探讨。ios
version: "3.8"
services:
postgres:
image: postgres:9.6.12-alpine
container_name: some-postgres
volumes:
- "~/Documents/docker_pgsql_init:/docker-entrypoint-initdb.d"
- "~/Documents/docker_pgsql_volume:/var/lib/postgresql/data"
ports:
- 5432:5432
environment:
- POSTGRES_PASSWORD=mysecret
deploy:
restart_policy:
condition: on-failure
max_attempts: 3
pgadmin:
image: dpage/pgadmin4
container_name: some-pgadmin
volumes:
- ${PWD}/servers.json:/pgadmin4/servers.json
ports:
- 8080:80
environment:
- PGADMIN_DEFAULT_EMAIL=user@domain.com
- PGADMIN_DEFAULT_PASSWORD=admin
deploy:
restart_policy:
condition: on-failure
max_attempts: 3
复制代码
该文件定义了两个要建立的“服务”:Postgres 和 pgAdmin。每一个服务都包含一个从 Docker Hub 拉取的容器。Postgres 和 pgAdmin 将分别开放 5432 端口和 8080 端口。将你写的任何程序指向主机名“localhost”,而后用浏览器访问 http://localhost:8080 便可访问 pgAdmin。git
继续阅读有关如何将 pgAdmin 指向 Postgres 的说明。程序员
在定义 Postgres 容器的这一行中,你须要准确指定所需的 Postgres 版本。在这里,版本是一个标签,而 9.6.12-alpine
就是示例中使用的版本。点击这里查看其余可用的版本。github
上面的 docker-compose.yml
文件为 Postgres 指定了两个 volume 映射。这两个映射将使 Postgres 能够访问你计算机上的目录。web
/docker-entrypoint-initdb.d
的文件夹包含了初始化 Postgres 将会用到的 SQL 文件。将所需的 SQL 文件和 Shell 脚本放在该目录中,它们将会按字母顺序自动执行。/var/lib/postgresql/data
的文件夹存放了数据库持久化存储所须要的实际文件。当 Postgres 启动时,他的简单运行流程以下图所示。若是数据库中没有数据,那么它将执行被映射到 /docker-entrypoint-initdb.d
目录中的每一个 SQL 文件和 Shell 脚本(按字母顺序)。若是被映射到 /var/lib/postgresql/data
目录的文件夹中有数据,那么它将会忽略掉这些文件。sql
你是否须要挂载这两个目录?这个得视状况而定。下表描述了经过 Postgres 的两个不一样映射获得的一个预期结果。docker
个人建议是对这两个文件目录都作映射。若是你不想再初始化你的数据库,你能够从 init 目录中删除文件。你也能够在你的计算机上删除任何可能已经持久化的数据(当你下一次运行 docker-compose up
命令时,Docker 将会在其位置从新建立一个空文件夹)。
专业提示:你能够将 CSV 文件放在计算机的 init 文件夹中,而后在 init 目录中经过适当的 SQL 命令将 CSV 文件中的数据填充到数据表中。
CREATE TABLE Employee(id, first_name, last_name, salary);
COPY Employee FROM '/docker-entrypoint-initdb.d/emp.csv'
WITH (FORMAT CSV, HEADER);
复制代码
尽管 pgAdmin 只是一个用于查看和配置数据库的工具,但必须配置其与数据库的链接。这能够经过可视化工具中的 add server
指令完成。这里须要注意的是,主机名(the hostname)是咱们在 YML 文件中配置的 container_name
这一参数的名称,即 some-postgres
。一样地,密码也已经在 YML 文件中指定了,即 mysecret
。
另外一种方法是经过在 JSON 文件中指定这些配置(除了密码以外的全部配置),经过这种方式能够免去大量的单击和输入操做。为了不手动配置 pgAdmin 到 Postgres 的链接,咱们须要将该 JSON 文件映射到容器 /pgadmin4/servers.json
上(在示例 YML 文件中的第 22 行)。
设置文件能够指定 pgAdmin 和 Postgres 之间的多个链接(以不一样用户的身份链接或者链接到多个不一样的数据库)。下面是只有一个数据库链接的示例。
{
"Servers": {
"1": {
"Name": "my-postgres",
"Group": "Servers",
"Port": 5432,
"Username": "postgres",
"Host": "some-postgres",
"SSLMode": "prefer",
"MaintenanceDB": "postgres"
}
}
}
复制代码
container_name
参数仅仅只表示一个名字。可是 pgAdmin 将使用这个名称访问 5432 端口上的数据库。缘由以下图所示。这两个容器经过私有网络相互链接,所以能够经过它们的主机名(容器名)也就是 some-postgres
和 some-pgadmin
相互访问。然而,你的主机(也就是你的计算机和 web 浏览器)只能访问容器对外暴露的 5432 端口和 8080 端口,所以你能够经过 localhost:5432
和 localhost:8080
访问它们。
内部网络的名称能够在 compose 文件中指定,可是为一个从未被代码引用的网络命名没有任何价值!若是你仍是好奇,能够随时查看你的私人及临时网络的名称。在下面的代码片断中,我从桌面运行了 Docker Compose,所以将该网络命名为 desktop_default
。
$ docker network ls
NETWORK ID NAME DRIVER SCOPE
23a6be9b8021 bridge bridge local
49a120440f88 desktop_default bridge local
44a949b56fa7 host host local
3892b16dca2d none null local
复制代码
在这里,我必须认可我在前言中过于简化了命令操做,但只是稍微简化了一点。
为了启动容器,可使用 docker-compose up -d
。-d
参数指定这是一个 detached
模式,它将会在后台运行,而且不会影响你在命令提示符中执行其余命令。
$ docker-compose up -d
Creating network "desktop_default" with the default driver
Creating some-postgres ... done
Creating some-pgadmin ... done
$
复制代码
为了关闭并删除容器,你可使用 docker-compose down -v
。-v
参数表示删除容器在运行时使用的 volume。这个不会删除计算机映射到容器上的目录。
$ docker-compose down -v
Stopping some-pgadmin ... done
Stopping some-postgres ... done
Removing some-pgadmin ... done
Removing some-postgres ... done
Removing network desktop_default
复制代码
随着时间的推移,若是不使用 -v
标志,就会累积没必要要的 volume。你可使用 docker volume ls
来验证这一点。
若是要调试一个没有正确启动的容器,请使用 docker logs [container_name]
。例如,因为 init 目录中的一个 SQL 文件中出现错误,数据库可能没法正确初始化。经过执行 docker logs some-postgres
命令,能够生成容器启动时记录的日志,经过对该日志的查阅,我在一个特殊命名的 SQL 文件中发现一个错误:
/usr/local/bin/docker-entrypoint.sh: running /docker-entrypoint-initdb.d/broken.sql
ERROR: syntax error at end of input at character 34
STATEMENT: CREATE TABLE Songs(id, name, year
psql:/docker-entrypoint-initdb.d/broken.sql:1: ERROR: syntax error at end of input
LINE 1: CREATE TABLE Song(id, name, year
复制代码
日志告诉我在 broken.sql
文件的第 1 行有一个错误。该命令缺乏右括号和分号。我能够修复这个错误,并使用 down
和 up
来验证。
使用 localhost 做为 YML 文件中指定的主机名和密码,链接到数据库很容易。
import psycopg2
# connect to DB
conn = psycopg2.connect(host="localhost", dbname="postgres", user="postgres",
password="mysecret")
cursor = conn.cursor()
# execute SQL commands in SQL file
cursor.execute(open("emp.sql", "r").read())
# retrieve data from the database
cursor.execute("SELECT * FROM Employee")
print(cursor.fetchall())
复制代码
简单的访问 http://localhost:8080 便可进入登陆界面,使用你在 docker-compose.yml
文件中定义的用户名和密码登陆便可(在咱们的示例中是 user@domain.com
和 admin
)。
若是你使用的是本文以前讨论的 servers.json
文件来指定链接细节,你将会在展开用户界面左侧的导航树时,收到系统要求你输入 Postgres 数据库的密码的提示。在咱们示例的 docker-compose.yml
文件中,这个密码是 mysecret
。若是你并无建立 servers.json
文件或文件中有错误,你就必须手动添加服务器。
如今,你应该可以查看和操做数据库了。
有时候,开发者须要一个熟悉的命令行。Docker 使得访问 PSQL 和执行高级用户命令等操做变得更加容易。执行下面的命令进入 PSQL 命令行。
链接后,你就能够执行全部 PSQL 命令,例如,输入 \i
用于导入外部数据库,输入 \dt
显示数据表的描述,输入 \df
显示函数的描述。想要退出,可使用 \q
命令。
$ docker exec -it some-postgres psql -U postgres
psql (9.6.12)
Type "help" for help.
postgres=# \dt
List of relations
Schema | Name | Type | Owner
--------+--------------+-------+----------
public | peak | table | postgres
public | climb | table | postgres
public | climber | table | postgres
复制代码
pgAdmin 是 PostgreSQL 最多见的 GUI 管理工具,但咱们还有其余选择。Adminer 的使用更加简单,而且你可能已经拥有使用它的经验了,由于它支持多种风格的 SQL。若是你是刚开始使用 PostgreSQL 或者只有很是简单的需求,那么它多是一个更合适你的工具。
在登陆界面上,设置主机名为 some-postgres
,密码为 mysecret
。
要在你的环境中用 Adminer 替换 pgAdmin,你须要在 docker-compose.yml
中替换几行有关 pgAdmin 容器的定义。
adminer:
image: adminer
container_name: some-adminer
ports:
- 8080:8080
deploy:
restart_policy:
condition: on-failure
max_attempts: 3
复制代码
全部优秀的开发者都依赖于产品文档和其余人员的经验。这是我在建立工做流程和编写本文时引用的参考资料。
若是发现译文存在错误或其余须要改进的地方,欢迎到 掘金翻译计划 对译文进行修改并 PR,也可得到相应奖励积分。文章开头的 本文永久连接 即为本文在 GitHub 上的 MarkDown 连接。
掘金翻译计划 是一个翻译优质互联网技术文章的社区,文章来源为 掘金 上的英文分享文章。内容覆盖 Android、iOS、前端、后端、区块链、产品、设计、人工智能等领域,想要查看更多优质译文请持续关注 掘金翻译计划、官方微博、知乎专栏。