Congratulations, @name! Darwin here with the last lesson of Module 5 - deploying a Flask application! ππ
You've built a functioning Safari Database application with forms, authentication and templates. Now it's time to publish it on the internet so the world can use it! π
Safari Analogy: Deployment is like opening the park to the public - until now the park only operated internally (localhost), now you're opening the gates for tourists from all over the world (internet)! π¦π
β `app.run(debug=True)` - development server β Auto-reload after code changes β Detailed errors in the browser β Localhost only - not accessible from the internet β Slow - not optimized
β WSGI server (Gunicorn, uWSGI) β No `debug=True` - security! β Environment variables - SECRET_KEY, DATABASE_URL β Publicly accessible - anyone can visit β Fast - optimized
β οΈ NEVER use `app.run(debug=True)` in production!
Gunicorn (Green Unicorn) is a popular WSGI server for Flask/Django applications.
WSGI = Web Server Gateway Interface - a standard for communication between a server and a Python application.
1pip install gunicorn1# Basic
2gunicorn app:app
3
4# With port and workers specified
5gunicorn app:app --bind 0.0.0.0:8000 --workers 4
6
7# With reload (dev only)
8gunicorn app:app --reloadFormat: `gunicorn <module>:<app_variable>`
Save all dependencies:
1pip freeze > requirements.txtrequirements.txt:
1Flask==3.0.0
2Flask-WTF==1.2.1
3Flask-Login==0.6.3
4Werkzeug==3.0.1
5gunicorn==21.2.0NEVER commit SECRET_KEY and sensitive data to git!
Use environment variables:
1# app.py
2import os
3
4app = Flask(__name__)
5
6# Get from environment variables
7app.config['SECRET_KEY'] = os.environ.get('SECRET_KEY') or 'dev-fallback-key'
8app.config['DATABASE_URL'] = os.environ.get('DATABASE_URL') or 'sqlite:///dev.db'
9
10# Debug only in dev
11app.config['DEBUG'] = os.environ.get('FLASK_ENV') == 'development'1# .gitignore
2venv/
3__pycache__/
4*.pyc
5*.pyo
6.env
7instance/
8.DS_Store1web: gunicorn app:appProcfile tells the platform how to run your application.
1python-3.11.0Specifies the Python version.
Render is a modern hosting platform with a free plan. A great alternative to Heroku!
Project structure:
1safari_web/
2βββ app.py
3βββ models.py
4βββ forms.py
5βββ requirements.txt
6βββ Procfile
7βββ .gitignore
8βββ templates/
9β βββ ...
10βββ static/
11 βββ ...app.py - last lines:
1if __name__ == '__main__':
2 # Only for local development
3 app.run(debug=True)Render will run via Procfile, so `if name` won't execute!
1git init
2git add .
3git commit -m "Initial commit - Safari Database"
4git branch -M main
5git remote add origin https://github.com/your-username/safari-web.git
6git push -u origin mainGo to https://render.com and register (FREE)
Click "New +" β "Web Service"
Connect your GitHub repository
Select the `safari-web` repository
Configuration:
Environment Variables - add:
Click "Create Web Service"
Render automatically:
Congratulations! Your application is LIVE! ππ
Railway is another great platform with a simple setup.
Domain: `https://safari-database.up.railway.app`
Before deployment make sure:
1app.config['DATABASE_URL'] = 'sqlite:///safari.db'Problems: SQLite is not recommended for production (concurrency issues).
Render/Railway offer FREE PostgreSQL!
Render: Add PostgreSQL Database β copy DATABASE_URL
1import os
2
3database_url = os.environ.get('DATABASE_URL')
4
5if database_url and database_url.startswith('postgres://'):
6 # Render uses postgres://, but SQLAlchemy needs postgresql://
7 database_url = database_url.replace('postgres://', 'postgresql://', 1)
8
9app.config['SQLALCHEMY_DATABASE_URI'] = database_url or 'sqlite:///dev.db'Flask automatically serves files from `static/`, but in production it's better to use a CDN or Nginx.
Basic Flask configuration:
1# app.py
2app = Flask(__name__)
3
4# Flask automatically serves static files from /static/
5# http://yourapp.com/static/css/style.cssIn templates:
1<link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
2<script src="{{ url_for('static', filename='js/script.js') }}"></script>Dashboard β Your Web Service β Logs
Project β Your Service β Logs
1[2024-01-15 10:23:45] INFO: Starting gunicorn 21.2.0
2[2024-01-15 10:23:45] INFO: Listening at: http://0.0.0.0:10000
3[2024-01-15 10:23:45] INFO: Using worker: sync
4[2024-01-15 10:23:45] INFO: Booting worker with pid: 421git add .
2git commit -m "Update: Add new feature"
3git push origin mainAuto-deploy = push to GitHub β automatic deploy! π
Instead of `safari-database.onrender.com` you can use your own domain:
1# app.py
2import os
3from flask import Flask, render_template, redirect, url_for, flash
4from flask_login import LoginManager, login_user, logout_user, login_required, current_user
5from flask_sqlalchemy import SQLAlchemy
6
7app = Flask(__name__)
8
9# Configuration from environment variables
10app.config['SECRET_KEY'] = os.environ.get('SECRET_KEY') or 'dev-key-change-in-production'
11app.config['SQLALCHEMY_DATABASE_URI'] = os.environ.get('DATABASE_URL') or 'sqlite:///dev.db'
12app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
13
14# Fix for Render PostgreSQL URL
15if app.config['SQLALCHEMY_DATABASE_URI'].startswith('postgres://'):
16 app.config['SQLALCHEMY_DATABASE_URI'] = app.config['SQLALCHEMY_DATABASE_URI'].replace('postgres://', 'postgresql://', 1)
17
18db = SQLAlchemy(app)
19login_manager = LoginManager(app)
20login_manager.login_view = 'login'
21
22# Models, routes, etc...
23
24if __name__ == '__main__':
25 # Only for local development
26 port = int(os.environ.get('PORT', 5000))
27 app.run(host='0.0.0.0', port=port, debug=os.environ.get('FLASK_ENV') == 'development')In this lesson you learned:
Final Safari Analogy: Deployment is like the grand opening of a safari park - you prepared the infrastructure (code), hired staff (WSGI server), secured the park (SECRET_KEY, HTTPS), and opened the gates for tourists from all over the world (internet)! Your Flask application lives and runs 24/7 in the cloud! π¦ππ
You've built a complete web application with:
Safari Database is now LIVE and accessible to everyone on the internet! π
Darwin is proud of you! Get ready for the next modules, where you'll learn advanced Python and AI techniques! π€π