Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions Tiltfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# -*- mode: Python -*-
# Tiltfile for FinMind local development

# Load extensions
load('ext://restart_process', 'docker_build_with_restart')
load('ext://helm_resource', 'helm_resource', 'helm_repo')

# Settings
allow_k8s_contexts(['docker-desktop', 'minikube', 'kind-finmind'])

# Build backend image
docker_build(
'finmind-backend',
context='.',
dockerfile='app/backend/Dockerfile',
live_update=[
sync('./app/backend', '/app'),
run('pip install -r /app/requirements.txt', trigger=['./app/backend/requirements.txt']),
]
)

# Build frontend image
docker_build(
'finmind-frontend',
context='.',
dockerfile='app/frontend/Dockerfile',
live_update=[
sync('./app/frontend/src', '/app/src'),
run('npm install', trigger=['./app/frontend/package.json']),
]
)

# Deploy with Helm
helm_resource(
'finmind',
chart='./deploy/helm',
namespace='finmind',
flags=[
'--create-namespace',
'--values=./deploy/helm/values.yaml',
'--set=image.backend.tag=latest',
'--set=image.frontend.tag=latest',
],
resource_deps=['finmind-backend', 'finmind-frontend'],
port_forwards=[
'8000:8000', # Backend API
'3000:3000', # Frontend
]
)

# Health check
local_resource(
'health-check',
cmd='curl -sf http://localhost:8000/api/health/ && echo "Backend OK"',
resource_deps=['finmind'],
auto_init=False,
trigger_mode=TRIGGER_MODE_MANUAL,
)
117 changes: 117 additions & 0 deletions deploy.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
#!/bin/bash
# deploy.sh - Universal one-click deployment for FinMind
# Usage: ./deploy.sh [platform]
# Platforms: railway, heroku, render, fly, digitalocean, aws, gcp, azure, k8s, docker

set -e

PLATFORM="${1:-docker}"
APP_NAME="finmind"

echo "FinMind Universal Deployment"
echo "Platform: $PLATFORM"
echo "================================"

case "$PLATFORM" in
docker)
echo "Starting with Docker Compose..."
docker-compose up -d
echo "Done! Frontend: http://localhost:3000 | Backend: http://localhost:8000"
;;

k8s|kubernetes)
echo "Deploying to Kubernetes with Helm..."
kubectl create namespace finmind --dry-run=client -o yaml | kubectl apply -f -
helm upgrade --install finmind ./deploy/helm \
--namespace finmind \
--create-namespace \
--values ./deploy/helm/values.yaml \
--wait
echo "Done! Run: kubectl port-forward svc/finmind-frontend 3000:3000 -n finmind"
;;

railway)
echo "Deploying to Railway..."
command -v railway >/dev/null 2>&1 || npm install -g @railway/cli
railway login
railway up
echo "Done! Check Railway dashboard for URL."
;;

heroku)
echo "Deploying to Heroku..."
command -v heroku >/dev/null 2>&1 || curl https://cli-assets.heroku.com/install.sh | sh
heroku create $APP_NAME 2>/dev/null || true
heroku addons:create heroku-postgresql:mini -a $APP_NAME 2>/dev/null || true
heroku addons:create heroku-redis:mini -a $APP_NAME 2>/dev/null || true
heroku container:push web -a $APP_NAME
heroku container:release web -a $APP_NAME
echo "Done! URL: https://$APP_NAME.herokuapp.com"
;;

render)
echo "Deploying to Render..."
echo "Please connect your GitHub repo at https://render.com/new"
echo "Use render.yaml for automatic configuration."
;;

fly)
echo "Deploying to Fly.io..."
command -v flyctl >/dev/null 2>&1 || curl -L https://fly.io/install.sh | sh
flyctl launch --name $APP_NAME --no-deploy 2>/dev/null || true
flyctl deploy
echo "Done! URL: https://$APP_NAME.fly.dev"
;;

digitalocean|do)
echo "Deploying to DigitalOcean App Platform..."
command -v doctl >/dev/null 2>&1 || snap install doctl
doctl apps create --spec deploy/do-app-spec.yaml
echo "Done! Check DigitalOcean dashboard."
;;

aws)
echo "Deploying to AWS ECS Fargate..."
aws ecr get-login-password | docker login --username AWS --password-stdin \
$(aws sts get-caller-identity --query Account --output text).dkr.ecr.us-east-1.amazonaws.com
docker-compose -f deploy/docker-compose.aws.yml push
aws ecs update-service --cluster finmind --service finmind-backend --force-new-deployment
echo "Done! Check AWS ECS console."
;;

gcp)
echo "Deploying to GCP Cloud Run..."
gcloud builds submit --tag gcr.io/$(gcloud config get-value project)/finmind-backend ./app/backend
gcloud run deploy finmind-backend \
--image gcr.io/$(gcloud config get-value project)/finmind-backend \
--platform managed \
--region us-central1 \
--allow-unauthenticated
echo "Done! Check GCP Cloud Run console."
;;

