A template repository for bootstrapping new applications on the Towlion platform.
- Click "Use this template" on GitHub to create a new repository
- Clone your new repo and configure environment variables
- Build and deploy
app/ # FastAPI backend
main.py # Application entry point
Dockerfile # Backend container image
models.py # SQLAlchemy models (User)
database.py # DB session management
auth.py # JWT + bcrypt helpers
deps.py # FastAPI dependencies (get_current_user)
schemas.py # Pydantic request/response models
storage.py # S3/MinIO file helpers
routers/
auth.py # Register, login, profile endpoints
alembic/ # Database migrations
deploy/
docker-compose.yml # App containers (multi-app mode)
docker-compose.standalone.yml # Full stack (self-hosted)
Caddyfile # Reverse proxy config
env.template # Environment variable reference
frontend/ # Optional Next.js frontend
scripts/
health-check.sh # Deployment health check
# Install dependencies
pip install -r requirements.txt
# Run the app
uvicorn app.main:app --reload --port 8000
# Verify it works
curl http://localhost:8000/healthThe template includes JWT-based authentication out of the box:
| Endpoint | Method | Description |
|---|---|---|
/api/auth/register |
POST | Create account (email, display_name, password) |
/api/auth/login |
POST | Get token (email, password) |
/api/auth/me |
GET | Current user profile (requires token) |
Use the Authorization: Bearer <token> header for authenticated requests.
To protect your own endpoints, add the get_current_user dependency:
from fastapi import Depends
from app.deps import get_current_user
from app.models import User
@app.get("/api/my-endpoint")
def my_endpoint(user: User = Depends(get_current_user)):
return {"user_id": user.id}Environment variables:
JWT_SECRET— Secret key for signing tokens (required in production)JWT_EXPIRY_HOURS— Token lifetime, default72CORS_ORIGINS— Comma-separated allowed origins, defaulthttp://localhost:3000
Copy deploy/env.template to deploy/.env and fill in your values. See the platform spec for details on required and optional variables.
Push to main to trigger the deploy workflow. The GitHub Action SSHs into the server and runs:
docker compose -f deploy/docker-compose.yml up -d --buildFor standalone deployment on a single server:
cp deploy/env.template deploy/.env
# Edit deploy/.env with your values
docker compose -f deploy/docker-compose.standalone.yml up -dThis includes PostgreSQL, Redis, MinIO, and Caddy alongside your app.
Configure these GitHub Actions secrets on your repository (Settings > Secrets and variables > Actions):
| Secret | Required | Description |
|---|---|---|
SERVER_HOST |
Yes | Server IP address |
SERVER_USER |
Yes | SSH user (typically deploy) |
SERVER_SSH_KEY |
Yes | SSH private key for deployment |
APP_DOMAIN |
Yes | Application domain (e.g., app.example.com) |
PREVIEW_DOMAIN |
No | Base domain for PR preview environments (e.g., example.com) |
Database and storage credentials are auto-generated on the server by the bootstrap script. They are not GitHub secrets.
The template does not include a celery-worker service by default. If your app needs background tasks:
- Add
celeryandredistorequirements.txt - Create
app/tasks.pywith your Celery app and tasks - Add the celery-worker service to
deploy/docker-compose.yml:
celery-worker:
build:
context: ..
dockerfile: app/Dockerfile
command: celery -A app.tasks worker --loglevel=info
env_file:
- .env
restart: unless-stopped
networks:
- towlion
deploy:
resources:
limits:
cpus: '0.25'
memory: 256M
reservations:
cpus: '0.10'
memory: 128MSecurity hardening is applied automatically by the platform:
- Security headers — HSTS, X-Content-Type-Options, X-Frame-Options, Referrer-Policy, and Permissions-Policy are set via the Caddy
(security_headers)snippet, imported by every app route - Trivy scanning — Every deploy scans the built Docker image for HIGH/CRITICAL vulnerabilities (non-blocking). A weekly cron scan covers all running images.
- Credential isolation — Per-app PostgreSQL users and MinIO buckets are provisioned by
create-app-credentials.sh
For full self-hosting instructions, see the platform documentation:
- Self-Hosting Guide — Fork model, server requirements, bootstrap process
- Deployment Tutorial — Step-by-step walkthrough from fork to running app