Skip to content

Commit 4741581

Browse files
KevenWMarkhamclaude
andcommitted
feat: add Docker deployment infrastructure for SmartHavenAI.com
Add complete Docker-based deployment setup including: - Multi-stage Dockerfile for production builds - Docker Compose orchestration for app, N8N, PostgreSQL, and Nginx - Nginx reverse proxy with SSL configuration - Let's Encrypt SSL certificate automation via Certbot - GitHub Actions CI/CD pipeline for automated deployments - Production environment template (.env.production.example) - PostgreSQL database initialization script - Security-hardened .dockerignore and .gitignore Deployment architecture: - Nginx: Reverse proxy with SSL termination - App: React + Vite application on port 3000 - N8N: Workflow automation on port 5678 - PostgreSQL 16: Shared database for app and N8N - Certbot: Automatic SSL certificate renewal Target: Hostinger VPS (72.62.86.210) Domains: smarthavenai.com, n8n.smarthavenai.com 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 1d4108b commit 4741581

File tree

9 files changed

+584
-0
lines changed

9 files changed

+584
-0
lines changed

.dockerignore

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# Dependencies
2+
node_modules
3+
**/node_modules
4+
5+
# Build outputs
6+
dist
7+
**/dist
8+
build
9+
**/build
10+
.next
11+
12+
# Testing
13+
coverage
14+
**/coverage
15+
test-results
16+
**/test-results
17+
playwright-report
18+
**/playwright-report
19+
20+
# Development files
21+
.git
22+
.github
23+
.vscode
24+
.idea
25+
*.log
26+
npm-debug.log*
27+
yarn-debug.log*
28+
yarn-error.log*
29+
pnpm-debug.log*
30+
31+
# Environment files
32+
.env
33+
.env.local
34+
.env.*.local
35+
.env.development
36+
.env.test
37+
38+
# OS files
39+
.DS_Store
40+
Thumbs.db
41+
42+
# Documentation
43+
*.md
44+
!README.md
45+
docs
46+
specs
47+
48+
# CI/CD
49+
.gitlab-ci.yml
50+
.travis.yml
51+
azure-pipelines.yml
52+
53+
# Temporary files
54+
*.tmp
55+
*.temp
56+
.cache

.env.production.example

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Production Environment Variables
2+
# Copy this to .env.production and fill in your values
3+
4+
# Database Configuration
5+
POSTGRES_USER=postgres
6+
POSTGRES_PASSWORD=your_secure_password_here
7+
POSTGRES_DB=transcript_parser
8+
9+
# N8N Database (separate database in same PostgreSQL instance)
10+
N8N_DB=n8n
11+
12+
# N8N Configuration
13+
N8N_USER=admin
14+
N8N_PASSWORD=your_secure_n8n_password_here
15+
N8N_HOST=n8n.smarthaven.ai.com
16+
17+
# Timezone
18+
TIMEZONE=America/New_York
19+
20+
# Application Configuration
21+
NODE_ENV=production
22+
PORT=3000
23+
24+
# Gemini AI API Key
25+
VITE_GEMINI_API_KEY=your_gemini_api_key_here
26+
27+
# Domain Configuration
28+
DOMAIN=smarthaven.ai.com

