Skip to content

Commit 96c9adf

Browse files
committed
feat: add ready to deploy stuff
1 parent dd2b584 commit 96c9adf

File tree

20 files changed

+1110
-11
lines changed

20 files changed

+1110
-11
lines changed

.dockerignore

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# Dependencies
2+
node_modules/
3+
bun.lock
4+
5+
# Development
6+
.git/
7+
.gitignore
8+
*.md
9+
!README.md
10+
11+
# Environment
12+
.env
13+
.env.*
14+
!.env.example
15+
16+
# IDE
17+
.vscode/
18+
.idea/
19+
*.swp
20+
*.swo
21+
*~
22+
23+
# Build artifacts
24+
dist/
25+
build/
26+
*.log
27+
28+
# Data directories (managed via volumes)
29+
storage/
30+
data/
31+
dev.db
32+
dev.db-journal
33+
34+
# Prisma
35+
prisma/migrations/
36+
*.db
37+
*.db-journal
38+
39+
# Docker
40+
Dockerfile
41+
docker-compose.yml
42+
.dockerignore
43+
44+
# Testing
45+
coverage/
46+
*.test.ts
47+
*.spec.ts
48+
49+
# OS
50+
.DS_Store
51+
Thumbs.db

.env.example

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@ DATABASE_URL="file:./dev.db"
44
# API Authentication
55
API_SECRET="your-secret-key-here"
66

7+
# GitHub API (optional)
8+
# Personal access token to avoid rate limiting when fetching user info
9+
# Create at: https://github.com/settings/tokens (no scopes needed for public user info)
10+
GITHUB_TOKEN=
11+
712
# Upload Configuration
813
MAX_UPLOAD_SIZE=10485760 # 10MB in bytes
914

@@ -13,3 +18,7 @@ DEFAULT_PAGE_SIZE=100
1318
# Local Storage Configuration
1419
LOCAL_STORAGE_PATH=./storage
1520
LOCAL_STORAGE_URL=http://localhost:3000/storage
21+
22+
# Production Deployment (Docker Compose)
23+
# Your domain name for automatic HTTPS via Caddy
24+
DOMAIN=store.vicinae.dev

.github/workflows/ci.yml

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
name: CI
2+
3+
on:
4+
pull_request:
5+
branches: [main, develop]
6+
push:
7+
branches: [main, develop]
8+
9+
jobs:
10+
lint-and-test:
11+
name: Lint and Test
12+
runs-on: ubuntu-latest
13+
14+
steps:
15+
- name: Checkout code
16+
uses: actions/checkout@v4
17+
18+
- name: Setup Bun
19+
uses: oven-sh/setup-bun@v1
20+
with:
21+
bun-version: latest
22+
23+
- name: Install dependencies
24+
run: bun install --frozen-lockfile
25+
26+
- name: Generate Prisma Client
27+
run: bun prisma generate
28+
29+
- name: Type check
30+
run: bun run type-check || echo "No type-check script found, skipping..."
31+
continue-on-error: true
32+
33+
- name: Lint
34+
run: bun run lint || echo "No lint script found, skipping..."
35+
continue-on-error: true
36+
37+
- name: Build check
38+
run: |
39+
# Verify that the app can be imported without errors
40+
bun build src/index.ts --target=bun --outdir=./dist
41+
42+
- name: Test
43+
run: bun test || echo "No tests found, skipping..."
44+
continue-on-error: true
45+
46+
build-docker:
47+
name: Build Docker Image
48+
runs-on: ubuntu-latest
49+
needs: lint-and-test
50+
51+
steps:
52+
- name: Checkout code
53+
uses: actions/checkout@v4
54+
55+
- name: Set up Docker Buildx
56+
uses: docker/setup-buildx-action@v3
57+
58+
- name: Build Docker image
59+
uses: docker/build-push-action@v5
60+
with:
61+
context: .
62+
push: false
63+
tags: vicinae-store:test
64+
cache-from: type=gha
65+
cache-to: type=gha,mode=max
66+
target: production
67+
68+
- name: Test Docker image
69+
run: |
70+
docker run --rm -d --name test-container \
71+
-e DATABASE_URL="file:./test.db" \
72+
-e API_SECRET="test-secret" \
73+
-e LOCAL_STORAGE_PATH="/app/storage" \
74+
-e LOCAL_STORAGE_URL="http://localhost:3000/storage" \
75+
vicinae-store:test
76+
77+
# Wait for container to be healthy
78+
sleep 10
79+
80+
# Check if container is running
81+
docker ps | grep test-container
82+
83+
# Check health endpoint
84+
docker exec test-container wget --spider --tries=3 http://localhost:3000/ || true
85+
86+
# Cleanup
87+
docker stop test-container

