RE:NODE

Deploy a Python app on Renode

How a RE:NODE Python server runs your code: the entry file on the Startup tab, requirements.txt, binding 0.0.0.0 on SERVER_PORT with a production server, and the errors first deploys hit.

All docs pages

A Python server runs one file from /home/container: the entry file named on the server's Startup tab. Before it starts, it installs requirements.txt when your repository has one.

How it starts#

  1. The branch is fetched into /home/container (on every start, or only the first - see the overview).
  2. requirements.txt at the repository root is installed with pip. Packages go into the user's site directory, so nothing needs root.
  3. The entry file named on the Startup tab (often the PY_FILE variable) is run.

When you link a repository, the panel points the Startup tab at the first of main.py, bot.py, app.py, run.py or __main__.py that exists. Any other name works too - set it on the Startup tab.

Two things that are not read:

  • `pyproject.toml` dependencies. Only requirements.txt is installed. Export them: pip freeze > requirements.txt, or uv pip compile pyproject.toml -o requirements.txt.
  • A `Procfile`. The server runs the entry file, not the command in a Procfile.

A minimal web app#

Start a production server from the entry file itself, bound to 0.0.0.0 and the port in SERVER_PORT. With FastAPI:

requirements.txt
fastapi==0.115.0uvicorn==0.30.6
main.py
import osimport uvicornfrom fastapi import FastAPIapp = FastAPI()@app.get("/")def home():    return {"hello": "renode"}if __name__ == "__main__":    # The server's port. Never hardcode one, never bind 127.0.0.1.    uvicorn.run(app, host="0.0.0.0", port=int(os.environ["SERVER_PORT"]))

With Flask, use a production WSGI server rather than app.run(), which is Flask's development server:

requirements.txt
flask==3.0.3waitress==3.0.0
app.py
import osfrom flask import Flaskfrom waitress import serveapp = Flask(__name__)@app.get("/")def home():    return "Hello from Renode"if __name__ == "__main__":    serve(app, host="0.0.0.0", port=int(os.environ["SERVER_PORT"]))

Django works the same way: start waitress (or another production server) from the entry file, bound to 0.0.0.0 and SERVER_PORT, and add the domain you serve it on to ALLOWED_HOSTS.

Configuration and .env#

Read configuration from the environment. Upload .env through the Files tab into /home/container, or set variables on the Startup tab, and load the file with python-dotenv:

python
import osfrom dotenv import load_dotenvload_dotenv()TOKEN = os.environ.get("API_TOKEN")if not TOKEN:    raise SystemExit("API_TOKEN is not set - upload .env through the Files tab")

Logging#

The console shows what your process writes to stdout. Python buffers it when it is not attached to a terminal, so output can arrive late or not at all before a crash. Print with flush=True, or set PYTHONUNBUFFERED=1.

System packages#

apt and other system package managers are not available in the container. Choose packages that ship wheels for Linux rather than ones that compile against system libraries at install time.

Checklist#

  • The entry file on the Startup tab exists in the repository.
  • requirements.txt is at the repository root, with pinned versions.
  • The app binds 0.0.0.0 and int(os.environ["SERVER_PORT"]), with a production server.
  • No password, token or key is committed; .env is in .gitignore.
  • Output is unbuffered so the console shows it.
  • Files the app writes at run time go under /home/container.

Common errors#

`ModuleNotFoundError` on start. The package is not in requirements.txt, or it is declared only in pyproject.toml.

`can't open file 'main.py'`. The Startup tab names a file the branch does not have. Set the entry file to the script that starts your app.

Running, but the address does not answer. The app is bound to 127.0.0.1, or to a hardcoded port such as 5000 or 8000.

Nothing appears in the console. Output is buffered - see Logging above.

More in Troubleshooting.

Questions this does not answer? Open a ticket from the panel, or start from the overview. These pages are also available as plain text for AI assistants at /llms.txt.