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
Need a server to try this on? Antihost offers Linux VPS plans with NVMe storage, full root access and a 14-day free trial.
Deploy a Pyramid application on a VPS by installing the project and its dependencies in an isolated Python environment, maintaining a production PasteDeploy configuration, serving the WSGI callable with Waitress or Gunicorn, and placing a reverse proxy such as nginx in front of it for public HTTP and HTTPS. Run the application as a supervised, non-root service and verify the complete request path before directing traffic to the server.
This guide covers Pyramid 2.x deployments on a Linux VPS, including production.ini, Gunicorn, Waitress, Unix sockets, nginx, TLS, service supervision, logging, and the failure modes that most often interrupt a first deployment.
Recommended Free Tools
What a production Pyramid deployment looks like
A Pyramid project is a Python application that exposes a WSGI callable. The callable is created by Pyramid’s configurator and can be run by any compatible WSGI server. The Pyramid Community Cookbook summarizes the model as client → WSGI server → application. On a public VPS, add a reverse proxy and TLS termination:
- A browser connects to the VPS on ports 80 or 443.
- nginx accepts the public connection, serves or caches suitable static files, and handles HTTPS.
- nginx forwards dynamic requests to Gunicorn or Waitress over a local TCP port or Unix socket.
- The WSGI server loads your Pyramid application from the project’s virtual environment.
- The application accesses its database, filesystem, and other services with production credentials.
Keep the WSGI server bound to localhost or a Unix socket. Exposing it directly to the internet makes TLS, request buffering, access controls, and operational recovery harder than necessary.
#1 Best Overall
Prerequisites and decisions before you log in
Use a supported Python runtime
Pyramid 2.0 runs on Python 3 only, according to the Pylons Project’s current Pyramid Quick Tour. Confirm the Python version supported by your application’s dependency lockfile and by the Linux distribution you selected. Do not assume that the distribution’s default interpreter is suitable for an older project; check the project’s packaging metadata first.
Create a deployment identity
Use a dedicated account such as pyramidapp rather than running the application as root. Give that account ownership only of the application release, virtual-environment, log, upload, and cache directories it actually needs. Keep deployment files outside writable upload directories so an uploaded file cannot replace application code.
Do these 3 things before closing this tab:
1Scan for outdated or missing drivers - takes under a minute2Repair Windows errors before they cause bigger problems3Fix the driver behind crashes, sound loss and screen glitchesPlan the network boundary
- Allow SSH only from the administrative networks that need it.
- Allow TCP 80 and 443 if the VPS will serve public HTTP and HTTPS.
- Do not open the Gunicorn or Waitress listener to the public internet when nginx can reach it locally.
- Choose a DNS name before requesting a publicly trusted certificate; certificate authorities validate the name, not the VPS address alone.
Prepare external services
Have database credentials, migration instructions, an email or object-storage configuration, and a backup destination ready before switching traffic. A process can start successfully while failing its first real request because a database schema, secret, or writable directory is missing.
Prepare the VPS and Python virtual environment
Update the operating system and install build tools
Log in with your administrative account, apply security updates, and install the Python interpreter, virtual-environment support, a compiler, and the development headers required by any dependency with native extensions. Package names vary by distribution, so use that distribution’s package manager and document the exact packages in your deployment notes.
Create the application account and directories
sudo useradd --system --create-home --home-dir /srv/pyramidapp --shell /usr/sbin/nologin pyramidapp
sudo install -d -o pyramidapp -g pyramidapp /srv/pyramidapp
sudo install -d -o pyramidapp -g pyramidapp /var/log/pyramidapp
The --system account is an example, not a requirement. If your release process needs interactive SSH access, use a normal, restricted deployment account and keep the runtime service account separate.
Create and activate the virtual environment
sudo -u pyramidapp python3 -m venv /srv/pyramidapp/venv
sudo -u pyramidapp /srv/pyramidapp/venv/bin/python -m pip install --upgrade pip setuptools wheel
sudo -u pyramidapp /srv/pyramidapp/venv/bin/python --version
Use absolute paths in service definitions. A service manager does not load the interactive shell profile that may otherwise place the virtual environment’s executables on PATH.
Install the Pyramid project and its dependencies
Deploy a released package or a controlled checkout
Copy a versioned release archive or a checked-out revision into a release directory owned by the deployment account. Avoid deploying an uncommitted working tree. The generated Pyramid project documentation uses pip install -e . for development; on production systems, install a built package or a pinned checkout unless you intentionally need editable behavior.
sudo -u pyramidapp /srv/pyramidapp/venv/bin/python -m pip install -r /srv/pyramidapp/current/requirements.txt
sudo -u pyramidapp /srv/pyramidapp/venv/bin/python -m pip install /srv/pyramidapp/current
If the project has no requirements file, install the package’s declared dependencies from its packaging configuration. Pin versions through the project’s normal lock or constraints process, and keep the resulting installation reproducible between releases.
Check that the package imports in the same environment
sudo -u pyramidapp /srv/pyramidapp/venv/bin/python -c "import your_pyramid_package; print(your_pyramid_package.__file__)"
sudo -u pyramidapp /srv/pyramidapp/venv/bin/python -m pip check
Replace your_pyramid_package with the import package named by your project. An import test that uses the system Python proves nothing about the interpreter Gunicorn or Waitress will use.
Maintain a separate production.ini
Pyramid projects commonly use PasteDeploy INI files. The generated project’s production.ini is intended to execute the application with production configuration, while a development file may enable debugging, reloaders, verbose diagnostics, or permissive settings that should never be exposed publicly.
Rank #2
Keep environment-specific values out of source control
- Store database URLs, signing keys, session secrets, and third-party credentials in root-readable or service-account-readable secret files.
- Use file permissions that prevent other VPS users from reading those secrets.
- Keep debug mode disabled and set an explicit, production host policy.
- Use production logging levels and destinations; do not rely on a terminal window remaining open.
Understand the PasteDeploy sections
A typical file contains an [app:main] section for Pyramid settings, a [pipeline:main] section when middleware is chained, and a [server:main] section for the development or light-production server invoked by pserve. Exact keys depend on the generated project and installed middleware; preserve the project’s documented names rather than copying an unrelated template.
[app:main]
use = egg:your-package
pyramid.reload_templates = false
pyramid.debug_authorization = false
pyramid.debug_notfound = false
pyramid.debug_routematch = false
[server:main]
use = egg:waitress#main
listen = 127.0.0.1:6543
The snippet illustrates the separation of application and server settings; it is not a universal configuration. Use the settings generated for your project, then change only values you understand. If Gunicorn loads the file, its PasteDeploy integration reads the application entry point while Gunicorn controls worker processes and binding.
Confirm the WSGI entry point
Open the project’s setup configuration and INI file and identify the application entry point, commonly an egg: reference that resolves to a PasteDeploy application factory. Start the server from the project’s virtual environment and watch for import or entry-point errors. A missing package installation, a misspelled distribution name, or an INI file copied from another project will prevent startup before nginx is involved.
Choose Waitress, Gunicorn, or mod_wsgi
The Pylons Project describes Waitress as a “production-quality pure-Python WSGI server with very acceptable performance.” The generated-project documentation uses it by default and describes it as suitable for development and light production. The same documentation identifies Gunicorn as another good production alternative, while mod_wsgi is appropriate when Apache is already the operational standard.
Free tools Windows power users keep installed
One-click scans. No signup required.
| Option | Best fit | Operational characteristics | Important limitation or requirement |
|---|---|---|---|
| Waitress | Simple cross-platform deployment, development, or light production | Pure Python, straightforward startup, commonly used through the project’s PasteDeploy configuration | Does not provide native TLS; place it behind nginx or another maintained proxy for public HTTPS |
| Gunicorn | Conventional Linux production process management | Supports PasteDeploy, multiple worker processes, and Unix sockets; integrates naturally with service managers and nginx | Gunicorn and the Pyramid package must be installed in the same virtual environment; a buffering HTTP proxy is generally beneficial |
| mod_wsgi | Sites already standardized on Apache | Runs WSGI applications inside or beside Apache’s process model and uses Apache’s existing configuration and logging practices | Requires Apache-specific operational knowledge and deployment decisions |
| NGINX Unit | Existing installations only, after an explicit maintenance review | Its Pyramid guide documents configuration | The guide states that NGINX Unit was archived and unmaintained as of October 2025; it should not be the default for a new deployment |
Compare maintenance status, operating-system support, process model, socket support, TLS integration, observability, and your team’s existing tooling. The correct choice depends on the workload and operations team, not on a single benchmark.
Run Pyramid with Waitress
For a generated project, the simplest check is to run PasteDeploy’s server command from the project directory:
cd /srv/pyramidapp/current
sudo -u pyramidapp /srv/pyramidapp/venv/bin/pserve production.ini
If the INI file’s server section uses Waitress, this starts the application on the configured local address. Keep this command attached to a terminal only for a short diagnostic check. For a persistent service, use systemd, supervisord, or another supervisor so the process restarts after failure and returns after a reboot.
Waitress is a suitable choice when simplicity and portability matter more than a larger multi-process setup. It still belongs behind a reverse proxy for TLS, public port handling, request buffering, access logging, and clean separation from the internet.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Run Pyramid with Gunicorn
Use the PasteDeploy command
The Pyramid Cookbook documents this direct command:
cd /srv/pyramidapp/current
sudo -u pyramidapp /srv/pyramidapp/venv/bin/gunicorn --paste production.ini
Because the command loads production.ini, the application entry point remains in the Pyramid project’s configuration rather than being duplicated on the command line. Run it manually first so syntax, imports, and credentials fail visibly.
Bind locally or to a Unix socket
For a local TCP listener, use an address such as 127.0.0.1:8000. A Unix socket avoids a TCP port collision and makes the local-only boundary explicit:
sudo -u pyramidapp /srv/pyramidapp/venv/bin/gunicorn
--paste production.ini
--bind unix:/run/pyramidapp/app.sock
--access-logfile -
--error-logfile -
--log-level info
Create /run/pyramidapp through the service manager or an early-boot directory rule, and ensure nginx can read and write to the socket directory as required. Do not place the socket in a world-writable directory such as a shared temporary location.
The Tool Desk
Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Set workers from measurements, not folklore
The Cookbook’s illustrative configuration uses four workers, preloads the application, sends access logs to standard error, and sets a log level. Four workers is an example configuration, not a sizing recommendation or benchmark. Worker needs vary with CPU count, memory, request latency, database limits, background work, and whether requests block on external services.
Begin with a conservative worker count that fits the VPS memory budget, observe response times and memory use under representative traffic, and adjust one variable at a time. Preloading can reduce duplicated memory for some applications but can also expose fork-safety problems in libraries that open connections during import. Test it before enabling it.
Supervise the process with systemd or supervisord
A service supervisor should start the application after the network and required mounts are available, restart it when it exits unexpectedly, preserve logs, and stop it cleanly during maintenance. The Pyramid Cookbook discusses nginx with pserve and supervisord as well as several system-service patterns; exact unit files depend on your Linux distribution and project paths.
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 →Systemd unit example
[Unit]
Description=Pyramid web application
After=network.target
[Service]
Type=simple
User=pyramidapp
Group=pyramidapp
WorkingDirectory=/srv/pyramidapp/current
ExecStart=/srv/pyramidapp/venv/bin/gunicorn --paste production.ini --bind unix:/run/pyramidapp/app.sock --access-logfile - --error-logfile -
Restart=on-failure
RestartSec=5
PrivateTmp=true
NoNewPrivileges=true
[Install]
WantedBy=multi-user.target
Save the unit under the distribution’s systemd unit directory, reload systemd, enable it for boot, and start it. The paths and hardening directives above must match your filesystem and application needs; a project that writes uploads or compiles templates may need explicitly writable directories.
sudo systemctl daemon-reload
sudo systemctl enable --now pyramidapp.service
sudo systemctl status pyramidapp.service
sudo journalctl -u pyramidapp.service -f
Use the service status and journal output to distinguish an application startup failure from an nginx routing problem. If the process exits immediately, run the exact ExecStart command as the service user in the same working directory.
Put nginx in front of the WSGI server
Proxy to a Unix socket
nginx should listen on the public interface and forward only dynamic requests to Gunicorn or Waitress. A minimal virtual-host shape is:
server {
listen 80;
server_name app.example.com;
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://unix:/run/pyramidapp/app.sock:
}
}
Check the exact proxy_pass socket syntax supported by your nginx build; a missing trailing delimiter or an incorrect socket path produces a gateway error even when Gunicorn is healthy. If you proxy to TCP instead, use a loopback address such as http://127.0.0.1:8000.
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 & 11Outdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchHandle static files deliberately
If nginx serves collected static assets directly, point an explicit location at a read-only directory and leave application routes under the proxy location. If Pyramid must generate or protect a file, proxy that route instead. Confirm that URL prefixes, cache headers, and filesystem permissions agree; a successful HTML response with missing CSS usually indicates a static-file path mismatch rather than a WSGI failure.
Enable HTTPS and preserve forwarded headers
Use a certificate for the configured hostname, redirect HTTP to HTTPS after validating the certificate path, and pass the original scheme and host to Pyramid. Applications commonly use those values when generating absolute URLs, setting secure cookies, or enforcing HTTPS. Configure trusted-proxy behavior according to the application’s security settings; never trust arbitrary forwarding headers from an untrusted public client.
Waitress does not provide TLS natively, which is why a maintained reverse proxy is required for public HTTPS. Gunicorn is also normally deployed behind that proxy rather than exposed directly.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Production verification before switching DNS
Test each layer locally, then test the public hostname. This avoids debugging five components at once.
- Import check: run the virtual environment’s Python interpreter and import the application package.
- Configuration check: start Gunicorn or
pservewithproduction.iniand confirm there are no parser, entry-point, or secret errors. - Local WSGI check: use
curlagainst the loopback listener or Unix-socket proxy and verify the expected status code and body. - Proxy check: request the nginx virtual host locally with the correct
Hostheader and confirm that the request reaches the application. - Static-asset check: load CSS, JavaScript, images, and cache-busted filenames from the production URL.
- Database check: run the project’s documented migrations with the same credentials and environment used by the service.
- Host and header check: verify trusted hosts, forwarded scheme handling, secure cookies, redirects, and any CSRF origin checks.
- TLS check: validate the certificate chain, hostname, HTTP-to-HTTPS redirect, and renewal procedure.
- Restart check: restart the service and nginx, reboot a staging VPS if possible, and verify that the socket, mounts, secrets, and application all return without manual intervention.
The cited Pyramid deployment material describes patterns rather than a test report for any particular application, so treat these checks as your acceptance criteria rather than assuming a successful process start proves readiness.
Troubleshoot common deployment failures
“ModuleNotFoundError” or an entry-point error
Usually the service is using a different Python interpreter, the package was not installed, or the INI file names the wrong distribution entry point. Print the interpreter path in the service command, run pip check inside that environment, and verify the package’s installed location.
nginx returns 502 Bad Gateway
Check whether the WSGI service is running, whether the socket exists, and whether nginx can traverse the socket directory and open the socket. Compare the socket path in the service command with proxy_pass. Read both the nginx error log and the service journal; a refused loopback connection points to a stopped listener, while a permission error points to filesystem ownership or mode bits.
The application starts but every request fails
Inspect database URLs, migrations, required environment variables, secret files, and outbound network permissions. A startup hook may not touch the database until the first request, so a clean service status is not proof that dependencies are reachable.
Redirect loops or cookies are insecure
Confirm that nginx sends X-Forwarded-Proto, that Pyramid trusts the proxy only on the private hop, and that the application’s HTTPS and secure-cookie settings match the public URL. A proxy that terminates TLS but fails to convey the original scheme can make an application redirect an already secure request back to HTTPS indefinitely.
Assets return 404 while pages load
Verify the application’s static URL prefix, nginx’s filesystem root, release-directory symlinks, and read permissions. Do not solve the problem by making the entire release tree world-writable.
Workers are killed or the VPS becomes unresponsive
Check memory pressure and swap activity, then reduce worker count or move expensive work out of request processes. Four Gunicorn workers from the Cookbook example are not a universal requirement. A small VPS can run out of memory before CPU utilization appears high.
Security and maintenance practices
- Apply operating-system and Python dependency security updates on a defined schedule.
- Keep the application account unprivileged and restrict write access to only upload, cache, and log locations.
- Rotate database credentials, signing keys, and TLS certificates through a documented process.
- Retain structured application and proxy logs long enough to investigate errors, while limiting access to sensitive request data.
- Back up the database and user-generated files separately from the VPS; periodically test restoration.
- Deploy immutable, versioned releases and retain the previous known-good release for rollback.
- Monitor health endpoints, process restarts, disk space, memory, certificate expiry, and database connectivity.
When to use Apache mod_wsgi instead
mod_wsgi remains a valid production alternative when Apache is already required for the site’s authentication, virtual-host, logging, or operations standards. It can reduce the number of moving parts in an Apache-centered environment, but it introduces Apache-specific process, daemon-mode, permissions, and Python-environment decisions. Choose it because your team operates Apache well, not because Pyramid requires it; Pyramid’s WSGI interface is server-agnostic.
Deployment checklist
- Dedicated non-root service account exists.
- Supported Python 3 runtime and build prerequisites are installed.
- Virtual environment contains the application and all pinned dependencies.
production.inidisables development diagnostics and references the correct application entry point.- Gunicorn, Waitress, or mod_wsgi is selected for a stated operational reason.
- WSGI server listens only on localhost or a protected Unix socket.
- nginx forwards the correct host, client, and scheme headers.
- HTTPS certificate and renewal process are verified.
- Database migrations, static assets, and writable directories are tested.
- systemd, supervisord, or another supervisor restarts the service and starts it after reboot.
- Application, proxy, and service logs are accessible to operators.
- Rollback, backup, and restore procedures have been exercised.
The Bottom Line
The reliable Pyramid VPS pattern is a production virtual environment plus a maintained PasteDeploy configuration, a supervised Waitress or Gunicorn process bound privately, and nginx handling public HTTP/HTTPS. Treat worker counts, socket paths, permissions, and database settings as workload-specific configuration, then validate the entire path before moving live traffic.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

