@panoptic-it-solutions/coolify-setup 1.1.15 → 1.1.17
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/detector.d.ts +1 -1
- package/dist/detector.js +16 -2
- package/dist/generator.d.ts +1 -0
- package/dist/generator.js +77 -53
- package/dist/index.js +7 -7
- package/dist/templates/dockerfile.d.ts +1 -1
- package/dist/templates/dockerfile.js +7 -9
- package/dist/templates/entrypoint.d.ts +1 -1
- package/dist/templates/entrypoint.js +2 -4
- package/dist/templates/migrate.d.ts +2 -2
- package/dist/templates/migrate.js +4 -5
- package/package.json +1 -1
package/dist/detector.d.ts
CHANGED
package/dist/detector.js
CHANGED
|
@@ -19,18 +19,32 @@ export async function detectProject() {
|
|
|
19
19
|
const hasYarnLock = exists('yarn.lock');
|
|
20
20
|
const hasDockerfile = exists('Dockerfile');
|
|
21
21
|
const hasDockerCompose = exists('docker-compose.yml');
|
|
22
|
-
const hasSrcApp = exists('src/app'); // Detect src/ directory structure
|
|
23
22
|
let packageManager = 'npm';
|
|
24
23
|
if (hasPnpmLock)
|
|
25
24
|
packageManager = 'pnpm';
|
|
26
25
|
else if (hasYarnLock)
|
|
27
26
|
packageManager = 'yarn';
|
|
27
|
+
// Detect where migrations are located (check in order of priority)
|
|
28
|
+
const possibleDbPaths = [
|
|
29
|
+
'src/lib/db', // Already in src/lib/db
|
|
30
|
+
'lib/db', // Already in lib/db
|
|
31
|
+
'src/db', // Common with src/ directory
|
|
32
|
+
'db', // Common without src/
|
|
33
|
+
'drizzle', // Alternative location
|
|
34
|
+
];
|
|
35
|
+
let dbPath = null;
|
|
36
|
+
for (const path of possibleDbPaths) {
|
|
37
|
+
if (exists(`${path}/migrations`)) {
|
|
38
|
+
dbPath = path;
|
|
39
|
+
break;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
28
42
|
return {
|
|
29
43
|
type: hasNextConfig ? 'nextjs' : 'node',
|
|
30
44
|
packageManager,
|
|
31
45
|
hasDockerfile,
|
|
32
46
|
hasDockerCompose,
|
|
33
47
|
name: hasPackageJson ? getProjectName() : 'my-project',
|
|
34
|
-
|
|
48
|
+
dbPath,
|
|
35
49
|
};
|
|
36
50
|
}
|
package/dist/generator.d.ts
CHANGED
package/dist/generator.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { existsSync, mkdirSync, writeFileSync, readFileSync } from 'fs';
|
|
1
|
+
import { existsSync, mkdirSync, writeFileSync, readFileSync, unlinkSync, readdirSync, rmSync } from 'fs';
|
|
2
2
|
import { join, dirname } from 'path';
|
|
3
3
|
import { execSync } from 'child_process';
|
|
4
4
|
import { generateDockerfile, generateDockerCompose, generateDockerComposeBuild, generateWorkflow, generateEntrypoint, generateMigrateScript, generateClaudeRules, } from './templates/index.js';
|
|
@@ -13,11 +13,11 @@ function writeFile(relativePath, content) {
|
|
|
13
13
|
ensureDir(fullPath);
|
|
14
14
|
writeFileSync(fullPath, content, 'utf-8');
|
|
15
15
|
}
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
// Default dbPath if none detected (for projects without existing migrations)
|
|
17
|
+
function getDefaultDbPath() {
|
|
18
|
+
// If project has src/app, use src/lib/db, otherwise use lib/db
|
|
19
19
|
const srcAppPath = join(process.cwd(), 'src/app');
|
|
20
|
-
return existsSync(
|
|
20
|
+
return existsSync(srcAppPath) ? 'src/lib/db' : 'lib/db';
|
|
21
21
|
}
|
|
22
22
|
function addEsbuildToPackageJson(packageManager) {
|
|
23
23
|
const packageJsonPath = join(process.cwd(), 'package.json');
|
|
@@ -53,34 +53,43 @@ function addEsbuildToPackageJson(packageManager) {
|
|
|
53
53
|
return false;
|
|
54
54
|
}
|
|
55
55
|
}
|
|
56
|
-
function
|
|
56
|
+
function cleanupOldMigrationFiles(currentDbPath) {
|
|
57
57
|
const cwd = process.cwd();
|
|
58
|
-
//
|
|
59
|
-
const
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
const
|
|
69
|
-
if
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
58
|
+
// Possible locations where we might have created files in previous runs
|
|
59
|
+
const possibleOldPaths = [
|
|
60
|
+
'lib/db',
|
|
61
|
+
'src/lib/db',
|
|
62
|
+
];
|
|
63
|
+
for (const oldPath of possibleOldPaths) {
|
|
64
|
+
// Skip if this is the current path
|
|
65
|
+
if (oldPath === currentDbPath)
|
|
66
|
+
continue;
|
|
67
|
+
const oldMigratePath = join(cwd, oldPath, 'migrate.ts');
|
|
68
|
+
const oldMigrationsPath = join(cwd, oldPath, 'migrations');
|
|
69
|
+
// Remove old migrate.ts if it exists
|
|
70
|
+
if (existsSync(oldMigratePath)) {
|
|
71
|
+
unlinkSync(oldMigratePath);
|
|
72
|
+
console.log(`Removed old ${oldPath}/migrate.ts`);
|
|
73
|
+
}
|
|
74
|
+
// Remove old migrations folder if it's a folder we created (check if parent only contains our files)
|
|
75
|
+
if (existsSync(oldMigrationsPath)) {
|
|
76
|
+
const parentPath = join(cwd, oldPath);
|
|
77
|
+
try {
|
|
78
|
+
const contents = readdirSync(parentPath);
|
|
79
|
+
// Only remove if directory only contains migrations and/or migrate.ts (our files)
|
|
80
|
+
const isOurFolder = contents.every((f) => f === 'migrations' || f === 'migrate.ts' || f === 'migrate.bundle.js');
|
|
81
|
+
if (isOurFolder) {
|
|
82
|
+
rmSync(parentPath, { recursive: true, force: true });
|
|
83
|
+
console.log(`Removed old ${oldPath}/ folder`);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
catch {
|
|
87
|
+
// Ignore errors during cleanup
|
|
88
|
+
}
|
|
76
89
|
}
|
|
77
90
|
}
|
|
78
|
-
// No migrations found - create empty folder so Docker build doesn't fail
|
|
79
|
-
ensureDir(join(destPath, 'dummy'));
|
|
80
|
-
console.log(`Created empty ${libDbPath}/migrations (no source migrations found)`);
|
|
81
|
-
return true;
|
|
82
91
|
}
|
|
83
|
-
function
|
|
92
|
+
function updateTsConfigExcludes(newMigratePath) {
|
|
84
93
|
const tsconfigPath = join(process.cwd(), 'tsconfig.json');
|
|
85
94
|
if (!existsSync(tsconfigPath)) {
|
|
86
95
|
console.log('Warning: tsconfig.json not found, skipping exclusion');
|
|
@@ -92,13 +101,26 @@ function excludeMigrateFromTsConfig(migratePath) {
|
|
|
92
101
|
if (!tsconfig.exclude) {
|
|
93
102
|
tsconfig.exclude = ['node_modules'];
|
|
94
103
|
}
|
|
95
|
-
//
|
|
96
|
-
|
|
97
|
-
|
|
104
|
+
// Old paths to remove from previous runs
|
|
105
|
+
const oldPaths = ['lib/db/migrate.ts', 'src/lib/db/migrate.ts'];
|
|
106
|
+
let modified = false;
|
|
107
|
+
// Remove old paths that are no longer used
|
|
108
|
+
for (const oldPath of oldPaths) {
|
|
109
|
+
const index = tsconfig.exclude.indexOf(oldPath);
|
|
110
|
+
if (index !== -1 && oldPath !== newMigratePath) {
|
|
111
|
+
tsconfig.exclude.splice(index, 1);
|
|
112
|
+
modified = true;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
// Add new path if not already present
|
|
116
|
+
if (!tsconfig.exclude.includes(newMigratePath)) {
|
|
117
|
+
tsconfig.exclude.push(newMigratePath);
|
|
118
|
+
modified = true;
|
|
119
|
+
}
|
|
120
|
+
if (modified) {
|
|
98
121
|
writeFileSync(tsconfigPath, JSON.stringify(tsconfig, null, 2) + '\n', 'utf-8');
|
|
99
|
-
return true;
|
|
100
122
|
}
|
|
101
|
-
return
|
|
123
|
+
return modified;
|
|
102
124
|
}
|
|
103
125
|
catch (error) {
|
|
104
126
|
console.log('Warning: Failed to update tsconfig.json:', error);
|
|
@@ -106,15 +128,15 @@ function excludeMigrateFromTsConfig(migratePath) {
|
|
|
106
128
|
}
|
|
107
129
|
}
|
|
108
130
|
export async function generateFiles(options) {
|
|
109
|
-
const { projectName, projectType, packageManager, includePostgres, includeRedis, includeMinio, } = options;
|
|
110
|
-
//
|
|
111
|
-
const
|
|
131
|
+
const { projectName, projectType, packageManager, includePostgres, includeRedis, includeMinio, dbPath: detectedDbPath, } = options;
|
|
132
|
+
// Use detected dbPath or fall back to default based on project structure
|
|
133
|
+
const dbPath = detectedDbPath ?? getDefaultDbPath();
|
|
112
134
|
// Generate Dockerfile
|
|
113
135
|
const dockerfile = generateDockerfile({
|
|
114
136
|
projectType,
|
|
115
137
|
packageManager,
|
|
116
138
|
includePostgres,
|
|
117
|
-
|
|
139
|
+
dbPath,
|
|
118
140
|
});
|
|
119
141
|
writeFile('Dockerfile', dockerfile);
|
|
120
142
|
// Generate docker-compose.yml
|
|
@@ -139,7 +161,7 @@ export async function generateFiles(options) {
|
|
|
139
161
|
const entrypoint = generateEntrypoint({
|
|
140
162
|
projectType,
|
|
141
163
|
includePostgres,
|
|
142
|
-
|
|
164
|
+
dbPath,
|
|
143
165
|
});
|
|
144
166
|
writeFile('entrypoint.sh', entrypoint);
|
|
145
167
|
// Generate Claude rules
|
|
@@ -147,31 +169,33 @@ export async function generateFiles(options) {
|
|
|
147
169
|
writeFile('.claude/rules/coolify.md', claudeRules);
|
|
148
170
|
// Generate migrate.ts if postgres is included
|
|
149
171
|
if (includePostgres) {
|
|
150
|
-
const migrateScript = generateMigrateScript({ projectType, usesSrcDirectory });
|
|
151
172
|
// For Next.js standalone projects, we need esbuild to bundle the migration script
|
|
152
173
|
if (projectType === 'nextjs') {
|
|
153
174
|
const added = addEsbuildToPackageJson(packageManager);
|
|
154
175
|
if (added) {
|
|
155
176
|
console.log('Added esbuild to devDependencies (required for migration bundling)');
|
|
156
177
|
}
|
|
157
|
-
//
|
|
158
|
-
|
|
159
|
-
//
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
if (!existsSync(existingMigratePath)) {
|
|
165
|
-
writeFile(migratePath, migrateScript);
|
|
178
|
+
// Clean up old files from previous runs (if dbPath changed)
|
|
179
|
+
cleanupOldMigrationFiles(dbPath);
|
|
180
|
+
// Create empty migrations folder if none exists
|
|
181
|
+
const migrationsPath = join(process.cwd(), dbPath, 'migrations');
|
|
182
|
+
if (!existsSync(migrationsPath)) {
|
|
183
|
+
ensureDir(join(migrationsPath, 'dummy'));
|
|
184
|
+
console.log(`Created empty ${dbPath}/migrations folder`);
|
|
166
185
|
}
|
|
167
|
-
//
|
|
168
|
-
const
|
|
169
|
-
|
|
170
|
-
|
|
186
|
+
// Always write migrate.ts (overwrites previous version to handle updates)
|
|
187
|
+
const migrateScript = generateMigrateScript({ projectType, dbPath });
|
|
188
|
+
const migratePath = `${dbPath}/migrate.ts`;
|
|
189
|
+
writeFile(migratePath, migrateScript);
|
|
190
|
+
// Update tsconfig.json excludes (removes old paths, adds new)
|
|
191
|
+
const updated = updateTsConfigExcludes(migratePath);
|
|
192
|
+
if (updated) {
|
|
193
|
+
console.log(`Updated tsconfig.json exclude for ${migratePath}`);
|
|
171
194
|
}
|
|
172
195
|
}
|
|
173
196
|
else {
|
|
174
197
|
// For Node.js projects, write to scripts/ directory
|
|
198
|
+
const migrateScript = generateMigrateScript({ projectType, dbPath });
|
|
175
199
|
writeFile('scripts/migrate.ts', migrateScript);
|
|
176
200
|
}
|
|
177
201
|
}
|
package/dist/index.js
CHANGED
|
@@ -64,6 +64,7 @@ async function main() {
|
|
|
64
64
|
includePostgres: response.includePostgres,
|
|
65
65
|
includeRedis: response.includeRedis,
|
|
66
66
|
includeMinio: response.includeMinio,
|
|
67
|
+
dbPath: project.dbPath,
|
|
67
68
|
});
|
|
68
69
|
// Track generated files for commit
|
|
69
70
|
const generatedFiles = [
|
|
@@ -85,13 +86,12 @@ async function main() {
|
|
|
85
86
|
else {
|
|
86
87
|
generatedFiles.push('package-lock.json');
|
|
87
88
|
}
|
|
88
|
-
// Add migrate script
|
|
89
|
+
// Add migrate script if postgres included
|
|
89
90
|
if (response.includePostgres) {
|
|
90
91
|
if (project.type === 'nextjs') {
|
|
91
|
-
// Use
|
|
92
|
-
const
|
|
93
|
-
generatedFiles.push(`${
|
|
94
|
-
generatedFiles.push(`${libDbPath}/migrations/`); // Include copied migrations folder
|
|
92
|
+
// Use detected dbPath, or fall back to default based on project structure
|
|
93
|
+
const dbPath = project.dbPath ?? (project.type === 'nextjs' ? 'lib/db' : 'db');
|
|
94
|
+
generatedFiles.push(`${dbPath}/migrate.ts`);
|
|
95
95
|
generatedFiles.push('tsconfig.json'); // May be modified with exclude
|
|
96
96
|
}
|
|
97
97
|
else {
|
|
@@ -106,8 +106,8 @@ async function main() {
|
|
|
106
106
|
console.log(chalk.green(' ✓ entrypoint.sh'));
|
|
107
107
|
if (response.includePostgres) {
|
|
108
108
|
if (project.type === 'nextjs') {
|
|
109
|
-
const
|
|
110
|
-
console.log(chalk.green(` ✓ ${
|
|
109
|
+
const dbPath = project.dbPath ?? 'lib/db';
|
|
110
|
+
console.log(chalk.green(` ✓ ${dbPath}/migrate.ts`));
|
|
111
111
|
}
|
|
112
112
|
else {
|
|
113
113
|
console.log(chalk.green(' ✓ scripts/migrate.ts'));
|
|
@@ -2,6 +2,6 @@ export interface DockerfileOptions {
|
|
|
2
2
|
projectType: 'nextjs' | 'node';
|
|
3
3
|
packageManager: 'pnpm' | 'npm' | 'yarn';
|
|
4
4
|
includePostgres: boolean;
|
|
5
|
-
|
|
5
|
+
dbPath: string;
|
|
6
6
|
}
|
|
7
7
|
export declare function generateDockerfile(options: DockerfileOptions): string;
|
|
@@ -5,9 +5,7 @@ export function generateDockerfile(options) {
|
|
|
5
5
|
return generateNodeDockerfile(options);
|
|
6
6
|
}
|
|
7
7
|
function generateNextjsDockerfile(options) {
|
|
8
|
-
const { packageManager, includePostgres,
|
|
9
|
-
// Use src/lib/db for projects with src/ directory structure
|
|
10
|
-
const libDbPath = usesSrcDirectory ? 'src/lib/db' : 'lib/db';
|
|
8
|
+
const { packageManager, includePostgres, dbPath } = options;
|
|
11
9
|
const installCmd = packageManager === 'pnpm'
|
|
12
10
|
? 'pnpm install --frozen-lockfile'
|
|
13
11
|
: packageManager === 'yarn'
|
|
@@ -41,12 +39,12 @@ function generateNextjsDockerfile(options) {
|
|
|
41
39
|
# Build the migration bundle (single JS file with all deps baked in)
|
|
42
40
|
# This avoids module resolution issues in the standalone container
|
|
43
41
|
# postgres is externalized and copied separately due to pnpm symlink resolution issues
|
|
44
|
-
RUN ${esbuildCmd} ${
|
|
42
|
+
RUN ${esbuildCmd} ${dbPath}/migrate.ts --bundle --platform=node --target=node22 --outfile=${dbPath}/migrate.bundle.js --external:dotenv --external:postgres` : '';
|
|
45
43
|
const migrationCopy = includePostgres ? `
|
|
46
44
|
|
|
47
45
|
# Copy database migrations and bundled migration script
|
|
48
|
-
COPY --from=builder --chown=nextjs:nodejs /app/${
|
|
49
|
-
COPY --from=builder --chown=nextjs:nodejs /app/${
|
|
46
|
+
COPY --from=builder --chown=nextjs:nodejs /app/${dbPath}/migrations ./${dbPath}/migrations
|
|
47
|
+
COPY --from=builder --chown=nextjs:nodejs /app/${dbPath}/migrate.bundle.js ./${dbPath}/migrate.bundle.js
|
|
50
48
|
|
|
51
49
|
# Copy postgres module for migration script (externalized from bundle due to pnpm symlinks)
|
|
52
50
|
COPY --from=builder --chown=nextjs:nodejs /app/node_modules/.pnpm/postgres@*/node_modules/postgres ./node_modules/postgres` : '';
|
|
@@ -137,7 +135,7 @@ CMD ["./entrypoint.sh"]
|
|
|
137
135
|
`;
|
|
138
136
|
}
|
|
139
137
|
function generateNodeDockerfile(options) {
|
|
140
|
-
const { packageManager, includePostgres } = options;
|
|
138
|
+
const { packageManager, includePostgres, dbPath } = options;
|
|
141
139
|
const installCmd = packageManager === 'pnpm'
|
|
142
140
|
? 'pnpm install --frozen-lockfile --prod'
|
|
143
141
|
: packageManager === 'yarn'
|
|
@@ -155,8 +153,8 @@ function generateNodeDockerfile(options) {
|
|
|
155
153
|
: '';
|
|
156
154
|
const migrationCopy = includePostgres ? `
|
|
157
155
|
# Copy migration files
|
|
158
|
-
COPY --chown=node:node
|
|
159
|
-
COPY --chown=node:node
|
|
156
|
+
COPY --chown=node:node ${dbPath}/migrations ./scripts/migrations
|
|
157
|
+
COPY --chown=node:node ${dbPath}/migrate.ts ./scripts/migrate.ts` : '';
|
|
160
158
|
const tsxInstall = includePostgres ? `
|
|
161
159
|
# Install tsx globally for running TypeScript migration scripts
|
|
162
160
|
RUN npm install -g tsx` : '';
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
export function generateEntrypoint(options) {
|
|
2
|
-
const { projectType, includePostgres,
|
|
3
|
-
// Use src/lib/db for projects with src/ directory, otherwise lib/db
|
|
4
|
-
const libDbPath = usesSrcDirectory ? 'src/lib/db' : 'lib/db';
|
|
2
|
+
const { projectType, includePostgres, dbPath } = options;
|
|
5
3
|
// For Next.js standalone, we run the bundled JS file (no tsx needed)
|
|
6
4
|
// For Node.js, we use tsx since full node_modules is available
|
|
7
5
|
const migrationStep = includePostgres
|
|
@@ -9,7 +7,7 @@ export function generateEntrypoint(options) {
|
|
|
9
7
|
? `
|
|
10
8
|
# Run database migrations (bundled JS with all deps baked in)
|
|
11
9
|
echo "⏳ Running database migrations..."
|
|
12
|
-
node ${
|
|
10
|
+
node ${dbPath}/migrate.bundle.js
|
|
13
11
|
`
|
|
14
12
|
: `
|
|
15
13
|
# Run database migrations
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export interface MigrateScriptOptions {
|
|
2
2
|
projectType: 'nextjs' | 'node';
|
|
3
|
-
|
|
3
|
+
dbPath: string;
|
|
4
4
|
}
|
|
5
|
-
export declare function generateMigrateScript(options
|
|
5
|
+
export declare function generateMigrateScript(options: MigrateScriptOptions): string;
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
export function generateMigrateScript(options) {
|
|
2
|
-
const projectType = options
|
|
3
|
-
|
|
4
|
-
// For
|
|
5
|
-
// For Node.js, migrations are in scripts/migrations (run with tsx)
|
|
2
|
+
const { projectType, dbPath } = options;
|
|
3
|
+
// For Next.js, migrations are in the detected dbPath (e.g., src/db, lib/db, etc.)
|
|
4
|
+
// For Node.js, migrations are copied to scripts/migrations (run with tsx)
|
|
6
5
|
const migrationsFolder = projectType === 'nextjs'
|
|
7
|
-
?
|
|
6
|
+
? `./${dbPath}/migrations`
|
|
8
7
|
: './scripts/migrations';
|
|
9
8
|
return `import { drizzle } from 'drizzle-orm/postgres-js';
|
|
10
9
|
import { migrate } from 'drizzle-orm/postgres-js/migrator';
|