@aifabrix/builder 2.5.1 → 2.5.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,14 @@
1
+ {
2
+ "default": true,
3
+ "MD007": false,
4
+ "MD012": false,
5
+ "MD013": false,
6
+ "MD022": false,
7
+ "MD024": { "siblings_only": true },
8
+ "MD029": false,
9
+ "MD031": false,
10
+ "MD032": false,
11
+ "MD033": false,
12
+ "MD041": false
13
+ }
14
+
package/lib/infra.js CHANGED
@@ -107,24 +107,42 @@ async function ensureAdminSecrets() {
107
107
  return adminSecretsPath;
108
108
  }
109
109
 
110
+ /**
111
+ * Generates pgAdmin4 configuration files (servers.json and pgpass)
112
+ * @param {string} infraDir - Infrastructure directory path
113
+ * @param {string} postgresPassword - PostgreSQL password
114
+ */
115
+ function generatePgAdminConfig(infraDir, postgresPassword) {
116
+ const serversJsonTemplatePath = path.join(__dirname, '..', 'templates', 'infra', 'servers.json.hbs');
117
+ if (!fs.existsSync(serversJsonTemplatePath)) {
118
+ return;
119
+ }
120
+
121
+ const serversJsonTemplateContent = fs.readFileSync(serversJsonTemplatePath, 'utf8');
122
+ const serversJsonTemplate = handlebars.compile(serversJsonTemplateContent);
123
+ const serversJsonContent = serversJsonTemplate({ postgresPassword });
124
+ const serversJsonPath = path.join(infraDir, 'servers.json');
125
+ fs.writeFileSync(serversJsonPath, serversJsonContent, { mode: 0o644 });
126
+
127
+ const pgpassContent = `postgres:5432:postgres:pgadmin:${postgresPassword}\n`;
128
+ const pgpassPath = path.join(infraDir, 'pgpass');
129
+ fs.writeFileSync(pgpassPath, pgpassContent, { mode: 0o600 });
130
+ }
131
+
110
132
  async function startInfra(developerId = null) {
111
133
  await checkDockerAvailability();
112
134
  const adminSecretsPath = await ensureAdminSecrets();
113
135
 
114
- // Get developer ID from parameter or config
115
136
  const devId = developerId || await config.getDeveloperId();
116
- // Convert to number for getDevPorts (it expects numbers)
117
137
  const devIdNum = typeof devId === 'string' ? parseInt(devId, 10) : devId;
118
138
  const ports = devConfig.getDevPorts(devIdNum);
119
139
  const idNum = devIdNum;
120
140
 
121
- // Load compose template (Handlebars)
122
141
  const templatePath = path.join(__dirname, '..', 'templates', 'infra', 'compose.yaml.hbs');
123
142
  if (!fs.existsSync(templatePath)) {
124
143
  throw new Error(`Compose template not found: ${templatePath}`);
125
144
  }
126
145
 
127
- // Create infra directory in AIFABRIX_HOME with dev ID
128
146
  const aifabrixDir = paths.getAifabrixHome();
129
147
  const infraDirName = getInfraDirName(devId);
130
148
  const infraDir = path.join(aifabrixDir, infraDirName);
@@ -132,8 +150,11 @@ async function startInfra(developerId = null) {
132
150
  fs.mkdirSync(infraDir, { recursive: true });
133
151
  }
134
152
 
135
- // Generate compose file from template
136
- // Register helper right before compiling to ensure it's available
153
+ const adminSecretsContent = fs.readFileSync(adminSecretsPath, 'utf8');
154
+ const postgresPasswordMatch = adminSecretsContent.match(/^POSTGRES_PASSWORD=(.+)$/m);
155
+ const postgresPassword = postgresPasswordMatch ? postgresPasswordMatch[1] : '';
156
+ generatePgAdminConfig(infraDir, postgresPassword);
157
+
137
158
  handlebars.registerHelper('eq', (a, b) => {
138
159
  if (a === null || a === undefined) a = '0';
139
160
  if (b === null || b === undefined) b = '0';
@@ -146,19 +167,20 @@ async function startInfra(developerId = null) {
146
167
  });
147
168
  const templateContent = fs.readFileSync(templatePath, 'utf8');
148
169
  const template = handlebars.compile(templateContent);
149
- // Dev 0: infra-aifabrix-network, Dev > 0: infra-dev{id}-aifabrix-network
150
170
  const networkName = idNum === 0 ? 'infra-aifabrix-network' : `infra-dev${devId}-aifabrix-network`;
151
- // Pass string devId to preserve leading zeros (e.g., "01") in container names
152
- // The eq helper will handle numeric comparisons correctly
171
+ const serversJsonPath = path.join(infraDir, 'servers.json');
172
+ const pgpassPath = path.join(infraDir, 'pgpass');
153
173
  const composeContent = template({
154
174
  devId: devId,
155
175
  postgresPort: ports.postgres,
156
176
  redisPort: ports.redis,
157
177
  pgadminPort: ports.pgadmin,
158
178
  redisCommanderPort: ports.redisCommander,
159
- networkName: networkName
179
+ networkName: networkName,
180
+ serversJsonPath: serversJsonPath,
181
+ pgpassPath: pgpassPath,
182
+ infraDir: infraDir
160
183
  });
161
-
162
184
  const composePath = path.join(infraDir, 'compose.yaml');
163
185
  fs.writeFileSync(composePath, composeContent);
164
186
 
@@ -170,6 +192,22 @@ async function startInfra(developerId = null) {
170
192
  await execAsyncWithCwd(`${composeCmd} -f "${composePath}" -p ${projectName} --env-file "${adminSecretsPath}" up -d`, { cwd: infraDir });
171
193
  logger.log('Infrastructure services started successfully');
172
194
 
195
+ // Copy pgAdmin4 config files into container after it starts
196
+ const pgadminContainerName = idNum === 0 ? 'aifabrix-pgadmin' : `aifabrix-dev${devId}-pgadmin`;
197
+ try {
198
+ await new Promise(resolve => setTimeout(resolve, 2000)); // Wait for container to be ready
199
+ if (fs.existsSync(serversJsonPath)) {
200
+ await execAsync(`docker cp "${serversJsonPath}" ${pgadminContainerName}:/pgadmin4/servers.json`);
201
+ }
202
+ if (fs.existsSync(pgpassPath)) {
203
+ await execAsync(`docker cp "${pgpassPath}" ${pgadminContainerName}:/pgpass`);
204
+ await execAsync(`docker exec ${pgadminContainerName} chmod 600 /pgpass`);
205
+ }
206
+ } catch (error) {
207
+ // Ignore copy errors - files might already be there or container not ready
208
+ logger.log('Note: Could not copy pgAdmin4 config files (this is OK if container was just restarted)');
209
+ }
210
+
173
211
  await waitForServices(devId);
174
212
  logger.log('All services are healthy and ready');
175
213
  } finally {
@@ -431,64 +469,25 @@ async function getAppStatus() {
431
469
  const apps = [];
432
470
 
433
471
  try {
434
- // Find all containers with pattern
435
- // Dev 0: aifabrix-* (but exclude infrastructure containers)
436
- // Dev > 0: aifabrix-dev{id}-*
437
472
  const filterPattern = devId === 0 ? 'aifabrix-' : `aifabrix-dev${devId}-`;
438
473
  const { stdout } = await execAsync(`docker ps --filter "name=${filterPattern}" --format "{{.Names}}\t{{.Ports}}\t{{.Status}}"`);
439
474
  const lines = stdout.trim().split('\n').filter(line => line.trim() !== '');
440
-
441
- // Infrastructure container names to exclude
442
- // Dev 0: aifabrix-{serviceName}, Dev > 0: aifabrix-dev{id}-{serviceName}
443
475
  const infraContainers = devId === 0
444
- ? [
445
- 'aifabrix-postgres',
446
- 'aifabrix-redis',
447
- 'aifabrix-pgadmin',
448
- 'aifabrix-redis-commander'
449
- ]
450
- : [
451
- `aifabrix-dev${devId}-postgres`,
452
- `aifabrix-dev${devId}-redis`,
453
- `aifabrix-dev${devId}-pgadmin`,
454
- `aifabrix-dev${devId}-redis-commander`
455
- ];
456
-
476
+ ? ['aifabrix-postgres', 'aifabrix-redis', 'aifabrix-pgadmin', 'aifabrix-redis-commander']
477
+ : [`aifabrix-dev${devId}-postgres`, `aifabrix-dev${devId}-redis`, `aifabrix-dev${devId}-pgadmin`, `aifabrix-dev${devId}-redis-commander`];
457
478
  for (const line of lines) {
458
479
  const [containerName, ports, status] = line.split('\t');
459
-
460
- // Skip infrastructure containers
461
- if (infraContainers.includes(containerName)) {
462
- continue;
463
- }
464
-
465
- // Extract app name from container name
466
- // Dev 0: aifabrix-{appName}, Dev > 0: aifabrix-dev{id}-{appName}
467
- const pattern = devId === 0
468
- ? /^aifabrix-(.+)$/
469
- : new RegExp(`^aifabrix-dev${devId}-(.+)$`);
480
+ if (infraContainers.includes(containerName)) continue;
481
+ const pattern = devId === 0 ? /^aifabrix-(.+)$/ : new RegExp(`^aifabrix-dev${devId}-(.+)$`);
470
482
  const appNameMatch = containerName.match(pattern);
471
- if (!appNameMatch) {
472
- continue;
473
- }
474
-
483
+ if (!appNameMatch) continue;
475
484
  const appName = appNameMatch[1];
476
-
477
- // Extract host port from ports string (e.g., "0.0.0.0:3100->3000/tcp")
478
485
  const portMatch = ports.match(/:(\d+)->\d+\//);
479
486
  const hostPort = portMatch ? portMatch[1] : 'unknown';
480
487
  const url = hostPort !== 'unknown' ? `http://localhost:${hostPort}` : 'unknown';
481
-
482
- apps.push({
483
- name: appName,
484
- container: containerName,
485
- port: ports,
486
- status: status.trim(),
487
- url: url
488
- });
488
+ apps.push({ name: appName, container: containerName, port: ports, status: status.trim(), url: url });
489
489
  }
490
490
  } catch (error) {
491
- // If no containers found, return empty array
492
491
  return [];
493
492
  }
494
493
 
package/lib/secrets.js CHANGED
@@ -379,7 +379,7 @@ async function generateAdminSecretsEnv(secretsPath) {
379
379
  POSTGRES_PASSWORD=${postgresPassword}
380
380
  PGADMIN_DEFAULT_EMAIL=admin@aifabrix.ai
381
381
  PGADMIN_DEFAULT_PASSWORD=${postgresPassword}
382
- REDIS_HOST=local:redis:6379
382
+ REDIS_HOST=local:redis:6379:0:
383
383
  REDIS_COMMANDER_USER=admin
384
384
  REDIS_COMMANDER_PASSWORD=${postgresPassword}
385
385
  `;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aifabrix/builder",
3
- "version": "2.5.1",
3
+ "version": "2.5.3",
4
4
  "description": "AI Fabrix Local Fabric & Deployment SDK",
5
5
  "main": "lib/index.js",
6
6
  "bin": {
@@ -13,7 +13,7 @@ services:
13
13
  POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
14
14
  POSTGRES_INITDB_ARGS: "--encoding=UTF-8 --lc-collate=C --lc-ctype=C"
15
15
  ports:
16
- - "5432:5432"
16
+ - "127.0.0.1:5432:5432"
17
17
  volumes:
18
18
  - postgres_data:/var/lib/postgresql/data
19
19
  - ./init-scripts:/docker-entrypoint-initdb.d
@@ -32,7 +32,7 @@ services:
32
32
  container_name: aifabrix-redis
33
33
  command: ["redis-server", "--appendonly", "yes"]
34
34
  ports:
35
- - "6379:6379"
35
+ - "127.0.0.1:6379:6379"
36
36
  volumes:
37
37
  - redis_data:/data
38
38
  networks:
@@ -53,7 +53,7 @@ services:
53
53
  PGADMIN_DEFAULT_PASSWORD: ${PGADMIN_DEFAULT_PASSWORD}
54
54
  PGADMIN_CONFIG_SERVER_MODE: 'False'
55
55
  ports:
56
- - "5050:80"
56
+ - "127.0.0.1:5050:80"
57
57
  volumes:
58
58
  - pgadmin_data:/var/lib/pgadmin
59
59
  restart: unless-stopped
@@ -73,7 +73,7 @@ services:
73
73
  HTTP_PASSWORD: ${REDIS_COMMANDER_PASSWORD}
74
74
  REDIS_PASSWORD: ""
75
75
  ports:
76
- - "8081:8081"
76
+ - "127.0.0.1:8081:8081"
77
77
  restart: unless-stopped
78
78
  depends_on:
79
79
  redis:
@@ -53,10 +53,24 @@ services:
53
53
  PGADMIN_DEFAULT_EMAIL: ${PGADMIN_DEFAULT_EMAIL}
54
54
  PGADMIN_DEFAULT_PASSWORD: ${PGADMIN_DEFAULT_PASSWORD}
55
55
  PGADMIN_CONFIG_SERVER_MODE: 'False'
56
+ PGADMIN_SERVER_JSON_FILE: /pgadmin4/servers.json
57
+ PGPASSFILE: /pgpass
56
58
  ports:
57
59
  - "{{pgadminPort}}:80"
58
60
  volumes:
59
61
  - {{#if (eq devId 0)}}pgadmin_data{{else}}dev{{devId}}_pgadmin_data{{/if}}:/var/lib/pgadmin
62
+ - {{infraDir}}:/host-config:ro
63
+ command: >
64
+ sh -c "
65
+ if [ -f /host-config/servers.json ]; then
66
+ cp /host-config/servers.json /pgadmin4/servers.json;
67
+ fi &&
68
+ if [ -f /host-config/pgpass ]; then
69
+ cp /host-config/pgpass /pgpass;
70
+ chmod 600 /pgpass;
71
+ fi &&
72
+ /entrypoint.sh
73
+ "
60
74
  restart: unless-stopped
61
75
  depends_on:
62
76
  postgres:
@@ -0,0 +1,21 @@
1
+ {
2
+ "Servers": {
3
+ "1": {
4
+ "Name": "PostgreSQL (pgvector)",
5
+ "Group": "Servers",
6
+ "Host": "postgres",
7
+ "Port": 5432,
8
+ "MaintenanceDB": "postgres",
9
+ "Username": "pgadmin",
10
+ "PassFile": "/pgpass",
11
+ "SSLMode": "prefer",
12
+ "Comment": "Auto-registered PostgreSQL server with pgvector extension"
13
+ }
14
+ }
15
+ }
16
+
17
+
18
+
19
+
20
+
21
+
@@ -34,6 +34,7 @@ services:
34
34
  db-init:
35
35
  image: pgvector/pgvector:pg15
36
36
  container_name: {{containerName}}-db-init
37
+ entrypoint: []
37
38
  env_file:
38
39
  - ${ADMIN_SECRETS_PATH}
39
40
  - {{envFile}}
@@ -51,10 +52,15 @@ services:
51
52
  {{/if}}
52
53
  networks:
53
54
  - {{networkName}}
54
- command: >
55
- sh -c "
55
+ volumes: []
56
+ tmpfs:
57
+ - /var/lib/postgresql/data
58
+ command:
59
+ - sh
60
+ - -c
61
+ - |
56
62
  export PGHOST=postgres PGPORT=5432 PGUSER=pgadmin &&
57
- export PGPASSWORD=\"${POSTGRES_PASSWORD}\" &&
63
+ export PGPASSWORD="${POSTGRES_PASSWORD}" &&
58
64
  echo 'Waiting for PostgreSQL to be ready...' &&
59
65
  counter=0 &&
60
66
  while [ ${counter:-0} -lt 30 ]; do
@@ -69,32 +75,41 @@ services:
69
75
  {{#if databases}}
70
76
  {{#each databases}}
71
77
  echo 'Creating {{name}} database and user...' &&
72
- if psql -d postgres -tAc \"SELECT 1 FROM pg_database WHERE datname = '{{name}}'\" 2>/dev/null | grep -q '^1$'; then
73
- echo 'Database \\\"{{name}}\\\" already exists, all ok.'
78
+ if psql -d postgres -tAc "SELECT 1 FROM pg_database WHERE datname = '{{name}}'" 2>/dev/null | grep -q '^1$'; then
79
+ echo 'Database "{{name}}" already exists, all ok.'
74
80
  else
75
- (psql -d postgres -c \"CREATE DATABASE \\\"{{name}}\\\";\" || true) &&
76
- (psql -d postgres -c \"DROP USER IF EXISTS \\\"{{pgUserOld name}}\\\";\" || true) &&
77
- (psql -d postgres -c \"CREATE USER {{pgUser name}} WITH PASSWORD '${DB_{{@index}}_PASSWORD}';\" || true) &&
78
- psql -d postgres -c \"GRANT ALL PRIVILEGES ON DATABASE \\\"{{name}}\\\" TO {{pgUser name}};\" || true &&
79
- psql -d {{name}} -c \"ALTER SCHEMA public OWNER TO {{pgUser name}};\" || true &&
80
- psql -d {{name}} -c \"GRANT ALL ON SCHEMA public TO {{pgUser name}};\" || true
81
+ echo 'Creating database "{{name}}"...' &&
82
+ psql -d postgres -c "CREATE DATABASE \"{{name}}\";" &&
83
+ echo 'Dropping old user if exists...' &&
84
+ psql -d postgres -c "DROP USER IF EXISTS \"{{pgUserOld name}}\";" || true &&
85
+ echo 'Creating user "{{pgUserName name}}"...' &&
86
+ psql -d postgres -c 'CREATE USER "{{pgUserName name}}" WITH PASSWORD '\''${DB_{{@index}}_PASSWORD}'\'';' &&
87
+ echo 'Granting privileges...' &&
88
+ psql -d postgres -c "GRANT ALL PRIVILEGES ON DATABASE \"{{name}}\" TO \"{{pgUserName name}}\";" &&
89
+ psql -d {{name}} -c "ALTER SCHEMA public OWNER TO \"{{pgUserName name}}\";" &&
90
+ psql -d {{name}} -c "GRANT ALL ON SCHEMA public TO \"{{pgUserName name}}\";" &&
91
+ echo 'Database "{{name}}" created successfully!'
81
92
  fi &&
82
93
  {{/each}}
83
94
  {{else}}
84
95
  echo 'Creating {{app.key}} database and user...' &&
85
- if psql -d postgres -tAc \"SELECT 1 FROM pg_database WHERE datname = '{{app.key}}'\" 2>/dev/null | grep -q '^1$'; then
86
- echo 'Database \\\"{{app.key}}\\\" already exists, all ok.'
96
+ if psql -d postgres -tAc "SELECT 1 FROM pg_database WHERE datname = '{{app.key}}'" 2>/dev/null | grep -q '^1$'; then
97
+ echo 'Database "{{app.key}}" already exists, all ok.'
87
98
  else
88
- (psql -d postgres -c \"CREATE DATABASE \\\"{{app.key}}\\\";\" || true) &&
89
- (psql -d postgres -c \"DROP USER IF EXISTS \\\"{{pgUserOld app.key}}\\\";\" || true) &&
90
- (psql -d postgres -c \"CREATE USER {{pgUser app.key}} WITH PASSWORD '${DB_0_PASSWORD:-${DB_PASSWORD}}';\" || true) &&
91
- psql -d postgres -c \"GRANT ALL PRIVILEGES ON DATABASE \\\"{{app.key}}\\\" TO {{pgUser app.key}};\" || true &&
92
- psql -d {{app.key}} -c \"ALTER SCHEMA public OWNER TO {{pgUser app.key}};\" || true &&
93
- psql -d {{app.key}} -c \"GRANT ALL ON SCHEMA public TO {{pgUser app.key}};\" || true
99
+ echo 'Creating database "{{app.key}}"...' &&
100
+ psql -d postgres -c "CREATE DATABASE \"{{app.key}}\";" &&
101
+ echo 'Dropping old user if exists...' &&
102
+ psql -d postgres -c "DROP USER IF EXISTS \"{{pgUserOld app.key}}\";" || true &&
103
+ echo 'Creating user "{{pgUserName app.key}}"...' &&
104
+ psql -d postgres -c 'CREATE USER "{{pgUserName app.key}}" WITH PASSWORD '\''${DB_0_PASSWORD:-${DB_PASSWORD}}'\'';' &&
105
+ echo 'Granting privileges...' &&
106
+ psql -d postgres -c "GRANT ALL PRIVILEGES ON DATABASE \"{{app.key}}\" TO \"{{pgUserName app.key}}\";" &&
107
+ psql -d {{app.key}} -c "ALTER SCHEMA public OWNER TO \"{{pgUserName app.key}}\";" &&
108
+ psql -d {{app.key}} -c "GRANT ALL ON SCHEMA public TO \"{{pgUserName app.key}}\";" &&
109
+ echo 'Database "{{app.key}}" created successfully!'
94
110
  fi &&
95
111
  {{/if}}
96
112
  echo 'Database initialization complete!'
97
- "
98
113
  restart: "no"
99
114
  {{/if}}
100
115
 
@@ -34,6 +34,7 @@ services:
34
34
  db-init:
35
35
  image: pgvector/pgvector:pg15
36
36
  container_name: {{containerName}}-db-init
37
+ entrypoint: []
37
38
  env_file:
38
39
  - ${ADMIN_SECRETS_PATH}
39
40
  - {{envFile}}
@@ -51,10 +52,15 @@ services:
51
52
  {{/if}}
52
53
  networks:
53
54
  - {{networkName}}
54
- command: >
55
- sh -c "
55
+ volumes: []
56
+ tmpfs:
57
+ - /var/lib/postgresql/data
58
+ command:
59
+ - sh
60
+ - -c
61
+ - |
56
62
  export PGHOST=postgres PGPORT=5432 PGUSER=pgadmin &&
57
- export PGPASSWORD=\"${POSTGRES_PASSWORD}\" &&
63
+ export PGPASSWORD="${POSTGRES_PASSWORD}" &&
58
64
  echo 'Waiting for PostgreSQL to be ready...' &&
59
65
  counter=0 &&
60
66
  while [ ${counter:-0} -lt 30 ]; do
@@ -69,32 +75,41 @@ services:
69
75
  {{#if databases}}
70
76
  {{#each databases}}
71
77
  echo 'Creating {{name}} database and user...' &&
72
- if psql -d postgres -tAc \"SELECT 1 FROM pg_database WHERE datname = '{{name}}'\" 2>/dev/null | grep -q '^1$'; then
73
- echo 'Database \\\"{{name}}\\\" already exists, all ok.'
78
+ if psql -d postgres -tAc "SELECT 1 FROM pg_database WHERE datname = '{{name}}'" 2>/dev/null | grep -q '^1$'; then
79
+ echo 'Database "{{name}}" already exists, all ok.'
74
80
  else
75
- (psql -d postgres -c \"CREATE DATABASE \\\"{{name}}\\\";\" || true) &&
76
- (psql -d postgres -c \"DROP USER IF EXISTS \\\"{{pgUserOld name}}\\\";\" || true) &&
77
- (psql -d postgres -c \"CREATE USER {{pgUser name}} WITH PASSWORD '${DB_{{@index}}_PASSWORD}';\" || true) &&
78
- psql -d postgres -c \"GRANT ALL PRIVILEGES ON DATABASE \\\"{{name}}\\\" TO {{pgUser name}};\" || true &&
79
- psql -d {{name}} -c \"ALTER SCHEMA public OWNER TO {{pgUser name}};\" || true &&
80
- psql -d {{name}} -c \"GRANT ALL ON SCHEMA public TO {{pgUser name}};\" || true
81
+ echo 'Creating database "{{name}}"...' &&
82
+ psql -d postgres -c "CREATE DATABASE \"{{name}}\";" &&
83
+ echo 'Dropping old user if exists...' &&
84
+ psql -d postgres -c "DROP USER IF EXISTS \"{{pgUserOld name}}\";" || true &&
85
+ echo 'Creating user "{{pgUserName name}}"...' &&
86
+ psql -d postgres -c 'CREATE USER "{{pgUserName name}}" WITH PASSWORD '\''${DB_{{@index}}_PASSWORD}'\'';' &&
87
+ echo 'Granting privileges...' &&
88
+ psql -d postgres -c "GRANT ALL PRIVILEGES ON DATABASE \"{{name}}\" TO \"{{pgUserName name}}\";" &&
89
+ psql -d {{name}} -c "ALTER SCHEMA public OWNER TO \"{{pgUserName name}}\";" &&
90
+ psql -d {{name}} -c "GRANT ALL ON SCHEMA public TO \"{{pgUserName name}}\";" &&
91
+ echo 'Database "{{name}}" created successfully!'
81
92
  fi &&
82
93
  {{/each}}
83
94
  {{else}}
84
95
  echo 'Creating {{app.key}} database and user...' &&
85
- if psql -d postgres -tAc \"SELECT 1 FROM pg_database WHERE datname = '{{app.key}}'\" 2>/dev/null | grep -q '^1$'; then
86
- echo 'Database \\\"{{app.key}}\\\" already exists, all ok.'
96
+ if psql -d postgres -tAc "SELECT 1 FROM pg_database WHERE datname = '{{app.key}}'" 2>/dev/null | grep -q '^1$'; then
97
+ echo 'Database "{{app.key}}" already exists, all ok.'
87
98
  else
88
- (psql -d postgres -c \"CREATE DATABASE \\\"{{app.key}}\\\";\" || true) &&
89
- (psql -d postgres -c \"DROP USER IF EXISTS \\\"{{pgUserOld app.key}}\\\";\" || true) &&
90
- (psql -d postgres -c \"CREATE USER {{pgUser app.key}} WITH PASSWORD '${DB_0_PASSWORD:-${DB_PASSWORD}}';\" || true) &&
91
- psql -d postgres -c \"GRANT ALL PRIVILEGES ON DATABASE \\\"{{app.key}}\\\" TO {{pgUser app.key}};\" || true &&
92
- psql -d {{app.key}} -c \"ALTER SCHEMA public OWNER TO {{pgUser app.key}};\" || true &&
93
- psql -d {{app.key}} -c \"GRANT ALL ON SCHEMA public TO {{pgUser app.key}};\" || true
99
+ echo 'Creating database "{{app.key}}"...' &&
100
+ psql -d postgres -c "CREATE DATABASE \"{{app.key}}\";" &&
101
+ echo 'Dropping old user if exists...' &&
102
+ psql -d postgres -c "DROP USER IF EXISTS \"{{pgUserOld app.key}}\";" || true &&
103
+ echo 'Creating user "{{pgUserName app.key}}"...' &&
104
+ psql -d postgres -c 'CREATE USER "{{pgUserName app.key}}" WITH PASSWORD '\''${DB_0_PASSWORD:-${DB_PASSWORD}}'\'';' &&
105
+ echo 'Granting privileges...' &&
106
+ psql -d postgres -c "GRANT ALL PRIVILEGES ON DATABASE \"{{app.key}}\" TO \"{{pgUserName app.key}}\";" &&
107
+ psql -d {{app.key}} -c "ALTER SCHEMA public OWNER TO \"{{pgUserName app.key}}\";" &&
108
+ psql -d {{app.key}} -c "GRANT ALL ON SCHEMA public TO \"{{pgUserName app.key}}\";" &&
109
+ echo 'Database "{{app.key}}" created successfully!'
94
110
  fi &&
95
111
  {{/if}}
96
112
  echo 'Database initialization complete!'
97
- "
98
113
  restart: "no"
99
114
  {{/if}}
100
115