-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathstart-database.sh
More file actions
executable file
·139 lines (119 loc) · 4.19 KB
/
start-database.sh
File metadata and controls
executable file
·139 lines (119 loc) · 4.19 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#!/usr/bin/env bash
# Use this script to start a docker container for a local development database
# TO RUN ON WINDOWS:
# 1. Install WSL (Windows Subsystem for Linux) - https://learn.microsoft.com/en-us/windows/wsl/install
# 2. Install Docker Desktop or Podman Deskop
# - Docker Desktop for Windows - https://docs.docker.com/docker-for-windows/install/
# - Podman Desktop - https://podman.io/getting-started/installation
# 3. Open WSL - `wsl`
# 4. Run this script - `./start-database.sh`
# On Linux and macOS you can run this script directly - `./start-database.sh`
set -euo pipefail
error() {
echo "Error: $*" >&2
}
if [ ! -f .env ]; then
error ".env was not found. Create it first with: cp .env.example .env"
exit 1
fi
# import env variables from .env
set -a
# shellcheck disable=SC1091
source .env
set +a
if [ -z "${DATABASE_URL:-}" ]; then
error "DATABASE_URL is missing from .env"
exit 1
fi
if [[ ! "$DATABASE_URL" =~ ^postgres(ql)?://([^:/@]+)(:([^@]*))?@([^:/?#]+)(:([0-9]+))?/([^?]+) ]]; then
error "DATABASE_URL must look like postgresql://user:password@host:port/database"
exit 1
fi
DB_PASSWORD="${BASH_REMATCH[4]:-}"
DB_PORT="${BASH_REMATCH[7]:-5432}"
DB_NAME="${BASH_REMATCH[8]}"
DB_CONTAINER_NAME="$DB_NAME-postgres"
if [ -z "$DB_PASSWORD" ]; then
error "DATABASE_URL must include a database password"
exit 1
fi
if [[ ! "$DB_PORT" =~ ^[0-9]+$ ]]; then
error "DATABASE_URL contains an invalid port: $DB_PORT"
exit 1
fi
if ! [ -x "$(command -v docker)" ] && ! [ -x "$(command -v podman)" ]; then
error "Docker or Podman is not installed.
Docker install guide: https://docs.docker.com/engine/install/
Podman install guide: https://podman.io/getting-started/installation"
exit 1
fi
# determine which docker command to use
if [ -x "$(command -v docker)" ]; then
DOCKER_CMD="docker"
elif [ -x "$(command -v podman)" ]; then
DOCKER_CMD="podman"
fi
if ! $DOCKER_CMD info > /dev/null 2>&1; then
error "$DOCKER_CMD daemon is not running. Start it and try again."
exit 1
fi
if [ "$($DOCKER_CMD ps -q -f "name=^/${DB_CONTAINER_NAME}$")" ]; then
echo "Database container '$DB_CONTAINER_NAME' is already running on port $DB_PORT."
exit 0
fi
if [ "$($DOCKER_CMD ps -q -a -f "name=^/${DB_CONTAINER_NAME}$")" ]; then
$DOCKER_CMD start "$DB_CONTAINER_NAME" >/dev/null
echo "Existing database container '$DB_CONTAINER_NAME' started on port $DB_PORT."
exit 0
fi
if [ "$DB_PORT" -lt 1 ] || [ "$DB_PORT" -gt 65535 ]; then
error "DATABASE_URL contains an out-of-range port: $DB_PORT"
exit 1
fi
if command -v nc >/dev/null 2>&1; then
if nc -z localhost "$DB_PORT" 2>/dev/null; then
error "Port $DB_PORT is already in use. Update DATABASE_URL in .env or stop the process using that port."
exit 1
fi
else
echo "Warning: Unable to check if port $DB_PORT is already in use (netcat not installed)"
read -p "Do you want to continue anyway? [y/N]: " -r REPLY
if ! [[ $REPLY =~ ^[Yy]$ ]]; then
echo "Aborting."
exit 1
fi
fi
if [ "$DB_PASSWORD" = "password" ]; then
echo "You are using the default database password"
read -p "Should we generate a random password for you? [y/N]: " -r REPLY
if ! [[ $REPLY =~ ^[Yy]$ ]]; then
echo "Please change the default password in the .env file and try again"
exit 1
fi
# Generate a random URL-safe password
if ! command -v openssl >/dev/null 2>&1; then
error "openssl is required to generate a random password. Install openssl or change DATABASE_URL manually."
exit 1
fi
DB_PASSWORD=$(openssl rand -base64 12 | tr '+/' '-_')
if [[ "$(uname)" == "Darwin" ]]; then
# macOS requires an empty string to be passed with the `i` flag
sed -i '' "s#:password@#:$DB_PASSWORD@#" .env
else
sed -i "s#:password@#:$DB_PASSWORD@#" .env
fi
fi
if container_id="$($DOCKER_CMD run -d \
--name "$DB_CONTAINER_NAME" \
-e POSTGRES_USER="postgres" \
-e POSTGRES_PASSWORD="$DB_PASSWORD" \
-e POSTGRES_DB="$DB_NAME" \
-p "$DB_PORT":5432 \
docker.io/postgres:17)"; then
echo "Database container '$DB_CONTAINER_NAME' was successfully created on port $DB_PORT."
echo "Container id: $container_id"
else
error "Failed to create database container '$DB_CONTAINER_NAME'."
echo "Try: $DOCKER_CMD logs $DB_CONTAINER_NAME" >&2
exit 1
fi