@panoptic-it-solutions/coolify-setup 1.1.19 → 1.1.21

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.
package/dist/index.js CHANGED
@@ -171,10 +171,35 @@ async function main() {
171
171
  console.log(chalk.yellow(' You may need to manually commit and push the generated files'));
172
172
  }
173
173
  console.log(chalk.bold.green('\n✅ Setup complete!\n'));
174
- console.log('Next steps:');
175
- console.log(chalk.cyan(' 1. Review the generated files'));
176
- console.log(chalk.cyan(' 2. Update .env with your secrets'));
177
- console.log(chalk.cyan(' 3. Configure Coolify to deploy from staging branch\n'));
174
+ console.log(chalk.bold('Coolify Setup Instructions:\n'));
175
+ console.log(chalk.cyan.bold('1. Create Staging Environment'));
176
+ console.log(' Server: panoptic-staging-server-1');
177
+ console.log(` • Name: ${response.projectName}:staging`);
178
+ console.log(' • Build Pack: Docker Compose');
179
+ console.log(' • Compose file: change /docker-compose.yaml → /docker-compose.yml');
180
+ console.log(' • Branch: staging');
181
+ console.log(` • Domain: https://${response.projectName}.staging.panoptic.tools\n`);
182
+ console.log(chalk.cyan.bold('2. Create Production Environment'));
183
+ console.log(' • Server: localhost');
184
+ console.log(` • Name: ${response.projectName}:prod`);
185
+ console.log(' • Build Pack: Docker Compose');
186
+ console.log(' • Compose file: change /docker-compose.yaml → /docker-compose.yml');
187
+ console.log(' • Branch: main');
188
+ console.log(` • Domain: https://${response.projectName}.panoptic.tools\n`);
189
+ console.log(chalk.cyan.bold('3. For Each Environment'));
190
+ console.log(' • Add environment variables in Coolify');
191
+ console.log(' • Generate domain (replace random string with app name)');
192
+ console.log(' • Deploy\n');
193
+ console.log(chalk.bold('Branching Strategy:\n'));
194
+ console.log(' develop → Default branch, main development');
195
+ console.log(' feature/** → New features');
196
+ console.log(' fix/** → Bug fixes');
197
+ console.log(' hotfix/** → Urgent fixes');
198
+ console.log(' staging → Staging deployment (auto-deploy on merge)');
199
+ console.log(' main → Production deployment (merge PR to deploy)\n');
200
+ console.log(chalk.bold('Deployment Flow:\n'));
201
+ console.log(' develop/feature/** → build → PR to staging → merge → staging deploys');
202
+ console.log(' → PR to main → merge → prod deploys\n');
178
203
  }
