Yes, you should use Docker to deploy web2py with nginx and PostgreSQL in most production scenarios, because it gives you reproducible builds, isolated dependencies, and a consistent environment from development to production. This article explains what Docker changes for a web2py stack, when it genuinely helps, when it adds unnecessary complexity, and how to structure the deployment safely.
Background: the classic web2py deployment stack
web2py is a full-stack Python web framework that has been around since 2007. It ships with its own web server (Rocket) for development, but for production the common recommendation is to put a reverse proxy like nginx in front of it and use a dedicated database such as PostgreSQL. The traditional way to deploy this stack is to install Python, web2py, nginx, and PostgreSQL directly on a server, configure each with system packages, and manage updates manually. That works, but it creates several recurring problems: version drift between machines, subtle differences between your laptop and the server, and a tedious setup process every time you move to a new host.
Docker containers package each component with its own runtime, libraries, and configuration, so the exact same image runs on any machine that has Docker installed. For a web2py app, that means you can freeze the Python version, the web2py version, and even the PostgreSQL client library version into an image, then run that same image in staging and production.
How Docker changes the deployment for web2py
Instead of installing nginx and PostgreSQL on the host OS, you run them as containers. A typical setup uses three containers:
- web2py app container – runs the web2py application with a production WSGI server like gunicorn or uWSGI, or web2py’s built-in Rocket server behind the proxy.
- nginx container – acts as the reverse proxy, terminates TLS/SSL, serves static files, and forwards dynamic requests to the web2py container.
- PostgreSQL container – stores the database, with a volume mounted for persistent data.
You define these three services in a docker-compose.yml file, which also handles networking between them. The web2py container connects to the database using the service name (e.g., db) as the hostname, and nginx routes traffic to the app container on an internal network port. This removes the need to manually configure PostgreSQL to listen on a public interface or to set up nginx to proxy to a Unix socket – Docker handles the inter-container communication.
How to choose: when Docker is the right call
Docker is not automatically the best choice for every web2py deployment. Consider these factors:
- Team size and reproducibility – if more than one person works on the app, or you deploy to multiple environments (staging, production), Docker’s image-based reproducibility saves real time. A new developer can run
docker-compose upand have the whole stack running in minutes. - Hosting provider – if you are on a VPS or a bare-metal server, Docker gives you flexibility to move between providers without reinstalling the stack. If you are on a managed platform like Heroku or a Kubernetes service, you are already using container concepts.
- Operational complexity – if you are a solo developer running a small app on a single server and you are comfortable with system packages, Docker adds a layer of indirection (images, volumes, networks) that you might not need. The learning curve is real, and debugging networking issues inside containers can be frustrating.
- Update and rollback – with Docker, you can version your images and roll back to a previous image instantly. With system packages, rolling back a Python or nginx update is harder.
For a small, low-traffic app where you are the only maintainer, installing directly on the host may be simpler and use fewer resources. For anything you expect to grow, or where you need to replicate the environment reliably, Docker is the better default.
Common problems and how to avoid them
Several issues come up repeatedly when people move web2py to Docker:
- Static files not served – web2py serves static files from the
staticfolder. In a container, the path must be correctly mounted or copied into the image. The common mistake is to let nginx try to serve files from a path that does not exist in its container. Solution: mount the web2py static directory as a volume in the nginx container, or copy it into the nginx image. - Database connection refused – the web2py app must use the correct hostname for PostgreSQL. Inside Docker Compose, the hostname is the service name, not
localhost. If you uselocalhostin your database URI, the app container will try to connect to itself and fail. - Permissions on mounted volumes – PostgreSQL stores data in a volume. If the volume is owned by the host user and the container runs as a different user, you get permission errors. Set the volume ownership explicitly in the compose file or run the container with a user that matches the host.
- Session and cache storage – web2py can store sessions in files, in the database, or in memcached. In a container, file-based sessions are lost when the container is recreated unless you mount a volume. For production, use the database or a dedicated cache container.
- uWSGI vs. built-in server – web2py’s built-in Rocket server is fine for development, but for production behind nginx you should run a WSGI server like uWSGI or gunicorn. Docker makes this easy, but you need to configure the correct socket and protocol (HTTP or uwsgi) in nginx.
Docker vs. traditional deployment: a practical comparison
To see the difference concretely, consider a typical upgrade scenario. With a traditional setup, upgrading Python or web2py means installing new packages on the host, hoping nothing breaks, and testing on the live server. With Docker, you build a new image from a Dockerfile that specifies the new version, test it locally, and then deploy that image. If something goes wrong, you roll back to the previous image.
Resource usage is another point of comparison. Containers add a small overhead compared to native processes, but they are far lighter than virtual machines. For a web2py app, the overhead is negligible. However, running three containers instead of three processes does use slightly more memory because each container runs its own instance of the base OS libraries (though they share the kernel).
Security is a double-edged sword. Containers isolate processes, which can limit the blast radius of a compromised web2py app. But images can also become outdated if you do not rebuild them regularly. You must keep the base images updated with security patches, just as you would with system packages.
Costs and operational considerations
Docker itself is free and open source, but it adds operational costs:
- Learning curve – you need to understand Dockerfiles, compose files, volumes, and networking. This is time you could spend on the app itself.
- Image maintenance – you must rebuild images when base images are updated, and you need a registry (public or private) to store them.
- Debugging complexity – logs are scattered across containers, and you need to use
docker logsor a logging aggregator. Network troubleshooting requires understanding Docker’s virtual networks. - Backup and restore – PostgreSQL data lives in a volume. You need to back up the volume or use
pg_dumpfrom within the container. This is not harder than a native backup, but it is different.
On the cost side, Docker does not require more server resources for a small app, but if you run many containers, you may need a larger instance. There is no licensing fee, but the time you spend maintaining Dockerfiles and compose files is a real cost.
Safety, security, and best practices
Security is a major reason to use Docker, but only if you do it right. Follow these practices:
- Do not run containers as root – create a non-root user in your Dockerfile for the web2py app. web2py itself does not need root privileges.
- Use secrets for database passwords – do not hardcode passwords in your compose file or Dockerfile. Use Docker secrets or environment variables injected at runtime.
- Keep images small and up to date – use a minimal base image like
python:3.12-slimand rebuild regularly to get security patches. - Expose only necessary ports – only nginx should be exposed to the public; the web2py app and PostgreSQL should be on an internal network.
- Back up the database volume – use
pg_dumpon a schedule, and test restores.
One common misconception is that Docker makes your app secure by default. It does not. You still need to configure firewalls, TLS, and database access properly. Docker just isolates processes, not vulnerabilities.
Alternatives to Docker for web2py deployment
If Docker feels like too much, there are other ways to deploy web2py with nginx and PostgreSQL:
- System packages – install Python, nginx, and PostgreSQL via your OS package manager. This is the traditional approach and works well for simple setups.
- Virtualenv + system services – use a Python virtualenv for web2py and its dependencies, but run nginx and PostgreSQL as system services. This gives you some isolation for Python without container overhead.
- Ansible or similar configuration management – automate the setup with a tool like Ansible, so you can reproduce the server configuration without Docker. This is a good middle ground if you dislike containers but want reproducibility.
- Platform as a Service (PaaS) – deploy to a PaaS like Heroku (which supports Python) or a similar service that handles the infrastructure. You still need to configure nginx and PostgreSQL, but the platform manages the servers.
Each alternative has trade-offs. System packages are simple but not reproducible. Ansible is reproducible but requires you to maintain playbooks. PaaS is easy but can be more expensive and less flexible.
Frequently Asked Questions
Is Docker slower than running web2py directly on the host?
No, not noticeably for a typical web2py app. Containers add a small overhead for networking and filesystem operations, but for most workloads the difference is under 5%. The performance bottleneck is usually the database or the application code, not the container layer.
Do I need to use Docker Compose or can I just use Docker?
You can use plain Docker with separate docker run commands, but Docker Compose is strongly recommended for a multi-container stack like web2py + nginx + PostgreSQL. Compose lets you define all services in one file, manage networking, and start everything with a single command. It also makes it easier to share the setup with teammates.
How do I update web2py inside a Docker container?
Update the web2py version in your Dockerfile (or the base image you use), rebuild the image, and redeploy. For minor updates, you can also copy new web2py files into a running container, but that is not recommended because it is not reproducible. Rebuilding the image is the clean way.
What is the best way to serve static files with web2py and nginx in Docker?
Let nginx serve static files directly. Mount the web2py static directory as a volume in the nginx container, and configure nginx to serve from that path. This offloads static file handling from the Python process, which is faster and more efficient.
Can I use Docker in production with a managed PostgreSQL service?
Yes. You can run web2py and nginx in containers and connect to a managed PostgreSQL service (like Amazon RDS or similar) instead of running PostgreSQL in a container. This is often a good idea because managed databases handle backups, replication, and scaling for you. You just need to set the database host to the managed service’s endpoint.
Is it safe to store database passwords in environment variables in Docker?
Environment variables are better than hardcoding, but they are not completely secure because they can be visible in the container’s configuration. For production, use Docker secrets or a secrets manager. At a minimum, do not commit the .env file to version control.
Related
Method: the standard formula for this calculation, rounded as each result states. See how the calculators work or report an error.
More cards in this drawer
- Valheim Server Not Showing in Community List Fixes
- DisplayPort vs HDMI: Which Cable Should You Use?
- Soundbar vs 2.1 Speaker System: Which Is Better?
- Survive Lava for Brainrot Tier List170 points
- MySQL Dump Import: Fix Common Errors
- Mouse Moving on Its Own? Causes & Fixes