Initial monorepo scaffold
Turborepo + pnpm monorepo for k3s homelab cluster on Intel NUCs. - Apps: Next.js web frontend, Express API (TypeScript, Dockerfiles, k8s manifests) - Packages: shared UI, ESLint config, TypeScript config, Drizzle DB schemas - Infra/Ansible: bare-metal provisioning with roles for common, k3s-server, k3s-agent, hardening - Infra/Kubernetes: ArgoCD GitOps (app-of-apps + ApplicationSets), platform components (cert-manager, Traefik, CloudNativePG, Valkey, Longhorn, Sealed Secrets), namespaces - Observability: kube-prometheus-stack, Loki, Promtail as ArgoCD Applications - CI/CD: GitHub Actions for PR builds, preview deploys, production deploys - DX: Taskfile, utility scripts, copier templates, Ubiquiti network docs
This commit is contained in:
6
packages/config-eslint/index.js
Normal file
6
packages/config-eslint/index.js
Normal file
@@ -0,0 +1,6 @@
|
||||
module.exports = {
|
||||
extends: ["next/core-web-vitals", "prettier"],
|
||||
rules: {
|
||||
"no-console": "warn",
|
||||
},
|
||||
};
|
||||
10
packages/config-eslint/package.json
Normal file
10
packages/config-eslint/package.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"name": "@homelab/config-eslint",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"main": "./index.js",
|
||||
"dependencies": {
|
||||
"eslint-config-next": "^15.1.0",
|
||||
"eslint-config-prettier": "^9.1.0"
|
||||
}
|
||||
}
|
||||
13
packages/config-typescript/base.json
Normal file
13
packages/config-typescript/base.json
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"strict": true,
|
||||
"esModuleInterop": true,
|
||||
"skipLibCheck": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"declaration": true,
|
||||
"declarationMap": true
|
||||
},
|
||||
"exclude": ["node_modules"]
|
||||
}
|
||||
14
packages/config-typescript/nextjs.json
Normal file
14
packages/config-typescript/nextjs.json
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"extends": "./base.json",
|
||||
"compilerOptions": {
|
||||
"target": "ES2017",
|
||||
"lib": ["dom", "dom.iterable", "esnext"],
|
||||
"allowJs": true,
|
||||
"noEmit": true,
|
||||
"module": "esnext",
|
||||
"moduleResolution": "bundler",
|
||||
"jsx": "preserve",
|
||||
"incremental": true,
|
||||
"plugins": [{ "name": "next" }]
|
||||
}
|
||||
}
|
||||
10
packages/config-typescript/node.json
Normal file
10
packages/config-typescript/node.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"extends": "./base.json",
|
||||
"compilerOptions": {
|
||||
"target": "ES2022",
|
||||
"module": "commonjs",
|
||||
"lib": ["ES2022"],
|
||||
"outDir": "./dist",
|
||||
"sourceMap": true
|
||||
}
|
||||
}
|
||||
6
packages/config-typescript/package.json
Normal file
6
packages/config-typescript/package.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"name": "@homelab/config-typescript",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"files": ["base.json", "nextjs.json", "node.json"]
|
||||
}
|
||||
10
packages/db/drizzle.config.ts
Normal file
10
packages/db/drizzle.config.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import { defineConfig } from "drizzle-kit";
|
||||
|
||||
export default defineConfig({
|
||||
schema: "./src/schema.ts",
|
||||
out: "./drizzle",
|
||||
dialect: "postgresql",
|
||||
dbCredentials: {
|
||||
url: process.env.DATABASE_URL!,
|
||||
},
|
||||
});
|
||||
22
packages/db/package.json
Normal file
22
packages/db/package.json
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"name": "@homelab/db",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"main": "./src/index.ts",
|
||||
"types": "./src/index.ts",
|
||||
"scripts": {
|
||||
"lint": "tsc --noEmit",
|
||||
"build": "tsc",
|
||||
"db:generate": "drizzle-kit generate",
|
||||
"db:migrate": "drizzle-kit migrate",
|
||||
"db:studio": "drizzle-kit studio"
|
||||
},
|
||||
"dependencies": {
|
||||
"drizzle-orm": "^0.36.0",
|
||||
"postgres": "^3.4.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"drizzle-kit": "^0.28.0",
|
||||
"typescript": "^5.7.0"
|
||||
}
|
||||
}
|
||||
8
packages/db/src/client.ts
Normal file
8
packages/db/src/client.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
import { drizzle } from "drizzle-orm/postgres-js";
|
||||
import postgres from "postgres";
|
||||
import * as schema from "./schema";
|
||||
|
||||
const connectionString = process.env.DATABASE_URL!;
|
||||
const client = postgres(connectionString);
|
||||
|
||||
export const db = drizzle(client, { schema });
|
||||
2
packages/db/src/index.ts
Normal file
2
packages/db/src/index.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export * from "./schema";
|
||||
export * from "./client";
|
||||
9
packages/db/src/schema.ts
Normal file
9
packages/db/src/schema.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import { pgTable, serial, text, timestamp } from "drizzle-orm/pg-core";
|
||||
|
||||
export const users = pgTable("users", {
|
||||
id: serial("id").primaryKey(),
|
||||
email: text("email").notNull().unique(),
|
||||
name: text("name"),
|
||||
createdAt: timestamp("created_at").defaultNow().notNull(),
|
||||
updatedAt: timestamp("updated_at").defaultNow().notNull(),
|
||||
});
|
||||
14
packages/db/tsconfig.json
Normal file
14
packages/db/tsconfig.json
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2022",
|
||||
"module": "commonjs",
|
||||
"lib": ["ES2022"],
|
||||
"strict": true,
|
||||
"esModuleInterop": true,
|
||||
"skipLibCheck": true,
|
||||
"outDir": "./dist",
|
||||
"declaration": true
|
||||
},
|
||||
"include": ["src/**/*"],
|
||||
"exclude": ["node_modules", "dist"]
|
||||
}
|
||||
18
packages/ui/package.json
Normal file
18
packages/ui/package.json
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"name": "@homelab/ui",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"main": "./src/index.ts",
|
||||
"types": "./src/index.ts",
|
||||
"scripts": {
|
||||
"lint": "tsc --noEmit",
|
||||
"build": "tsc"
|
||||
},
|
||||
"devDependencies": {
|
||||
"typescript": "^5.7.0",
|
||||
"@types/react": "^19.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^19.0.0"
|
||||
}
|
||||
}
|
||||
13
packages/ui/src/button.tsx
Normal file
13
packages/ui/src/button.tsx
Normal file
@@ -0,0 +1,13 @@
|
||||
import React from "react";
|
||||
|
||||
interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
||||
variant?: "primary" | "secondary";
|
||||
}
|
||||
|
||||
export function Button({ variant = "primary", children, ...props }: ButtonProps) {
|
||||
return (
|
||||
<button data-variant={variant} {...props}>
|
||||
{children}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
1
packages/ui/src/index.ts
Normal file
1
packages/ui/src/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export { Button } from "./button";
|
||||
17
packages/ui/tsconfig.json
Normal file
17
packages/ui/tsconfig.json
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2017",
|
||||
"lib": ["dom", "dom.iterable", "esnext"],
|
||||
"jsx": "react-jsx",
|
||||
"module": "esnext",
|
||||
"moduleResolution": "bundler",
|
||||
"strict": true,
|
||||
"esModuleInterop": true,
|
||||
"skipLibCheck": true,
|
||||
"declaration": true,
|
||||
"declarationMap": true,
|
||||
"outDir": "./dist"
|
||||
},
|
||||
"include": ["src/**/*"],
|
||||
"exclude": ["node_modules", "dist"]
|
||||
}
|
||||
Reference in New Issue
Block a user