azure)
echo "Deploying to Azure Container Apps..."
az containerapp up \
--name $APP_NAME \
--resource-group finmind-rg \
--location eastus \
--environment finmind-env \
--image finmind-backend:latest \
--target-port 8000 \
--ingress external
echo "Done! Check Azure portal."
;;

tilt)
echo "Starting Tilt local dev environment..."
command -v tilt >/dev/null 2>&1 || curl -fsSL https://raw.githubusercontent.com/tilt-dev/tilt/master/scripts/install.sh | bash
tilt up
;;

*)
echo "Unknown platform: $PLATFORM"
echo "Available: docker, k8s, railway, heroku, render, fly, digitalocean, aws, gcp, azure, tilt"
exit 1
;;
esac
15 changes: 15 additions & 0 deletions deploy/helm/Chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
apiVersion: v2
name: finmind
description: FinMind - Personal Finance Management Application
type: application
version: 1.0.0
appVersion: "1.0.0"
keywords:
- finance
- personal-finance
- budgeting
home: https://github.com/rohitdash08/FinMind
sources:
- https://github.com/rohitdash08/FinMind
maintainers:
- name: FinMind Team
75 changes: 75 additions & 0 deletions deploy/helm/templates/deployment.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Release.Name }}-backend
labels:
app: {{ .Release.Name }}-backend
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
app: {{ .Release.Name }}-backend
template:
metadata:
labels:
app: {{ .Release.Name }}-backend
spec:
containers:
- name: backend
image: "{{ .Values.image.backend.repository }}:{{ .Values.image.backend.tag }}"
imagePullPolicy: {{ .Values.image.backend.pullPolicy }}
ports:
- containerPort: 8000
envFrom:
- secretRef:
name: {{ .Values.secrets.existingSecret }}
env:
- name: DEBUG
value: {{ .Values.env.DEBUG | quote }}
- name: ALLOWED_HOSTS
value: {{ .Values.env.ALLOWED_HOSTS | quote }}
resources:
{{- toYaml .Values.resources.backend | nindent 12 }}
livenessProbe:
httpGet:
path: /api/health/
port: 8000
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /api/health/
port: 8000
initialDelaySeconds: 5
periodSeconds: 5
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Release.Name }}-frontend
labels:
app: {{ .Release.Name }}-frontend
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
app: {{ .Release.Name }}-frontend
template:
metadata:
labels:
app: {{ .Release.Name }}-frontend
spec:
containers:
- name: frontend
image: "{{ .Values.image.frontend.repository }}:{{ .Values.image.frontend.tag }}"
imagePullPolicy: {{ .Values.image.frontend.pullPolicy }}
ports:
- containerPort: 3000
resources:
{{- toYaml .Values.resources.frontend | nindent 12 }}
livenessProbe:
httpGet:
path: /
port: 3000
initialDelaySeconds: 15
periodSeconds: 10
26 changes: 26 additions & 0 deletions deploy/helm/templates/hpa.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{{- if .Values.autoscaling.enabled }}
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: {{ .Release.Name }}-backend-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: {{ .Release.Name }}-backend
minReplicas: {{ .Values.autoscaling.minReplicas }}
maxReplicas: {{ .Values.autoscaling.maxReplicas }}
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }}
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }}
{{- end }}
29 changes: 29 additions & 0 deletions deploy/helm/templates/ingress.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{{- if .Values.ingress.enabled }}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ .Release.Name }}-ingress
annotations:
{{- toYaml .Values.ingress.annotations | nindent 4 }}
spec:
ingressClassName: {{ .Values.ingress.className }}
{{- if .Values.ingress.tls }}
tls:
{{- toYaml .Values.ingress.tls | nindent 4 }}
{{- end }}
rules:
{{- range .Values.ingress.hosts }}
- host: {{ .host }}
http:
paths:
{{- range .paths }}
- path: {{ .path }}
pathType: {{ .pathType }}
backend:
service:
name: {{ $.Release.Name }}-{{ .service }}
port:
number: {{ if eq .service "backend" }}{{ $.Values.service.backend.port }}{{ else }}{{ $.Values.service.frontend.port }}{{ end }}
{{- end }}
{{- end }}
{{- end }}
23 changes: 23 additions & 0 deletions deploy/helm/templates/service.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
apiVersion: v1
kind: Service
metadata:
name: {{ .Release.Name }}-backend
spec:
type: {{ .Values.service.backend.type }}
selector:
app: {{ .Release.Name }}-backend
ports:
- port: {{ .Values.service.backend.port }}
targetPort: 8000
---
apiVersion: v1
kind: Service
metadata:
name: {{ .Release.Name }}-frontend
spec:
type: {{ .Values.service.frontend.type }}
selector:
app: {{ .Release.Name }}-frontend
ports:
- port: {{ .Values.service.frontend.port }}
targetPort: 3000
Loading