@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('
|
|
175
|
-
console.log(chalk.cyan('
|
|
176
|
-
console.log(
|
|
177
|
-
console.log(
|
|
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
|
-
|
|
10
|
-
|
|
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
|
-
|
|
15
|
-
|
|
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
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
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
|
}
|