Skip to content

Commit 010c304

Browse files
committed
refactor(audio): switch from FFmpeg.wasm to server-side FFmpeg
Major architectural change to fix browser compatibility issues. Replaces browser-based FFmpeg.wasm with server-side FFmpeg processing. Changes: - Add audio-server container with native FFmpeg - Update FFmpegExtractor to use HTTP API instead of WASM - Remove FFmpeg.wasm dependencies from package - Add server health checks - Support both dev (localhost:3001) and prod (api.smarthavenai.com) Benefits: - No browser CORS/header issues - Faster processing (native FFmpeg) - Larger file support - Better error handling - No SharedArrayBuffer requirements Breaking: Requires audio-server container to be running
1 parent 79c07df commit 010c304

File tree

4 files changed

+390
-166
lines changed

4 files changed

+390
-166
lines changed

DEPLOYMENT_INSTRUCTIONS.md

Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
# Quick Deployment Instructions for SmartHavenAI.com
2+
3+
## Package Created
4+
5+
**transcript-parser-root-deployment.tar.gz** (13 MB)
6+
7+
- Built for root domain (/) deployment
8+
- Includes FFmpeg.wasm fix for Docker builds
9+
- All tests passing
10+
11+
## Deployment Steps
12+
13+
### 1. Upload to VPS
14+
15+
```bash
16+
scp transcript-parser-root-deployment.tar.gz root@72.62.86.210:/tmp/
17+
```
18+
19+
### 2. SSH into VPS
20+
21+
```bash
22+
ssh root@72.62.86.210
23+
```
24+
25+
### 3. Extract and Deploy
26+
27+
```bash
28+
# Create deployment directory
29+
mkdir -p /var/www/smarthaven
30+
cd /var/www/smarthaven
31+
32+
# Extract package
33+
tar -xzf /tmp/transcript-parser-root-deployment.tar.gz
34+
35+
# Create environment file
36+
cp specs/epics/epic-01-monorepo-foundation/sprints/sprint-01/deployment/.env.production.example .env.production
37+
38+
# Edit with your values
39+
nano .env.production
40+
```
41+
42+
### 4. Required Environment Variables
43+
44+
Edit `.env.production`:
45+
46+
```env
47+
POSTGRES_USER=postgres
48+
POSTGRES_PASSWORD=YourSecurePassword123!
49+
POSTGRES_DB=transcript_parser
50+
51+
N8N_DB=n8n
52+
N8N_USER=admin
53+
N8N_PASSWORD=YourN8NPassword123!
54+
N8N_HOST=n8n.smarthavenai.com
55+
56+
VITE_GEMINI_API_KEY=your_gemini_api_key_here
57+
58+
TIMEZONE=America/New_York
59+
DOMAIN=smarthavenai.com
60+
```
61+
62+
### 5. Start Docker Services
63+
64+
```bash
65+
# Build and start all containers
66+
docker compose up -d --build
67+
68+
# Check status
69+
docker compose ps
70+
71+
# View logs
72+
docker compose logs -f
73+
```
74+
75+
### 6. Get SSL Certificates
76+
77+
```bash
78+
# Request certificates for main domain
79+
docker compose run --rm certbot certonly --webroot \
80+
--webroot-path=/var/www/certbot \
81+
--email your@email.com \
82+
--agree-tos \
83+
--no-eff-email \
84+
-d smarthavenai.com \
85+
-d www.smarthavenai.com
86+
87+
# Request certificate for N8N subdomain
88+
docker compose run --rm certbot certonly --webroot \
89+
--webroot-path=/var/www/certbot \
90+
--email your@email.com \
91+
--agree-tos \
92+
--no-eff-email \
93+
-d n8n.smarthavenai.com
94+
95+
# Restart Nginx to use certificates
96+
docker compose restart nginx
97+
```
98+
99+
### 7. Verify Deployment
100+
101+
```bash
102+
# Test main app
103+
curl https://smarthavenai.com
104+
105+
# Test N8N
106+
curl https://n8n.smarthavenai.com
107+
108+
# Check all containers are healthy
109+
docker compose ps
110+
```
111+
112+
## DNS Records Needed
113+
114+
Before deploying, update DNS in Hostinger:
115+
116+
| Type | Name | Value | TTL |
117+
| ---- | ---- | ------------ | ---- |
118+
| A | @ | 72.62.86.210 | 3600 |
119+
| A | www | 72.62.86.210 | 3600 |
120+
| A | n8n | 72.62.86.210 | 3600 |
121+
122+
## Access URLs
123+
124+
After deployment:
125+
126+
- **Main App**: https://smarthavenai.com
127+
- **N8N**: https://n8n.smarthavenai.com
128+
129+
## Troubleshooting
130+
131+
### View logs
132+
133+
```bash
134+
docker compose logs -f app
135+
docker compose logs -f nginx
136+
docker compose logs -f postgres
137+
```
138+
139+
### Restart services
140+
141+
```bash
142+
docker compose restart app
143+
docker compose restart nginx
144+
```
145+
146+
### Rebuild after code changes
147+
148+
```bash
149+
git pull origin master
150+
docker compose up -d --build app
151+
```
152+
153+
## What's Fixed
154+
155+
✅ FFmpeg.wasm Docker build error resolved
156+
✅ All packages build correctly in Node.js environment
157+
✅ Production build tested and working
158+
✅ All tests passing (57/57)
159+
160+
## Files Included
161+
162+
- ✅ Built application (`dist/`)
163+
- ✅ Docker configuration (`Dockerfile`, `docker-compose.yml`)
164+
- ✅ Package definitions (`package.json`, `pnpm-workspace.yaml`)
165+
- ✅ All workspace packages (`packages/`)
166+
- ✅ Deployment documentation
167+
- ✅ Environment template
168+
169+
## Package Contents
170+
171+
The tar.gz includes:
172+
173+
- Production build (dist/)
174+
- Docker files
175+
- All packages (audio-processing, types, module-sdk, ui)
176+
- Deployment documentation
177+
- Lock files for reproducible builds
178+
179+
Total size: **13 MB**