179
204
  main().catch((error) => {
180
205
  console.error(chalk.red('Error:'), error);
@@ -5,6 +5,83 @@ export function generateClaudeRules() {
5
5
 
6
6
  This project uses Coolify for deployment. Coolify has specific behaviors that require careful handling of Docker Compose configurations.
7
7
 
8
+ ## Branching Strategy
9
+
10
+ This project uses a trunk-based development workflow with deployment branches:
11
+
12
+ ### Branch Types
13
+
14
+ | Branch | Purpose | Deploys To |
15
+ |--------|---------|------------|
16
+ | \`develop\` | Default branch, main development | - |
17
+ | \`feature/**\` | New features (e.g., \`feature/user-auth\`) | - |
18
+ | \`fix/**\` | Bug fixes (e.g., \`fix/login-error\`) | - |
19
+ | \`hotfix/**\` | Urgent production fixes | - |
20
+ | \`staging\` | Staging environment deployment | Staging server |
21
+ | \`main\` | Production environment deployment | Production server |
22
+
23
+ ### Workflow
24
+
25
+ 1. **Development**: Create branches from \`develop\`
26
+ - Features: \`feature/feature-name\`
27
+ - Fixes: \`fix/bug-description\`
28
+ - Hotfixes: \`hotfix/urgent-fix\`
29
+
30
+ 2. **Build**: Push triggers GitHub Actions
31
+ - Builds Docker image
32
+ - Pushes to private registry
33
+ - Creates PR to \`staging\` branch
34
+
35
+ 3. **Staging Deployment**: Merge PR to \`staging\`
36
+ - Coolify auto-deploys to staging server
37
+ - GitHub Actions creates PR to \`main\`
38
+ - Test changes in staging environment
39
+
40
+ 4. **Production Deployment**: Merge PR to \`main\`
41
+ - Coolify auto-deploys to production server
42
+
43
+ ### Branch Protection Rules
44
+
45
+ - \`develop\` is the default branch
46
+ - Direct pushes to \`staging\` and \`main\` should be avoided
47
+ - All changes go through PRs for traceability
48
+
49
+ ## Coolify Setup Instructions
50
+
51
+ ### Creating Projects in Coolify
52
+
53
+ Create two projects using GitHub private repo integration:
54
+
55
+ #### Staging Environment
56
+ - **Server:** panoptic-staging-server-1
57
+ - **Name:** \`app-name:staging\`
58
+ - **Build Pack:** Docker Compose
59
+ - **Compose File:** Change from \`/docker-compose.yaml\` to \`/docker-compose.yml\`
60
+ - **Branch:** staging
61
+ - **Domain:** Generate, then replace random string with app name
62
+ - Example: \`https://app-name.staging.panoptic.tools\`
63
+
64
+ #### Production Environment
65
+ - **Server:** localhost
66
+ - **Name:** \`app-name:prod\`
67
+ - **Build Pack:** Docker Compose
68
+ - **Compose File:** Change from \`/docker-compose.yaml\` to \`/docker-compose.yml\`
69
+ - **Branch:** main
70
+ - **Domain:** Generate, then replace random string with app name
71
+ - Example: \`https://app-name.panoptic.tools\`
72
+
73
+ ### Configuration Steps
74
+
75
+ 1. Create new project in Coolify
76
+ 2. Select "GitHub Private Repository"
77
+ 3. Choose the repository
78
+ 4. Set build pack to "Docker Compose"
79
+ 5. Change compose file path from \`/docker-compose.yaml\` to \`/docker-compose.yml\`
80
+ 6. Continue to add environment variables
81
+ 7. In the GitSource tab, select the correct branch (staging/main)
82
+ 8. Generate domain and replace random string with app name
83
+ 9. Deploy
84
+
8
85
  ## Critical Coolify Behaviors
9
86
 
10
87
  ### 1. Helper Container Architecture
@@ -36,6 +36,9 @@ function generateNextjsDockerfile(options) {
36
36
  // postgres must be externalized due to pnpm's symlink structure causing resolution issues
37
37
  const migrationBundle = includePostgres ? `
38
38
 
39
+ # Create migrations folder if it doesn't exist (may be gitignored)
40
+ RUN mkdir -p ${dbPath}/migrations
41
+
39
42
  # Build the migration bundle (single JS file with all deps baked in)
40
43
  # This avoids module resolution issues in the standalone container
41
44
  # postgres is externalized and copied separately due to pnpm symlink resolution issues
@@ -2,17 +2,26 @@ export function generateEntrypoint(options) {
2
2
  const { projectType, includePostgres, dbPath } = options;
3
3
  // For Next.js standalone, we run the bundled JS file (no tsx needed)
4
4
  // For Node.js, we use tsx since full node_modules is available
5
+ // Check if migrations exist before running (folder may be empty if gitignored)
5
6
  const migrationStep = includePostgres
6
7
  ? projectType === 'nextjs'
7
8
  ? `
8
- # Run database migrations (bundled JS with all deps baked in)
9
- echo " Running database migrations..."
10
- node ${dbPath}/migrate.bundle.js
9
+ # Run database migrations if any exist (bundled JS with all deps baked in)
10
+ if [ -n "$(ls -A ${dbPath}/migrations 2>/dev/null)" ]; then
11
+ echo "⏳ Running database migrations..."
12
+ node ${dbPath}/migrate.bundle.js
13
+ else
14
+ echo "⏭️ No migrations found, skipping..."
15
+ fi
11
16
  `
12
17
  : `
13
- # Run database migrations
14
- echo " Running database migrations..."
15
- npx tsx scripts/migrate.ts
18
+ # Run database migrations if any exist
19
+ if [ -n "$(ls -A scripts/migrations 2>/dev/null)" ]; then
20
+ echo "⏳ Running database migrations..."
21
+ npx tsx scripts/migrate.ts
22
+ else
23
+ echo "⏭️ No migrations found, skipping..."
24
+ fi
16
25
  `
17
26
  : '';
18
27
  const startCmd = projectType === 'nextjs'
@@ -7,6 +7,7 @@ on:
7
7
  push:
8
8
  branches:
9
9
  - develop
10
+ - staging
10
11
  - 'feature/**'
11
12
  - 'fix/**'
12
13
  - 'hotfix/**'
@@ -50,28 +51,81 @@ jobs:
50
51
  echo "branch=staging" >> $GITHUB_OUTPUT
51
52
 
52
53
  - name: Create deploy PR
53
- env:
54
- GH_TOKEN: \${{ secrets.GITHUB_TOKEN }}
55
- run: |
56
- TARGET_BRANCH=\${{ steps.target.outputs.branch }}
57
- SOURCE_BRANCH=\${{ github.ref_name }}
58
-
59
- # Check if PR already exists
60
- EXISTING_PR=\$(gh pr list --head "\$SOURCE_BRANCH" --base "\$TARGET_BRANCH" --json number -q '.[0].number' || echo "")
61
-
62
- if [ -n "\$EXISTING_PR" ]; then
63
- echo "PR #\$EXISTING_PR already exists for \$SOURCE_BRANCH -> \$TARGET_BRANCH"
64
- else
65
- gh pr create \\
66
- --title "Deploy: \$SOURCE_BRANCH -> \$TARGET_BRANCH" \\
67
- --body "Automated deployment PR from \$SOURCE_BRANCH to \$TARGET_BRANCH.
68
-
69
- **Commit:** \${{ steps.sha.outputs.sha }}
70
- **Image:** \${{ env.REGISTRY }}/\${{ env.PROJECT_NAME }}-app:\${{ steps.sha.outputs.sha }}
71
-
72
- Merge this PR to trigger deployment." \\
73
- --base "\$TARGET_BRANCH" \\
74
- --head "\$SOURCE_BRANCH" || echo "PR creation skipped (may already exist or no changes)"
75
- fi
54
+ uses: actions/github-script@v7
55
+ with:
56
+ script: |
57
+ const targetBranch = '\${{ steps.target.outputs.branch }}';
58
+ const sourceBranch = '\${{ github.ref_name }}';
59
+
60
+ // Check if PR already exists
61
+ const { data: prs } = await github.rest.pulls.list({
62
+ owner: context.repo.owner,
63
+ repo: context.repo.repo,
64
+ head: \`\${context.repo.owner}:\${sourceBranch}\`,
65
+ base: targetBranch,
66
+ state: 'open'
67
+ });
68
+
69
+ if (prs.length > 0) {
70
+ console.log(\`PR #\${prs[0].number} already exists for \${sourceBranch} -> \${targetBranch}\`);
71
+ return;
72
+ }
73
+
74
+ try {
75
+ const { data: pr } = await github.rest.pulls.create({
76
+ owner: context.repo.owner,
77
+ repo: context.repo.repo,
78
+ title: \`Deploy: \${sourceBranch} -> \${targetBranch}\`,
79
+ body: \`Automated deployment PR from \${sourceBranch} to \${targetBranch}.
80
+
81
+ **Commit:** \${{ steps.sha.outputs.sha }}
82
+ **Image:** \${{ env.REGISTRY }}/\${{ env.PROJECT_NAME }}-app:\${{ steps.sha.outputs.sha }}
83
+
84
+ Merge this PR to trigger deployment.\`,
85
+ head: sourceBranch,
86
+ base: targetBranch
87
+ });
88
+ console.log(\`Created PR #\${pr.number}\`);
89
+ } catch (error) {
90
+ console.log(\`PR creation skipped: \${error.message}\`);
91
+ }
92
+
93
+ - name: Create production PR
94
+ if: github.ref == 'refs/heads/staging'
95
+ uses: actions/github-script@v7
96
+ with:
97
+ script: |
98
+ // Check if PR already exists
99
+ const { data: prs } = await github.rest.pulls.list({
100
+ owner: context.repo.owner,
101
+ repo: context.repo.repo,
102
+ head: \`\${context.repo.owner}:staging\`,
103
+ base: 'main',
104
+ state: 'open'
105
+ });
106
+
107
+ if (prs.length > 0) {
108
+ console.log(\`PR #\${prs[0].number} already exists for staging -> main\`);
109
+ return;
110
+ }
111
+
112
+ try {
113
+ const { data: pr } = await github.rest.pulls.create({
114
+ owner: context.repo.owner,
115
+ repo: context.repo.repo,
116
+ title: 'Deploy to Production: staging -> main',
117
+ body: \`Promote staging to production.
118
+
119
+ **Commit:** \${{ steps.sha.outputs.sha }}
120
+ **Image:** \${{ env.REGISTRY }}/\${{ env.PROJECT_NAME }}-app:\${{ steps.sha.outputs.sha }}
121
+
122
+ Merge this PR to deploy to production.\`,
123
+ head: 'staging',
124
+ base: 'main'
125
+ });
126
+ console.log(\`Created PR #\${pr.number}\`);
127
+ } catch (error) {
128
+ console.log(\`PR creation skipped: \${error.message}\`);
129
+ }
76
130
  `;
77
131
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@panoptic-it-solutions/coolify-setup",
3
- "version": "1.1.19",
3
+ "version": "1.1.21",
4
4
  "description": "CLI tool for setting up Coolify deployment on Panoptic projects",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",