create-rykira-app 1.0.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.
- package/README.md +50 -0
- package/bin/cli.js +149 -0
- package/deployment.md +168 -0
- package/how-to-deploy-package.md +132 -0
- package/package.json +23 -0
- package/starter-usage.md +132 -0
- package/template/.dockerignore +11 -0
- package/template/.env.example +20 -0
- package/template/.eslintrc.js +13 -0
- package/template/.github/workflows/ci.yml +60 -0
- package/template/.prettierignore +7 -0
- package/template/.prettierrc +11 -0
- package/template/README.md +21 -0
- package/template/apps/admin/app/favicon.ico +0 -0
- package/template/apps/admin/app/layout.tsx +30 -0
- package/template/apps/admin/app/page.tsx +19 -0
- package/template/apps/admin/components/.gitkeep +0 -0
- package/template/apps/admin/components/theme-provider.tsx +71 -0
- package/template/apps/admin/components.json +23 -0
- package/template/apps/admin/eslint.config.js +4 -0
- package/template/apps/admin/hooks/.gitkeep +0 -0
- package/template/apps/admin/lib/.gitkeep +0 -0
- package/template/apps/admin/next-env.d.ts +6 -0
- package/template/apps/admin/next.config.mjs +6 -0
- package/template/apps/admin/nixpacks.toml +8 -0
- package/template/apps/admin/package.json +32 -0
- package/template/apps/admin/postcss.config.mjs +1 -0
- package/template/apps/admin/tsconfig.json +23 -0
- package/template/apps/api/nixpacks.toml +8 -0
- package/template/apps/api/package.json +32 -0
- package/template/apps/api/src/index.ts +11 -0
- package/template/apps/api/src/server.ts +21 -0
- package/template/apps/api/tsconfig.json +18 -0
- package/template/apps/web/app/favicon.ico +0 -0
- package/template/apps/web/app/layout.tsx +30 -0
- package/template/apps/web/app/page.tsx +19 -0
- package/template/apps/web/components/.gitkeep +0 -0
- package/template/apps/web/components/theme-provider.tsx +71 -0
- package/template/apps/web/components.json +23 -0
- package/template/apps/web/eslint.config.js +4 -0
- package/template/apps/web/hooks/.gitkeep +0 -0
- package/template/apps/web/lib/.gitkeep +0 -0
- package/template/apps/web/next-env.d.ts +6 -0
- package/template/apps/web/next.config.mjs +6 -0
- package/template/apps/web/nixpacks.toml +8 -0
- package/template/apps/web/package.json +32 -0
- package/template/apps/web/postcss.config.mjs +1 -0
- package/template/apps/web/tsconfig.json +23 -0
- package/template/infrastructure/docker/Dockerfile.admin +36 -0
- package/template/infrastructure/docker/Dockerfile.api +36 -0
- package/template/infrastructure/docker/Dockerfile.web +48 -0
- package/template/infrastructure/docker/compose.dev.yml +50 -0
- package/template/infrastructure/docker/compose.prod.yml +119 -0
- package/template/infrastructure/scripts/deploy.sh +3 -0
- package/template/infrastructure/scripts/dev.sh +5 -0
- package/template/infrastructure/scripts/init-traefik.sh +10 -0
- package/template/infrastructure/scripts/setup-server.sh +25 -0
- package/template/infrastructure/scripts/update.sh +7 -0
- package/template/infrastructure/traefik/acme.json +0 -0
- package/template/infrastructure/traefik/dynamic.yml +23 -0
- package/template/infrastructure/traefik/traefik.yml +26 -0
- package/template/package.json +25 -0
- package/template/packages/eslint-config/README.md +3 -0
- package/template/packages/eslint-config/base.js +32 -0
- package/template/packages/eslint-config/next.js +51 -0
- package/template/packages/eslint-config/package.json +26 -0
- package/template/packages/eslint-config/react-internal.js +41 -0
- package/template/packages/typescript-config/README.md +3 -0
- package/template/packages/typescript-config/base.json +20 -0
- package/template/packages/typescript-config/nextjs.json +13 -0
- package/template/packages/typescript-config/package.json +9 -0
- package/template/packages/typescript-config/react-library.json +8 -0
- package/template/packages/ui/components.json +23 -0
- package/template/packages/ui/eslint.config.js +4 -0
- package/template/packages/ui/package.json +52 -0
- package/template/packages/ui/postcss.config.mjs +6 -0
- package/template/packages/ui/src/components/.gitkeep +0 -0
- package/template/packages/ui/src/components/accordion.tsx +74 -0
- package/template/packages/ui/src/components/alert-dialog.tsx +187 -0
- package/template/packages/ui/src/components/alert.tsx +76 -0
- package/template/packages/ui/src/components/aspect-ratio.tsx +22 -0
- package/template/packages/ui/src/components/avatar.tsx +109 -0
- package/template/packages/ui/src/components/badge.tsx +52 -0
- package/template/packages/ui/src/components/breadcrumb.tsx +125 -0
- package/template/packages/ui/src/components/button-group.tsx +87 -0
- package/template/packages/ui/src/components/button.tsx +60 -0
- package/template/packages/ui/src/components/calendar.tsx +221 -0
- package/template/packages/ui/src/components/card.tsx +103 -0
- package/template/packages/ui/src/components/carousel.tsx +242 -0
- package/template/packages/ui/src/components/chart.tsx +356 -0
- package/template/packages/ui/src/components/checkbox.tsx +29 -0
- package/template/packages/ui/src/components/collapsible.tsx +21 -0
- package/template/packages/ui/src/components/combobox.tsx +297 -0
- package/template/packages/ui/src/components/command.tsx +196 -0
- package/template/packages/ui/src/components/context-menu.tsx +271 -0
- package/template/packages/ui/src/components/dialog.tsx +157 -0
- package/template/packages/ui/src/components/direction.tsx +6 -0
- package/template/packages/ui/src/components/drawer.tsx +131 -0
- package/template/packages/ui/src/components/dropdown-menu.tsx +268 -0
- package/template/packages/ui/src/components/empty.tsx +101 -0
- package/template/packages/ui/src/components/field.tsx +238 -0
- package/template/packages/ui/src/components/hover-card.tsx +51 -0
- package/template/packages/ui/src/components/input-group.tsx +158 -0
- package/template/packages/ui/src/components/input-otp.tsx +87 -0
- package/template/packages/ui/src/components/input.tsx +20 -0
- package/template/packages/ui/src/components/item.tsx +201 -0
- package/template/packages/ui/src/components/kbd.tsx +26 -0
- package/template/packages/ui/src/components/label.tsx +20 -0
- package/template/packages/ui/src/components/menubar.tsx +280 -0
- package/template/packages/ui/src/components/native-select.tsx +52 -0
- package/template/packages/ui/src/components/navigation-menu.tsx +168 -0
- package/template/packages/ui/src/components/pagination.tsx +130 -0
- package/template/packages/ui/src/components/popover.tsx +90 -0
- package/template/packages/ui/src/components/progress.tsx +83 -0
- package/template/packages/ui/src/components/radio-group.tsx +38 -0
- package/template/packages/ui/src/components/resizable.tsx +50 -0
- package/template/packages/ui/src/components/scroll-area.tsx +55 -0
- package/template/packages/ui/src/components/select.tsx +201 -0
- package/template/packages/ui/src/components/separator.tsx +25 -0
- package/template/packages/ui/src/components/sheet.tsx +135 -0
- package/template/packages/ui/src/components/sidebar.tsx +723 -0
- package/template/packages/ui/src/components/skeleton.tsx +13 -0
- package/template/packages/ui/src/components/slider.tsx +59 -0
- package/template/packages/ui/src/components/sonner.tsx +49 -0
- package/template/packages/ui/src/components/spinner.tsx +10 -0
- package/template/packages/ui/src/components/switch.tsx +32 -0
- package/template/packages/ui/src/components/table.tsx +116 -0
- package/template/packages/ui/src/components/tabs.tsx +82 -0
- package/template/packages/ui/src/components/textarea.tsx +18 -0
- package/template/packages/ui/src/components/toggle-group.tsx +89 -0
- package/template/packages/ui/src/components/toggle.tsx +44 -0
- package/template/packages/ui/src/components/tooltip.tsx +66 -0
- package/template/packages/ui/src/hooks/.gitkeep +0 -0
- package/template/packages/ui/src/hooks/use-mobile.ts +19 -0
- package/template/packages/ui/src/lib/.gitkeep +0 -0
- package/template/packages/ui/src/lib/utils.ts +6 -0
- package/template/packages/ui/src/styles/globals.css +128 -0
- package/template/packages/ui/tsconfig.json +11 -0
- package/template/packages/ui/tsconfig.lint.json +8 -0
- package/template/pnpm-lock.yaml +9103 -0
- package/template/pnpm-workspace.yaml +3 -0
- package/template/tsconfig.json +4 -0
- package/template/turbo.json +24 -0
package/README.md
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# create-rykira-app
|
|
2
|
+
|
|
3
|
+
A powerful, production-ready full-stack starter template generator.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Monorepo**: Powered by Turborepo and pnpm workspaces.
|
|
8
|
+
- **Frontend**: Next.js 15 (App Router), React 19, Tailwind CSS v4.
|
|
9
|
+
- **UI Library**: Shared Shadcn/UI component library.
|
|
10
|
+
- **Backend**: Express.js with TypeScript, Zod validation.
|
|
11
|
+
- **Infrastructure**:
|
|
12
|
+
- Docker Compose for Dev & Prod.
|
|
13
|
+
- Traefik v3 Reverse Proxy with Let's Encrypt.
|
|
14
|
+
- Postgres & Redis.
|
|
15
|
+
- **Deployment**: Ready for Coolify or manual VPS deployment.
|
|
16
|
+
|
|
17
|
+
## Usage
|
|
18
|
+
|
|
19
|
+
Run the following command to scaffold a new project:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npx create-rykira-app my-app
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Follow the interactive prompts to customize your project:
|
|
26
|
+
- Project Name
|
|
27
|
+
- Description
|
|
28
|
+
- Author
|
|
29
|
+
- Include/Exclude Admin Panel
|
|
30
|
+
- Include/Exclude Express API
|
|
31
|
+
|
|
32
|
+
## Getting Started
|
|
33
|
+
|
|
34
|
+
Once created:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
cd my-app
|
|
38
|
+
pnpm install
|
|
39
|
+
cp .env.example .env
|
|
40
|
+
# Update .env variables if needed
|
|
41
|
+
pnpm dev
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Deployment
|
|
45
|
+
|
|
46
|
+
Refer to `plan.md` (included in the template) or the generated README for detailed deployment instructions.
|
|
47
|
+
|
|
48
|
+
## License
|
|
49
|
+
|
|
50
|
+
MIT
|
package/bin/cli.js
ADDED
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { Command } from 'commander';
|
|
4
|
+
import inquirer from 'inquirer';
|
|
5
|
+
import fs from 'fs-extra';
|
|
6
|
+
import path from 'path';
|
|
7
|
+
import { fileURLToPath } from 'url';
|
|
8
|
+
import chalk from 'chalk';
|
|
9
|
+
import ora from 'ora';
|
|
10
|
+
import Handlebars from 'handlebars';
|
|
11
|
+
|
|
12
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
13
|
+
const __dirname = path.dirname(__filename);
|
|
14
|
+
|
|
15
|
+
const program = new Command();
|
|
16
|
+
|
|
17
|
+
program
|
|
18
|
+
.name('create-rykira-app')
|
|
19
|
+
.description('Scaffold a new Rykira Starter Package project')
|
|
20
|
+
.version('1.0.0')
|
|
21
|
+
.argument('[project-directory]', 'Directory to create the project in')
|
|
22
|
+
.action(async (projectDirectory) => {
|
|
23
|
+
console.log(chalk.bold.blue('🚀 Welcome to Rykira Starter App Generator!'));
|
|
24
|
+
|
|
25
|
+
let targetDir = projectDirectory;
|
|
26
|
+
|
|
27
|
+
if (!targetDir) {
|
|
28
|
+
const answers = await inquirer.prompt([
|
|
29
|
+
{
|
|
30
|
+
type: 'input',
|
|
31
|
+
name: 'projectName',
|
|
32
|
+
message: 'What is the name of your project?',
|
|
33
|
+
default: 'my-rykira-app',
|
|
34
|
+
validate: (input) => {
|
|
35
|
+
if (/^([a-z0-9\-\_\.]+)$/.test(input)) return true;
|
|
36
|
+
return 'Project name may only include lower-case letters, numbers, dashes, underscores, and dots.';
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
]);
|
|
40
|
+
targetDir = answers.projectName;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const rootDir = path.resolve(process.cwd(), targetDir);
|
|
44
|
+
|
|
45
|
+
if (fs.existsSync(rootDir)) {
|
|
46
|
+
console.error(chalk.red(`Error: Directory ${targetDir} already exists.`));
|
|
47
|
+
process.exit(1);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const promptAnswers = await inquirer.prompt([
|
|
51
|
+
{
|
|
52
|
+
type: 'input',
|
|
53
|
+
name: 'description',
|
|
54
|
+
message: 'Project description:',
|
|
55
|
+
default: 'A modern full-stack application',
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
type: 'input',
|
|
59
|
+
name: 'author',
|
|
60
|
+
message: 'Author name:',
|
|
61
|
+
default: 'Rykira User',
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
type: 'confirm',
|
|
65
|
+
name: 'includeAdmin',
|
|
66
|
+
message: 'Include Admin Panel?',
|
|
67
|
+
default: true,
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
type: 'confirm',
|
|
71
|
+
name: 'includeApi',
|
|
72
|
+
message: 'Include Express API?',
|
|
73
|
+
default: true,
|
|
74
|
+
},
|
|
75
|
+
]);
|
|
76
|
+
|
|
77
|
+
const spinner = ora(`Creating project in ${chalk.green(rootDir)}...`).start();
|
|
78
|
+
|
|
79
|
+
try {
|
|
80
|
+
// Copy template files
|
|
81
|
+
const templateDir = path.resolve(__dirname, '../template');
|
|
82
|
+
await fs.copy(templateDir, rootDir, {
|
|
83
|
+
filter: (src) => {
|
|
84
|
+
// Avoid copying node_modules
|
|
85
|
+
return !src.includes('node_modules');
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
// Process Handlebars templates
|
|
90
|
+
const packageJsonPath = path.join(rootDir, 'package.json');
|
|
91
|
+
const packageJsonContent = await fs.readFile(packageJsonPath, 'utf-8');
|
|
92
|
+
const template = Handlebars.compile(packageJsonContent);
|
|
93
|
+
const result = template({
|
|
94
|
+
projectName: path.basename(rootDir),
|
|
95
|
+
projectDescription: promptAnswers.description,
|
|
96
|
+
authorName: promptAnswers.author,
|
|
97
|
+
});
|
|
98
|
+
await fs.writeFile(packageJsonPath, result);
|
|
99
|
+
|
|
100
|
+
// Handle Admin Panel removal
|
|
101
|
+
if (!promptAnswers.includeAdmin) {
|
|
102
|
+
spinner.text = 'Removing Admin Panel...';
|
|
103
|
+
await fs.remove(path.join(rootDir, 'apps/admin'));
|
|
104
|
+
await fs.remove(path.join(rootDir, 'infrastructure/docker/Dockerfile.admin'));
|
|
105
|
+
// Note: You might need to clean up pnpm-workspace.yaml or turbo.json if strict
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// Handle API removal
|
|
109
|
+
if (!promptAnswers.includeApi) {
|
|
110
|
+
spinner.text = 'Removing Express API...';
|
|
111
|
+
await fs.remove(path.join(rootDir, 'apps/api'));
|
|
112
|
+
await fs.remove(path.join(rootDir, 'infrastructure/docker/Dockerfile.api'));
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// Update Compose files with project name
|
|
116
|
+
const composeProdPath = path.join(rootDir, 'infrastructure/docker/compose.prod.yml');
|
|
117
|
+
const composeDevPath = path.join(rootDir, 'infrastructure/docker/compose.dev.yml');
|
|
118
|
+
|
|
119
|
+
const updateComposeFile = async (filePath) => {
|
|
120
|
+
if (fs.existsSync(filePath)) {
|
|
121
|
+
const content = await fs.readFile(filePath, 'utf-8');
|
|
122
|
+
const composeTemplate = Handlebars.compile(content);
|
|
123
|
+
const composeResult = composeTemplate({
|
|
124
|
+
projectName: path.basename(rootDir)
|
|
125
|
+
});
|
|
126
|
+
await fs.writeFile(filePath, composeResult);
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
await updateComposeFile(composeProdPath);
|
|
131
|
+
await updateComposeFile(composeDevPath);
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
spinner.succeed(chalk.green('Project created successfully!'));
|
|
135
|
+
|
|
136
|
+
console.log('\nNext steps:');
|
|
137
|
+
console.log(chalk.cyan(` cd ${targetDir}`));
|
|
138
|
+
console.log(chalk.cyan(' pnpm install'));
|
|
139
|
+
console.log(chalk.cyan(' cp .env.example .env'));
|
|
140
|
+
console.log(chalk.cyan(' pnpm dev'));
|
|
141
|
+
|
|
142
|
+
} catch (error) {
|
|
143
|
+
spinner.fail(chalk.red('Failed to create project'));
|
|
144
|
+
console.error(error);
|
|
145
|
+
process.exit(1);
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
program.parse(process.argv);
|
package/deployment.md
ADDED
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
# Deployment Guide
|
|
2
|
+
|
|
3
|
+
This guide covers how to deploy the Rykira Starter Package application using Coolify (automated) or manually using Docker and Traefik on a VPS.
|
|
4
|
+
|
|
5
|
+
## Table of Contents
|
|
6
|
+
|
|
7
|
+
- [Prerequisites](#prerequisites)
|
|
8
|
+
- [Environment Configuration](#environment-configuration)
|
|
9
|
+
- [Option 1: Deploy with Coolify (Recommended)](#option-1-deploy-with-coolify-recommended)
|
|
10
|
+
- [Option 2: Manual Deployment (Docker & Traefik)](#option-2-manual-deployment-docker--traefik)
|
|
11
|
+
- [Post-Deployment Verification](#post-deployment-verification)
|
|
12
|
+
- [Troubleshooting](#troubleshooting)
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Prerequisites
|
|
17
|
+
|
|
18
|
+
- **Domain Name**: A domain name pointing to your server IP (e.g., `example.com`, `*.example.com`).
|
|
19
|
+
- **VPS/Server**: A server running Ubuntu 22.04/24.04 (minimum 2GB RAM, 2 vCPUs recommended).
|
|
20
|
+
- **Git Repository**: Your project pushed to a Git provider (GitHub, GitLab, etc.).
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Environment Configuration
|
|
25
|
+
|
|
26
|
+
All deployments require a `.env` file. Use the `.env.example` as a template.
|
|
27
|
+
|
|
28
|
+
### Required Variables
|
|
29
|
+
|
|
30
|
+
```env
|
|
31
|
+
# Domain Configuration
|
|
32
|
+
DOMAIN=example.com
|
|
33
|
+
ACME_EMAIL=admin@example.com
|
|
34
|
+
|
|
35
|
+
# Postgres Configuration
|
|
36
|
+
POSTGRES_USER=postgres
|
|
37
|
+
POSTGRES_PASSWORD=secure_password_here
|
|
38
|
+
POSTGRES_DB=rykira
|
|
39
|
+
|
|
40
|
+
# Redis Configuration
|
|
41
|
+
REDIS_PASSWORD=secure_redis_password_here
|
|
42
|
+
|
|
43
|
+
# Database Connection Strings (Internal Docker Network)
|
|
44
|
+
DATABASE_URL=postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB}
|
|
45
|
+
REDIS_URL=redis://:${REDIS_PASSWORD}@redis:6379
|
|
46
|
+
|
|
47
|
+
# App Secrets
|
|
48
|
+
NEXTAUTH_SECRET=generate_a_long_random_string
|
|
49
|
+
auth_secret=generate_a_long_random_string
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## Option 1: Deploy with Coolify (Recommended)
|
|
55
|
+
|
|
56
|
+
Coolify is an open-source, self-hostable Heroku alternative that makes deployment easy.
|
|
57
|
+
|
|
58
|
+
### Step 1: Prepare Your Project
|
|
59
|
+
1. Ensure `nixpacks.toml` files exist in `apps/web`, `apps/admin`, and `apps/api` (included in this template).
|
|
60
|
+
2. Push your code to a GitHub repository.
|
|
61
|
+
|
|
62
|
+
### Step 2: Configure Coolify
|
|
63
|
+
1. **Create a Project** in your Coolify dashboard.
|
|
64
|
+
2. **Add a Resource**: Select **Git Repository** (Private or Public).
|
|
65
|
+
3. **Select Repository**: Choose your project repo.
|
|
66
|
+
|
|
67
|
+
### Step 3: Add Services
|
|
68
|
+
You will deploy each app as a separate resource, or use a Docker Compose stack.
|
|
69
|
+
|
|
70
|
+
#### Method A: Docker Compose Stack (Easiest)
|
|
71
|
+
1. In Coolify, select **Docker Compose**.
|
|
72
|
+
2. Paste the contents of `infrastructure/docker/compose.prod.yml`.
|
|
73
|
+
3. **IMPORTANT**: Replace `{{projectName}}` with your actual project name in the Compose file content before pasting, or ensure you set it as a variable if Coolify supports it.
|
|
74
|
+
4. Go to **Environment Variables** in Coolify and add all variables from your `.env` file.
|
|
75
|
+
5. Click **Deploy**.
|
|
76
|
+
|
|
77
|
+
#### Method B: Individual Services (Nixpacks)
|
|
78
|
+
1. **Web App (`apps/web`)**:
|
|
79
|
+
- **Build Pack**: Nixpacks
|
|
80
|
+
- **Base Directory**: `/`
|
|
81
|
+
- **Build Command**: `pnpm install && pnpm turbo build --filter=web...`
|
|
82
|
+
- **Start Command**: `pnpm start:web`
|
|
83
|
+
- **Environment Variables**: Add all required envs.
|
|
84
|
+
- **Domains**: Set to `https://app.example.com`.
|
|
85
|
+
|
|
86
|
+
2. **API (`apps/api`)**:
|
|
87
|
+
- **Build Pack**: Nixpacks
|
|
88
|
+
- **Base Directory**: `/`
|
|
89
|
+
- **Build Command**: `pnpm install && pnpm turbo build --filter=api...`
|
|
90
|
+
- **Start Command**: `node apps/api/dist/index.js`
|
|
91
|
+
- **Environment Variables**: Add all required envs.
|
|
92
|
+
- **Domains**: Set to `https://api.example.com`.
|
|
93
|
+
|
|
94
|
+
3. **Database & Redis**:
|
|
95
|
+
- Use Coolify's **Databases** tab to provision PostgreSQL and Redis.
|
|
96
|
+
- Update your App's `DATABASE_URL` and `REDIS_URL` to point to these internal Coolify databases.
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
## Option 2: Manual Deployment (Docker & Traefik)
|
|
101
|
+
|
|
102
|
+
This method gives you full control using standard Docker Compose and Traefik v3 as a reverse proxy.
|
|
103
|
+
|
|
104
|
+
### Step 1: Server Setup
|
|
105
|
+
1. SSH into your server.
|
|
106
|
+
2. Clone your repository:
|
|
107
|
+
```bash
|
|
108
|
+
git clone https://github.com/your/repo.git my-app
|
|
109
|
+
cd my-app
|
|
110
|
+
```
|
|
111
|
+
3. Run the setup script to install Docker and configure UFW firewall:
|
|
112
|
+
```bash
|
|
113
|
+
chmod +x infrastructure/scripts/setup-server.sh
|
|
114
|
+
./infrastructure/scripts/setup-server.sh
|
|
115
|
+
```
|
|
116
|
+
*You may need to log out and log back in for Docker group changes to take effect.*
|
|
117
|
+
|
|
118
|
+
### Step 2: Traefik Initialization
|
|
119
|
+
1. Initialize the ACME JSON file for SSL certificates:
|
|
120
|
+
```bash
|
|
121
|
+
chmod +x infrastructure/scripts/init-traefik.sh
|
|
122
|
+
./infrastructure/scripts/init-traefik.sh
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### Step 3: Deploy
|
|
126
|
+
1. Create your `.env` file:
|
|
127
|
+
```bash
|
|
128
|
+
cp .env.example .env
|
|
129
|
+
nano .env
|
|
130
|
+
# Fill in your secrets and domain
|
|
131
|
+
```
|
|
132
|
+
2. Run the deployment script:
|
|
133
|
+
```bash
|
|
134
|
+
chmod +x infrastructure/scripts/deploy.sh
|
|
135
|
+
./infrastructure/scripts/deploy.sh
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### Step 4: Verify
|
|
139
|
+
- Check running containers: `docker compose ps`
|
|
140
|
+
- View logs: `docker compose logs -f`
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
## Post-Deployment Verification
|
|
145
|
+
|
|
146
|
+
1. **Check Health**:
|
|
147
|
+
- Visit `https://api.example.com/health` (should return JSON status).
|
|
148
|
+
2. **Check SSL**:
|
|
149
|
+
- Visit `https://app.example.com` - ensure lock icon is present.
|
|
150
|
+
3. **Database Connection**:
|
|
151
|
+
- Verify the API can read/write to the database (try logging in or creating a user).
|
|
152
|
+
|
|
153
|
+
---
|
|
154
|
+
|
|
155
|
+
## Troubleshooting
|
|
156
|
+
|
|
157
|
+
### "Acme.json permission denied"
|
|
158
|
+
- Run: `chmod 600 infrastructure/traefik/acme.json`
|
|
159
|
+
|
|
160
|
+
### "Gateway Timeout" (504)
|
|
161
|
+
- Check if the app container is running: `docker compose ps`
|
|
162
|
+
- Check logs: `docker compose logs web`
|
|
163
|
+
- Ensure the port in `compose.prod.yml` matches the app's listening port (default 3000 for web, 4000 for api).
|
|
164
|
+
|
|
165
|
+
### Database Connection Error
|
|
166
|
+
- Ensure `DATABASE_URL` is using the container name `postgres` (not `localhost`) if running inside Docker.
|
|
167
|
+
- Check if Postgres is healthy: `docker compose ps postgres`
|
|
168
|
+
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# How to Deploy as an NPM Package
|
|
2
|
+
|
|
3
|
+
This guide explains how to package, test, and publish the `create-rykira-app` CLI tool to the npm registry.
|
|
4
|
+
|
|
5
|
+
## Prerequisites
|
|
6
|
+
|
|
7
|
+
- **npm Account**: Create one at [npmjs.com](https://www.npmjs.com/).
|
|
8
|
+
- **Login**: Run `npm login` in your terminal.
|
|
9
|
+
|
|
10
|
+
## Package Configuration
|
|
11
|
+
|
|
12
|
+
Ensure `package.json` in the root is configured correctly (already done in this template):
|
|
13
|
+
|
|
14
|
+
```json
|
|
15
|
+
{
|
|
16
|
+
"name": "create-rykira-app",
|
|
17
|
+
"version": "1.0.0",
|
|
18
|
+
"bin": {
|
|
19
|
+
"create-rykira-app": "./bin/cli.js"
|
|
20
|
+
},
|
|
21
|
+
"files": [
|
|
22
|
+
"bin",
|
|
23
|
+
"template",
|
|
24
|
+
"project.json",
|
|
25
|
+
"plan.md"
|
|
26
|
+
],
|
|
27
|
+
"engines": {
|
|
28
|
+
"node": ">=18"
|
|
29
|
+
}
|
|
30
|
+
// ... dependencies
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
**Critical Files to Include**:
|
|
35
|
+
- `bin/`: The executable CLI logic.
|
|
36
|
+
- `template/`: The actual starter project files.
|
|
37
|
+
- `project.json` & `plan.md`: Metadata and docs.
|
|
38
|
+
|
|
39
|
+
**Critical Files to Ignore (`.npmignore`)**:
|
|
40
|
+
- `node_modules`
|
|
41
|
+
- `.git`
|
|
42
|
+
- `.env`
|
|
43
|
+
- `test-project` (local test folders)
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## Testing Locally
|
|
48
|
+
|
|
49
|
+
Before publishing, always test the package locally to ensure it works as expected.
|
|
50
|
+
|
|
51
|
+
### 1. Link the Package
|
|
52
|
+
Run this in the project root:
|
|
53
|
+
```bash
|
|
54
|
+
npm link
|
|
55
|
+
```
|
|
56
|
+
This makes the `create-rykira-app` command available globally on your machine, pointing to your local code.
|
|
57
|
+
|
|
58
|
+
### 2. Test the Command
|
|
59
|
+
Go to a temporary directory and run:
|
|
60
|
+
```bash
|
|
61
|
+
create-rykira-app my-test-project
|
|
62
|
+
```
|
|
63
|
+
- Verify all prompts appear.
|
|
64
|
+
- Verify the directory is created.
|
|
65
|
+
- Verify files are copied correctly.
|
|
66
|
+
- Verify Handlebars replacements (Project Name in `package.json`, `docker-compose.yml`) worked.
|
|
67
|
+
- Verify optional modules (Admin, API) were removed if deselected.
|
|
68
|
+
|
|
69
|
+
### 3. Unlink
|
|
70
|
+
After testing, remove the global link:
|
|
71
|
+
```bash
|
|
72
|
+
npm unlink -g create-rykira-app
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
77
|
+
## Publishing to NPM
|
|
78
|
+
|
|
79
|
+
### 1. Version Management
|
|
80
|
+
Update the version number in `package.json` according to SemVer:
|
|
81
|
+
```bash
|
|
82
|
+
npm version patch # 1.0.0 -> 1.0.1
|
|
83
|
+
# or
|
|
84
|
+
npm version minor # 1.0.0 -> 1.1.0
|
|
85
|
+
# or
|
|
86
|
+
npm version major # 1.0.0 -> 2.0.0
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### 2. Publish
|
|
90
|
+
Run the publish command:
|
|
91
|
+
```bash
|
|
92
|
+
npm publish --access public
|
|
93
|
+
```
|
|
94
|
+
*Note: The `--access public` flag is required for scoped packages (`@username/package`), but good practice generally.*
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## Quality Assurance Checklist
|
|
99
|
+
|
|
100
|
+
- [ ] **Clean Install**: `npm install` runs without errors in the generated project.
|
|
101
|
+
- [ ] **Scripts Work**: `pnpm dev`, `pnpm build` work in the generated project.
|
|
102
|
+
- [ ] **Docker Compose**: `docker compose up` works in the generated project.
|
|
103
|
+
- [ ] **Template Integrity**: No `node_modules` or `.git` folders inside the `template/` directory before publishing (npm usually ignores them, but double-check).
|
|
104
|
+
- [ ] **Executable**: `bin/cli.js` has `#!/usr/bin/env node` at the top and is executable (`chmod +x`).
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
## Continuous Delivery (Optional)
|
|
109
|
+
|
|
110
|
+
You can automate publishing using the included GitHub Actions workflow (`.github/workflows/release.yml` - *to be created if desired*).
|
|
111
|
+
|
|
112
|
+
Example `release.yml`:
|
|
113
|
+
```yaml
|
|
114
|
+
name: Release
|
|
115
|
+
on:
|
|
116
|
+
push:
|
|
117
|
+
tags:
|
|
118
|
+
- 'v*'
|
|
119
|
+
jobs:
|
|
120
|
+
publish:
|
|
121
|
+
runs-on: ubuntu-latest
|
|
122
|
+
steps:
|
|
123
|
+
- uses: actions/checkout@v4
|
|
124
|
+
- uses: actions/setup-node@v4
|
|
125
|
+
with:
|
|
126
|
+
node-version: 20
|
|
127
|
+
registry-url: 'https://registry.npmjs.org'
|
|
128
|
+
- run: npm install
|
|
129
|
+
- run: npm publish
|
|
130
|
+
env:
|
|
131
|
+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
132
|
+
```
|
package/package.json
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "create-rykira-app",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "CLI to scaffold Rykira Starter Package",
|
|
5
|
+
"bin": {
|
|
6
|
+
"create-rykira-app": "./bin/cli.js"
|
|
7
|
+
},
|
|
8
|
+
"scripts": {
|
|
9
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
10
|
+
},
|
|
11
|
+
"dependencies": {
|
|
12
|
+
"chalk": "^5.3.0",
|
|
13
|
+
"commander": "^12.0.0",
|
|
14
|
+
"fs-extra": "^11.2.0",
|
|
15
|
+
"handlebars": "^4.7.8",
|
|
16
|
+
"inquirer": "^9.2.15",
|
|
17
|
+
"ora": "^8.0.1"
|
|
18
|
+
},
|
|
19
|
+
"engines": {
|
|
20
|
+
"node": ">=18"
|
|
21
|
+
},
|
|
22
|
+
"type": "module"
|
|
23
|
+
}
|
package/starter-usage.md
ADDED
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# Starter Usage Guide
|
|
2
|
+
|
|
3
|
+
This guide provides a detailed overview of the Rykira Starter Package monorepo structure, development workflow, and how to use the included packages.
|
|
4
|
+
|
|
5
|
+
## Monorepo Structure
|
|
6
|
+
|
|
7
|
+
This project uses [Turborepo](https://turbo.build/) and [pnpm workspaces](https://pnpm.io/workspaces) to manage multiple applications and packages in a single repository.
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
.
|
|
11
|
+
├── apps/ # Application source code
|
|
12
|
+
│ ├── web/ # Next.js public-facing app
|
|
13
|
+
│ ├── admin/ # Next.js admin dashboard
|
|
14
|
+
│ └── api/ # Express.js backend API
|
|
15
|
+
├── packages/ # Shared libraries
|
|
16
|
+
│ ├── ui/ # Shadcn/UI component library
|
|
17
|
+
│ ├── eslint-config/ # Shared ESLint configurations
|
|
18
|
+
│ └── typescript-config/ # Shared TypeScript configurations
|
|
19
|
+
├── infrastructure/ # Deployment & DevOps configs
|
|
20
|
+
│ ├── docker/ # Dockerfiles & Compose files
|
|
21
|
+
│ ├── scripts/ # Helper bash scripts
|
|
22
|
+
│ └── traefik/ # Traefik proxy config
|
|
23
|
+
└── package.json # Root configuration
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## Setting Up Development Environment
|
|
29
|
+
|
|
30
|
+
### Prerequisites
|
|
31
|
+
- Node.js >= 18
|
|
32
|
+
- pnpm >= 9 (`npm install -g pnpm`)
|
|
33
|
+
- Docker & Docker Compose (optional, for local DB/Redis)
|
|
34
|
+
|
|
35
|
+
### Installation
|
|
36
|
+
|
|
37
|
+
1. **Install Dependencies**:
|
|
38
|
+
```bash
|
|
39
|
+
pnpm install
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
2. **Environment Variables**:
|
|
43
|
+
Copy the example file:
|
|
44
|
+
```bash
|
|
45
|
+
cp .env.example .env
|
|
46
|
+
```
|
|
47
|
+
*Note: The default `.env` is configured to work out-of-the-box with the local Docker setup.*
|
|
48
|
+
|
|
49
|
+
3. **Start Infrastructure (DB & Redis)**:
|
|
50
|
+
Start Postgres and Redis containers in the background:
|
|
51
|
+
```bash
|
|
52
|
+
./infrastructure/scripts/dev.sh
|
|
53
|
+
```
|
|
54
|
+
*Or manually: `docker compose -f infrastructure/docker/compose.dev.yml up -d`*
|
|
55
|
+
|
|
56
|
+
4. **Start Applications**:
|
|
57
|
+
Run all apps in development mode:
|
|
58
|
+
```bash
|
|
59
|
+
pnpm dev
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
- **Web**: http://localhost:3000
|
|
63
|
+
- **Admin**: http://localhost:3001
|
|
64
|
+
- **API**: http://localhost:4000
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## Package Usage Guide
|
|
69
|
+
|
|
70
|
+
### 1. UI Package (`packages/ui`)
|
|
71
|
+
A shared component library built with [Shadcn/UI](https://ui.shadcn.com/) and Tailwind CSS v4.
|
|
72
|
+
|
|
73
|
+
- **Location**: `packages/ui/src/components`
|
|
74
|
+
- **Usage in Apps**:
|
|
75
|
+
```tsx
|
|
76
|
+
import { Button } from "@workspace/ui/components/button";
|
|
77
|
+
|
|
78
|
+
export default function Page() {
|
|
79
|
+
return <Button>Click me</Button>;
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
- **Adding New Components**:
|
|
83
|
+
Currently, you manually add Shadcn components to `packages/ui/src/components`.
|
|
84
|
+
*Tip: You can run `npx shadcn@latest add [component]` inside the `packages/ui` folder if configured.*
|
|
85
|
+
|
|
86
|
+
### 2. Apps (`web`, `admin`)
|
|
87
|
+
Next.js 15 applications using the App Router.
|
|
88
|
+
|
|
89
|
+
- **Styling**: Tailwind CSS v4 is configured. It imports the shared config from `@workspace/ui`.
|
|
90
|
+
- **Fetching Data**:
|
|
91
|
+
You can fetch data directly from the DB (Server Components) or call the Express API.
|
|
92
|
+
|
|
93
|
+
### 3. API (`apps/api`)
|
|
94
|
+
Express.js backend with TypeScript.
|
|
95
|
+
|
|
96
|
+
- **Endpoints**: Defined in `src/server.ts` or router files.
|
|
97
|
+
- **Validation**: Uses `zod` for request validation.
|
|
98
|
+
- **Database**: Connects to Postgres using `pg` or an ORM (Prisma/Drizzle recommended to be added).
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## Development Workflow
|
|
103
|
+
|
|
104
|
+
### Adding Dependencies
|
|
105
|
+
To add a dependency to a specific app (e.g., `web`):
|
|
106
|
+
```bash
|
|
107
|
+
pnpm add [package-name] --filter web
|
|
108
|
+
```
|
|
109
|
+
To add to the root workspace:
|
|
110
|
+
```bash
|
|
111
|
+
pnpm add [package-name] -w
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### Running Commands
|
|
115
|
+
- **Build all**: `pnpm build`
|
|
116
|
+
- **Lint all**: `pnpm lint`
|
|
117
|
+
- **Typecheck**: `pnpm typecheck`
|
|
118
|
+
- **Run command on specific app**: `pnpm --filter web run [command]`
|
|
119
|
+
|
|
120
|
+
### Database Management
|
|
121
|
+
The starter uses a raw Docker Postgres container.
|
|
122
|
+
- **Connect**: Use a GUI like DBeaver or TablePlus with credentials from `.env`.
|
|
123
|
+
- **Persistence**: Data is stored in the `postgres_data` Docker volume.
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
|
|
127
|
+
## Best Practices
|
|
128
|
+
|
|
129
|
+
1. **Shared Code**: Put reusable logic (utilities, types, constants) in a `packages/core` or `packages/lib` package (create one if needed) to share between API and Frontend.
|
|
130
|
+
2. **Environment Variables**: Always validate env vars (e.g., using `t3-env` or `zod`) at the start of your application.
|
|
131
|
+
3. **Type Safety**: Share TypeScript interfaces/types via a shared package to ensure contract safety between API and Frontend.
|
|
132
|
+
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# Domain Configuration
|
|
2
|
+
DOMAIN=localhost
|
|
3
|
+
# ACME Email for Let's Encrypt
|
|
4
|
+
ACME_EMAIL=admin@example.com
|
|
5
|
+
|
|
6
|
+
# Postgres Configuration
|
|
7
|
+
POSTGRES_USER=postgres
|
|
8
|
+
POSTGRES_PASSWORD=postgres
|
|
9
|
+
POSTGRES_DB=rykira
|
|
10
|
+
|
|
11
|
+
# Redis Configuration
|
|
12
|
+
REDIS_PASSWORD=
|
|
13
|
+
|
|
14
|
+
# Database Connection Strings (Docker Internal)
|
|
15
|
+
DATABASE_URL=postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB}
|
|
16
|
+
REDIS_URL=redis://redis:6379
|
|
17
|
+
|
|
18
|
+
# App Secrets (Generate strong random strings for production)
|
|
19
|
+
NEXTAUTH_SECRET=changeme
|
|
20
|
+
auth_secret=changeme
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// Root-level ESLint config for a Turborepo workspace.
|
|
2
|
+
// App/package lint rules live in each workspace's eslint.config.js.
|
|
3
|
+
/** @type {import("eslint").Linter.Config} */
|
|
4
|
+
module.exports = {
|
|
5
|
+
root: true,
|
|
6
|
+
ignorePatterns: [
|
|
7
|
+
"**/node_modules/**",
|
|
8
|
+
"**/.next/**",
|
|
9
|
+
"**/dist/**",
|
|
10
|
+
"**/.turbo/**",
|
|
11
|
+
"**/coverage/**",
|
|
12
|
+
],
|
|
13
|
+
}
|