.github/workflows/deploy.yml

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
name: Deploy
2+
3+
on:
4+
push:
5+
branches: [main]
6+
workflow_dispatch:
7+
8+
jobs:
9+
build-and-push:
10+
name: Build and Push Docker Image
11+
runs-on: ubuntu-latest
12+
13+
steps:
14+
- name: Checkout code
15+
uses: actions/checkout@v4
16+
17+
- name: Set up Docker Buildx
18+
uses: docker/setup-buildx-action@v3
19+
20+
- name: Log in to GitHub Container Registry
21+
uses: docker/login-action@v3
22+
with:
23+
registry: ghcr.io
24+
username: ${{ github.actor }}
25+
password: ${{ secrets.GITHUB_TOKEN }}
26+
27+
- name: Extract metadata
28+
id: meta
29+
uses: docker/metadata-action@v5
30+
with:
31+
images: ghcr.io/${{ github.repository }}
32+
tags: |
33+
type=ref,event=branch
34+
type=sha,prefix={{branch}}-
35+
type=raw,value=latest,enable={{is_default_branch}}
36+
37+
- name: Build and push Docker image
38+
uses: docker/build-push-action@v5
39+
with:
40+
context: .
41+
push: true
42+
tags: ${{ steps.meta.outputs.tags }}
43+
labels: ${{ steps.meta.outputs.labels }}
44+
cache-from: type=gha
45+
cache-to: type=gha,mode=max
46+
target: production
47+
48+
deploy:
49+
name: Deploy to Server
50+
runs-on: ubuntu-latest
51+
needs: build-and-push
52+
environment:
53+
name: production
54+
url: https://${{ vars.DOMAIN }}
55+
56+
steps:
57+
- name: Checkout code
58+
uses: actions/checkout@v4
59+
60+
- name: Deploy to server via SSH
61+
uses: appleboy/ssh-action@v1.0.0
62+
with:
63+
host: ${{ secrets.DEPLOY_HOST }}
64+
username: ${{ secrets.DEPLOY_USER }}
65+
key: ${{ secrets.DEPLOY_SSH_KEY }}
66+
port: ${{ secrets.DEPLOY_PORT || 22 }}
67+
script: |
68+
set -e
69+
70+
# Navigate to application directory
71+
cd ${{ secrets.DEPLOY_PATH || '/opt/vicinae-store' }}
72+
73+
# Log in to GitHub Container Registry
74+
echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin
75+
76+
# Pull latest image
77+
docker-compose pull app
78+
79+
# Run migrations (if any)
80+
docker-compose run --rm app bun prisma migrate deploy || true
81+
82+
# Recreate and restart app container
83+
docker-compose up -d --force-recreate app
84+
85+
# Wait for health check
86+
echo "Waiting for application to be healthy..."
87+
sleep 10
88+
89+
# Verify deployment
90+
docker-compose ps app
91+
92+
# Clean up old images
93+
docker image prune -f
94+
95+
echo "Deployment completed successfully!"
96+
97+
- name: Notify deployment status
98+
if: always()
99+
run: |
100+
if [ "${{ job.status }}" == "success" ]; then
101+
echo "✅ Deployment successful!"
102+
else
103+
echo "❌ Deployment failed!"
104+
exit 1
105+
fi

Caddyfile

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
# Caddyfile for Vicinae Extension Store
2+
# Caddy automatically provisions and renews SSL certificates via Let's Encrypt
3+
4+
{$DOMAIN} {
5+
# Enable compression
6+
encode gzip zstd
7+
8+
# Reverse proxy to Hono app
9+
reverse_proxy app:3000 {
10+
# Health check
11+
health_uri /
12+
health_interval 30s
13+
health_timeout 5s
14+
15+
# Headers
16+
header_up X-Real-IP {remote_host}
17+
header_up X-Forwarded-For {remote_host}
18+
header_up X-Forwarded-Proto {scheme}
19+
}
20+
21+
# Security headers
22+
header {
23+
# Remove server header
24+
-Server
25+
26+
# Security headers
27+
X-Content-Type-Options "nosniff"
28+
X-Frame-Options "DENY"
29+
Referrer-Policy "strict-origin-when-cross-origin"
30+
31+
# CORS headers for extension downloads
32+
Access-Control-Allow-Origin "*"
33+
Access-Control-Allow-Methods "GET, POST, OPTIONS"
34+
Access-Control-Allow-Headers "Content-Type, Authorization"
35+
}
36+
37+
# Rate limiting for uploads (100 requests per minute)
38+
rate_limit {
39+
zone upload {
40+
key {remote_host}
41+
events 100
42+
window 1m
43+
}
44+
45+
match {
46+
path /extension/upload
47+
}
48+
}
49+
50+
# Logging
51+
log {
52+
output file /data/access.log {
53+
roll_size 100mb
54+
roll_keep 5
55+
}
56+
format json
57+
}
58+
}

0 commit comments

Comments
 (0)