首先,我喜欢让开发人员选择他们想要设置环境的方式,尤其是数据库。有些人喜欢直接启动 postgres 服务器,有些人喜欢启动 docker-compose 或简单地启动 docker。
现在假设您无论如何都想设置所有内容。您有多种选择:
启动数据库
使用泊坞窗
如果你想从 docker 初始化所有东西,你可以添加一个入口点来创建数据库。在其中创建一个文件夹init_script 和一个文件:
./init_scripts/init_db.sh
#!/bin/bash
set -e
set -u
function create_user_and_database() {
local database=$1
echo "Creating database '$database' with user '$POSTGRES_USER'"
psql -v ON_ERROR_STOP=1 \
--username "$POSTGRES_USER" \
--dbname=postgres <<-EOSQL
CREATE DATABASE $database;
EOSQL
}
if [ -n "$POSTGRES_MY_DB" ]; then
create_user_and_database $POSTGRES_MY_DB
echo "Database $POSTGRES_MY_DB created"
fi
灵感来自this script,它可以创建多个 postgres 数据库。然后您可以简单地添加其他脚本来创建表。
现在你可以启动 docker 了
docker start my_postgres_container || docker run \
--name my_postgres_container \
--volume "$PWD/init_scripts:/docker-entrypoint-initdb.d/" \
--env POSTGRES_USER=my_user \
--env POSTGRES_PASSWORD=my_password \
--env POSTGRES_MY_DB=my_database \
--publish 5432:5432 \
--rm \
postgres:13
一个卷被挂载到文件夹init_scripts/docker-entrypoint-initdb.d/,docker 将查看它以初始化数据库。
这个脚本可以从 npm 或 yarn 执行:
"scripts": {
"setup_db": "docker start ...."
}
与某些数据库相反,您 cannot 启动内存中的 postgres。
实例化数据库(postgres 已经在运行)
来自 nodejs 脚本
独立于 postgres 系统,您可以使用脚本从主连接创建新数据库。
function createDatabase() {
const client = new Client(masterPostgresUri);
const user = 'my_user';
const database = 'my_database';
await client.connect();
try {
await client.query(`CREATE USER ${user};`);
await client.query(`CREATE DATABASE ${database};`);
await client.query(`GRANT ALL PRIVILEGES ON DATABASE ${database} TO ${user};`);
} catch (_err) {
// The database might already exist, you may want to check before
}
client.end();
}
要创建表,您可以使用相同的脚本但改用新的数据库连接 uri。
这个脚本也可以在设置中启动。
来自迁移工具
有多种工具可以处理设置和迁移。如果您使用例如 ORM Sequelize,那么在迁移脚本中设置所有内容可能是一个不错的选择。 Sequelize migrations
对我来说,没有完美的解决方案,即使你创建了一个命令来启动一个正确配置的 docker,有人可能会说它没有安装 docker,所以你仍然有依赖。因此,我认为让开发人员选择启动 postgres 的最佳解决方案是很棒的。关于表的创建和迁移,我认为一个工具是合适的,因为这是你必须在生产环境中处理的问题,它会在应用程序重启期间处理它。