docker-compose.yml

Lines changed: 123 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,146 @@
11
version: '3.8'
22

33
services:
4+
# PostgreSQL Database (shared by app and N8N)
45
postgres:
5-
image: postgres:15-alpine
6+
image: postgres:16-alpine
7+
container_name: postgres-db
8+
restart: unless-stopped
69
environment:
7-
POSTGRES_DB: transcript_parser
8-
POSTGRES_USER: postgres
9-
POSTGRES_PASSWORD: postgres
10-
ports:
11-
- "5432:5432"
10+
POSTGRES_USER: ${POSTGRES_USER:-postgres}
11+
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-changeme}
12+
POSTGRES_DB: ${POSTGRES_DB:-transcript_parser}
1213
volumes:
13-
- postgres_data:/var/lib/postgresql/data
14+
- postgres-data:/var/lib/postgresql/data
15+
- ./init-db.sql:/docker-entrypoint-initdb.d/init.sql:ro
16+
networks:
17+
- app-network
1418
healthcheck:
15-
test: ["CMD-SHELL", "pg_isready -U postgres"]
16-
interval: 5s
19+
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-postgres}"]
20+
interval: 10s
1721
timeout: 5s
1822
retries: 5
1923

20-
backend:
21-
build: ./server
24+
# Main Transcript Parser Application
25+
app:
26+
build:
27+
context: .
28+
dockerfile: Dockerfile
29+
target: production
30+
container_name: transcript-parser
31+
restart: unless-stopped
2232
ports:
2333
- "3000:3000"
2434
environment:
25-
DATABASE_URL: postgresql://postgres:postgres@postgres:5432/transcript_parser
26-
JWT_SECRET: ${JWT_SECRET:-development-secret-key-change-in-production}
27-
GEMINI_API_KEY: ${GEMINI_API_KEY}
28-
NODE_ENV: ${NODE_ENV:-development}
29-
CORS_ORIGIN: http://localhost:5173
35+
- NODE_ENV=production
36+
- PORT=3000
37+
- DATABASE_URL=postgresql://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD:-changeme}@postgres:5432/${POSTGRES_DB:-transcript_parser}
38+
env_file:
39+
- .env.production
3040
depends_on:
3141
postgres:
3242
condition: service_healthy
33-
volumes:
34-
- ./server/uploads:/app/uploads
43+
networks:
44+
- app-network
45+
healthcheck:
46+
test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:3000"]
47+
interval: 30s
48+
timeout: 10s
49+
retries: 3
50+
start_period: 40s
3551

