@aifabrix/builder 2.1.7 → 2.3.0

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.
Files changed (43) hide show
  1. package/lib/app-deploy.js +73 -29
  2. package/lib/app-list.js +132 -0
  3. package/lib/app-readme.js +11 -4
  4. package/lib/app-register.js +435 -0
  5. package/lib/app-rotate-secret.js +164 -0
  6. package/lib/app-run.js +98 -84
  7. package/lib/app.js +13 -0
  8. package/lib/audit-logger.js +195 -15
  9. package/lib/build.js +155 -42
  10. package/lib/cli.js +104 -8
  11. package/lib/commands/app.js +8 -391
  12. package/lib/commands/login.js +130 -36
  13. package/lib/commands/secure.js +260 -0
  14. package/lib/config.js +315 -4
  15. package/lib/deployer.js +221 -183
  16. package/lib/infra.js +177 -112
  17. package/lib/push.js +34 -7
  18. package/lib/secrets.js +89 -23
  19. package/lib/templates.js +1 -1
  20. package/lib/utils/api-error-handler.js +465 -0
  21. package/lib/utils/api.js +165 -16
  22. package/lib/utils/auth-headers.js +84 -0
  23. package/lib/utils/build-copy.js +162 -0
  24. package/lib/utils/cli-utils.js +49 -3
  25. package/lib/utils/compose-generator.js +57 -16
  26. package/lib/utils/deployment-errors.js +90 -0
  27. package/lib/utils/deployment-validation.js +60 -0
  28. package/lib/utils/dev-config.js +83 -0
  29. package/lib/utils/docker-build.js +24 -0
  30. package/lib/utils/env-template.js +30 -10
  31. package/lib/utils/health-check.js +18 -1
  32. package/lib/utils/infra-containers.js +101 -0
  33. package/lib/utils/local-secrets.js +0 -2
  34. package/lib/utils/secrets-encryption.js +203 -0
  35. package/lib/utils/secrets-path.js +22 -3
  36. package/lib/utils/token-manager.js +381 -0
  37. package/package.json +2 -2
  38. package/templates/applications/README.md.hbs +155 -23
  39. package/templates/applications/miso-controller/Dockerfile +7 -119
  40. package/templates/infra/compose.yaml.hbs +93 -0
  41. package/templates/python/docker-compose.hbs +25 -17
  42. package/templates/typescript/docker-compose.hbs +25 -17
  43. package/test-output.txt +0 -5431
@@ -2,56 +2,193 @@
2
2
 
3
3
  Build, run, and deploy {{displayName}} using `@aifabrix/builder`.
4
4
 
5
- ## Install
5
+ ---
6
+
7
+ ## Quick Start
8
+
9
+ ### 1. Install
6
10
 
7
11
  ```bash
8
12
  npm install -g @aifabrix/builder
9
13
  ```
10
14
 
11
- ## Build
15
+ ### 2. First Time Setup
12
16
 
13
17
  ```bash
14
- aifabrix build {{appName}}
15
- ```
18
+ # Check your environment
19
+ aifabrix doctor
16
20
 
17
- Builds Docker image: `{{imageName}}:latest`
21
+ # Login to controller
22
+ aifabrix login --method device --environment dev
18
23
 
19
- ## Run Locally
24
+ # Register your application (gets you credentials automatically)
25
+ aifabrix app register {{appName}} --environment dev
26
+ ```
27
+
28
+ ### 3. Build & Run Locally
20
29
 
21
30
  ```bash
31
+ # Build the Docker image
32
+ aifabrix build {{appName}}
33
+
34
+ # Generate environment variables
35
+ aifabrix resolve {{appName}}
36
+
37
+ # Run locally
22
38
  aifabrix run {{appName}}
23
39
  ```
24
40
 
25
- **Access:** http://localhost:{{port}}
41
+ **Access your app:** http://localhost:{{port}}
26
42
 
27
- **Logs:**
43
+ **View logs:**
28
44
  ```bash
29
- docker logs {{appName}} -f
45
+ docker logs aifabrix-{{appName}} -f
30
46
  ```
31
47
 
32
48
  **Stop:**
33
49
  ```bash
