JustAPI Bot

[email protected]
2026-07-14 23:23:48 +0600 committed NaN years ago
3116958
commit 3116958
5 files changed
+568 -8
▼docs-site/src/content/docs/FREE-DEPLOYMENT.md
+395-0
1
+# OpenCodeHub — Free Deployment Options
2
+
3
+> Deploy OpenCodeHub for free with persistent file storage for git repositories.
4
+
5
+---
6
+
7
+## Quick Comparison
8
+
9
+| Platform | Cost | Storage | RAM | CPU | Best For |
10
+|----------|------|---------|-----|-----|----------|
11
+| **Oracle Cloud Free** | $0 forever | 200GB | 24GB | 4 ARM cores | Best overall |
12
+| **Home Server/NAS** | $0 | Unlimited | Your hardware | Your hardware | Privacy-focused |
13
+| **Fly.io** | $0 (limited) | 3GB free | 256MB | Shared | Quick testing |
14
+| **Google Cloud Free** | $0 forever | 30GB | 1GB | 0.25 vCPU | Light usage |
15
+| **Railway** | $5 trial | 1GB | 512MB | Shared | Quick demo |
16
+| **Hetzner** | ~€4/mo | 40GB | 4GB | 2 vCPU | Best value paid |
17
+
18
+---
19
+
20
+## Option 1: Oracle Cloud Free Tier (Recommended)
21
+
22
+**Always Free** — No credit card charge, no time limit.
23
+
24
+### What You Get
25
+- 4 ARM cores (Ampere A1)
26
+- 24 GB RAM
27
+- 200 GB boot volume
28
+- 2 x 1TB block volumes (total 2TB)
29
+- Free PostgreSQL database
30
+- Free Redis
31
+
32
+### Steps
33
+
34
+```bash
35
+# 1. Sign up at cloud.oracle.com
36
+# 2. Create a VM instance:
37
+# - Name: opencodehub
38
+# - Image: Ubuntu 22.04
39
+# - Shape: VM.Standard.A1.Flex (4 OCPU, 24 GB RAM)
40
+# - Upload SSH key
41
+# - Create boot volume: 100 GB
42
+
43
+# 3. SSH into your instance
44
+ssh -i ~/.ssh/key ubuntu@YOUR_PUBLIC_IP
45
+
46
+# 4. Install Docker
47
+curl -fsSL https://get.docker.com -o get-docker.sh
48
+sudo sh get-docker.sh
49
+sudo usermod -aG docker $USER
50
+
51
+# 5. Install Docker Compose
52
+sudo apt install docker-compose-plugin -y
53
+
54
+# 6. Clone OpenCodeHub
55
+git clone https://github.com/swadhinbiswas/OpencodeHub.git
56
+cd OpencodeHub
57
+
58
+# 7. Configure
59
+cp .env.example .env
60
+nano .env # Edit secrets
61
+
62
+# 8. Start
63
+sudo docker compose up -d
64
+
65
+# 9. Create admin
66
+sudo docker compose exec app bun run scripts/seed-admin.ts
67
+```
68
+
69
+### Access Your Instance
70
+```
71
+Web: http://YOUR_PUBLIC_IP:4321
72
+SSH: ssh://git@YOUR_PUBLIC_IP:2222/owner/repo.git
73
+HTTPS: Set up Nginx + Let's Encrypt (free)
74
+```
75
+
76
+---
77
+
78
+## Option 2: Home Server / NAS
79
+
80
+**$0 forever** — Use hardware you already own.
81
+
82
+### What You Need
83
+- Any computer running Linux/Mac/Windows
84
+- 2GB+ RAM recommended
85
+- 20GB+ free disk space
86
+
87
+### Quick Start (Linux/Mac)
88
+
89
+```bash
90
+# Install Docker
91
+curl -fsSL https://get.docker.com | sh
92
+
93
+# Clone and start
94
+git clone https://github.com/swadhinbiswas/OpencodeHub.git
95
+cd OpencodeHub
96
+cp .env.example .env
97
+nano .env # Set secrets
98
+docker compose up -d
99
+
100
+# Create admin
101
+docker compose exec app bun run scripts/seed-admin.ts
102
+```
103
+
104
+### NAS Deployment
105
+
106
+**Synology / TrueNAS / QNAP:**
107
+1. Install Docker from Package Center
108
+2. Use Docker Compose or Portainer
109
+3. Mount a shared folder for `/data`
110
+
111
+### Access from Anywhere
112
+- **Tailscale** (free): `tailscale up` → access via Tailscale IP
113
+- **Cloudflare Tunnel** (free): Expose without opening ports
114
+- **Port forwarding**: Open port 4321 on your router
115
+
116
+---
117
+
118
+## Option 3: Fly.io Free Tier
119
+
120
+**Free** — 3GB persistent volume included.
121
+
122
+### Steps
123
+
124
+```bash
125
+# 1. Install flyctl
126
+curl -L https://fly.io/install.sh | sh
127
+
128
+# 2. Login
129
+fly auth login
130
+
131
+# 3. Launch
132
+fly launch --name opencodehub
133
+
134
+# 4. Add persistent volume
135
+fly volume create opencodehub_data --region sjc --size 3
136
+
137
+# 5. Set secrets
138
+fly secrets set JWT_SECRET=$(openssl rand -hex 32)
139
+fly secrets set SESSION_SECRET=$(openssl rand -hex 32)
140
+fly secrets set DATABASE_URL="postgresql://..."
141
+fly secrets set REDIS_URL="redis://..."
142
+
143
+# 6. Deploy
144
+fly deploy
145
+```
146
+
147
+### Limitations
148
+- 3GB storage (enough for small repos)
149
+- 256MB RAM (may be slow for large repos)
150
+- Apps休眠 after inactivity (cold starts take ~30s)
151
+
152
+---
153
+
154
+## Option 4: Google Cloud Free Tier
155
+
156
+**Always Free** — e2-micro instance.
157
+
158
+### Steps
159
+
160
+```bash
161
+# 1. Sign up at cloud.google.com
162
+# 2. Create e2-micro VM:
163
+# - Machine type: e2-micro (0.25 vCPU, 1GB RAM)
164
+# - Boot disk: 30GB SSD (free)
165
+# - Firewall: Allow HTTP (80), SSH (22)
166
+
167
+# 3. SSH in and install Docker
168
+ssh -i ~/.ssh/key USER@EXTERNAL_IP
169
+sudo apt update && sudo apt install docker.io docker-compose-plugin -y
170
+
171
+# 4. Deploy OpenCodeHub
172
+git clone https://github.com/swadhinbiswas/OpencodeHub.git
173
+cd OpencodeHub
174
+cp .env.example .env
175
+nano .env
176
+docker compose up -d
177
+```
178
+
179
+### Limitations
180
+- Only 1GB RAM (tight for production)
181
+- 0.25 vCPU (slow builds)
182
+- Good for personal/light use
183
+
184
+---
185
+
186
+## Option 5: Self-Hosted on Existing VPS
187
+
188
+If you already have a VPS (Hetzner, DigitalOcean, Linode, etc.):
189
+
190
+```bash
191
+# SSH into your server
192
+ssh root@YOUR_SERVER_IP
193
+
194
+# One-line install
195
+curl -fsSL https://raw.githubusercontent.com/swadhinbiswas/OpencodeHub/main/install.sh | bash
196
+```
197
+
198
+---
199
+
200
+## Option 6: Docker on Windows/Mac
201
+
202
+For local development or personal use:
203
+
204
+```bash
205
+# Install Docker Desktop for Windows/Mac
206
+# https://docs.docker.com/get-docker/
207
+
208
+# Clone and start
209
+git clone https://github.com/swadhinbiswas/OpencodeHub.git
210
+cd OpencodeHub
211
+cp .env.example .env
212
+nano .env
213
+docker compose up -d
214
+
215
+# Create admin
216
+docker compose exec app bun run scripts/seed-admin.ts
217
+```
218
+
219
+---
220
+
221
+## Storage Configuration
222
+
223
+### Local Storage (Default)
224
+```bash
225
+STORAGE_TYPE=local
226
+STORAGE_PATH=/data/storage
227
+GIT_REPOS_PATH=/data/repositories
228
+```
229
+
230
+### S3-Compatible (MinIO on same server)
231
+```bash
232
+# Add to docker-compose.yml:
233
+minio:
234
+ image: minio/minio
235
+ command: server /data --console-address ":9001"
236
+ volumes:
237
+ - ./data/minio:/data
238
+ ports:
239
+ - "9001:9001"
240
+
241
+STORAGE_TYPE=s3
242
+STORAGE_ENDPOINT=http://minio:9000
243
+STORAGE_BUCKET=opencodehub
244
+STORAGE_ACCESS_KEY_ID=minioadmin
245
+STORAGE_SECRET_ACCESS_KEY=minioadmin
246
+```
247
+
248
+---
249
+
250
+## HTTPS Setup (Free)
251
+
252
+### With Let's Encrypt + Nginx
253
+
254
+```bash
255
+# Install Nginx and Certbot
256
+sudo apt install nginx certbot python3-certbot-nginx -y
257
+
258
+# Create Nginx config
259
+sudo nano /etc/nginx/sites-available/opencodehub
260
+```
261
+
262
+```nginx
263
+server {
264
+ listen 80;
265
+ server_name git.yourdomain.com;
266
+ return 301 https://$host$request_uri;
267
+}
268
+
269
+server {
270
+ listen 443 ssl http2;
271
+ server_name git.yourdomain.com;
272
+
273
+ ssl_certificate /etc/letsencrypt/live/git.yourdomain.com/fullchain.pem;
274
+ ssl_certificate_key /etc/letsencrypt/live/git.yourdomain.com/privkey.pem;
275
+
276
+ client_max_body_size 500M;
277
+
278
+ location / {
279
+ proxy_pass http://localhost:4321;
280
+ proxy_set_header Host $host;
281
+ proxy_set_header X-Real-IP $remote_addr;
282
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
283
+ proxy_set_header X-Forwarded-Proto $scheme;
284
+ }
285
+
286
+ # WebSocket support
287
+ location /api/realtime {
288
+ proxy_pass http://localhost:4321;
289
+ proxy_http_version 1.1;
290
+ proxy_set_header Upgrade $http_upgrade;
291
+ proxy_set_header Connection "upgrade";
292
+ }
293
+}
294
+```
295
+
296
+```bash
297
+# Enable and get SSL
298
+sudo ln -s /etc/nginx/sites-available/opencodehub /etc/nginx/sites-enabled/
299
+sudo certbot --nginx -d git.yourdomain.com
300
+```
301
+
302
+---
303
+
304
+## Environment Variables (Production)
305
+
306
+```bash
307
+# Generate all secrets
308
+JWT_SECRET=$(openssl rand -hex 32)
309
+SESSION_SECRET=$(openssl rand -hex 32)
310
+INTERNAL_HOOK_SECRET=$(openssl rand -hex 32)
311
+CRON_SECRET=$(openssl rand -hex 32)
312
+RUNNER_SECRET=$(openssl rand -hex 32)
313
+AI_CONFIG_ENCRYPTION_KEY=$(openssl rand -hex 32)
314
+WORKFLOW_SECRET_ENCRYPTION_KEY=$(openssl rand -hex 32)
315
+
316
+# Your .env file
317
+DATABASE_DRIVER=postgres
318
+DATABASE_URL=postgresql://opencodehub:PASSWORD@localhost:5432/opencodehub
319
+DATABASE_SSL=false
320
+REDIS_URL=redis://localhost:6379
321
+SITE_URL=https://git.yourdomain.com
322
+STORAGE_TYPE=local
323
+GIT_REPOS_PATH=/data/repositories
324
+NODE_ENV=production
325
+```
326
+
327
+---
328
+
329
+## Backup Strategy
330
+
331
+### Automated Backup Script
332
+```bash
333
+#!/bin/bash
334
+# backup.sh — Run daily via cron
335
+BACKUP_DIR="/backups/$(date +%Y-%m-%d)"
336
+mkdir -p "$BACKUP_DIR"
337
+
338
+# Database dump
339
+docker compose exec -T postgres pg_dump -U opencodehub opencodehub > "$BACKUP_DIR/db.sql"
340
+
341
+# Git repos
342
+tar czf "$BACKUP_DIR/repos.tar.gz" ./data/repositories/
343
+
344
+# Upload to S3 (optional)
345
+# aws s3 sync "$BACKUP_DIR" s3://your-backup-bucket/opencodehub/
346
+```
347
+
348
+### Cron Job
349
+```bash
350
+# Add to crontab
351
+crontab -e
352
+0 2 * * * /path/to/backup.sh
353
+```
354
+
355
+---
356
+
357
+## Monitoring
358
+
359
+### Health Check
360
+```bash
361
+# Check if app is running
362
+curl -f http://localhost:4321/api/health || echo "DOWN"
363
+
364
+# Check Docker status
365
+docker compose ps
366
+docker compose logs --tail=50 app
367
+```
368
+
369
+### Uptime Robot (Free)
370
+1. Sign up at uptimerobot.com
371
+2. Add HTTP monitor: `http://YOUR_IP:4321/api/health`
372
+3. Get notified if your instance goes down
373
+
374
+---
375
+
376
+## Recommended Free Setup
377
+
378
+For a **personal Git server** that stores all your code:
379
+
380
+| Component | Choice |
381
+|-----------|--------|
382
+| **Cloud** | Oracle Cloud Free Tier |
383
+| **Server** | ARM A1 (4 cores, 24GB RAM) |
384
+| **Storage** | 100GB boot + 1TB block volume |
385
+| **Database** | PostgreSQL (Docker) |
386
+| **Cache** | Redis (Docker) |
387
+| **HTTPS** | Nginx + Let's Encrypt |
388
+| **Access** | Tailscale (private) or port forwarding |
389
+| **Backups** | Cron script + local S3 |
390
+
391
+**Total cost: $0/month forever.**
392
+
393
+---
394
+
395
+*Generated for OpenCodeHub free deployment.*
0
396
▼docs-site/src/content/docs/RENDER-DEPLOYMENT.md
+163-0
1
+# OpenCodeHub — Render Deployment Guide
2
+
3
+> Deploy to Render (Singapore) with free PostgreSQL + Upstash Redis. $0/month.
4
+
5
+---
6
+
7
+## What You Get
8
+
9
+- OpenCodeHub running in Asia (Singapore)
10
+- Free PostgreSQL database
11
+- Free Redis via Upstash
12
+- 1GB persistent storage for git repos
13
+- HTTPS included
14
+- Admin account
15
+
16
+---
17
+
18
+## Step 1: Create Upstash Redis (2 min)
19
+
20
+1. Go to **https://upstash.com** → Sign up (free)
21
+2. Click **Create Database**
22
+3. Settings:
23
+ - **Name**: `opencodehub`
24
+ - **Region**: **Asia Pacific (Singapore)**
25
+ - **Plan**: Pay as you go (free tier: 10K commands/day)
26
+4. Click **Create**
27
+5. Copy the **Redis URL** (looks like `rediss://...@...`)
28
+6. Keep this tab open — you'll need it in Step 3
29
+
30
+---
31
+
32
+## Step 2: Deploy to Render (5 min)
33
+
34
+1. Go to **https://render.com** → Sign up (free)
35
+2. Click **New** → **Blueprint**
36
+3. Connect your GitHub account
37
+4. Select your OpenCodeHub repository
38
+5. Render detects `render.yaml` and shows:
39
+ - `opencodehub-db` (PostgreSQL — Singapore)
40
+ - `opencodehub` (Web Service — Singapore)
41
+6. Click **Apply**
42
+7. Wait for deployment (~3-5 min first time)
43
+
44
+---
45
+
46
+## Step 3: Set Redis URL (1 min)
47
+
48
+1. Go to your Web Service → **Environment** tab
49
+2. Find `REDIS_URL` (shows "Not set")
50
+3. Click the pencil icon → Paste your **Upstash Redis URL**
51
+4. Click **Save**
52
+
53
+---
54
+
55
+## Step 4: Set Site URL (1 min)
56
+
57
+1. In the same **Environment** tab
58
+2. Find `SITE_URL` (shows "Not set")
59
+3. Click the pencil icon → Enter your Render URL:
60
+ ```
61
+ https://opencodehub.onrender.com
62
+ ```
63
+ (Replace with your actual URL from the service overview)
64
+4. Click **Save**
65
+
66
+---
67
+
68
+## Step 5: Manual Deploy
69
+
70
+1. Go to your Web Service → **Manual Deploy**
71
+2. Click **Deploy latest commit**
72
+3. Wait for build to complete (~2-3 min)
73
+4. Click the **URL** at the top to open your instance
74
+
75
+---
76
+
77
+## Step 6: Create Admin Account
78
+
79
+You'll see the **Setup Wizard**. Fill in:
80
+
81
+| Field | Value |
82
+|-------|-------|
83
+| Username | `admin` (or your choice) |
84
+| Email | Your email |
85
+| Password | Strong password |
86
+
87
+Click **Create Account** — you're now logged in as admin!
88
+
89
+---
90
+
91
+## Step 7: Test It
92
+
93
+```bash
94
+# Create a repo via web UI, then clone:
95
+git clone https://opencodehub.onrender.com/your-username/my-repo.git
96
+
97
+# Push code:
98
+cd my-repo
99
+echo "# Hello" > README.md
100
+git add . && git commit -m "Initial"
101
+git push origin main
102
+```
103
+
104
+---
105
+
106
+## Done! Summary
107
+
108
+| Component | Service | Region | Cost |
109
+|-----------|---------|--------|------|
110
+| App | Render Free | Singapore | $0 |
111
+| PostgreSQL | Render Free | Singapore | $0 |
112
+| Redis | Upstash Free | Singapore | $0 |
113
+| Storage | Render Disk 1GB | Singapore | $0 |
114
+| **Total** | | | **$0/month** |
115
+
116
+---
117
+
118
+## Keep Alive (Optional)
119
+
120
+Render free tier spins down after 15min inactivity. To prevent:
121
+
122
+1. Go to **https://uptimerobot.com** → Sign up (free)
123
+2. Add Monitor → Type: HTTP(s)
124
+3. URL: `https://opencodehub.onrender.com/api/health`
125
+4. Monitoring interval: 5 minutes
126
+5. Save — your app stays awake
127
+
128
+---
129
+
130
+## Upgrade Path (When You Grow)
131
+
132
+| Need | Upgrade | Cost |
133
+|------|---------|------|
134
+| Always-on (no spin-down) | Render Starter | $7/mo |
135
+| More storage (10GB+) | Render Disk upgrade | $1-7/mo |
136
+| More Redis commands | Upstash Pay-as-you-go | ~$0.20/10K |
137
+| PostgreSQL expiry | Render Starter DB | $7/mo |
138
+
139
+---
140
+
141
+## Troubleshooting
142
+
143
+**App won't start?**
144
+- Check **Logs** tab in Render
145
+- Verify `REDIS_URL` is set correctly
146
+- Ensure `SITE_URL` matches your Render URL
147
+
148
+**Redis connection failed?**
149
+- Verify Redis URL from Upstash (starts with `rediss://`)
150
+- Check Upstash dashboard shows "Active"
151
+- Ensure region is Singapore
152
+
153
+**Git clone fails?**
154
+- Use HTTPS: `git clone https://your-url.onrender.com/user/repo.git`
155
+- SSH not available on Render free tier (use HTTPS)
156
+
157
+**Slow first request?**
158
+- Normal for free tier (cold start ~30s)
159
+- Add UptimeRobot ping to keep it warm
160
+
161
+---
162
+
163
+*OpenCodeHub — Deployed on Render, Asia Region, $0/month.*
0
164
▼src/pages/[owner]/index.astro
+5-5
64
64
try {
65
65
const [result] = await db
66
66
.select({ count: sql`count(*)` })
67
- .from(schema.activity)
68
- .where(eq(schema.activity.userId, user.id));
67
+ .from(schema.activities)
68
+ .where(eq(schema.activities.userId, user.id));
69
69
contributionCount = Number(result?.count) || 0;
70
70
} catch {}
71
71
72
72
// 7. Fetch recent activity
73
73
let recentActivity: any[] = [];
74
74
try {
75
- recentActivity = await db.query.activity.findMany({
76
- where: eq(schema.activity.userId, user.id),
77
- orderBy: [desc(schema.activity.createdAt)],
75
+ recentActivity = await db.query.activities.findMany({
76
+ where: eq(schema.activities.userId, user.id),
77
+ orderBy: [desc(schema.activities.createdAt)],
78
78
limit: 5,
79
79
});
80
80
} catch {}
81
81
▼src/pages/index.astro
+4-2
2
2
import { getDatabase, schema } from "@/db";
3
3
import BaseLayout from "@/layouts/BaseLayout.astro";
4
4
import { eq, count } from "drizzle-orm";
5
+import type { NodePgDatabase } from "drizzle-orm/node-postgres";
5
6
import { BookOpen, Star } from "lucide-react";
6
7
import HeroSection from "@/components/home/HeroSection";
7
8
import FeaturesSection from "@/components/home/FeaturesSection";
29
30
});
30
31
31
32
// Get basic stats
32
- const [repoCountResult] = await db.select({ count: count() }).from(schema.repositories).limit(1);
33
+ const dbTyped = db as NodePgDatabase<typeof schema>;
34
+ const [repoCountResult] = await dbTyped.select({ count: count() }).from(schema.repositories).limit(1);
33
35
const repoCount = Number(repoCountResult?.count) || 0;
34
36
35
- const [userCountResult] = await db.select({ count: count() }).from(schema.users).limit(1);
37
+ const [userCountResult] = await dbTyped.select({ count: count() }).from(schema.users).limit(1);
36
38
const userCount = Number(userCountResult?.count) || 0;
37
39
38
40
stats.repos = repoCount;
39
41
▼src/pages/settings/security.astro
+1-1
69
69
</SettingsLayout>
70
70
71
71
<script>
72
- const disableBtn = document.getElementById("disable-2fa-btn");
72
+ const disableBtn = document.getElementById("disable-2fa-btn") as HTMLButtonElement | null;
73
73
74
74
disableBtn?.addEventListener("click", async () => {
75
75
if (confirm("Are you sure you want to disable 2FA? This will make your account less secure.")) {
76
76