This guide covers deployment strategies for Flet applications, from simple static hosting to enterprise-scale server deployments.
Deployment Options
Flet applications can be deployed in several ways:
| Type | Use Case | Hosting Requirements |
|---|
| Static Web | Calculators, tools, demos | CDN, static hosting |
| Server-Side Web | Multi-user apps, dashboards | Python server |
| Desktop | Offline apps, enterprise tools | User’s computer |
| Mobile | Native mobile experience | App stores |
Static Web Deployment
Deploy WebAssembly-based Flet apps to any static hosting service.
GitHub Pages
Free hosting for public repositories:
Build your app
flet build web --base-url "/repository-name"
Replace repository-name with your GitHub repository name.Create deployment script
#!/bin/bash
set -e
# Build the app
flet build web --base-url "/repository-name"
# Navigate to build output
cd build/web
# Initialize git repository
git init
git add -A
git commit -m "Deploy to GitHub Pages"
# Force push to gh-pages branch
git push -f [email protected]:username/repository-name.git main:gh-pages
cd ../..
Make executable: chmod +x deploy.shEnable GitHub Pages
- Go to repository Settings > Pages
- Select
gh-pages branch
- Click Save
Your app will be available at https://username.github.io/repository-name/
Netlify
One-click deployment with automatic HTTPS:
Create netlify.toml
[build]
command = "pip install flet && flet build web"
publish = "build/web"
[[redirects]]
from = "/*"
to = "/index.html"
status = 200
Deploy via CLI
# Install Netlify CLI
npm install -g netlify-cli
# Build your app
flet build web
# Deploy
netlify deploy --prod --dir=build/web
Or connect your GitHub repository for automatic deployments.
Vercel
Fast global CDN deployment:
Create vercel.json
{
"buildCommand": "pip install flet && flet build web",
"outputDirectory": "build/web",
"rewrites": [
{ "source": "/(.*)", "destination": "/" }
]
}
Deploy
# Install Vercel CLI
npm install -g vercel
# Deploy
vercel --prod
Cloudflare Pages
Free hosting with global CDN:
Deploy via Wrangler
npm install -g wrangler
wrangler pages publish build/web --project-name=my-flet-app
Or connect your repository in Cloudflare dashboard for automatic deployments.
Amazon S3 + CloudFront
Scalable static hosting:
Upload to S3
aws s3 sync build/web/ s3://my-bucket-name/ \
--acl public-read \
--cache-control max-age=31536000
Create CloudFront distribution
aws cloudfront create-distribution \
--origin-domain-name my-bucket-name.s3.amazonaws.com \
--default-root-object index.html
Server-Side Web Deployment
Deploy dynamic Flet apps that run Python on the server.
Railway
Simple deployment from Git:
Create project files
import flet as ft
import os
def main(page: ft.Page):
page.add(ft.Text("Hello from Railway!"))
if __name__ == "__main__":
ft.app(
target=main,
view=ft.AppView.WEB_BROWSER,
port=int(os.getenv("PORT", 8000)),
host="0.0.0.0"
)
[build]
builder = "NIXPACKS"
[deploy]
startCommand = "python main.py"
Deploy
- Push code to GitHub
- Connect repository in Railway
- Deploy automatically
Render
Free tier for web apps:
Create app
import flet as ft
import os
def main(page: ft.Page):
page.add(ft.Text("Hello from Render!"))
if __name__ == "__main__":
ft.app(
target=main,
view=ft.AppView.WEB_BROWSER,
port=int(os.getenv("PORT", 10000)),
host="0.0.0.0"
)
Create render.yaml
services:
- type: web
name: my-flet-app
runtime: python
buildCommand: pip install -r requirements.txt
startCommand: python main.py
Deploy
- Connect repository in Render
- Deploy as Web Service
Fly.io
Deploy near users globally:
Create Dockerfile
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["python", "main.py"]
Create fly.toml
app = "my-flet-app"
[build]
dockerfile = "Dockerfile"
[env]
PORT = "8000"
[[services]]
internal_port = 8000
protocol = "tcp"
[[services.ports]]
port = 80
handlers = ["http"]
[[services.ports]]
port = 443
handlers = ["tls", "http"]
Deploy
flyctl launch
flyctl deploy
Docker + Cloud Run (GCP)
Serverless container deployment:
Create optimized Dockerfile
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
# Use Cloud Run's PORT environment variable
ENV PORT=8080
CMD exec python main.py
import flet as ft
import os
def main(page: ft.Page):
page.add(ft.Text("Hello from Cloud Run!"))
if __name__ == "__main__":
ft.app(
target=main,
view=ft.AppView.WEB_BROWSER,
port=int(os.getenv("PORT", 8080)),
host="0.0.0.0"
)
Build and deploy
# Build and push to Google Container Registry
gcloud builds submit --tag gcr.io/PROJECT_ID/my-flet-app
# Deploy to Cloud Run
gcloud run deploy my-flet-app \
--image gcr.io/PROJECT_ID/my-flet-app \
--platform managed \
--region us-central1 \
--allow-unauthenticated
Kubernetes
For production-scale deployments:
Create deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: flet-app
spec:
replicas: 3
selector:
matchLabels:
app: flet-app
template:
metadata:
labels:
app: flet-app
spec:
containers:
- name: flet-app
image: my-registry.com/flet-app:1.0.0
ports:
- containerPort: 8000
env:
- name: PORT
value: "8000"
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "500m"
---
apiVersion: v1
kind: Service
metadata:
name: flet-app
spec:
selector:
app: flet-app
ports:
- port: 80
targetPort: 8000
type: LoadBalancer
Deploy
kubectl apply -f deployment.yaml
Desktop Application Distribution
Windows
Option 1: Direct Download
- Host installer on your website
- Distribute via USB or network share
Option 2: Microsoft Store
- Convert to MSIX package
- Submit to Microsoft Store
- Requires Windows Developer account ($19 one-time)
Option 3: Chocolatey
Create package for Chocolatey repository:
choco pack
choco push my-app.1.0.0.nupkg --source https://push.chocolatey.org/
macOS
Option 1: Direct Download
- Distribute signed DMG file
- Users drag to Applications folder
Option 2: Homebrew Cask
Create formula:
cask "my-app" do
version "1.0.0"
sha256 "..."
url "https://example.com/MyApp-#{version}.dmg"
name "My Application"
homepage "https://example.com"
app "MyApp.app"
end
Option 3: Mac App Store
- Requires Apple Developer account ($99/year)
- Additional review process
Linux
Option 1: AppImage
- Single-file distribution
- No installation required
- Works on most distributions
Option 2: Snap Store
name: my-app
version: '1.0.0'
summary: My Flet Application
description: A cross-platform app built with Flet
base: core20
confinement: strict
parts:
my-app:
plugin: dump
source: ./build/linux/x64/release/bundle/
apps:
my-app:
command: my_app
Build and publish:
snapcraft
snapcraft push my-app_1.0.0_amd64.snap --release stable
Option 3: Flatpak
- Sandboxed application
- Available in Flathub
Mobile Application Distribution
Android
Google Play Store
Build signed AAB
flet build aab \
--android-signing-key-store "release.jks" \
--android-signing-key-alias "release"
Upload to Play Console
- Create app in Play Console
- Complete store listing
- Upload AAB file
- Submit for review (1-3 days)
Direct Distribution (APK)
- Host APK on your website
- Users enable “Unknown Sources”
- Install directly
iOS
App Store
Build IPA
flet build ipa \
--ios-team-id "TEAM_ID" \
--ios-provisioning-profile "Distribution Profile" \
--ios-export-method "app-store"
Upload via Transporter
- Open Transporter app
- Drag IPA file
- Click “Deliver”
TestFlight (Beta)
- Upload IPA to App Store Connect
- Invite testers via email
- No review required for internal testing
Environment Configuration
Environment Variables
Manage configuration across environments:
import os
class Config:
# Development defaults
DEBUG = os.getenv("DEBUG", "false").lower() == "true"
PORT = int(os.getenv("PORT", 8000))
HOST = os.getenv("HOST", "localhost")
# Database
DATABASE_URL = os.getenv("DATABASE_URL", "sqlite:///app.db")
# API Keys
API_KEY = os.getenv("API_KEY")
Use in your app:
import flet as ft
from config import Config
def main(page: ft.Page):
page.add(ft.Text(f"Running on port {Config.PORT}"))
if __name__ == "__main__":
ft.app(
target=main,
view=ft.AppView.WEB_BROWSER,
port=Config.PORT,
host=Config.HOST
)
Production Settings
For production deployments:
import flet as ft
import os
def main(page: ft.Page):
# Your app code
pass
if __name__ == "__main__":
ft.app(
target=main,
view=ft.AppView.WEB_BROWSER,
port=int(os.getenv("PORT", 8000)),
host="0.0.0.0", # Listen on all interfaces
# assets_dir="assets", # Serve static assets
# upload_dir="uploads", # Handle file uploads
)
Always use host="0.0.0.0" in production to accept connections from outside the container/server.
Monitoring and Logging
Application Logging
import logging
import flet as ft
# Configure logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)
def main(page: ft.Page):
logger.info(f"New session started: {page.session_id}")
def on_error(e):
logger.error(f"Error in session {page.session_id}: {e}")
page.on_error = on_error
page.add(ft.Text("Hello!"))
ft.app(target=main)
Health Checks
For load balancers and orchestrators:
import flet as ft
from flet import Page
def health_check(page: Page):
"""Simple health check endpoint"""
page.add(ft.Text("OK"))
page.update()
def main(page: Page):
# Main app logic
pass
# Run with health check
ft.app(
target=main,
route_url_strategy="path",
)
SSL/TLS Configuration
For production web deployments, always use HTTPS:
Using Reverse Proxy (Recommended)
Use nginx or Caddy in front of your Flet app:
server {
listen 443 ssl http2;
server_name example.com;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
location / {
proxy_pass http://localhost:8000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
Caching Static Assets
For web deployments:
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
CDN Configuration
Use CDN for static web apps:
- Cloudflare
- AWS CloudFront
- Fastly
- Akamai
Compression
Enable gzip/brotli compression:
gzip on;
gzip_types text/plain text/css application/json application/javascript;
gzip_min_length 1000;
Deployment Checklist
Next Steps