Quick wins for a faster PC:
Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Repair Windows errors before they cause bigger problemsFix Now →Scan for outdated or missing drivers - takes under a minuteDriver Scan →The reliable Pyramid VPS layout is straightforward: install the application in an isolated Python environment, keep a separate PasteDeploy production.ini, run the WSGI callable with Waitress or Gunicorn on localhost or a Unix socket, place nginx in front for public HTTP and HTTPS, and supervise the process with systemd or another service manager.
Need a server to try this on? Antihost offers Linux VPS plans with NVMe storage, full root access and a 14-day free trial.
This guide walks through that layout, explains when each server is appropriate, and gives a deployment sequence you can adapt to your Linux distribution, project package, database, and domain.
As an Amazon Associate I earn from qualifying purchases.
Understand the production architecture
A Pyramid application is a WSGI application: Pyramid’s configurator builds a callable, and a WSGI server invokes that callable for each request. The public web server should not normally expose the Python process directly. A typical request path is:
Browser → nginx on ports 80/443 → Gunicorn or Waitress on localhost or a Unix socket → Pyramid application → database and other services.
#1 Best Overall
nginx handles the public-facing concerns that a Python WSGI server is not intended to handle alone, including TLS termination, connection buffering, request-size policy, and forwarding traffic to a local backend. The WSGI server concentrates on running Python code. A service manager starts it at boot, restarts it after a failure, and provides a consistent place to inspect status and logs.
Pyramid 2.0 runs on Python 3 only. Confirm the Python version supported by your Pyramid release and by every dependency before choosing the VPS operating-system image. Do not assume that the system Python is suitable for your project; use a virtual environment owned by a dedicated, non-root account.
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 matchPrepare the VPS safely
Create a deployment account and directories
Use a separate account for the application instead of running the WSGI process as root. The exact commands vary by distribution, but the principle is the same: the account needs to read the application and its virtual environment, write only to directories that genuinely require writes, and have no unnecessary administrative privileges.
sudo adduser --disabled-password --gecos "" pyramidapp
sudo mkdir -p /srv/pyramidapp
sudo chown -R pyramidapp:pyramidapp /srv/pyramidapp
sudo -u pyramidapp -H bash
Keep uploaded files, generated reports, caches, and logs in explicitly chosen locations. Avoid making the entire source tree writable by the service. Store secrets outside version control and restrict their permissions to the deployment account and the service manager.
Install Python and build prerequisites
On a Debian- or Ubuntu-family VPS, a typical starting point is:
sudo apt update
sudo apt install python3 python3-venv python3-dev build-essential nginx git
Use the equivalent packages for your distribution. Some Python dependencies contain native extensions and therefore need a compiler, Python headers, or system libraries. Install only the libraries your dependency lock file requires, and remove build tools later if your operational policy permits.
Create and verify the virtual environment
As the deployment account, create the environment beside the application code:
cd /srv/pyramidapp
python3 -m venv .venv
. .venv/bin/activate
python -m pip install --upgrade pip
Every installation and service command must use this same environment. A common failure is installing Gunicorn globally while the application package is installed only in .venv; the server then cannot import the project.
Install the application reproducibly
For a generated Pyramid project, the project documentation supports pip install -e . for development. Editable installs are convenient while coding, but a production release is usually better represented by a built wheel or source distribution installed at a specific version:
. .venv/bin/activate
python -m pip install -r requirements.txt
python -m pip install dist/your_project-*.whl
If your release process has no built artifact yet, installing the package from the project directory is still possible; make the choice explicit and record the commit or package version being deployed. Install Gunicorn or Waitress into the same environment as the application:
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Rank #2
python -m pip install gunicorn waitress
Do not install both merely because this example does. Install the server you selected, plus any tools required by your deployment process.
Separate production configuration from development
Pyramid projects commonly use PasteDeploy INI files. Keep development settings, such as a debug-friendly server or local database, separate from the file used by the VPS. A file named production.ini should select the production application configuration and production-safe logging, credentials, and database settings.
A generated project has its own application entry point. The following is an illustrative shape, not a universal file; replace the distribution and entry-point names with those created by your project:
[app:main]
use = egg:myproject
[server:main]
use = egg:waitress#main
listen = 127.0.0.1:6543
The app:main section identifies the WSGI application. The server:main section is used when starting the file with a PasteDeploy-compatible server such as pserve. Gunicorn’s PasteDeploy loader reads the application configuration directly, while its bind address, worker count, and logging options can be supplied on the command line or in Gunicorn configuration.
Keep secrets and environment-specific values out of source
Database passwords, signing keys, mail credentials, and API tokens should come from a protected environment file or the service manager’s environment settings rather than from a committed INI file. Ensure the application reads the same variable names in staging and production, and test that a missing secret causes a clear startup failure instead of silently selecting a development default.
Confirm the WSGI import before adding nginx
From the virtual environment, verify that the package can be imported:
. .venv/bin/activate
python -c "import myproject; print('import ok')"
Use the module and object names defined by your project. If the import fails here, a reverse proxy cannot fix it. Check the installed distribution, the current working directory, dependency versions, and any required environment variables first.
Choose Waitress, Gunicorn, or mod_wsgi
Any WSGI server capable of loading the Pyramid callable can serve the application. The practical choice depends on maintenance, process management, operating-system support, socket and proxy behavior, and the tools your team already operates.
The Tool Desk
Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →| Server | Best fit | Strengths | Important limits or prerequisites | Proxy and TLS approach |
|---|---|---|---|---|
| Waitress | Simple cross-platform deployments, development, and light production | Pure Python, straightforward configuration, and described by its documentation as production-quality with very acceptable performance | Still needs a service supervisor and operational monitoring; it does not provide native TLS | Put nginx or another maintained reverse proxy in front for HTTPS and public traffic |
| Gunicorn | Conventional Linux production deployments | Supports PasteDeploy, multiple worker processes, Unix sockets, and familiar logging options | Gunicorn and the Pyramid package must be installed in the same virtual environment; a buffering HTTP proxy is generally beneficial | Bind to localhost or a Unix socket and let nginx terminate TLS |
| mod_wsgi | Sites whose operational standard is Apache | Integrates the WSGI application into an existing Apache deployment | Requires Apache-specific configuration and operating knowledge | Apache can provide the public HTTP/HTTPS layer |
| NGINX Unit | Existing installations only, after an explicit maintenance review | Its Pyramid guide documents a configuration model | NGINX states that Unit was archived and unmaintained as of October 2025, so it should not be the default for a new deployment | Do not select it for a new production system without accepting its unmaintained status |
Waitress is often the least complicated starting point. Gunicorn is a common production alternative when you want worker processes, Unix-socket support, and an established Linux process model. mod_wsgi makes sense when Apache already supplies your team’s monitoring, TLS, and deployment conventions. None of these choices removes the need for backups, updates, logs, and a restart policy.
Start Pyramid with Waitress for a simple deployment
If your project was generated with a Waitress server section, activate the virtual environment and run:
. .venv/bin/activate
pserve production.ini
For a direct command that bypasses the server section, use the entry point documented by your project. Bind to 127.0.0.1 rather than all interfaces when nginx is on the same VPS. Waitress is suitable for development and light production, but it does not terminate TLS itself, so it should remain behind nginx for an internet-facing site.
Run this command manually only to validate the application. A production process should be launched by systemd, supervisord, or another supervisor so that it starts after a reboot and is restarted according to a deliberate policy.
Run Gunicorn with PasteDeploy
Use the documented PasteDeploy command
The direct Gunicorn form for a Pyramid PasteDeploy file is:
. .venv/bin/activate
gunicorn --paste production.ini
For a public deployment, bind Gunicorn to a local address or Unix socket rather than exposing its listening port directly to the internet. A representative command is:
gunicorn --paste /srv/pyramidapp/production.ini
--bind unix:/run/pyramidapp/app.sock
--workers 4
--preload
--access-logfile -
--error-logfile -
--log-level info
The four-worker value above is the Cookbook’s illustrative configuration, not a sizing rule or benchmark. Worker count depends on CPU, memory, request duration, database limits, and whether the application performs blocking work. Begin with a measured, conservative setting and observe memory use, latency, error rates, and database connections before changing it. Preloading can reduce duplicated application memory in some deployments, but it also means that initialization occurs before workers fork; test applications that create connections or other process-specific resources during import.
Do these 3 things before closing this tab:
1Repair Windows errors before they cause bigger problems2Scan for outdated or missing drivers - takes under a minute3Clear out junk files and repair common Windows errorsChoose a socket path and permissions deliberately
A Unix socket avoids an exposed backend TCP port and is efficient on a single VPS. The service account must be able to create the socket directory, and nginx must be able to connect to the socket. Create a runtime directory through the service manager rather than leaving a stale socket in the application tree. If you prefer TCP, bind to 127.0.0.1:8000 or another local port and use that address in nginx.
Keep access and error logs visible to the supervisor
Sending Gunicorn access and error logs to standard output and standard error, as in the command above, lets systemd or supervisord collect them. Add application-level logging for database failures, background jobs, and request exceptions, and define retention so logs cannot fill the disk.
Put nginx in front of the WSGI server
Configure nginx to listen publicly and forward only the application traffic that should reach Pyramid. The following example assumes Gunicorn created /run/pyramidapp/app.sock:
upstream pyramid_backend {
server unix:/run/pyramidapp/app.sock;
}
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://pyramid_backend;
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;
}
}
Replace the hostname and socket path. Enable the site using your distribution’s nginx layout, validate the configuration, and reload nginx without dropping existing connections. The exact enablement commands differ between distributions.
Recommended Free Tools
Forward headers safely
The forwarded headers allow Pyramid and downstream code to know the original host, client address, and scheme. Trust them only from your own proxy. Do not configure the application to accept arbitrary client-supplied forwarding headers when the VPS is reachable through another untrusted proxy or load balancer. Configure Pyramid’s host and proxy-related settings according to the version and middleware used by your project, then test redirects and generated absolute URLs.
Serve static assets intentionally
Let nginx serve versioned static files directly when your build process produces a stable directory, and forward dynamic routes to Pyramid. Verify that the filesystem path is readable by nginx and that a missing asset returns a real 404 rather than being passed to an application route accidentally. Keep user uploads outside the source tree and apply an explicit size and content policy.
Terminate HTTPS at the proxy
Obtain a certificate through an ACME-compatible certificate process or another trusted certificate authority, configure nginx for ports 80 and 443, and redirect HTTP to HTTPS once the certificate works. Confirm certificate renewal before relying on it. Waitress and Gunicorn are application servers; nginx or Apache should handle public TLS, protocol policy, and certificate rotation.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Supervise the process with systemd or supervisord
Example systemd unit
On a systemd-based VPS, a unit can create a runtime directory, run the virtual-environment executable, and restart the process after an abnormal exit:
[Unit]
Description=Pyramid application
After=network.target
[Service]
User=pyramidapp
Group=www-data
WorkingDirectory=/srv/pyramidapp
RuntimeDirectory=pyramidapp
RuntimeDirectoryMode=0750
UMask=0007
EnvironmentFile=/etc/pyramidapp/pyramidapp.env
ExecStart=/srv/pyramidapp/.venv/bin/gunicorn --paste /srv/pyramidapp/production.ini --bind unix:/run/pyramidapp/app.sock --workers 4 --access-logfile - --error-logfile -
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
This is a template: adjust the account, group, paths, environment file, worker count, and socket permissions. The nginx worker must have permission to traverse the runtime directory and connect to the socket. After placing the unit in the systemd service directory, reload units, enable the service, start it, and inspect its status and journal. Do not grant the service account more filesystem access than required.
Use supervisord when it is already your standard
The Pyramid Cookbook also describes nginx with pserve and supervisord, along with several system-service patterns. supervisord can launch the same virtual-environment command and capture its output. Do not run both supervisord and systemd for the same process; two supervisors can create competing restarts and confusing logs.
Define restart behavior carefully
An automatic restart handles crashes, not every deployment concern. Use a controlled release procedure that stops or reloads workers, runs migrations at the correct point, checks health, and rolls back when the new package cannot start. Avoid an aggressive restart loop that hides a persistent configuration or database error.
Validate the deployment before switching traffic
Test from the inside out. This separates an application error from a socket, proxy, DNS, or certificate error.
Free tools Windows power users keep installed
One-click scans. No signup required.
- Import test: from the application directory, activate
.venvand import the installed project. Resolve missing modules and environment variables before starting a service. - Backend test: if using a TCP listener, request it with
curl -i http://127.0.0.1:8000/. For a Unix socket, usecurl --unix-socket /run/pyramidapp/app.sock -i http://localhost/. Replace the path with a route that your application actually serves. - Service test: reboot or restart the service and confirm that the socket is recreated and the process is running under the intended account.
- Proxy test: request the site through nginx and verify status codes, Host handling, redirects, forwarded scheme, request bodies, and error pages.
- Static-file test: load representative CSS, JavaScript, images, and user-upload paths. Check permissions and cache behavior.
- Database test: verify credentials, network access, migrations, connection limits, and transaction behavior using the production database or a safe staging clone.
- TLS test: check the certificate name, complete chain, HTTP-to-HTTPS redirect, renewal process, and application-generated HTTPS URLs.
- Failure test: stop the WSGI process and confirm that nginx returns an appropriate temporary error, then start it again and verify recovery. Inspect both proxy and application logs.
The deployment patterns above are not a test report for your particular application. Load, memory, database behavior, and response times must be measured with your own routes and traffic profile.
Troubleshoot common failures
| Symptom | Likely cause | Checks and corrective action |
|---|---|---|
| Gunicorn exits immediately with an import error | The package is not installed in the selected virtual environment, the working directory is wrong, or a required variable is absent | Run the import test with the exact Python executable in ExecStart; reinstall the package and dependencies; inspect the service journal |
| nginx returns 502 Bad Gateway | The WSGI process is stopped, the socket path differs, or nginx lacks socket permissions | Check service status, confirm the socket exists at the configured path, compare user/group and directory permissions, and read nginx’s error log |
| Requests work locally but not through nginx | Proxy routing, Host handling, forwarded scheme, or firewall configuration is incorrect | Validate nginx syntax, test the configured server name, inspect forwarded headers, and ensure only the intended public ports are open |
| HTTPS redirects loop or generated links use HTTP | The application does not trust the proxy’s scheme header or nginx is forwarding an incorrect value | Set and validate X-Forwarded-Proto, configure Pyramid’s proxy awareness appropriately, and test both direct and proxied requests |
| Static files return 404 or 403 | The build output is absent, the nginx alias/root is wrong, or filesystem traversal permissions are insufficient | Check the deployed asset path, nginx configuration, ownership, and directory permissions; request one known file directly |
| Workers consume excessive memory | Too many workers, large imports, preload behavior, or a leak in application code | Measure resident memory per worker, reduce workers temporarily, review initialization and long-lived objects, and test changes under representative traffic |
| Changes are not visible after deployment | Old workers are still serving, the wrong virtual environment is active, or a cache is returning old assets | Confirm the running command and package version, perform a controlled restart or reload, and use versioned static filenames |
Operate the VPS after launch
- Patch the operating system, Python dependencies, Pyramid, nginx, and the selected WSGI server on a scheduled basis. Read release notes for compatibility changes before upgrading production.
- Back up the database and any user-generated files separately from the application source. Test restoration rather than assuming a successful backup command is sufficient.
- Monitor process liveness, HTTP error rates, latency, disk space, memory, database availability, and certificate expiry. A simple uptime check does not reveal application-level failures.
- Keep deployment artifacts and configuration history so you can identify which package, migration, and environment values were released.
- Restrict inbound ports to what the site needs, usually SSH plus HTTP and HTTPS, and protect administrative interfaces with stronger access controls.
- Review log contents for credentials or personal data before sending them to a central system. Set rotation and retention limits.
A practical decision path
Choose Waitress when you want the smallest operational surface, need cross-platform behavior, and have light production traffic behind nginx. Choose Gunicorn when your Linux operations already use it, when PasteDeploy loading and worker processes fit your deployment model, or when a Unix socket and conventional process controls are useful. Choose mod_wsgi when Apache is already the maintained standard for your organization. Do not make NGINX Unit the default for a new project: its own documentation records that the project was archived and unmaintained as of October 2025.
Whichever server you select, the durable deployment pattern is the same: an isolated Python environment, a tested production INI, a local-only WSGI listener, a maintained reverse proxy for public HTTP and TLS, a single process supervisor, and a repeatable verification and rollback procedure.
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.
Do these 3 things before closing this tab:
1Clear out junk files and repair common Windows errors2Fix the driver behind crashes, sound loss and screen glitches3Repair Windows errors before they cause bigger problems




