iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more
Antihost offers VPS plans with one-click Docker, NVMe storage and a 14-day free trial.
For a production web2py installation, place Nginx in front of web2py, use uWSGI to pass dynamic requests, and run PostgreSQL as a protected stateful service. Docker is optional: it improves packaging repeatability, but it does not solve database persistence, secrets, backups, upgrades, or monitoring.
The conventional host installation follows web2py’s documented deployment pattern most directly. Choose containers when your team already operates image builds and orchestration, and make the same operational controls explicit in the container setup.
Do these 3 things before closing this tab:
1Scan for outdated or missing drivers - takes under a minute2Clear out junk files and repair common Windows errors3Fix the driver behind crashes, sound loss and screen glitchesWhat the production architecture looks like
web2py includes a Rocket server, but the web2py manual describes it as having limited configuration capability and recommends placing production deployments behind Nginx, Apache, Lighttpd, or Cherokee. Nginx handles the public connection, TLS termination, and static files. uWSGI then carries dynamic WSGI requests to web2py through a Unix socket or another private endpoint.
PostgreSQL is a separate stateful tier. It should be reachable only from the application network, not from the public internet. The web and database services can share a host for a small installation, but separate machines connected through a protected internal network or SSL tunnel are preferable when the workload and operations justify them.
#1 Best Overall
| Layer | Primary responsibility | Important decision |
|---|---|---|
| Nginx | Public HTTP/HTTPS, TLS termination, static-file delivery, request forwarding | Keep administrative endpoints protected by HTTPS and network policy |
| uWSGI | WSGI gateway between Nginx and web2py | Use the uWSGI adapter; Nginx does not speak WSGI directly |
| web2py | Application code and dynamic responses | Record the Python and web2py versions and pin them |
| PostgreSQL | Persistent relational data | Private network access, least-privilege credentials, autovacuum, tested backups |
Why uWSGI is required with Nginx
web2py is built on WSGI, while Nginx uses the uWSGI protocol. They are related but not interchangeable. The uWSGI process loads the web2py application and exposes a socket; Nginx includes the uWSGI parameter definitions and forwards dynamic requests to that socket. A typical documented endpoint is unix:///tmp/web2py.socket.
Docker or a conventional host installation?
Neither option is universally superior. The right choice depends on how your team builds, deploys, backs up, and monitors services.
| Decision area | Conventional host install | Docker-based install |
|---|---|---|
| Repeatability | Configuration management records package and service settings | Image definitions make application and Nginx packaging reproducible |
| Database state | Managed disks or a dedicated database host hold PostgreSQL data | A persistent volume or external database is still required; a container layer is not a backup |
| Operations | Host service supervision, log rotation, upgrades, and rollback are explicit | Compose or an orchestrator must define supervision, logs, health checks, limits, and rollout behavior |
| Security boundary | Host firewall and service listeners define exposure | Container networks add a boundary, but published ports, secrets, and image contents still require review |
| Lifecycle | Package repositories and manually selected web2py versions must be tracked | Tags and digests must be pinned and checked for Python/web2py compatibility |
When a host installation is the better default
Use the conventional path when you want to follow the official recipe with the fewest additional decisions. Install Nginx, uWSGI, PostgreSQL, and the Python database adapter on the host, then keep PostgreSQL data on managed storage or a separate database machine. This is often easier for a small operations team that already has host patching, monitoring, and backup procedures.
When Docker is reasonable
Docker is a sensible packaging choice when your team already builds images, uses Compose or an orchestrator, and can operate persistent storage. It can put Nginx and the web2py runtime in repeatable artifacts, while PostgreSQL runs in its own service or on a managed platform. Containers do not remove the need to design storage, credentials, network rules, upgrade procedures, restore drills, and observability.
A Docker Hub listing shows an example image combining Nginx and web2py, but the available information does not establish a maintained tag, security policy, Compose definition, PostgreSQL compatibility, or health checks. Treat such an image as something to inspect and rebuild or pin deliberately, not as a production endorsement.
Check versions before you deploy
The web2py project overview states that web2py 2.27.1 is the last release supporting Python 2.7. web2py 3.x requires Python 3.9 or newer and is in limited maintenance mode; the project recommends moving to its successor, py4web.
Rank #2
If you are maintaining an existing web2py application, document its current Python and web2py versions and test the exact combination before changing it. For a new project, include the maintenance status in the framework decision rather than assuming that a current container image implies long-term support. Pin package versions and image digests in the deployment repository, and re-check compatibility before upgrades.
Deploy web2py, Nginx, and PostgreSQL without Docker
1. Prepare PostgreSQL as a private service
- Install PostgreSQL from your operating system distribution or use a managed PostgreSQL service.
- Create a database and an application login with only the permissions the application needs. Do not use a superuser for normal web2py requests.
- Keep PostgreSQL on its private interface or internal network. The conventional PostgreSQL port is
5432; do not publish it to the internet merely because the default port is known. - Enable PostgreSQL
autovacuum. It is part of normal maintenance and should not be disabled as a shortcut for performance. - Write down the storage location, retention policy, backup schedule, and restore owner before putting application traffic on the database.
2. Configure the web2py database adapter
In the application DAL configuration, use the PostgreSQL adapter and the private service address. The manual gives this connection form:
db = DAL("postgres://myuser:mypassword@localhost:5432/mydb")
Replace the illustrative username, password, host, and database with values stored through your deployment’s secret mechanism. Do not commit a real password to source control. If PostgreSQL runs on another host, use its internal DNS name or address and enforce TLS or an equivalent protected network path.
3. Run web2py behind uWSGI
Install uWSGI with the Python environment used by web2py and configure it to load the application, manage worker processes, and create a private socket. The socket must be readable and writable by the Nginx worker account and by the uWSGI process; mismatched ownership or permissions commonly produces a gateway error.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Use a service supervisor supplied by your operating system or hosting platform so uWSGI starts after boot, restarts on failure, and writes logs to a location with retention limits. Keep the uWSGI listener private; Nginx is the public entry point.
4. Configure Nginx for static and dynamic requests
Create the documented server block at /etc/nginx/sites-available/web2py and enable it using the activation method provided by your distribution. The static-file location should point to the web2py application’s static directory so Nginx can serve those files without invoking Python. The dynamic location includes uwsgi_params and forwards to the web2py socket.
server {
listen 80;
server_name _;
# Set this location's root or alias to your web2py static directory.
location /static/ {
# static-file directive for the directory used by your application
}
location / {
include uwsgi_params;
uwsgi_pass unix:///tmp/web2py.socket;
}
}
The static directive is intentionally installation-specific: web2py application layout and distribution paths differ, so point it at the directory that actually contains the files and verify permissions. Do not route static assets through uWSGI unless you have a specific reason to do so.
5. Terminate HTTPS at Nginx
Add an HTTPS server block that listens on port 443, references the certificate and private-key files issued for your hostname, and forwards application traffic using the same uWSGI location. Redirect plain HTTP to HTTPS after you have verified the certificate and renewal process. The web2py manual warns that exposing administrative interfaces such as the admin application or appadmin without HTTPS is dangerous.
server {
listen 443 ssl;
server_name _;
ssl_certificate /etc/ssl/certs/web2py.crt;
ssl_certificate_key /etc/ssl/private/web2py.key;
location / {
include uwsgi_params;
uwsgi_pass unix:///tmp/web2py.socket;
}
}
Use real certificate paths and a specific hostname in your installation, restrict administrative URLs by network policy or VPN where possible, and test renewal before the first certificate expires.
6. Validate the complete request path
- Check that PostgreSQL accepts a connection from the web2py host using the application account.
- Confirm that uWSGI is running and that
/tmp/web2py.socketexists with the expected owner and mode. - Validate Nginx syntax with the distribution’s Nginx configuration test command, then reload Nginx rather than stopping it.
- Request a static asset and a dynamic page separately. This distinguishes an Nginx path or permission problem from an application or database problem.
- Review Nginx, uWSGI, web2py, and PostgreSQL logs together while performing a login and a database-backed operation.
How to structure the Docker deployment
A containerized design should still separate responsibilities: one service for Nginx and web2py (or separate Nginx and application services), and a separate PostgreSQL service or managed database. Put them on a private application network and publish only Nginx’s HTTPS port.
Persist the database outside the container layer
Mount PostgreSQL’s data directory on durable storage or use a managed database. Recreating a PostgreSQL container must not delete the database. Schedule pg_dump backups, store them outside the host that runs the database, and periodically perform a real pg_restore into an isolated instance. A backup job that has never been restored is an assumption, not a recovery plan.
Define readiness, limits, and logs
- Add a health check that tests actual PostgreSQL readiness and web2py responsiveness, not merely whether a process exists.
- Define startup ordering, but do not confuse ordering with readiness; the application should retry or wait until PostgreSQL accepts connections.
- Set CPU and memory limits appropriate to the workload and monitor for throttling or out-of-memory kills.
- Send container logs to a retained central destination and define rotation so a full filesystem cannot stop the service.
- Pin image tags or digests and keep the Dockerfile, dependency lock data, and configuration in version control.
Handle secrets and upgrades explicitly
Pass database credentials through the platform’s secret facility rather than baking them into an image or committing them to a Compose file. Test an image upgrade against a database copy, record the rollback image and schema procedure, and verify that the selected Python version remains supported by the chosen web2py release.
PC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11Crashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minuteSecurity and reliability checklist
- HTTPS: terminate TLS at Nginx and keep admin and appadmin interfaces off the public network whenever practical.
- Database access: use least-privilege accounts, private network rules, and encryption or an SSL tunnel for cross-host connections.
- Authentication configuration: review PostgreSQL access rules carefully. Do not copy an illustrative
trustauthentication setting from a tutorial into an internet-facing deployment without a security review. - Maintenance: leave autovacuum enabled and monitor disk space, connection saturation, slow queries, and failed jobs.
- Backups: schedule
pg_dump, protect backup files, define retention, and testpg_restorerecovery on a schedule. - Isolation: place web and database tiers on separate hosts or isolated networks when practical.
- Observability: retain Nginx access/error logs, uWSGI and application logs, PostgreSQL logs, service health, resource usage, and backup results.
Common deployment failures and fixes
Nginx returns 502 Bad Gateway
Check whether uWSGI is running, whether the socket path exactly matches unix:///tmp/web2py.socket, and whether Nginx can access the socket. If the socket disappears after a restart, inspect the uWSGI service logs and its working directory. If the socket exists but connections fail, verify the uWSGI protocol configuration rather than treating it as a generic HTTP upstream.
Static files return 404 or are served by Python
Verify that the Nginx static location points to the actual web2py static directory, that the Nginx account can traverse every parent directory, and that the request path matches the location. Keep a separate test for a known static asset so application routing does not hide a filesystem error.
web2py cannot connect to PostgreSQL
Check the DAL hostname, port 5432, database name, credentials, PostgreSQL listener address, and firewall rules. Test from the web2py host using the same account. A containerized application may be using a service name while a host installation uses an internal DNS name; do not assume localhost means the database container.
HTTPS works but administration is still exposed
TLS protects traffic in transit but does not make an administrative endpoint safe to expose broadly. Restrict the route by network, VPN, firewall, or an additional access-control layer, and audit Nginx logs for unexpected access.
Quick wins for a faster PC:
Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Clear out junk files and repair common Windows errorsFree Scan →Decision guide
Choose a conventional host deployment when you need the shortest path from the web2py manual to a working service and already manage servers with configuration management. Choose Docker when repeatable images and an existing container platform are more valuable than minimizing moving parts. In either case, the non-negotiable design is the same: Nginx in front, uWSGI between Nginx and web2py, PostgreSQL protected and persistent, HTTPS for administration, pinned versions, and recoverable backups.
Finally, include web2py’s limited-maintenance status in the long-term plan. Existing applications can be deployed safely with disciplined operations, but a new system should compare the current Python/web2py support situation with py4web before committing to a framework that may require migration later.