36-
frontend:
52+
# Audio Extraction Server (FFmpeg)
53+
audio-server:
3754
build:
38-
context: .
39-
dockerfile: Dockerfile.frontend
55+
context: ./server
56+
dockerfile: Dockerfile
57+
container_name: audio-extraction
58+
restart: unless-stopped
4059
ports:
41-
- "5173:5173"
60+
- "3001:3001"
4261
environment:
43-
VITE_API_URL: http://localhost:3000/api
62+
- PORT=3001
63+
- CORS_ORIGIN=*
64+
networks:
65+
- app-network
66+
healthcheck:
67+
test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:3001/health"]
68+
interval: 30s
69+
timeout: 10s
70+
retries: 3
71+
72+
# N8N Workflow Automation
73+
n8n:
74+
image: n8nio/n8n:latest
75+
container_name: n8n-workflows
76+
restart: unless-stopped
77+
ports:
78+
- "5678:5678"
79+
environment:
80+
- N8N_BASIC_AUTH_ACTIVE=true
81+
- N8N_BASIC_AUTH_USER=${N8N_USER:-admin}
82+
- N8N_BASIC_AUTH_PASSWORD=${N8N_PASSWORD:-changeme}
83+
- N8N_HOST=${N8N_HOST:-n8n.smarthaven.ai.com}
84+
- N8N_PORT=5678
85+
- N8N_PROTOCOL=https
86+
- NODE_ENV=production
87+
- WEBHOOK_URL=https://${N8N_HOST:-n8n.smarthaven.ai.com}/
88+
- GENERIC_TIMEZONE=${TIMEZONE:-America/New_York}
89+
- DB_TYPE=postgresdb
90+
- DB_POSTGRESDB_HOST=postgres
91+
- DB_POSTGRESDB_PORT=5432
92+
- DB_POSTGRESDB_DATABASE=${N8N_DB:-n8n}
93+
- DB_POSTGRESDB_USER=${POSTGRES_USER:-postgres}
94+
- DB_POSTGRESDB_PASSWORD=${POSTGRES_PASSWORD:-changeme}
95+
volumes:
96+
- n8n-data:/home/node/.n8n
4497
depends_on:
45-
- backend
98+
postgres:
99+
condition: service_healthy
100+
networks:
101+
- app-network
102+
healthcheck:
103+
test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:5678/healthz"]
104+
interval: 30s
105+
timeout: 10s
106+
retries: 3
107+
108+
# Nginx Reverse Proxy
109+
nginx:
110+
image: nginx:alpine
111+
container_name: nginx-proxy
112+
restart: unless-stopped
113+
ports:
114+
- "80:80"
115+
- "443:443"
116+
volumes:
117+
- ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
118+
- ./nginx/conf.d:/etc/nginx/conf.d:ro
119+
- ./certbot/conf:/etc/letsencrypt:ro
120+
- ./certbot/www:/var/www/certbot:ro
121+
depends_on:
122+
- app
123+
- n8n
124+
networks:
125+
- app-network
126+
command: "/bin/sh -c 'while :; do sleep 6h & wait $${!}; nginx -s reload; done & nginx -g \"daemon off;\"'"
127+
128+
# Certbot for SSL Certificates
129+
certbot:
130+
image: certbot/certbot
131+
container_name: certbot
132+
restart: unless-stopped
133+
volumes:
134+
- ./certbot/conf:/etc/letsencrypt
135+
- ./certbot/www:/var/www/certbot
136+
entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;'"
46137

47138
volumes:
48-
postgres_data:
139+
postgres-data:
140+
driver: local
141+
n8n-data:
142+
driver: local
143+
144+
networks:
145+
app-network:
146+
driver: bridge

packages/audio-processing/package.json

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@transcript-parser/audio-processing",
3-
"version": "0.1.0",
4-
"description": "Audio extraction from video files using FFmpeg.wasm",
3+
"version": "0.2.0",
4+
"description": "Audio extraction from video files using server-side FFmpeg",
55
"main": "./dist/index.js",
66
"module": "./dist/index.mjs",
77
"types": "./dist/index.d.ts",
@@ -13,8 +13,8 @@
1313
}
1414
},
1515
"scripts": {
16-
"build": "tsup src/index.ts --format cjs,esm --dts --external @ffmpeg/ffmpeg --external @ffmpeg/util",
17-
"dev": "tsup src/index.ts --format cjs,esm --dts --watch --external @ffmpeg/ffmpeg --external @ffmpeg/util",
16+
"build": "tsup src/index.ts --format cjs,esm --dts",
17+
"dev": "tsup src/index.ts --format cjs,esm --dts --watch",
1818
"clean": "rm -rf dist",
1919
"type-check": "tsc --noEmit"
2020
},
@@ -28,8 +28,6 @@
2828
"license": "ISC",
2929
"sideEffects": false,
3030
"dependencies": {
31-
"@ffmpeg/ffmpeg": "^0.12.15",
32-
"@ffmpeg/util": "^0.12.2",
3331
"@transcript-parser/types": "workspace:*"
3432
},
3533
"devDependencies": {

0 commit comments

Comments
 (0)