update readme

This commit is contained in:
2025-10-08 14:23:46 +07:00
parent 9c177abda0
commit 070ce26b3d
9 changed files with 388 additions and 53 deletions

173
README.md
View File

@@ -1,53 +1,66 @@
# 🐱 CatSave - Go + Next.js Monorepo # 🐱 NekoFlow - Go + Next.js Monorepo
Single binary application with Go backend + Next.js frontend. [![Language](https://img.shields.io/badge/Language-English-blue)](README.md)
[![Language](https://img.shields.io/badge/Language-Tiếng_Việt-red)](README.vi.md)
## 📦 Structure > **[Đọc bằng tiếng Việt](README.vi.md)**
Single binary application combining Go backend with Next.js frontend.
## 📦 Project Structure
``` ```
catsave/ nekoflow/
├── apps/ ├── apps/
│ ├── web/ # Next.js frontend (static export) │ ├── web/ # Next.js 14 (Frontend - Static Export)
│ └── server-go/ # Go backend + static file server │ └── server-go/ # Go backend + Static file server
├── scripts/ # Build scripts ├── scripts/ # Build scripts
└── dist/ # Build output └── dist/ # Build output
``` ```
## 🚀 Development ## 🚀 Quick Start
### Prerequisites
- Node.js 18+
- Go 1.21+
### Installation
### Quick Start
```bash ```bash
# 1. Install dependencies # 1. Install dependencies
npm install npm install
# 2. Option A: Dev Next.js only # 2. Option A: Dev Next.js only (with hot reload)
npm run dev:web # http://localhost:3000 npm run dev:web # http://localhost:3000
# 3. Option B: Dev with Go # 3. Option B: Full stack with Go
npm run build:dev # Build Next.js + sync to Go npm run build:dev # Build Next.js + sync to Go
npm run dev:go # Run Go server npm run dev:go # Run Go server → http://localhost:8080
``` ```
### Workflow ## 💻 Development
**Frontend Development (Next.js):** ### Frontend Development (Next.js)
```bash ```bash
npm run dev:web # Hot reload on :3000 npm run dev:web # Hot reload on port 3000
``` ```
**Full Stack Development (Next.js + Go):** ### Full Stack Development (Next.js + Go)
**Terminal 1: Build & sync when you change Next.js code**
```bash ```bash
# Terminal 1: Build & sync on changes
npm run build:dev npm run build:dev
```
# Terminal 2: Run Go server **Terminal 2: Run Go server**
```bash
npm run dev:go # http://localhost:8080 npm run dev:go # http://localhost:8080
``` ```
**After changing Next.js code:** **After changing Next.js code:**
```bash ```bash
npm run build:dev # Re-build and sync npm run build:dev # Re-build and sync
# Go server will auto-serve new files # Go server will auto-serve new files (no restart needed)
``` ```
## 🔨 Build ## 🔨 Build
@@ -62,38 +75,134 @@ npm run build:dev
```bash ```bash
npm run build npm run build
# → Builds Next.js + Go binary # → Builds Next.js + Go binary
# → Output: dist/catsave (single binary) # → Output: dist/nekoflow (single binary ~10-30MB)
``` ```
### Available Commands ### Available Commands
| Command | Description | | Command | Description |
|---------|-------------| |---------|-------------|
| `npm run dev:web` | Dev Next.js only (port 3000) | | `npm run dev:web` | Dev Next.js only (port 3000, hot reload) |
| `npm run dev:go` | Run Go server (port 8080) | | `npm run dev:go` | Run Go server (port 8080) |
| `npm run build:web` | Build Next.js static export | | `npm run build:web` | Build Next.js static export |
| `npm run sync:static` | Copy Next.js → Go static | | `npm run sync:static` | Copy Next.js build → Go static folder |
| `npm run build:dev` | Build + sync (development) | | `npm run build:dev` | Build + sync (for development) |
| `npm run build` | Full production build | | `npm run build` | Full production build (creates binary) |
## 🎯 Deploy ## 🎯 Deploy
### Simple Deployment
```bash ```bash
# Just copy the binary # Just copy and run the binary
./dist/catsave ./dist/nekoflow
# Runs on http://localhost:8080 # Or specify port
PORT=8080 ./dist/nekoflow
```
### Deploy to Linux Server
```bash
# 1. Build for Linux
npm run build
# 2. Upload
scp dist/nekoflow-linux user@server:/opt/nekoflow
# 3. Run on server
ssh user@server
chmod +x /opt/nekoflow
./nekoflow
```
### Docker (Optional)
```dockerfile
FROM scratch
COPY dist/nekoflow /nekoflow
ENTRYPOINT ["/nekoflow"]
``` ```
## 🏗️ Architecture ## 🏗️ Architecture
- **Go**: API + serve static files (embedded) ### How It Works
- **Next.js**: Static export (HTML/CSS/JS)
- **Result**: One binary file (~10-30MB)
## 📝 Tech Stack ```
┌─────────────────────────────────────┐
│ Single Binary (nekoflow) │
│ │
│ ┌────────────┐ ┌──────────────┐ │
│ │ Go Server │ │ Static Files │ │
│ │ │ │ (Next.js) │ │
│ │ - API │ │ - HTML │ │
│ │ - Router │ │ - CSS │ │
│ │ - Embedded │ │ - JS │ │
│ └────────────┘ └──────────────┘ │
└─────────────────────────────────────┘
Single Port (8080)
┌─────────────┐
│ Browser │
│ - UI │
│ - API call │
└─────────────┘
```
- Go 1.21+ ### Tech Stack
- Next.js 14
**Frontend:**
- Next.js 14 (Static Export)
- React 18
- TypeScript - TypeScript
- Tailwind CSS - Tailwind CSS
**Backend:**
- Go 1.21+
- gorilla/mux (Router)
- embed (Static files)
**Build:**
- npm workspaces
- Bash scripts
- Go build
## ❓ FAQ
### Is this SSR (Server-Side Rendering)?
**No.** This uses Next.js **Static Export** (SSG - Static Site Generation).
- Next.js pre-renders pages to HTML at build time
- Go only serves static files (HTML/CSS/JS)
- React hydrates on the client-side
- API calls happen client-side via `fetch()`
### Can I use getServerSideProps?
**No.** Static Export doesn't support:
- `getServerSideProps()`
- `getServerData()`
- ISR (Incremental Static Regeneration)
Use `'use client'` with `useEffect()` and `fetch()` instead.
### Why Go + Next.js?
-**Single binary** - Easy deployment
-**No Node.js runtime** needed in production
-**Performance** - Go is fast and lightweight
-**Modern DX** - React + TypeScript + Tailwind
-**Cross-platform** - Compile for Linux/Mac/Windows
### Binary size?
Typically **10-30MB** depending on:
- Go code size
- Next.js bundle size
- Static assets (images, fonts)
## 📝 License
MIT
## 🤝 Contributing
Contributions welcome! Feel free to open issues or PRs.
---
**Built with ❤️ using Go + Next.js + TypeScript**

226
README.vi.md Normal file
View File

@@ -0,0 +1,226 @@
# 🐱 NekoFlow - Monorepo Go + Next.js
[![Ngôn ngữ](https://img.shields.io/badge/Language-English-blue)](README.md)
[![Ngôn ngữ](https://img.shields.io/badge/Language-Tiếng_Việt-red)](README.vi.md)
> **[Read in English](README.md)**
Ứng dụng single binary kết hợp Go backend với Next.js frontend.
## 📦 Cấu Trúc Dự Án
```
nekoflow/
├── apps/
│ ├── web/ # Next.js 14 (Frontend - Static Export)
│ └── server-go/ # Go backend + Static file server
├── scripts/ # Build scripts
└── dist/ # Build output
```
## 🚀 Bắt Đầu Nhanh
### Yêu Cầu
- Node.js 18+
- Go 1.21+
### Cài Đặt
```bash
# 1. Cài dependencies
npm install
# 2. Tùy chọn A: Dev chỉ Next.js (có hot reload)
npm run dev:web # http://localhost:3000
# 3. Tùy chọn B: Full stack với Go
npm run build:dev # Build Next.js + sync sang Go
npm run dev:go # Chạy Go server → http://localhost:8080
```
## 💻 Phát Triển
### Phát Triển Frontend (Next.js)
```bash
npm run dev:web # Hot reload trên port 3000
```
### Phát Triển Full Stack (Next.js + Go)
**Terminal 1: Build & sync khi sửa code Next.js**
```bash
npm run build:dev
```
**Terminal 2: Chạy Go server**
```bash
npm run dev:go # http://localhost:8080
```
**Sau khi sửa code Next.js:**
```bash
npm run build:dev # Build lại và sync
# Go server tự động serve files mới (không cần restart)
```
## 🔨 Build
### Development Build (Nhanh)
```bash
npm run build:dev
# → Build Next.js + sync vào folder static của Go
```
### Production Binary
```bash
npm run build
# → Build Next.js + Go binary
# → Output: dist/nekoflow (single binary ~10-30MB)
```
### Các Lệnh Có Sẵn
| Lệnh | Mô Tả |
|------|-------|
| `npm run dev:web` | Dev Next.js riêng (port 3000, hot reload) |
| `npm run dev:go` | Chạy Go server (port 8080) |
| `npm run build:web` | Build Next.js static export |
| `npm run sync:static` | Copy Next.js build → folder static của Go |
| `npm run build:dev` | Build + sync (cho development) |
| `npm run build` | Build production đầy đủ (tạo binary) |
## 🎯 Deploy
### Deploy Đơn Giản
```bash
# Chỉ cần copy và chạy binary
./dist/nekoflow
# Hoặc chỉ định port
PORT=8080 ./dist/nekoflow
```
### Deploy Lên Linux Server
```bash
# 1. Build cho Linux
npm run build
# 2. Upload
scp dist/nekoflow-linux user@server:/opt/nekoflow
# 3. Chạy trên server
ssh user@server
chmod +x /opt/nekoflow
./nekoflow
```
### Docker (Tùy Chọn)
```dockerfile
FROM scratch
COPY dist/nekoflow /nekoflow
ENTRYPOINT ["/nekoflow"]
```
## 🏗️ Kiến Trúc
### Cách Hoạt Động
```
┌─────────────────────────────────────┐
│ Single Binary (nekoflow) │
│ │
│ ┌────────────┐ ┌──────────────┐ │
│ │ Go Server │ │ Static Files │ │
│ │ │ │ (Next.js) │ │
│ │ - API │ │ - HTML │ │
│ │ - Router │ │ - CSS │ │
│ │ - Embedded │ │ - JS │ │
│ └────────────┘ └──────────────┘ │
└─────────────────────────────────────┘
Single Port (8080)
┌─────────────┐
│ Browser │
│ - UI │
│ - API call │
└─────────────┘
```
### Tech Stack
**Frontend:**
- Next.js 14 (Static Export)
- React 18
- TypeScript
- Tailwind CSS
**Backend:**
- Go 1.21+
- gorilla/mux (Router)
- embed (Static files)
**Build:**
- npm workspaces
- Bash scripts
- Go build
## ❓ Câu Hỏi Thường Gặp
### Đây có phải SSR (Server-Side Rendering)?
**Không.** Dự án này dùng Next.js **Static Export** (SSG - Static Site Generation).
- Next.js pre-render pages thành HTML tại thời điểm build
- Go chỉ serve static files (HTML/CSS/JS)
- React hydrate trên client-side
- API calls xảy ra client-side qua `fetch()`
### Có thể dùng getServerSideProps?
**Không.** Static Export không hỗ trợ:
- `getServerSideProps()`
- `getServerData()`
- ISR (Incremental Static Regeneration)
Dùng `'use client'` với `useEffect()``fetch()` thay thế.
### Tại sao Go + Next.js?
-**Single binary** - Deploy dễ dàng
-**Không cần Node.js runtime** trong production
-**Performance** - Go nhanh và nhẹ
-**Modern DX** - React + TypeScript + Tailwind
-**Cross-platform** - Compile cho Linux/Mac/Windows
### Kích thước binary?
Thường **10-30MB** tùy thuộc:
- Kích thước code Go
- Bundle size của Next.js
- Static assets (hình ảnh, fonts)
### Next.js chỉ là tool để code HTML/CSS/JS dễ hơn?
**Đúng!** Với Static Export:
- Next.js giúp code dễ hơn (React, TypeScript, Components)
- Build ra HTML/CSS/JS thuần
- Go chỉ serve files tĩnh
- Giống như bạn tự viết HTML/CSS/JS nhưng với DX tốt hơn
### HTML của Next.js có gọi Go API?
**Có!** Flow hoạt động:
1. User vào http://localhost:8080
2. Go serve index.html (static)
3. Browser load HTML + React JS
4. React code chạy: `fetch('/api/health')`
5. Request về Go API endpoint
6. Go trả JSON response
7. React update UI
## 📝 License
MIT
## 🤝 Đóng Góp
Chào mừng mọi đóng góp! Thoải mái mở issues hoặc PRs.
---
**Built with ❤️ using Go + Next.js + TypeScript**

View File

@@ -1,4 +1,4 @@
module github.com/catsave/server module github.com/nekoflow/server
go 1.21 go 1.21

View File

@@ -43,7 +43,7 @@ func main() {
port = "8080" port = "8080"
} }
log.Printf("🚀 CatSave server starting on http://localhost:%s\n", port) log.Printf("🚀 NekoFlow server starting on http://localhost:%s\n", port)
log.Printf("📱 Web UI: http://localhost:%s\n", port) log.Printf("📱 Web UI: http://localhost:%s\n", port)
log.Printf("🔌 API: http://localhost:%s/api/health\n", port) log.Printf("🔌 API: http://localhost:%s/api/health\n", port)
@@ -57,7 +57,7 @@ func healthHandler(w http.ResponseWriter, r *http.Request) {
response := HealthResponse{ response := HealthResponse{
Status: "ok", Status: "ok",
Message: "Go backend is running! 🐹", Message: "NekoFlow Go backend is running! 🐹",
Timestamp: time.Now().Format(time.RFC3339), Timestamp: time.Now().Format(time.RFC3339),
} }

View File

@@ -1,5 +1,5 @@
{ {
"name": "@catsave/web", "name": "@nekoflow/web",
"version": "1.0.0", "version": "1.0.0",
"private": true, "private": true,
"scripts": { "scripts": {

View File

@@ -2,7 +2,7 @@ import type { Metadata } from 'next'
import './globals.css' import './globals.css'
export const metadata: Metadata = { export const metadata: Metadata = {
title: 'CatSave', title: 'NekoFlow',
description: 'Go + Next.js Single Binary Application', description: 'Go + Next.js Single Binary Application',
} }

View File

@@ -21,7 +21,7 @@ export default function Home() {
<span className="text-5xl">🐱</span> <span className="text-5xl">🐱</span>
</div> </div>
<h1 className="text-5xl font-bold text-gray-900 mb-4"> <h1 className="text-5xl font-bold text-gray-900 mb-4">
CatSave NekoFlow
</h1> </h1>
<p className="text-xl text-gray-600 mb-8"> <p className="text-xl text-gray-600 mb-8">
Go + Next.js Single Binary Go + Next.js Single Binary

View File

@@ -1,14 +1,14 @@
{ {
"name": "catsave-monorepo", "name": "nekoflow-monorepo",
"version": "1.0.0", "version": "1.0.0",
"private": true, "private": true,
"workspaces": [ "workspaces": [
"apps/web" "apps/web"
], ],
"scripts": { "scripts": {
"dev:web": "npm --workspace @catsave/web run dev", "dev:web": "npm --workspace @nekoflow/web run dev",
"dev:go": "cd apps/server-go && go run main.go", "dev:go": "cd apps/server-go && go run main.go",
"build:web": "npm --workspace @catsave/web run build", "build:web": "npm --workspace @nekoflow/web run build",
"sync:static": "bash scripts/sync-static.sh", "sync:static": "bash scripts/sync-static.sh",
"build:dev": "npm run build:web && npm run sync:static", "build:dev": "npm run build:web && npm run sync:static",
"build:go": "bash scripts/build-go.sh", "build:go": "bash scripts/build-go.sh",

View File

@@ -1,6 +1,6 @@
#!/bin/bash #!/bin/bash
echo "🔨 Building CatSave Single Binary..." echo "🔨 Building NekoFlow Single Binary..."
# Colors # Colors
GREEN='\033[0;32m' GREEN='\033[0;32m'
@@ -36,31 +36,31 @@ cd apps/server-go
go mod download go mod download
# Build for Linux # Build for Linux
GOOS=linux GOARCH=amd64 go build -ldflags="-s -w" -o ../../dist/catsave-linux main.go GOOS=linux GOARCH=amd64 go build -ldflags="-s -w" -o ../../dist/nekoflow-linux main.go
echo " ✅ Built: dist/catsave-linux" echo " ✅ Built: dist/nekoflow-linux"
# Build for current OS # Build for current OS
go build -ldflags="-s -w" -o ../../dist/catsave main.go go build -ldflags="-s -w" -o ../../dist/nekoflow main.go
echo " ✅ Built: dist/catsave" echo " ✅ Built: dist/nekoflow"
cd ../.. cd ../..
# Get file sizes # Get file sizes
SIZE_LINUX=$(du -h dist/catsave-linux 2>/dev/null | cut -f1) SIZE_LINUX=$(du -h dist/nekoflow-linux 2>/dev/null | cut -f1)
SIZE_LOCAL=$(du -h dist/catsave 2>/dev/null | cut -f1) SIZE_LOCAL=$(du -h dist/nekoflow 2>/dev/null | cut -f1)
echo "" echo ""
echo -e "${GREEN}✅ Build complete!${NC}" echo -e "${GREEN}✅ Build complete!${NC}"
echo "" echo ""
echo "📦 Output:" echo "📦 Output:"
echo " - dist/catsave (${SIZE_LOCAL:-N/A})" echo " - dist/nekoflow (${SIZE_LOCAL:-N/A})"
echo " - dist/catsave-linux (${SIZE_LINUX:-N/A})" echo " - dist/nekoflow-linux (${SIZE_LINUX:-N/A})"
echo "" echo ""
echo -e "${YELLOW}To run:${NC}" echo -e "${YELLOW}To run:${NC}"
echo " ./dist/catsave" echo " ./dist/nekoflow"
echo "" echo ""
echo -e "${YELLOW}To deploy to Linux server:${NC}" echo -e "${YELLOW}To deploy to Linux server:${NC}"
echo " scp dist/catsave-linux user@server:/opt/catsave" echo " scp dist/nekoflow-linux user@server:/opt/nekoflow"
echo " ssh user@server '/opt/catsave'" echo " ssh user@server '/opt/nekoflow'"
echo "" echo ""