What Wodby sets up for an application that runs on this service. Check it before adding a server configuration or connection settings to the code.
The container runs Gunicorn with a configuration file the image writes on every start:
gunicorn -c /usr/local/etc/gunicorn/config.py --pythonpath "$GUNICORN_PYTHONPATH" "$GUNICORN_APP"
GUNICORN_APPnames the WSGI callable asmodule:callable. The image default ismyapp.wsgi:application; set the variable on the service, or in the Dockerfile, when the application lives elsewhere.- Gunicorn listens on
0.0.0.0:8080. The port is fixed in the generated configuration and is the port of the service's HTTP endpoint. - The image does not include Gunicorn. It must be one of the application's dependencies.
- Access and error logs go to the container's output.
Do not add a Gunicorn configuration file to the repository to change workers or timeouts: the container does not load it. Set these variables on the service instead: GUNICORN_WORKERS, GUNICORN_WORKER_CLASS, GUNICORN_WORKER_CONNECTIONS, GUNICORN_TIMEOUT, GUNICORN_KEEPALIVE, GUNICORN_BACKLOG, GUNICORN_LOGLEVEL, GUNICORN_PROC_NAME, GUNICORN_PYTHONPATH. A change applies with the next deployment of the service.
Links to other services reach the application as environment variables. Nothing in the image reads them: the application reads them itself. Do not hardcode hosts or credentials.
| Link | Variables |
|---|---|
| Database (MariaDB, MySQL or PostgreSQL) | DB_HOST, DB_PORT, DB_NAME (also DB_DATABASE), DB_USERNAME, DB_PASSWORD, DB_DRIVER (also DB_CONNECTION) |
SMTP_HOST, SMTP_PORT |
|
| Redis or Valkey | REDIS_HOST, REDIS_PORT, REDIS_PASSWORD |
| OpenTelemetry Collector | OTEL_EXPORTER_OTLP_ENDPOINT, OTEL_EXPORTER_OTLP_PROTOCOL (http/protobuf), OTEL_EXPORTER_OTLP_HEADERS (the Collector's ingest token) |
All links are optional. A variable is present only while its link exists and the linked service is enabled. The mail link carries no credentials. The OpenTelemetry variables are the standard SDK settings: an application or agent that uses an OpenTelemetry SDK exports to the Collector without further configuration; set OTEL_SERVICE_NAME to name the application in traces.
WODBY_HOSTSis a JSON array of the environment's hosts, not a comma-separated string.WODBY_PRIMARY_HOSTandWODBY_PRIMARY_URLare the canonical ones for links generated outside a request.WODBY_APP_SERVICE_NAMEis this service's host name inside the environment. Other services reach the application at that name on port 8080.WODBY_ENV_TYPEtells a development environment from a production-like one.
The code is copied to /usr/src/app, the working directory. The service's own Dockerfile then runs pip install -r requirements.txt when that file exists, and nothing else. A pipeline that passes a Dockerfile from the repository (wodby ci build python -f Dockerfile) uses that file instead, and the repository's Dockerfile then owns dependency installation. uv is available in the image.
The service declares no volume of its own: files written inside the container are lost when it is replaced.
- The checkout is mounted at
/usr/src/appand served as it is on disk. - Workspace setup installs dependencies with
workspace-python prepare:uv sync --lockedwhenuv.lockexists, otherwisepip install -r requirements.txtinto a virtual environment. One of the two must exist. Run it again after changing dependencies. - The virtual environment is
.wodby-workspace/venvin the checkout..wodby-workspace/and__pycache__/are kept out of Git status without touching.gitignore. Use.wodby-workspace/venv/bin/pythonfor commands that need the application's packages. - The application is started with
python -m gunicorn --bind "$HOST:$PORT" --reload --reload-engine poll "$GUNICORN_APP", withHOSTandPORTdefaulting to0.0.0.0and8080. The generated Gunicorn configuration and theGUNICORN_*tuning variables are not used here. WORKSPACE_PYTHON_COMMANDon the service replaces that start command. A custom command must do its own reloading.- A change to variables or linked services still needs a deployment of the environment.
curl -s -o /dev/null -w '%{http_code}' localhost:8080from the container shows whether the application answers on the expected port.printenv | grep -E '^(DB|SMTP|REDIS)_' | cut -d= -f1lists the link variables that are present.