create-veap 0.1.4 → 0.3.1
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/README.md +72 -1
- package/bin/veap.js +1 -0
- package/dist/commands/init.d.ts +2 -2
- package/dist/commands/init.js +6 -8
- package/dist/index.js +5 -0
- package/dist/package-manager.d.ts +29 -10
- package/dist/package-manager.js +85 -22
- package/package.json +1 -1
- package/stubs/docker/.dockerignore.stub +39 -39
- package/stubs/docker/Dockerfile.stub +49 -49
- package/stubs/docker/compose.yml.stub +58 -58
- package/stubs/overlay-full/AGENTS.md.stub +1 -1
- package/stubs/overlay-full/README.md.stub +132 -0
- package/stubs/overlay-full/app/(site)/layout.tsx.stub +10 -0
- package/stubs/overlay-full/app/[[...catchAll]]/page.tsx.stub +47 -47
- package/stubs/overlay-full/app/api/[...catchAll]/route.ts.stub +111 -111
- package/stubs/overlay-full/app/error.tsx.stub +34 -34
- package/stubs/overlay-full/app/globals.css.stub +123 -123
- package/stubs/overlay-full/app/layout.tsx.stub +71 -71
- package/stubs/overlay-full/app/storage/[...path]/route.ts.stub +61 -61
- package/stubs/overlay-full/components/footer.tsx.stub +25 -0
- package/stubs/overlay-full/components/navbar.tsx.stub +61 -0
- package/stubs/overlay-full/components/site-layout.tsx.stub +22 -0
- package/stubs/overlay-full/lib/plugins.gen.ts.stub +6 -6
- package/stubs/overlay-full/lib/veap.ts.stub +27 -26
- package/stubs/overlay-full/migrations/index.ts.stub +1 -1
- package/stubs/overlay-full/next.config.ts.stub +44 -34
- package/stubs/overlay-full/proxy.ts.stub +27 -27
package/README.md
CHANGED
|
@@ -1,3 +1,74 @@
|
|
|
1
1
|
# create-veap
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
The official project initializer for [Veap Framework](https://veap.pl) applications. Scaffolds a full plugin-enabled Veap project on top of the official `create-next-app`.
|
|
4
|
+
|
|
5
|
+
## Quickstart
|
|
6
|
+
|
|
7
|
+
Initialize a new Veap project using your preferred package manager:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
# Using Bun (recommended)
|
|
11
|
+
bun create veap my-app
|
|
12
|
+
|
|
13
|
+
# Using pnpm
|
|
14
|
+
pnpm create veap my-app
|
|
15
|
+
|
|
16
|
+
# Using npm
|
|
17
|
+
npm create veap my-app
|
|
18
|
+
|
|
19
|
+
# Using Yarn
|
|
20
|
+
yarn create veap my-app
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Or execute directly through a package runner:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
bunx create-veap my-app
|
|
27
|
+
# or
|
|
28
|
+
npx create-veap my-app
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
When you omit the project name in an interactive terminal, `create-veap` prompts for a project name and optional Docker configuration.
|
|
32
|
+
|
|
33
|
+
## Command options
|
|
34
|
+
|
|
35
|
+
| Flag | Description |
|
|
36
|
+
| ---------------- | ---------------------------------------------------------------------------- |
|
|
37
|
+
| `--docker` | Generate Docker configuration (`Dockerfile`, `compose.yml`, `.dockerignore`). |
|
|
38
|
+
| `--no-docker` | Skip Docker configuration without prompting. |
|
|
39
|
+
| `--skip-install` | Do not run the package manager install step. |
|
|
40
|
+
| `--pm <manager>` | Specify package manager (`bun`, `pnpm`, `npm`, `yarn`). |
|
|
41
|
+
| `--pnpm` | Force pnpm as package manager. |
|
|
42
|
+
| `--bun` | Force Bun as package manager. |
|
|
43
|
+
| `--npm` | Force npm as package manager. |
|
|
44
|
+
| `--yarn` | Force Yarn as package manager. |
|
|
45
|
+
|
|
46
|
+
### Automatic package manager detection
|
|
47
|
+
|
|
48
|
+
`create-veap` automatically detects the package manager from the execution command (`bun create`, `pnpm create`, `npm create`, `yarn create`, `bunx`, or `npx`) and environment variables without prompting.
|
|
49
|
+
|
|
50
|
+
If you want to use a different package manager than the runner (for example, executing via Bun while configuring the generated project for pnpm), pass the target package manager flag:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
bun create veap my-app --pnpm
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## What it scaffolds
|
|
57
|
+
|
|
58
|
+
- Next.js 16 App Router with React Server Components, TypeScript, and Tailwind CSS v4.
|
|
59
|
+
- Veap overlay with virtual routing (`app/[[...catchAll]]/page.tsx` and `app/api/[...catchAll]/route.ts`).
|
|
60
|
+
- Service provider composition root in `lib/veap.ts`.
|
|
61
|
+
- Workspace configuration for plugins (`plugins/` directory).
|
|
62
|
+
- Default environment configuration (`.env`) with generated `ENCRYPTION_KEY` and local SQLite database.
|
|
63
|
+
- Agent instructions (`AGENTS.md`) and project guide (`README.md`).
|
|
64
|
+
|
|
65
|
+
## Documentation
|
|
66
|
+
|
|
67
|
+
For full documentation and guides, visit:
|
|
68
|
+
- [https://veap.pl/docs](https://veap.pl/docs)
|
|
69
|
+
- [Installation Guide](https://veap.pl/docs/getting-started/installation)
|
|
70
|
+
- [CLI Reference](https://veap.pl/docs/reference/cli)
|
|
71
|
+
|
|
72
|
+
## License
|
|
73
|
+
|
|
74
|
+
MIT
|
package/bin/veap.js
CHANGED
package/dist/commands/init.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
import { type ResolvePackageManagerOptions } from "../package-manager.js";
|
|
2
|
+
export declare function initProject(name?: string, options?: ResolvePackageManagerOptions & {
|
|
2
3
|
docker?: boolean;
|
|
3
4
|
skipInstall?: boolean;
|
|
4
|
-
pm?: string;
|
|
5
5
|
}): Promise<void>;
|
package/dist/commands/init.js
CHANGED
|
@@ -2,12 +2,12 @@ import fs from "node:fs";
|
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { fileURLToPath } from "node:url";
|
|
4
4
|
import ora from "ora";
|
|
5
|
-
import {
|
|
5
|
+
import { appendGitignore, clearAppDirectory, injectVeapDependencies, writeEnvFile, } from "../mutate.js";
|
|
6
6
|
import { applyPackageManager, pmInstall, pmRunCommand, resolvePackageManager, } from "../package-manager.js";
|
|
7
|
-
import { scaffoldNextApp } from "../scaffold.js";
|
|
8
|
-
import { promptConfirm, promptProjectName } from "../prompts.js";
|
|
9
7
|
import { parseProjectName, projectNameError } from "../project-name.js";
|
|
10
|
-
import {
|
|
8
|
+
import { promptConfirm, promptProjectName } from "../prompts.js";
|
|
9
|
+
import { scaffoldNextApp } from "../scaffold.js";
|
|
10
|
+
import { processStubs } from "../utils.js";
|
|
11
11
|
export async function initProject(name, options) {
|
|
12
12
|
// ---- Resolve the project name: from the CLI argument or the interactive
|
|
13
13
|
// prompt (which resolves to a default on non-TTY, so scripts never hang).
|
|
@@ -32,9 +32,8 @@ export async function initProject(name, options) {
|
|
|
32
32
|
if (withDocker === undefined) {
|
|
33
33
|
withDocker = await promptConfirm("Include Docker configuration?", false);
|
|
34
34
|
}
|
|
35
|
-
// Resolve the package manager
|
|
36
|
-
|
|
37
|
-
const pm = await resolvePackageManager({ pm: options?.pm });
|
|
35
|
+
// Resolve the package manager automatically (or from flags)
|
|
36
|
+
const pm = await resolvePackageManager(options);
|
|
38
37
|
const overlayFolder = "../../stubs/overlay-full";
|
|
39
38
|
console.log(`🚀 Initializing new Veap project (Full plugin-enabled): ${projectName} in ${destDir}...`);
|
|
40
39
|
try {
|
|
@@ -75,7 +74,6 @@ export async function initProject(name, options) {
|
|
|
75
74
|
path.join(destDir, "public"),
|
|
76
75
|
path.join(destDir, "storage"),
|
|
77
76
|
path.join(destDir, "plugins"),
|
|
78
|
-
path.join(destDir, "templates"),
|
|
79
77
|
]) {
|
|
80
78
|
if (!fs.existsSync(dir)) {
|
|
81
79
|
fs.mkdirSync(dir, { recursive: true });
|
package/dist/index.js
CHANGED
|
@@ -5,8 +5,13 @@ const cli = cac("create-veap");
|
|
|
5
5
|
cli
|
|
6
6
|
.command("[name]", "Initialize a new Veap project (asks for details when omitted)")
|
|
7
7
|
.option("--docker", "Initialize Docker configuration")
|
|
8
|
+
.option("--no-docker", "Skip Docker configuration")
|
|
8
9
|
.option("--skip-install", "Skip dependencies installation")
|
|
9
10
|
.option("--pm <manager>", "Package manager to use: pnpm, npm, yarn or bun (auto-detected when omitted)")
|
|
11
|
+
.option("--pnpm, --use-pnpm", "Use pnpm as package manager")
|
|
12
|
+
.option("--bun, --use-bun", "Use bun as package manager")
|
|
13
|
+
.option("--npm, --use-npm", "Use npm as package manager")
|
|
14
|
+
.option("--yarn, --use-yarn", "Use yarn as package manager")
|
|
10
15
|
.action(async (name, options) => {
|
|
11
16
|
await initProject(name, options);
|
|
12
17
|
});
|
|
@@ -7,6 +7,15 @@ export interface PackageManagerDetection {
|
|
|
7
7
|
/** Human-readable detail, e.g. "pnpm@11.9.0" or "pnpm-lock.yaml". */
|
|
8
8
|
detail?: string;
|
|
9
9
|
}
|
|
10
|
+
/**
|
|
11
|
+
* Detects the package manager currently executing the process.
|
|
12
|
+
*
|
|
13
|
+
* Inspects:
|
|
14
|
+
* 1. `npm_config_user_agent` (set when invoked via npx, bunx, pnpm dlx, yarn create)
|
|
15
|
+
* 2. `process.versions.bun` (running directly inside Bun runtime)
|
|
16
|
+
* 3. `npm_execpath` (path containing the binary name)
|
|
17
|
+
*/
|
|
18
|
+
export declare function detectRunningPackageManager(env?: NodeJS.ProcessEnv, versions?: NodeJS.ProcessVersions): PackageManager | null;
|
|
10
19
|
/**
|
|
11
20
|
* Detects the package manager to default to by inspecting `dir` (usually the
|
|
12
21
|
* directory the scaffolding command was launched from).
|
|
@@ -18,22 +27,32 @@ export declare function detectPackageManager(dir: string): PackageManagerDetecti
|
|
|
18
27
|
* Interactive numbered-choice prompt rendered on readline (no external
|
|
19
28
|
* prompt library, matching the rest of this CLI).
|
|
20
29
|
*
|
|
21
|
-
*
|
|
22
|
-
* Enter accepts it. Accepts a number (1-4) or a name (`pnpm`, `npm`,
|
|
23
|
-
* `yarn`, `bun`). On EOF / closed stdin (piped input, CI) resolves to the
|
|
24
|
-
* detected default instead of hanging.
|
|
30
|
+
* Kept as a fallback helper.
|
|
25
31
|
*/
|
|
26
32
|
export declare function promptPackageManager(detection: PackageManagerDetection): Promise<PackageManager>;
|
|
33
|
+
export interface ResolvePackageManagerOptions {
|
|
34
|
+
pm?: string;
|
|
35
|
+
pnpm?: boolean;
|
|
36
|
+
bun?: boolean;
|
|
37
|
+
npm?: boolean;
|
|
38
|
+
yarn?: boolean;
|
|
39
|
+
usePnpm?: boolean;
|
|
40
|
+
useBun?: boolean;
|
|
41
|
+
useNpm?: boolean;
|
|
42
|
+
useYarn?: boolean;
|
|
43
|
+
}
|
|
27
44
|
/**
|
|
28
45
|
* Resolves the package manager to use for a new project.
|
|
29
46
|
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
47
|
+
* Priority:
|
|
48
|
+
* 1. Explicit manager flag: `--pnpm`, `--bun`, `--npm`, `--yarn`
|
|
49
|
+
* 2. Explicit `--pm <name>` flag
|
|
50
|
+
* 3. Auto-detected from currently running environment (e.g. `bun create`, `pnpm dlx`, `npx`)
|
|
51
|
+
* 4. Auto-detected from current directory (packageManager field, lockfiles, or default)
|
|
52
|
+
*
|
|
53
|
+
* Automatically resolves without prompting.
|
|
33
54
|
*/
|
|
34
|
-
export declare function resolvePackageManager(options?:
|
|
35
|
-
pm?: string;
|
|
36
|
-
}): Promise<PackageManager>;
|
|
55
|
+
export declare function resolvePackageManager(options?: ResolvePackageManagerOptions, cwd?: string): Promise<PackageManager>;
|
|
37
56
|
/**
|
|
38
57
|
* Applies the chosen package manager to the freshly scaffolded project:
|
|
39
58
|
*
|
package/dist/package-manager.js
CHANGED
|
@@ -21,6 +21,43 @@ const LOCKFILES = [
|
|
|
21
21
|
{ file: "package-lock.json", pm: "npm" },
|
|
22
22
|
];
|
|
23
23
|
const isPackageManager = (value) => PACKAGE_MANAGERS.includes(value);
|
|
24
|
+
/**
|
|
25
|
+
* Detects the package manager currently executing the process.
|
|
26
|
+
*
|
|
27
|
+
* Inspects:
|
|
28
|
+
* 1. `npm_config_user_agent` (set when invoked via npx, bunx, pnpm dlx, yarn create)
|
|
29
|
+
* 2. `process.versions.bun` (running directly inside Bun runtime)
|
|
30
|
+
* 3. `npm_execpath` (path containing the binary name)
|
|
31
|
+
*/
|
|
32
|
+
export function detectRunningPackageManager(env = process.env, versions = process.versions) {
|
|
33
|
+
const userAgent = env.npm_config_user_agent;
|
|
34
|
+
if (userAgent) {
|
|
35
|
+
if (userAgent.startsWith("pnpm"))
|
|
36
|
+
return "pnpm";
|
|
37
|
+
if (userAgent.startsWith("bun"))
|
|
38
|
+
return "bun";
|
|
39
|
+
if (userAgent.startsWith("yarn"))
|
|
40
|
+
return "yarn";
|
|
41
|
+
if (userAgent.startsWith("npm"))
|
|
42
|
+
return "npm";
|
|
43
|
+
}
|
|
44
|
+
// Running directly under Bun runtime (e.g. `bun create veap` or `bunx create-veap`)
|
|
45
|
+
if (typeof versions?.bun === "string") {
|
|
46
|
+
return "bun";
|
|
47
|
+
}
|
|
48
|
+
const execPath = env.npm_execpath;
|
|
49
|
+
if (execPath) {
|
|
50
|
+
if (execPath.includes("pnpm"))
|
|
51
|
+
return "pnpm";
|
|
52
|
+
if (execPath.includes("bun"))
|
|
53
|
+
return "bun";
|
|
54
|
+
if (execPath.includes("yarn"))
|
|
55
|
+
return "yarn";
|
|
56
|
+
if (execPath.includes("npm"))
|
|
57
|
+
return "npm";
|
|
58
|
+
}
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
24
61
|
/**
|
|
25
62
|
* Detects the package manager to default to by inspecting `dir` (usually the
|
|
26
63
|
* directory the scaffolding command was launched from).
|
|
@@ -53,13 +90,12 @@ export function detectPackageManager(dir) {
|
|
|
53
90
|
return {
|
|
54
91
|
pm: "pnpm",
|
|
55
92
|
source: "lockfile",
|
|
56
|
-
detail: `multiple lockfiles found: ${found
|
|
57
|
-
.map((l) => l.file)
|
|
58
|
-
.join(", ")}`,
|
|
93
|
+
detail: `multiple lockfiles found: ${found.map((l) => l.file).join(", ")}`,
|
|
59
94
|
};
|
|
60
95
|
}
|
|
61
|
-
|
|
62
|
-
|
|
96
|
+
const first = found[0];
|
|
97
|
+
if (found.length === 1 && first) {
|
|
98
|
+
return { pm: first.pm, source: "lockfile", detail: first.file };
|
|
63
99
|
}
|
|
64
100
|
// 3. Framework default
|
|
65
101
|
return { pm: "pnpm", source: "default" };
|
|
@@ -76,10 +112,7 @@ function formatDetection(d) {
|
|
|
76
112
|
* Interactive numbered-choice prompt rendered on readline (no external
|
|
77
113
|
* prompt library, matching the rest of this CLI).
|
|
78
114
|
*
|
|
79
|
-
*
|
|
80
|
-
* Enter accepts it. Accepts a number (1-4) or a name (`pnpm`, `npm`,
|
|
81
|
-
* `yarn`, `bun`). On EOF / closed stdin (piped input, CI) resolves to the
|
|
82
|
-
* detected default instead of hanging.
|
|
115
|
+
* Kept as a fallback helper.
|
|
83
116
|
*/
|
|
84
117
|
export async function promptPackageManager(detection) {
|
|
85
118
|
console.log(formatDetection(detection));
|
|
@@ -125,8 +158,11 @@ export async function promptPackageManager(detection) {
|
|
|
125
158
|
if (String(asNumber) === value &&
|
|
126
159
|
asNumber >= 1 &&
|
|
127
160
|
asNumber <= PACKAGE_MANAGERS.length) {
|
|
128
|
-
|
|
129
|
-
|
|
161
|
+
const chosen = PACKAGE_MANAGERS[asNumber - 1];
|
|
162
|
+
if (chosen) {
|
|
163
|
+
finish(chosen);
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
130
166
|
}
|
|
131
167
|
if (isPackageManager(value)) {
|
|
132
168
|
finish(value);
|
|
@@ -142,25 +178,52 @@ export async function promptPackageManager(detection) {
|
|
|
142
178
|
/**
|
|
143
179
|
* Resolves the package manager to use for a new project.
|
|
144
180
|
*
|
|
145
|
-
*
|
|
146
|
-
*
|
|
147
|
-
*
|
|
181
|
+
* Priority:
|
|
182
|
+
* 1. Explicit manager flag: `--pnpm`, `--bun`, `--npm`, `--yarn`
|
|
183
|
+
* 2. Explicit `--pm <name>` flag
|
|
184
|
+
* 3. Auto-detected from currently running environment (e.g. `bun create`, `pnpm dlx`, `npx`)
|
|
185
|
+
* 4. Auto-detected from current directory (packageManager field, lockfiles, or default)
|
|
186
|
+
*
|
|
187
|
+
* Automatically resolves without prompting.
|
|
148
188
|
*/
|
|
149
|
-
export async function resolvePackageManager(options) {
|
|
150
|
-
|
|
189
|
+
export async function resolvePackageManager(options, cwd = process.cwd()) {
|
|
190
|
+
// 1. Explicit boolean flags: --pnpm, --bun, --npm, --yarn
|
|
191
|
+
if (options?.pnpm || options?.usePnpm) {
|
|
192
|
+
console.log("📦 Using package manager: pnpm (specified via --pnpm flag)");
|
|
193
|
+
return "pnpm";
|
|
194
|
+
}
|
|
195
|
+
if (options?.bun || options?.useBun) {
|
|
196
|
+
console.log("📦 Using package manager: bun (specified via --bun flag)");
|
|
197
|
+
return "bun";
|
|
198
|
+
}
|
|
199
|
+
if (options?.npm || options?.useNpm) {
|
|
200
|
+
console.log("📦 Using package manager: npm (specified via --npm flag)");
|
|
201
|
+
return "npm";
|
|
202
|
+
}
|
|
203
|
+
if (options?.yarn || options?.useYarn) {
|
|
204
|
+
console.log("📦 Using package manager: yarn (specified via --yarn flag)");
|
|
205
|
+
return "yarn";
|
|
206
|
+
}
|
|
207
|
+
// 2. Explicit --pm <name> flag
|
|
151
208
|
if (options?.pm) {
|
|
152
209
|
const requested = options.pm.trim().toLowerCase();
|
|
153
210
|
if (isPackageManager(requested)) {
|
|
211
|
+
console.log(`📦 Using package manager: ${requested} (specified via --pm flag)`);
|
|
154
212
|
return requested;
|
|
155
213
|
}
|
|
156
214
|
console.error(`Error: Unknown package manager "${options.pm}". Allowed: ${PACKAGE_MANAGERS.join(", ")}.`);
|
|
157
215
|
process.exit(1);
|
|
158
216
|
}
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
217
|
+
// 3. Auto-detected from currently running execution environment
|
|
218
|
+
const running = detectRunningPackageManager();
|
|
219
|
+
if (running) {
|
|
220
|
+
console.log(`📦 Package manager detected: ${running} (from running environment)`);
|
|
221
|
+
return running;
|
|
162
222
|
}
|
|
163
|
-
|
|
223
|
+
// 4. Auto-detected from directory context or framework default
|
|
224
|
+
const detection = detectPackageManager(cwd);
|
|
225
|
+
console.log(formatDetection(detection));
|
|
226
|
+
return detection.pm;
|
|
164
227
|
}
|
|
165
228
|
/**
|
|
166
229
|
* Applies the chosen package manager to the freshly scaffolded project:
|
|
@@ -189,11 +252,11 @@ export function applyPackageManager(projectDir, pm) {
|
|
|
189
252
|
// undefined in package.json to avoid a shadowing duplicate). Written
|
|
190
253
|
// only when missing - an existing one is the source of truth.
|
|
191
254
|
if (!fs.existsSync(pnpmWorkspace)) {
|
|
192
|
-
fs.writeFileSync(pnpmWorkspace, 'packages:\n - "plugins/*"\n
|
|
255
|
+
fs.writeFileSync(pnpmWorkspace, 'packages:\n - "plugins/*"\n', "utf-8");
|
|
193
256
|
}
|
|
194
257
|
}
|
|
195
258
|
else {
|
|
196
|
-
pkg.workspaces = ["plugins/*"
|
|
259
|
+
pkg.workspaces = ["plugins/*"];
|
|
197
260
|
if (fs.existsSync(pnpmWorkspace)) {
|
|
198
261
|
// Switching away from pnpm: the file would shadow the workspaces field.
|
|
199
262
|
fs.rmSync(pnpmWorkspace);
|
package/package.json
CHANGED
|
@@ -1,39 +1,39 @@
|
|
|
1
|
-
node_modules/
|
|
2
|
-
.pnpm-store/
|
|
3
|
-
npm-debug.log*
|
|
4
|
-
yarn-debug.log*
|
|
5
|
-
yarn-error.log*
|
|
6
|
-
pnpm-debug.log*
|
|
7
|
-
|
|
8
|
-
.next/
|
|
9
|
-
out/
|
|
10
|
-
dist/
|
|
11
|
-
build/
|
|
12
|
-
.vercel/
|
|
13
|
-
|
|
14
|
-
coverage/
|
|
15
|
-
*.test.*
|
|
16
|
-
*.spec.*
|
|
17
|
-
|
|
18
|
-
.git/
|
|
19
|
-
.gitignore
|
|
20
|
-
.vscode/
|
|
21
|
-
.idea/
|
|
22
|
-
*.swp
|
|
23
|
-
*.log
|
|
24
|
-
|
|
25
|
-
.env
|
|
26
|
-
.env*.local
|
|
27
|
-
|
|
28
|
-
Dockerfile*
|
|
29
|
-
.dockerignore
|
|
30
|
-
compose.yaml
|
|
31
|
-
compose.yml
|
|
32
|
-
|
|
33
|
-
*.md
|
|
34
|
-
docs/
|
|
35
|
-
|
|
36
|
-
.turbo/
|
|
37
|
-
.tmp/
|
|
38
|
-
.temp/
|
|
39
|
-
.DS_Store
|
|
1
|
+
node_modules/
|
|
2
|
+
.pnpm-store/
|
|
3
|
+
npm-debug.log*
|
|
4
|
+
yarn-debug.log*
|
|
5
|
+
yarn-error.log*
|
|
6
|
+
pnpm-debug.log*
|
|
7
|
+
|
|
8
|
+
.next/
|
|
9
|
+
out/
|
|
10
|
+
dist/
|
|
11
|
+
build/
|
|
12
|
+
.vercel/
|
|
13
|
+
|
|
14
|
+
coverage/
|
|
15
|
+
*.test.*
|
|
16
|
+
*.spec.*
|
|
17
|
+
|
|
18
|
+
.git/
|
|
19
|
+
.gitignore
|
|
20
|
+
.vscode/
|
|
21
|
+
.idea/
|
|
22
|
+
*.swp
|
|
23
|
+
*.log
|
|
24
|
+
|
|
25
|
+
.env
|
|
26
|
+
.env*.local
|
|
27
|
+
|
|
28
|
+
Dockerfile*
|
|
29
|
+
.dockerignore
|
|
30
|
+
compose.yaml
|
|
31
|
+
compose.yml
|
|
32
|
+
|
|
33
|
+
*.md
|
|
34
|
+
docs/
|
|
35
|
+
|
|
36
|
+
.turbo/
|
|
37
|
+
.tmp/
|
|
38
|
+
.temp/
|
|
39
|
+
.DS_Store
|
|
@@ -1,49 +1,49 @@
|
|
|
1
|
-
# Stage 1: Base image with pnpm
|
|
2
|
-
FROM node:22-alpine AS base
|
|
3
|
-
RUN apk add --no-cache libc6-compat
|
|
4
|
-
ENV PNPM_HOME="/pnpm"
|
|
5
|
-
ENV PATH="$PNPM_HOME:$PATH"
|
|
6
|
-
|
|
7
|
-
RUN corepack enable
|
|
8
|
-
RUN corepack prepare pnpm@10.29.3 --activate
|
|
9
|
-
|
|
10
|
-
# Stage 2: Install dependencies
|
|
11
|
-
FROM base AS deps
|
|
12
|
-
WORKDIR /app
|
|
13
|
-
COPY . .
|
|
14
|
-
RUN --mount=type=cache,id=pnpm,target=/pnpm/store \
|
|
15
|
-
pnpm config set store-dir /pnpm/store && \
|
|
16
|
-
pnpm config set fetch-retries 10 && \
|
|
17
|
-
pnpm config set fetch-retry-maxtimeout 120000 && \
|
|
18
|
-
pnpm config set fetch-timeout 600000 && \
|
|
19
|
-
pnpm install --frozen-lockfile
|
|
20
|
-
|
|
21
|
-
# Stage 3: Build the project
|
|
22
|
-
FROM base AS builder
|
|
23
|
-
WORKDIR /app
|
|
24
|
-
COPY --from=deps /app ./
|
|
25
|
-
RUN pnpm build
|
|
26
|
-
|
|
27
|
-
# Stage 4: Production runner
|
|
28
|
-
FROM base AS runner
|
|
29
|
-
WORKDIR /app
|
|
30
|
-
|
|
31
|
-
ENV NODE_ENV=production
|
|
32
|
-
ENV NEXT_TELEMETRY_DISABLED=1
|
|
33
|
-
|
|
34
|
-
RUN addgroup --system --gid 1001 nodejs
|
|
35
|
-
RUN adduser --system --uid 1001 nextjs
|
|
36
|
-
|
|
37
|
-
# Automatically leverage output traces to reduce image size
|
|
38
|
-
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
|
|
39
|
-
COPY --from=builder --chown=nextjs:nodejs /app/.next/static .next/static
|
|
40
|
-
COPY --from=builder --chown=nextjs:nodejs /app/public public
|
|
41
|
-
|
|
42
|
-
USER nextjs
|
|
43
|
-
|
|
44
|
-
EXPOSE 3000
|
|
45
|
-
|
|
46
|
-
ENV PORT=3000
|
|
47
|
-
ENV HOSTNAME="0.0.0.0"
|
|
48
|
-
|
|
49
|
-
CMD ["node", "./server.js"]
|
|
1
|
+
# Stage 1: Base image with pnpm
|
|
2
|
+
FROM node:22-alpine AS base
|
|
3
|
+
RUN apk add --no-cache libc6-compat
|
|
4
|
+
ENV PNPM_HOME="/pnpm"
|
|
5
|
+
ENV PATH="$PNPM_HOME:$PATH"
|
|
6
|
+
|
|
7
|
+
RUN corepack enable
|
|
8
|
+
RUN corepack prepare pnpm@10.29.3 --activate
|
|
9
|
+
|
|
10
|
+
# Stage 2: Install dependencies
|
|
11
|
+
FROM base AS deps
|
|
12
|
+
WORKDIR /app
|
|
13
|
+
COPY . .
|
|
14
|
+
RUN --mount=type=cache,id=pnpm,target=/pnpm/store \
|
|
15
|
+
pnpm config set store-dir /pnpm/store && \
|
|
16
|
+
pnpm config set fetch-retries 10 && \
|
|
17
|
+
pnpm config set fetch-retry-maxtimeout 120000 && \
|
|
18
|
+
pnpm config set fetch-timeout 600000 && \
|
|
19
|
+
pnpm install --frozen-lockfile
|
|
20
|
+
|
|
21
|
+
# Stage 3: Build the project
|
|
22
|
+
FROM base AS builder
|
|
23
|
+
WORKDIR /app
|
|
24
|
+
COPY --from=deps /app ./
|
|
25
|
+
RUN pnpm build
|
|
26
|
+
|
|
27
|
+
# Stage 4: Production runner
|
|
28
|
+
FROM base AS runner
|
|
29
|
+
WORKDIR /app
|
|
30
|
+
|
|
31
|
+
ENV NODE_ENV=production
|
|
32
|
+
ENV NEXT_TELEMETRY_DISABLED=1
|
|
33
|
+
|
|
34
|
+
RUN addgroup --system --gid 1001 nodejs
|
|
35
|
+
RUN adduser --system --uid 1001 nextjs
|
|
36
|
+
|
|
37
|
+
# Automatically leverage output traces to reduce image size
|
|
38
|
+
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
|
|
39
|
+
COPY --from=builder --chown=nextjs:nodejs /app/.next/static .next/static
|
|
40
|
+
COPY --from=builder --chown=nextjs:nodejs /app/public public
|
|
41
|
+
|
|
42
|
+
USER nextjs
|
|
43
|
+
|
|
44
|
+
EXPOSE 3000
|
|
45
|
+
|
|
46
|
+
ENV PORT=3000
|
|
47
|
+
ENV HOSTNAME="0.0.0.0"
|
|
48
|
+
|
|
49
|
+
CMD ["node", "./server.js"]
|
|
@@ -1,58 +1,58 @@
|
|
|
1
|
-
services:
|
|
2
|
-
# Node.js service (use with: docker compose up {{name}} --build)
|
|
3
|
-
{{name}}:
|
|
4
|
-
build:
|
|
5
|
-
context: .
|
|
6
|
-
dockerfile: Dockerfile
|
|
7
|
-
image: {{name}}-image
|
|
8
|
-
container_name: {{name}}
|
|
9
|
-
env_file:
|
|
10
|
-
- .env
|
|
11
|
-
environment:
|
|
12
|
-
NODE_ENV: production
|
|
13
|
-
PORT: "3000"
|
|
14
|
-
NEXT_TELEMETRY_DISABLED: "1"
|
|
15
|
-
DATABASE_URL: "postgresql://postgres:postgres@database:5432/postgres?sslmode=disable"
|
|
16
|
-
depends_on:
|
|
17
|
-
database:
|
|
18
|
-
condition: service_healthy
|
|
19
|
-
redis:
|
|
20
|
-
condition: service_started
|
|
21
|
-
ports:
|
|
22
|
-
- "80:3000"
|
|
23
|
-
restart: unless-stopped
|
|
24
|
-
volumes:
|
|
25
|
-
- ./storage:/app/public/storage
|
|
26
|
-
|
|
27
|
-
# PostgreSQL service
|
|
28
|
-
database:
|
|
29
|
-
image: postgres:17-alpine
|
|
30
|
-
container_name: {{name}}-db
|
|
31
|
-
restart: always
|
|
32
|
-
environment:
|
|
33
|
-
POSTGRES_USER: postgres
|
|
34
|
-
POSTGRES_PASSWORD: postgres
|
|
35
|
-
POSTGRES_DB: postgres
|
|
36
|
-
ports:
|
|
37
|
-
- "5432:5432"
|
|
38
|
-
volumes:
|
|
39
|
-
- postgres_data:/var/lib/postgresql/data
|
|
40
|
-
healthcheck:
|
|
41
|
-
test: ["CMD-SHELL", "pg_isready -U postgres -d postgres"]
|
|
42
|
-
interval: 5s
|
|
43
|
-
timeout: 5s
|
|
44
|
-
retries: 5
|
|
45
|
-
|
|
46
|
-
# Redis service
|
|
47
|
-
redis:
|
|
48
|
-
image: redis:7-alpine
|
|
49
|
-
container_name: {{name}}-redis
|
|
50
|
-
restart: always
|
|
51
|
-
ports:
|
|
52
|
-
- "6379:6379"
|
|
53
|
-
volumes:
|
|
54
|
-
- redis_data:/data
|
|
55
|
-
|
|
56
|
-
volumes:
|
|
57
|
-
postgres_data:
|
|
58
|
-
redis_data:
|
|
1
|
+
services:
|
|
2
|
+
# Node.js service (use with: docker compose up {{name}} --build)
|
|
3
|
+
{{name}}:
|
|
4
|
+
build:
|
|
5
|
+
context: .
|
|
6
|
+
dockerfile: Dockerfile
|
|
7
|
+
image: {{name}}-image
|
|
8
|
+
container_name: {{name}}
|
|
9
|
+
env_file:
|
|
10
|
+
- .env
|
|
11
|
+
environment:
|
|
12
|
+
NODE_ENV: production
|
|
13
|
+
PORT: "3000"
|
|
14
|
+
NEXT_TELEMETRY_DISABLED: "1"
|
|
15
|
+
DATABASE_URL: "postgresql://postgres:postgres@database:5432/postgres?sslmode=disable"
|
|
16
|
+
depends_on:
|
|
17
|
+
database:
|
|
18
|
+
condition: service_healthy
|
|
19
|
+
redis:
|
|
20
|
+
condition: service_started
|
|
21
|
+
ports:
|
|
22
|
+
- "80:3000"
|
|
23
|
+
restart: unless-stopped
|
|
24
|
+
volumes:
|
|
25
|
+
- ./storage:/app/public/storage
|
|
26
|
+
|
|
27
|
+
# PostgreSQL service
|
|
28
|
+
database:
|
|
29
|
+
image: postgres:17-alpine
|
|
30
|
+
container_name: {{name}}-db
|
|
31
|
+
restart: always
|
|
32
|
+
environment:
|
|
33
|
+
POSTGRES_USER: postgres
|
|
34
|
+
POSTGRES_PASSWORD: postgres
|
|
35
|
+
POSTGRES_DB: postgres
|
|
36
|
+
ports:
|
|
37
|
+
- "5432:5432"
|
|
38
|
+
volumes:
|
|
39
|
+
- postgres_data:/var/lib/postgresql/data
|
|
40
|
+
healthcheck:
|
|
41
|
+
test: ["CMD-SHELL", "pg_isready -U postgres -d postgres"]
|
|
42
|
+
interval: 5s
|
|
43
|
+
timeout: 5s
|
|
44
|
+
retries: 5
|
|
45
|
+
|
|
46
|
+
# Redis service
|
|
47
|
+
redis:
|
|
48
|
+
image: redis:7-alpine
|
|
49
|
+
container_name: {{name}}-redis
|
|
50
|
+
restart: always
|
|
51
|
+
ports:
|
|
52
|
+
- "6379:6379"
|
|
53
|
+
volumes:
|
|
54
|
+
- redis_data:/data
|
|
55
|
+
|
|
56
|
+
volumes:
|
|
57
|
+
postgres_data:
|
|
58
|
+
redis_data:
|