.github/workflows/deploy.yml

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
name: Deploy to SmartHavenAI.com
2+
3+
on:
4+
push:
5+
branches:
6+
- master
7+
workflow_dispatch:
8+
9+
jobs:
10+
test:
11+
name: Run Tests
12+
runs-on: ubuntu-latest
13+
14+
steps:
15+
- name: Checkout code
16+
uses: actions/checkout@v4
17+
18+
- name: Setup Node.js
19+
uses: actions/setup-node@v4
20+
with:
21+
node-version: '20'
22+
23+
- name: Install pnpm
24+
uses: pnpm/action-setup@v2
25+
with:
26+
version: 8
27+
28+
- name: Install dependencies
29+
run: pnpm install
30+
31+
- name: Run unit tests
32+
run: pnpm test
33+
34+
- name: Install Playwright
35+
run: npx playwright install --with-deps
36+
37+
- name: Run E2E tests
38+
run: pnpm test:e2e --run
39+
40+
- name: Upload test results
41+
if: failure()
42+
uses: actions/upload-artifact@v3
43+
with:
44+
name: test-results
45+
path: test-results/
46+
47+
build:
48+
name: Build Application
49+
needs: test
50+
runs-on: ubuntu-latest
51+
52+
steps:
53+
- name: Checkout code
54+
uses: actions/checkout@v4
55+
56+
- name: Setup Node.js
57+
uses: actions/setup-node@v4
58+
with:
59+
node-version: '20'
60+
61+
- name: Install pnpm
62+
uses: pnpm/action-setup@v2
63+
with:
64+
version: 8
65+
66+
- name: Install dependencies
67+
run: pnpm install
68+
69+
- name: Build application
70+
run: pnpm build
71+
72+
- name: Upload build artifacts
73+
uses: actions/upload-artifact@v3
74+
with:
75+
name: dist
76+
path: dist/
77+
78+
deploy:
79+
name: Deploy to Hostinger
80+
needs: build
81+
runs-on: ubuntu-latest
82+
if: github.ref == 'refs/heads/master'
83+
84+
steps:
85+
- name: Checkout code
86+
uses: actions/checkout@v4
87+
88+
- name: Download build artifacts
89+
uses: actions/download-artifact@v3
90+
with:
91+
name: dist
92+
path: dist/
93+
94+
- name: Install SSH key
95+
uses: shimataro/ssh-key-action@v2
96+
with:
97+
key: ${{ secrets.HOSTINGER_SSH_KEY }}
98+
known_hosts: ${{ secrets.HOSTINGER_KNOWN_HOSTS }}
99+
100+
- name: Create deployment package
101+
run: |
102+
tar -czf deploy.tar.gz dist/ package.json pnpm-lock.yaml ecosystem.config.js
103+
104+
- name: Upload to server
105+
run: |
106+
scp deploy.tar.gz ${{ secrets.HOSTINGER_USER }}@${{ secrets.HOSTINGER_HOST }}:/var/www/smarthaven/
107+
108+
- name: Deploy on server
109+
run: |
110+
ssh ${{ secrets.HOSTINGER_USER }}@${{ secrets.HOSTINGER_HOST }} << 'ENDSSH'
111+
cd /var/www/smarthaven
112+
113+
# Backup current deployment
114+
if [ -d "dist" ]; then
115+
tar -czf backup-$(date +%Y%m%d-%H%M%S).tar.gz dist/
116+
ls -t backup-*.tar.gz | tail -n +6 | xargs -r rm
117+
fi
118+
119+
# Extract new deployment
120+
tar -xzf deploy.tar.gz
121+
rm deploy.tar.gz
122+
123+
# Restart PM2 if needed
124+
if pm2 list | grep -q "transcript-parser"; then
125+
pm2 restart transcript-parser
126+
else
127+
pm2 start ecosystem.config.js
128+
pm2 save
129+
fi
130+
131+
echo "Deployment complete!"
132+
ENDSSH
133+
134+
- name: Verify deployment
135+
run: |
136+
echo "Waiting for application to start..."
137+
sleep 10
138+
curl -f https://smarthaven.ai.com || exit 1
139+
echo "✅ Deployment verified!"

.gitignore

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,12 @@ dist
1212
dist-ssr
1313
*.local
1414

15+
# Environment variables
16+
.env
17+
.env.local
18+
.env.*.local
19+
!.env.example
20+
1521
# Editor directories and files
1622
.vscode/*
1723
!.vscode/extensions.json
@@ -37,3 +43,35 @@ windows-installer/
3743
*.deb
3844
*.rpm
3945
*.zip
46+
47+
# TypeScript build info
48+
*.tsbuildinfo
49+
50+
# Turborepo cache
51+
.turbo
52+
53+
# Test coverage
54+
coverage/
55+
.nyc_output/
56+
57+
# Cache directories
58+
.cache/
59+
60+
# Hosting credentials (sensitive)
61+
docs/hosting/
62+
63+
# Deployment files (production secrets)
64+
.env.production
65+
.env.staging
66+
certbot/
67+
*.pem
68+
*.key
69+
70+
# Playwright test artifacts
71+
test-results/
72+
playwright-report/
73+
!playwright-report/index.html
74+
75+
# E2E test screenshots
76+
tests/e2e/*.png
77+
tests/e2e/*.webm

Dockerfile

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# Multi-stage Dockerfile for Transcript Parser
2+
# Stage 1: Build the application
3+
FROM node:20-alpine AS builder
4+
5+
# Set working directory
6+
WORKDIR /app
7+
8+
# Install pnpm
9+
RUN npm install -g pnpm
10+
11+
# Copy package files
12+
COPY package.json pnpm-lock.yaml pnpm-workspace.yaml ./
13+
COPY packages ./packages
14+
15+
# Install dependencies
16+
RUN pnpm install --frozen-lockfile
17+
18+
# Copy source code
19+
COPY . .
20+
21+
# Build all packages
22+
RUN pnpm build
23+
24+
# Stage 2: Production image
25+
FROM node:20-alpine AS production
26+
27+
# Set working directory
28+
WORKDIR /app
29+
30+
# Install pnpm and serve (for static file serving)
31+
RUN npm install -g pnpm serve
32+
33+
# Copy built application from builder
34+
COPY --from=builder /app/dist ./dist
35+
COPY --from=builder /app/package.json ./
36+
COPY --from=builder /app/pnpm-lock.yaml ./
37+
38+
# Create non-root user for security
39+
RUN addgroup -g 1001 -S nodejs && \
40+
adduser -S nodejs -u 1001
41+
42+
# Change ownership
43+
RUN chown -R nodejs:nodejs /app
44+
45+
# Switch to non-root user
46+
USER nodejs
47+
48+
# Expose port
49+
EXPOSE 3000
50+
51+
# Health check
52+
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
53+
CMD node -e "require('http').get('http://localhost:3000', (r) => {process.exit(r.statusCode === 200 ? 0 : 1)})"
54+
55+
# Start the application
56+
CMD ["serve", "-s", "dist", "-l", "3000"]

0 commit comments

Comments
 (0)