34
- docker stop {{appName}}
50
+ docker stop aifabrix-{{appName}}
35
51
  ```
36
52
 
37
- ## Push to Azure Container Registry
53
+ ### 4. Deploy to Azure
38
54
 
39
55
  ```bash
40
- aifabrix push {{appName}} --registry {{registry}} --tag latest
56
+ # Build with version tag
57
+ aifabrix build {{appName}} --tag v1.0.0
58
+
59
+ # Push to registry
60
+ aifabrix push {{appName}} --registry {{registry}} --tag "v1.0.0,latest"
61
+
62
+ # Deploy to miso-controller
63
+ aifabrix deploy {{appName}} --controller https://controller.aifabrix.ai --environment dev
41
64
  ```
42
65
 
43
- **Note:** ACR push requires `az login` or ACR credentials in `variables.yaml`
66
+ ---
67
+
68
+ ## Using miso-client
69
+
70
+ > [miso-client](https://github.com/esystemsdev/aifabrix-miso-client)
71
+
72
+ After registering your app, you automatically get credentials in your secret file. Use miso-client for login, RBAC, audit logs, etc.
73
+
74
+ **Rotate credentials if needed:**
75
+ ```bash
76
+ aifabrix app rotate-secret {{appName}} --environment dev
77
+ ```
78
+
79
+ ---
80
+
81
+ ## Reference
82
+
83
+ ### Common Commands
84
+
85
+ ```bash
86
+ # Development
87
+ aifabrix build {{appName}} # Build app
88
+ aifabrix run {{appName}} # Run locally
89
+ aifabrix dockerfile {{appName}} --force # Generate Dockerfile
90
+ aifabrix resolve {{appName}} # Generate .env file
91
+
92
+ # Deployment
93
+ aifabrix json {{appName}} # Preview deployment JSON
94
+ aifabrix genkey {{appName}} # Generate deployment key
95
+ aifabrix push {{appName}} --registry {{registry}} # Push to ACR
96
+ aifabrix deploy {{appName}} --controller <url> # Deploy to Azure
97
+
98
+ # Management
99
+ aifabrix app register {{appName}} --environment dev
100
+ aifabrix app list --environment dev
101
+ aifabrix app rotate-secret {{appName}} --environment dev
102
+
103
+ # Utilities
104
+ aifabrix doctor # Check environment
105
+ aifabrix login --method device --environment dev # Login
106
+ aifabrix --help # Get help
107
+ ```
108
+
109
+ ### Build Options
110
+
111
+ ```bash
112
+ aifabrix build {{appName}} --tag v1.0.0 # Custom tag
113
+ aifabrix build {{appName}} --force-template # Force template regeneration
114
+ aifabrix build {{appName}} --language typescript # Override language detection
115
+ ```
116
+
117
+ ### Run Options
118
+
119
+ ```bash
120
+ aifabrix run {{appName}} --port {{port}} # Custom port
121
+ aifabrix run {{appName}} --debug # Debug output
122
+ ```
123
+
124
+ ### Push Options
125
+
126
+ ```bash
127
+ aifabrix push {{appName}} --registry {{registry}} --tag v1.0.0
128
+ aifabrix push {{appName}} --registry {{registry}} --tag "v1.0.0,latest,stable"
129
+ ```
130
+
131
+ ### Deploy Options
132
+
133
+ ```bash
134
+ aifabrix deploy {{appName}} --controller <url> --environment dev
135
+ aifabrix deploy {{appName}} --controller <url> --environment dev --no-poll
136
+ ```
137
+
138
+ ### Login Methods
139
+
140
+ ```bash
141
+ # Device code flow
142
+ aifabrix login --method device --environment dev
143
+
144
+ # Credentials (reads from secrets.local.yaml)
145
+ aifabrix login --method credentials --app {{appName}} --environment dev
146
+
147
+ # Explicit credentials
148
+ aifabrix login --method credentials --app {{appName}} --client-id $CLIENT_ID --client-secret $CLIENT_SECRET --environment dev
149
+ ```
150
+
151
+ ### Environment Variables
152
+
153
+ ```bash
154
+ export AIFABRIX_HOME=/custom/path
155
+ export AIFABRIX_SECRETS=/path/to/secrets.yaml
156
+ ```
157
+
158
+ ---
159
+
160
+ ## Troubleshooting
161
+
162
+ - **"Docker not running"** → Start Docker Desktop
163
+ - **"Not logged in"** → Run `aifabrix login` first
164
+ - **"Port already in use"** → Use `--port` flag or change `build.localPort` in `variables.yaml` (default: {{port}})
165
+ - **"Authentication failed"** → Run `aifabrix login` again
166
+ - **"Build fails"** → Check Docker is running and `variables.yaml` → `build.secrets` path is correct
167
+ - **"Can't connect"** → Verify infrastructure is running{{#if hasDatabase}} and PostgreSQL is accessible{{/if}}
168
+
169
+ **Regenerate files:**
170
+ ```bash
171
+ aifabrix resolve {{appName}} --force
172
+ aifabrix json {{appName}}
173
+ aifabrix genkey {{appName}}
174
+ ```
175
+
176
+ ---
44
177
 
45
178
  ## Prerequisites
46
179
 
47
180
  - `@aifabrix/builder` installed globally
48
181
  - Docker Desktop running
49
- - Infrastructure running (`aifabrix up`)
182
+ - Azure CLI installed (for push command)
183
+ - Authenticated with controller (for deploy command)
184
+ {{#unless hasAnyService}}
185
+ - Infrastructure running
186
+ {{/unless}}
50
187
  {{#if hasDatabase}}
51
- - PostgreSQL database
188
+ - PostgreSQL database (ensure infrastructure is running)
52
189
  {{/if}}
53
190
  {{#if hasRedis}}
54
- - Redis
191
+ - Redis (ensure infrastructure is running)
55
192
  {{/if}}
56
193
  {{#if hasStorage}}
57
194
  - File storage configured
@@ -60,11 +197,6 @@ aifabrix push {{appName}} --registry {{registry}} --tag latest
60
197
  - Authentication/RBAC configured
61
198
  {{/if}}
62
199
 
63
- ## Troubleshooting
64
-
65
- **Build fails:** Check Docker is running and `variables.yaml` → `build.secrets` path is correct
66
-
67
- **Can't connect:** Verify infrastructure is running (`aifabrix up`){{#if hasDatabase}} and PostgreSQL is accessible{{/if}}
68
-
69
- **Port in use:** Change `build.localPort` in `variables.yaml` (default: {{port}})
200
+ ---
70
201
 
202
+ **Application**: {{appName}} | **Port**: {{port}} | **Registry**: {{registry}} | **Image**: {{imageName}}:latest
@@ -1,115 +1,5 @@
1
- # AI Fabrix Miso Controller - Optimized Dockerfile
2
- FROM node:18-alpine
3
-
4
- # Install only essential runtime dependencies
5
- RUN apk add --no-cache \
6
- curl \
7
- wget \
8
- openssl \
9
- openssl-dev
10
-
11
- # Install PNPM globally
12
- RUN npm install -g pnpm
13
-
14
- # Install tsconfig-paths globally for path resolution
15
- RUN npm install -g tsconfig-paths
16
-
17
- # Set working directory
18
- WORKDIR /app
19
-
20
- # Copy package files for dependency resolution
21
- COPY package*.json ./
22
- COPY pnpm-workspace.yaml ./
23
- COPY packages/miso-azure/package*.json ./packages/miso-azure/
24
- COPY packages/miso-controller/package*.json ./packages/miso-controller/
25
- COPY packages/miso-controller/bin ./packages/miso-controller/bin
26
- COPY packages/miso-ui/package*.json ./packages/miso-ui/
27
-
28
- # Create .npmrc for hoisting to fix module resolution in Docker
29
- RUN echo "shamefully-hoist=true" > .npmrc
30
-
31
- # Install all dependencies (including dev for building)
32
- RUN pnpm install
33
-
34
- # Copy only the source code we need
35
- COPY packages/miso-azure/src ./packages/miso-azure/src
36
- COPY packages/miso-azure/tsconfig.json ./packages/miso-azure/
37
- COPY packages/miso-controller/src ./packages/miso-controller/src
38
- COPY packages/miso-controller/tsconfig.json ./packages/miso-controller/
39
- COPY packages/miso-controller/tsconfig.docker.json ./packages/miso-controller/
40
- COPY packages/miso-controller/openapi/openapi-complete.yaml ./packages/miso-controller/dist/openapi/
41
- COPY packages/miso-controller/openapi/openapi-complete.json ./packages/miso-controller/dist/openapi/
42
- COPY packages/miso-ui/src ./packages/miso-ui/src
43
- COPY packages/miso-ui/tsconfig.json ./packages/miso-ui/
44
- COPY packages/miso-ui/tsconfig.app.json ./packages/miso-ui/
45
- COPY packages/miso-ui/tsconfig.node.json ./packages/miso-ui/
46
- COPY packages/miso-ui/vite.config.ts ./packages/miso-ui/
47
- COPY packages/miso-ui/index.html ./packages/miso-ui/
48
-
49
- # Fix Rollup native module issue for Alpine Linux
50
- RUN pnpm add @rollup/rollup-linux-x64-musl @types/express-serve-static-core --workspace-root
51
-
52
- # Build packages
53
- WORKDIR /app/packages/miso-azure
54
- RUN pnpm run build
55
-
56
- WORKDIR /app/packages/miso-ui
57
- RUN pnpm run build
58
-
59
- WORKDIR /app/packages/miso-controller
60
- RUN pnpm run db:generate
61
- RUN pnpm exec tsc -p tsconfig.docker.json || true
62
- # Copy sensitive-fields.config.json to dist folder
63
- RUN mkdir -p dist/src/services/logging && \
64
- cp src/services/logging/sensitive-fields.config.json dist/src/services/logging/ || true
65
- # Copy generated Prisma logs client to dist folder (needed at runtime)
66
- RUN mkdir -p dist/database/generated && \
67
- cp -r src/database/generated/logs-client dist/database/generated/ || true
68
-
69
- # Return to root to prune correctly (needed to keep workspace dependencies)
70
- WORKDIR /app
71
-
72
- # Remove source files and build artifacts, but preserve Prisma schema files and OpenAPI files
73
- RUN mkdir -p packages/miso-controller/dist/database/prisma && \
74
- cp packages/miso-controller/src/database/prisma/*.prisma packages/miso-controller/dist/database/prisma/ || true
75
- RUN rm -rf packages/miso-azure/src packages/miso-controller/src packages/miso-ui/src
76
- RUN rm -rf packages/miso-azure/tsconfig.json packages/miso-ui/tsconfig.json
77
- RUN rm -rf packages/*/node_modules packages/*/.git packages/*/.github
78
-
79
- # Reinstall to recreate symlinks after removing source files
80
- # This ensures workspace dependencies are properly linked
81
- RUN pnpm install --frozen-lockfile --filter "@aifabrix/miso-controller..." || pnpm install --frozen-lockfile
82
-
83
- # Manually remove known dev dependencies
84
- RUN rm -rf node_modules/markdownlint node_modules/markdownlint-cli node_modules/prettier
85
- RUN rm -rf .pnpm/markdownlint* .pnpm/prettier*
86
-
87
- # Create non-root user
88
- RUN addgroup -g 1001 -S nodejs && \
89
- adduser -S miso -u 1001
90
-
91
- # Create necessary directories for mount points (with fallback to local storage)
92
- RUN mkdir -p /mnt/data/logs /mnt/data/data /mnt/data/backup /mnt/data/config
93
- RUN mkdir -p /app/data/logs /app/data/data /app/data/backup /app/data/config
94
-
95
- # Change ownership of app directory and mount points
96
- RUN chown -R miso:nodejs /app /mnt/data
97
-
98
- # Switch to non-root user
99
- USER miso
100
-
101
- # Set working directory to controller
102
- WORKDIR /app/packages/miso-controller
103
-
104
- # Expose port
105
- EXPOSE 3000
106
-
107
- # Health check
108
- HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \
109
- CMD wget --no-verbose --tries=1 --spider http://localhost:3000/health || exit 1
110
-
111
- # Set environment variable for tsconfig-paths
112
- ENV TS_NODE_PROJECT=tsconfig.docker.json
1
+ # AI Fabrix Miso Controller - Build from base image
2
+ FROM aifabrix/miso-controller:latest
113
3
 
114
4
  # Set default data paths (can be overridden by environment variables)
115
5
  ENV LOG_PATH=/mnt/data/logs
@@ -117,12 +7,10 @@ ENV DATA_PATH=/mnt/data/data
117
7
  ENV BACKUP_PATH=/mnt/data/backup
118
8
  ENV CONFIG_PATH=/mnt/data/config
119
9
 
120
- # Create symlinks for fallback to local storage if mounts are not provided
121
- RUN ln -sf /app/data/logs /mnt/data/logs || true
122
- RUN ln -sf /app/data/data /mnt/data/data || true
123
- RUN ln -sf /app/data/backup /mnt/data/backup || true
124
- RUN ln -sf /app/data/config /mnt/data/config || true
10
+ # Expose port
11
+ EXPOSE 3000
125
12
 
126
- # Start the application
127
- CMD ["node", "-r", "tsconfig-paths/register", "dist/src/server.js"]
13
+ # Health check
14
+ HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \
15
+ CMD wget --no-verbose --tries=1 --spider http://localhost:3000/health || exit 1
128
16
 
@@ -0,0 +1,93 @@
1
+ # AI Fabrix Infrastructure Stack
2
+ # Shared infrastructure services only
3
+ # Generated by AI Fabrix Builder SDK
4
+ # Developer ID: {{devId}}
5
+
6
+ services:
7
+ # PostgreSQL Database with pgvector extension
8
+ postgres:
9
+ image: pgvector/pgvector:pg15
10
+ container_name: {{#if (eq devId 0)}}aifabrix-postgres{{else}}aifabrix-dev{{devId}}-postgres{{/if}}
11
+ environment:
12
+ POSTGRES_DB: postgres
13
+ POSTGRES_USER: pgadmin
14
+ POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
15
+ POSTGRES_INITDB_ARGS: "--encoding=UTF-8 --lc-collate=C --lc-ctype=C"
16
+ ports:
17
+ - "{{postgresPort}}:5432"
18
+ volumes:
19
+ - dev{{devId}}_postgres_data:/var/lib/postgresql/data
20
+ - ./init-scripts:/docker-entrypoint-initdb.d
21
+ networks:
22
+ - {{networkName}}
23
+ healthcheck:
24
+ test: ["CMD-SHELL", "pg_isready -U pgadmin -d postgres"]
25
+ interval: 10s
26
+ timeout: 5s
27
+ retries: 5
28
+ restart: unless-stopped
29
+
30
+ # Redis Cache
31
+ redis:
32
+ image: redis:7-alpine
33
+ container_name: {{#if (eq devId 0)}}aifabrix-redis{{else}}aifabrix-dev{{devId}}-redis{{/if}}
34
+ command: ["redis-server", "--appendonly", "yes"]
35
+ ports:
36
+ - "{{redisPort}}:6379"
37
+ volumes:
38
+ - dev{{devId}}_redis_data:/data
39
+ networks:
40
+ - {{networkName}}
41
+ healthcheck:
42
+ test: ["CMD", "redis-cli", "ping"]
43
+ interval: 10s
44
+ timeout: 5s
45
+ retries: 5
46
+ restart: unless-stopped
47
+
48
+ # Optional: pgAdmin for database management
49
+ pgadmin:
50
+ image: dpage/pgadmin4:latest
51
+ container_name: {{#if (eq devId 0)}}aifabrix-pgadmin{{else}}aifabrix-dev{{devId}}-pgadmin{{/if}}
52
+ environment:
53
+ PGADMIN_DEFAULT_EMAIL: ${PGADMIN_DEFAULT_EMAIL}
54
+ PGADMIN_DEFAULT_PASSWORD: ${PGADMIN_DEFAULT_PASSWORD}
55
+ PGADMIN_CONFIG_SERVER_MODE: 'False'
56
+ ports:
57
+ - "{{pgadminPort}}:80"
58
+ restart: unless-stopped
59
+ depends_on:
60
+ postgres:
61
+ condition: service_healthy
62
+ networks:
63
+ - {{networkName}}
64
+
65
+ # Optional: Redis Commander for Redis management
66
+ redis-commander:
67
+ image: rediscommander/redis-commander:latest
68
+ container_name: {{#if (eq devId 0)}}aifabrix-redis-commander{{else}}aifabrix-dev{{devId}}-redis-commander{{/if}}
69
+ environment:
70
+ REDIS_HOSTS: ${REDIS_HOST}
71
+ HTTP_USER: ${REDIS_COMMANDER_USER}
72
+ HTTP_PASSWORD: ${REDIS_COMMANDER_PASSWORD}
73
+ REDIS_PASSWORD: ""
74
+ ports:
75
+ - "{{redisCommanderPort}}:8081"
76
+ restart: unless-stopped
77
+ depends_on:
78
+ redis:
79
+ condition: service_healthy
80
+ networks:
81
+ - {{networkName}}
82
+
83
+ volumes:
84
+ dev{{devId}}_postgres_data:
85
+ driver: local
86
+ dev{{devId}}_redis_data:
87
+ driver: local
88
+
89
+ networks:
90
+ {{networkName}}:
91
+ driver: bridge
92
+ name: {{networkName}}
93
+
@@ -5,13 +5,13 @@
5
5
  services:
6
6
  {{app.key}}:
7
7
  image: {{image.name}}:{{image.tag}}
8
- container_name: aifabrix-{{app.key}}
8
+ container_name: {{containerName}}
9
9
  env_file:
10
10
  - {{envFile}}
11
11
  ports:
12
12
  - "{{hostPort}}:{{containerPort}}"
13
13
  networks:
14
- - infra_aifabrix-network
14
+ - {{networkName}}
15
15
  {{#if requiresStorage}}
16
16
  volumes:
17
17
  - "{{mountVolume}}:/mnt/data"
@@ -33,7 +33,7 @@ services:
33
33
  # Database Initialization
34
34
  db-init:
35
35
  image: pgvector/pgvector:pg15
36
- container_name: aifabrix-{{app.key}}-db-init
36
+ container_name: {{containerName}}-db-init
37
37
  env_file:
38
38
  - ${ADMIN_SECRETS_PATH}
39
39
  - {{envFile}}
@@ -50,7 +50,7 @@ services:
50
50
  DB_PASSWORD: {{lookup databasePasswords.array 0}}
51
51
  {{/if}}
52
52
  networks:
53
- - infra_aifabrix-network
53
+ - {{networkName}}
54
54
  command: >
55
55
  sh -c "
56
56
  export PGHOST=postgres PGPORT=5432 PGUSER=pgadmin &&
@@ -69,21 +69,29 @@ services:
69
69
  {{#if databases}}
70
70
  {{#each databases}}
71
71
  echo 'Creating {{name}} database and user...' &&
72
- (psql -d postgres -c \"CREATE DATABASE \\\"{{name}}\\\";\" || true) &&
73
- (psql -d postgres -c \"DROP USER IF EXISTS {{pgUserOld name}};\" || true) &&
74
- (psql -d postgres -c \"CREATE USER {{pgUser name}} WITH PASSWORD '${DB_{{@index}}_PASSWORD}';\" || true) &&
75
- psql -d postgres -c \"GRANT ALL PRIVILEGES ON DATABASE \\\"{{name}}\\\" TO {{pgUser name}};\" || true &&
76
- psql -d {{name}} -c \"ALTER SCHEMA public OWNER TO {{pgUser name}};\" || true &&
77
- psql -d {{name}} -c \"GRANT ALL ON SCHEMA public TO {{pgUser name}};\" || true &&
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.'
74
+ 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
+ fi &&
78
82
  {{/each}}
79
83
  {{else}}
80
84
  echo 'Creating {{app.key}} database and user...' &&
81
- (psql -d postgres -c \"CREATE DATABASE \\\"{{app.key}}\\\";\" || true) &&
82
- (psql -d postgres -c \"DROP USER IF EXISTS {{pgUserOld app.key}};\" || true) &&
83
- (psql -d postgres -c \"CREATE USER {{pgUser app.key}} WITH PASSWORD '${DB_0_PASSWORD:-${DB_PASSWORD}}';\" || true) &&
84
- psql -d postgres -c \"GRANT ALL PRIVILEGES ON DATABASE \\\"{{app.key}}\\\" TO {{pgUser app.key}};\" || true &&
85
- psql -d {{app.key}} -c \"ALTER SCHEMA public OWNER TO {{pgUser app.key}};\" || true &&
86
- psql -d {{app.key}} -c \"GRANT ALL ON SCHEMA public TO {{pgUser app.key}};\" || true &&
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.'
87
+ 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
94
+ fi &&
87
95
  {{/if}}
88
96
  echo 'Database initialization complete!'
89
97
  "
@@ -91,5 +99,5 @@ services:
91
99
  {{/if}}
92
100
 
93
101
  networks:
94
- infra_aifabrix-network:
102
+ {{networkName}}:
95
103
  external: true
@@ -5,13 +5,13 @@
5
5
  services:
6
6
  {{app.key}}:
7
7
  image: {{image.name}}:{{image.tag}}
8
- container_name: aifabrix-{{app.key}}
8
+ container_name: {{containerName}}
9
9
  env_file:
10
10
  - {{envFile}}
11
11
  ports:
12
12
  - "{{hostPort}}:{{containerPort}}"
13
13
  networks:
14
- - infra_aifabrix-network
14
+ - {{networkName}}
15
15
  {{#if requiresStorage}}
16
16
  volumes:
17
17
  - "{{mountVolume}}:/mnt/data"
@@ -33,7 +33,7 @@ services:
33
33
  # Database Initialization
34
34
  db-init:
35
35
  image: pgvector/pgvector:pg15
36
- container_name: aifabrix-{{app.key}}-db-init
36
+ container_name: {{containerName}}-db-init
37
37
  env_file:
38
38
  - ${ADMIN_SECRETS_PATH}
39
39
  - {{envFile}}
@@ -50,7 +50,7 @@ services:
50
50
  DB_PASSWORD: {{lookup databasePasswords.array 0}}
51
51
  {{/if}}
52
52
  networks:
53
- - infra_aifabrix-network
53
+ - {{networkName}}
54
54
  command: >
55
55
  sh -c "
56
56
  export PGHOST=postgres PGPORT=5432 PGUSER=pgadmin &&
@@ -69,21 +69,29 @@ services:
69
69
  {{#if databases}}
70
70
  {{#each databases}}
71
71
  echo 'Creating {{name}} database and user...' &&
72
- (psql -d postgres -c \"CREATE DATABASE \\\"{{name}}\\\";\" || true) &&
73
- (psql -d postgres -c \"DROP USER IF EXISTS {{pgUserOld name}};\" || true) &&
74
- (psql -d postgres -c \"CREATE USER {{pgUser name}} WITH PASSWORD '${DB_{{@index}}_PASSWORD}';\" || true) &&
75
- psql -d postgres -c \"GRANT ALL PRIVILEGES ON DATABASE \\\"{{name}}\\\" TO {{pgUser name}};\" || true &&
76
- psql -d {{name}} -c \"ALTER SCHEMA public OWNER TO {{pgUser name}};\" || true &&
77
- psql -d {{name}} -c \"GRANT ALL ON SCHEMA public TO {{pgUser name}};\" || true &&
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.'
74
+ 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
+ fi &&
78
82
  {{/each}}
79
83
  {{else}}
80
84
  echo 'Creating {{app.key}} database and user...' &&
81
- (psql -d postgres -c \"CREATE DATABASE \\\"{{app.key}}\\\";\" || true) &&
82
- (psql -d postgres -c \"DROP USER IF EXISTS {{pgUserOld app.key}};\" || true) &&
83
- (psql -d postgres -c \"CREATE USER {{pgUser app.key}} WITH PASSWORD '${DB_0_PASSWORD:-${DB_PASSWORD}}';\" || true) &&
84
- psql -d postgres -c \"GRANT ALL PRIVILEGES ON DATABASE \\\"{{app.key}}\\\" TO {{pgUser app.key}};\" || true &&
85
- psql -d {{app.key}} -c \"ALTER SCHEMA public OWNER TO {{pgUser app.key}};\" || true &&
86
- psql -d {{app.key}} -c \"GRANT ALL ON SCHEMA public TO {{pgUser app.key}};\" || true &&
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.'
87
+ 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
94
+ fi &&
87
95
  {{/if}}
88
96
  echo 'Database initialization complete!'
89
97
  "
@@ -91,5 +99,5 @@ services:
91
99
  {{/if}}
92
100
 
93
101
  networks:
94
- infra_aifabrix-network:
102
+ {{networkName}}:
95
103
  external: true