From a folder on your laptop to a live URL, step by step.
Render is a platform service: you connect a Git repository, tell it how to install and start your app, and it handles servers, HTTPS and redeploys. This guide takes a minimal Flask app from your laptop to a public URL, and covers the details that usually trip people up the first time.
Make a project folder with a virtual environment, and install Flask plus gunicorn, the production server Render will use:
mkdir flask-render-demo
cd flask-render-demo
python -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install flask gunicorn
Create app.py:
import os
from flask import Flask, jsonify
app = Flask(__name__)
app.config["SECRET_KEY"] = os.environ.get("SECRET_KEY", "dev-only-change-me")
@app.get("/")
def home():
return "Hello from Flask on Render!"
@app.get("/api/health")
def health():
return jsonify(status="ok")
Check it runs locally with Flask's development server:
flask --app app run --debug
Open http://127.0.0.1:5000 and you should see the greeting.
flask run for local development.
Render installs packages from requirements.txt. Generate it from your virtual environment:
pip freeze > requirements.txt
Then create .gitignore so your virtual environment and secrets never reach GitHub:
.venv/
__pycache__/
.env
*.db
Optionally, pin your Python version by adding a .python-version file containing a version such as 3.13, so Render uses the same one you tested with.
git init
git add .
git commit -m "Flask app ready for Render"
Create an empty repository on GitHub, then follow the commands it shows to add the remote and push.
In the Render dashboard, choose New → Web Service, connect your GitHub account and pick the repository. Fill in:
pip install -r requirements.txtgunicorn app:app
In gunicorn app:app, the first app is the file (app.py) and the second is the Flask object inside it. You don't need to configure a port: Render sets a PORT environment variable and gunicorn binds to it automatically.
Click create, watch the build log, and after a minute or two your app is live at a .onrender.com address.
Never commit secrets. In your service's Environment tab, add SECRET_KEY with a long random value (python -c "import secrets; print(secrets.token_hex(32))" generates one). Your code already reads it with os.environ.get. Database URLs and API keys go here too.
By default Render redeploys whenever you push to the connected branch. Make a change, commit, push, and watch the new version build. If a build fails, the previous version keeps running.
gunicorn: command not found or ModuleNotFoundError - the package is missing from requirements.txt. Install it locally, re-run pip freeze > requirements.txt, commit and push.Failed to find attribute 'app' - your start command doesn't match your file or variable name. If your file is main.py with application = Flask(__name__), the command is gunicorn main:application.pip freeze captured something like pywin32, delete that line from requirements.txt.
Add a database: create a free Postgres database on Neon, store its connection string in a DATABASE_URL environment variable, and connect with SQLAlchemy or psycopg. Or put a frontend in front of your API with our Vue + Flask + SQLite guide.