Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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

A production Flask deployment on a Linux VPS should follow this path: Internet → nginx on ports 80/443 → Gunicorn on localhost or a Unix socket → Flask → PostgreSQL. nginx terminates TLS and serves static files, Gunicorn runs the WSGI application as an unprivileged user, systemd keeps the process running, and PostgreSQL stores application data.

This arrangement avoids Flask’s development server, limits the public attack surface, and gives you a clear path from one VPS to separate application and database servers. The instructions below use Ubuntu-style commands; adapt package names and service paths if you use another Linux distribution.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Choose the deployment shape before you install anything

You can run PostgreSQL on the same VPS as Flask or use a managed PostgreSQL service. Both can work; the important difference is who operates the database.

Decision area PostgreSQL on the VPS Managed PostgreSQL
Operational control Full control over PostgreSQL version, extensions, configuration and maintenance windows. Provider controls much of the platform; you normally control databases, roles and parameters exposed by the service.
Setup effort Install, secure, patch, monitor and back up PostgreSQL yourself. Provisioning is quicker, but you must configure network access, credentials, TLS and provider-specific backups.
Security boundary Keep PostgreSQL bound to localhost when the app is on the same host. Protect a network endpoint with a private network or tightly restricted source addresses and TLS.
Scaling path Vertical scaling is simple; separating the database later requires migration planning. Many services offer storage, compute and read-replica options without changing the application architecture.
Backup responsibility You schedule backups, copy them off-host and test restores. The service may provide automated backups, but you still need retention, export and restore procedures appropriate to your application.
Monthly cost Low incremental cost because the database shares the VPS, offset by your administration time and disk requirements. Recurring database charges and network egress may apply in addition to the VPS.

For a small application, a single VPS with PostgreSQL on localhost is a practical starting point. Choose a managed database when losing database administration time, maintenance automation or independent scaling is worth the additional recurring cost.

#1 Best Overall
Sale
Compressed Air Duster,130000RPM Super Power Cordless Air Duster,Rechargeable Brushless Blower,3 Gear Adjustable Blower with LED Light,Dust Remover for Computer/House/Outdoor/Car
  • Powerful Turbo Fan:CAGIWIRU Electric Air Duster have reached speed up to 130000RPM,Can efficient remove dust and debris.With LED light and Three Adjustable Speed to meet with different cleaning tasks.
  • With Attached USB C Fasting Charging cable.Charing 3 hours,Enjoy up to 240 minutes of use on the lowest setting, For third speed can use for 25mins.with four charging options to meet with your needs.
  • Wide Application:Upgraded attached 5 different nozzles,making it suitable for a variety of scenes, such as car,pet, pc, keyboards, and other electronic devices. It also serves for office and home clean duster.
  • Handy Design & Portable:Cordless air duster electric nozzle is Light weight and small size, design and comfortable to hold and space saving, convenient to carry around. You can put it in your room or inside the car without taking up space.
  • Warranty & Support: Our Electric air duster comes with 5 years warranty and 24/7 customer service. During this period, if you have any questions,pls kindly feel free to contact us.

Prepare the Linux VPS

Create a non-root deployment account

Connect over SSH with the provider’s initial account, create a dedicated account, and grant only the administrative access it needs. Do not run the web process as root. Flask’s documentation says the development server is intended only for local development, and its Gunicorn guidance warns that running Gunicorn as root would execute application code as root.

sudo adduser --system --group --home /srv/flaskapp flaskapp
sudo mkdir -p /srv/flaskapp
sudo chown -R flaskapp:flaskapp /srv/flaskapp
sudo usermod -aG sudo YOUR_ADMIN_USER

Use your normal administrative account for SSH and sudo; reserve flaskapp for the service. Configure SSH keys, disable password authentication only after key login is confirmed, and avoid permitting direct root login.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Update packages and install the base stack

sudo apt update
sudo apt upgrade -y
sudo apt install -y python3 python3-venv python3-pip git nginx postgresql

Ubuntu’s PostgreSQL instructions use apt install postgresql as the baseline installation. Reboot if a kernel or critical system package update requests it, then reconnect before continuing.

Restrict network exposure

Allow SSH and the public web ports, and keep PostgreSQL private when it is local:

sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
sudo ufw status verbose

Do not open port 5432 to the internet for a local database. If PostgreSQL is on another host, use a private network where possible, allow only the application server’s address, and require TLS.

Install the Flask application in an isolated environment

Copy the code and create a virtual environment

Clone the repository as the deployment account, or copy a reviewed release archive into /srv/flaskapp. The application must expose a WSGI target such as wsgi:app, where wsgi.py contains an object named app. An application-factory project can instead expose the factory target required by your Gunicorn command.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
sudo -u flaskapp git clone YOUR_REPOSITORY_URL /srv/flaskapp
sudo -u flaskapp python3 -m venv /srv/flaskapp/.venv
sudo -u flaskapp /srv/flaskapp/.venv/bin/pip install --upgrade pip
sudo -u flaskapp /srv/flaskapp/.venv/bin/pip install -r /srv/flaskapp/requirements.txt

Pin production dependencies in requirements.txt (or your lock-file workflow), including Flask, Gunicorn, your PostgreSQL driver and your migration tool. Install them inside the virtual environment, never into the system Python.

Rank #2
EVEO® Screen Cleaner Spray Kit (Streak-Free) TV Screen Cleaner for Smart TV, Lcd, LEd, Oled | Computer Screen Cleaner Spray and Wipe Microfiber Cloth - TV, Monitor, Laptop, iPad, Car - 6.7oz 1 Pack
  • Screen Cleaner is Your Screen’s New Bestfriend! - EVEO is proud to present a screen cleaner that’s perfectly suited for your TV. Meet your new screen cleaner, computer screen cleaner, laptop cleaner, iPad cleaner, Macbook,tv cleaner or any other electronic device. Our screen cleaner spray and wipe along with the included plush microfiber cloth, easily removes dust, fingerprints & other smudges on the screen’s surface. Clean effectively for a streak-free screen
  • Gentle on your Screens - Our screen cleaner spray and wipes is compatible to be used even for the most sensitive LCD, LED, CRT, and OLED screens in proper use. Be at ease knowing that this product is compatible with all the major brands: LG, SONY, Samsung, Sharp, iPad, iPhone, Android screens, Kindle, PC monitors - we’ve got you covered! Can be used as LCD screen cleaner, tv cleaner, smart tv screen cleaner, and more
  • Premium Super Soft Plush Microfiber Cloth - Included in this efficient screen cleaning kit. This screen cleaner spray and wipe has our signature plush microfiber cloth specially designed to comply with screens and monitors and leave them streak-free. Has been shown to effectively absorbs stubborn stains, zero streaks, and no fiber shedding. Always use this together with our screen cleaner for the best results
  • Easy-to-Use Screen Cleaner Kit + microfiber cleaning cloth - The EVEO Screen Cleaning Kit will easily be your new favorite tool when it comes to taking care of the things you love most, quick and easy solution for a streak-free screen. Simply screw on the sprayer gun on the screen cleaner bottle. Spray the cleaning liquid onto the microfiber cloth, then wipe the screen until desired cleanliness & shine is achieved.
  • Quality Screen Care Kit Worth Purchasing - Enjoy a convenient Screen Cleaner anytime, anywhere you need it. Your satisfaction is our top priority. We stand behind the quality of our products and that’s why, you shouldn’t be worrying at all. We manufacture the Best Screen Cleaner. and can be used for laptop cleaning kit, laptop screen cleaner, tv screen cleaner for smart tv. MacBook screen cleaner, monitor cleaner or screen cleaner spray for electronic devices with microfiber cleaning cloth

Check the WSGI target before creating services

sudo -u flaskapp bash -lc 'cd /srv/flaskapp && .venv/bin/python -c "from wsgi import app; print(app)"'

If this import fails, correct the module path, package layout, or configuration before proceeding. A common production failure is a mismatch between the file and object name in module:app.

Install and secure PostgreSQL

Create a dedicated role and database

Web requests should never use the PostgreSQL superuser. Create one login role for the application and make that role the owner of its database:

sudo -u postgres psql
CREATE ROLE app_user LOGIN PASSWORD 'REPLACE_WITH_A_LONG_RANDOM_PASSWORD';
CREATE DATABASE app_db OWNER app_user;
q

Use a unique password generated by a password manager. Grant additional privileges only when a migration or extension genuinely requires them; the runtime account should have the minimum rights needed by the application.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Store the connection string outside the repository

Create a root-owned environment file. The following example connects to a local PostgreSQL listener:

sudo install -o root -g flaskapp -m 0640 /dev/null /etc/flaskapp.env
sudo sh -c 'cat > /etc/flaskapp.env' <<'EOF'
DATABASE_URL=postgresql://app_user:REPLACE_ME@127.0.0.1:5432/app_db
SECRET_KEY=REPLACE_WITH_A_RANDOM_SECRET
FLASK_CONFIG=production
FLASK_DEBUG=0
EOF

Replace every placeholder, then verify that the file is not world-readable:

sudo chown root:flaskapp /etc/flaskapp.env
sudo chmod 0640 /etc/flaskapp.env
sudo ls -l /etc/flaskapp.env

Your configuration code should read DATABASE_URL from the environment and fail clearly if it is missing. Never commit this file or print its contents in logs.

Understand PostgreSQL authentication

Ubuntu commonly uses peer authentication for local Unix-socket connections and scram-sha-256 for host connections. Because the example URL uses 127.0.0.1, PostgreSQL evaluates host rules in pg_hba.conf. Ubuntu stores the main configuration under /etc/postgresql/<version>/main.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #3
BladeHawks RGB Gaming Mouse Pad Extra Large Extended 31.5x12 Inch-Black
  • 【Large size】:Measuring 800 x 300 mm/ 31. 5×12 inches, which is wider and taller than others. Large mouse pad can perfectly fit your keyboard and mouse of any size, and there is also ample space for peripherals such as phones, tablets, etc.
  • 【LED backlight mouse pad】:Blade Hawks RGB mouse pad provides 7 static modes and 7 dynamic modes will give you the options you are looking for. Power-off memory function remembers the last lighting mode you selected. The super glow fiber Chroma will give you a colorful gaming setup that you want.
  • 【Anti-slip rubber base】:Made from Natural rubber, this gaming mousepad will firmly grip your desktop, allowing you to enjoy the ultimate precision in the games you are most passionate about. It also comes with a texture that enhances this ability even further.
  • 【Smooth and waterproof surface】: Micro-textured cloth surface, for extremely precise mouse control and a smooth movement. When liquid splashes on the gaming mouse pad, it forms water droplets and slides down. Will not delay your work or gameplay.
  • 【Plug and play】: This mouse and keyboard pad is powered by USB, plug and play, no driver required. One button control light modes. Press one time to change the lighting mode, press twice to change the brightness, press and hold about 3 seconds turn ON/OFF.

Inspect the active rules before changing them:

sudo -u postgres psql -c 'SHOW hba_file;'
sudo -u postgres psql -c 'SHOW config_file;'

Use the narrowest rule that matches the application’s source address and role. If a database is reachable over a network, restrict source addresses, require TLS, and replace Ubuntu’s bundled test-oriented SSL setup with a certificate issued by a trusted certificate authority. After editing pg_hba.conf or related settings, reload or restart PostgreSQL according to the change and verify a real application connection.

Apply schema migrations deliberately

Use the migration system your project already adopted, such as Flask-Migrate/Alembic. Generate and review migrations in development; do not create unreviewed schema changes on the production server.

sudo -u flaskapp bash -lc 'cd /srv/flaskapp && set -a && . /etc/flaskapp.env && set +a && .venv/bin/flask db upgrade'

Run this only after confirming that the release’s migration files are present and that DATABASE_URL points to the intended database. For large or locking migrations, schedule a maintenance window and measure their effect before applying them to production.

Run Flask with Gunicorn under systemd

Create the service unit

Gunicorn is the production WSGI server; systemd supervises it, starts it at boot, and restarts it after an unexpected exit. Save this unit as /etc/systemd/system/flaskapp.service:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
[Unit]
Description=Gunicorn service for Flask application
After=network.target

[Service]
User=flaskapp
Group=flaskapp
WorkingDirectory=/srv/flaskapp
EnvironmentFile=/etc/flaskapp.env
Environment="PATH=/srv/flaskapp/.venv/bin"
ExecStart=/srv/flaskapp/.venv/bin/gunicorn --workers 3 --bind 127.0.0.1:8000 wsgi:app
Restart=always

[Install]
WantedBy=multi-user.target

Three workers is only an example. Tune the worker count for your workload, request latency and available memory; too many workers can exhaust RAM. For a Unix-socket design, bind Gunicorn to a socket path owned by the service account and configure nginx to use that exact path. Gunicorn’s deployment documentation also describes systemd socket activation.

Enable and inspect the service

sudo systemctl daemon-reload
sudo systemctl enable --now flaskapp
sudo systemctl status flaskapp
sudo journalctl -u flaskapp -n 100 --no-pager

Before adding nginx, test the local listener:

curl -i http://127.0.0.1:8000/health

Create a lightweight health endpoint that checks application readiness without exposing secrets. If the endpoint depends on PostgreSQL, make that dependency explicit so a database outage is visible.

Put nginx in front of Gunicorn

Configure the reverse proxy

Create /etc/nginx/sites-available/flaskapp and replace example.com with your domain. The upstream address must exactly match Gunicorn’s bind address.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #4
Sale
Vaydeer Wrist Rest for Keyboard and Mouse, Computer Ergonomic Wrist Support Pad, Soft Memory Foam Arm Cushion for Desk, Palm Hand Office Laptop Typing
  • 【Softer and More Comfortable】Vaydeer wrist rest has unique diamond pattern, which is the combination of softness and aesthetics. The materials of wrist rest are improved into higher quality memory foam and covered with silky smooth lycra. The computer wrist rest makes you as comfortable and cushiony as like rest your wrists on clouds.
  • 【Ergonomic Wrist Saver】The wrist rests for keyboard and mouse comes with a 17.32×3.15×0.83 inch keyboard wrist pad and a 5.94×3.15×0.83 inch mouse wrist support. Based on ergonomic design, the unique concave shape is the perfect fit for your wrist joints. The wrist rest pad fits most computer keyboards and laptops, improve hand and wrist posture, release your wrist and arm stress.
  • 【Non-Slip Rubber Bottom】Featuring an anti-skid silicone base on the bottom, this wrist keyboard support stays firmly in place on your desk, preventing the padding from sliding around, ensuring stable and consistent wrist support during extended computer sessions.
  • 【Better Experience & Pain Relief】Our keyboard arm rest is beneficial to alleviate the soreness caused by direct contact and friction between your arm and a hard desk surface, reducing the risk of wrist fatigue or carpal tunnel. The soft texture of memory foam can evenly distribute the pressure around your wrists and provide good support with just enough give.
  • 【Helpful in Multiple Scenarios】Whether you're working, studying, writing, typing, gaming, this keyboard and mouse rest combo is an essential accessory to add comfort and support to your hands and wrists. It’s also a great gift for men, women, family, friend, coworker, gamer, teacher, etc.
server {
    listen 80;
    server_name example.com www.example.com;

    location /static/ {
        alias /srv/flaskapp/static/;
        access_log off;
        expires 7d;
    }

    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://127.0.0.1:8000;
    }
}

Ensure nginx can traverse the static-file directory and that the alias points to the directory produced by your asset build. Serving large static assets directly from nginx avoids sending them through Flask workers.

sudo ln -s /etc/nginx/sites-available/flaskapp /etc/nginx/sites-enabled/flaskapp
sudo nginx -t
sudo systemctl reload nginx

Keep the default site disabled if it would conflict with your server name:

sudo rm -f /etc/nginx/sites-enabled/default
sudo nginx -t
sudo systemctl reload nginx

Enable HTTPS with an ACME client

Point DNS at the VPS, then obtain a certificate with an established ACME client such as Certbot:

sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d example.com -d www.example.com
sudo certbot renew --dry-run

Certbot normally adds the TLS listener and an HTTP-to-HTTPS redirect. Confirm both the certificate and redirect from an external client, and keep automatic renewal enabled. If you write the TLS server block yourself, retain the same proxy headers and proxy target while redirecting every HTTP request to HTTPS.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Make Flask proxy-aware and production-safe

Because nginx terminates TLS, Flask must trust the forwarded scheme and host only from your trusted proxy. With Werkzeug, configure ProxyFix with counts that match your proxy chain; for a single nginx instance, one forwarded proxy is typical:

from werkzeug.middleware.proxy_fix import ProxyFix

app.wsgi_app = ProxyFix(app.wsgi_app, x_for=1, x_proto=1, x_host=1)

Use the equivalent setting for your framework integration. This allows URL generation, redirects and secure-cookie behavior to reflect HTTPS. Do not blindly trust forwarded headers when clients can reach the application directly; keep Gunicorn bound to localhost or a protected Unix socket.

Set debug mode off, use a strong random SECRET_KEY, and keep third-party credentials in the protected environment file. If a secret is ever committed or written to logs, rotate it immediately and remove the exposed value from active configuration.

Best Value
Sale
Under Desk Cable Management Tray No Drill, Metal Mesh Cable Management Under Desk with Clamp Mount, 2 Hole Cable Tray with Wire Management and Cord Organizer for Home Office Standing Desk
  • 【No Drill Mounted】Cable management tray can be assembled in as little as 3 minutes or less-simply. Side clips easily clampe the edge of desk, pass through the holes on the sides, and secure excess cables with baskets. Desk cable management supports inward or outward installation to meet your needs in different scenarios, and provides you with great convenience when collecting and organizing wires.
  • 【Rubber Pad Protects Desk】Wire organizer under desk built-in soft rubber pads on the clamp protect your desk from scratches, so you will not damage your furniture or office.
  • 【Sturdy and Beautiful】Cord management under desk is made of high-quality carbon steel and holds about 15 lbs. The wire basket has 2 holes on each side of the tray to enable your cables to pass freely. Cable baskets are suitable for desk thickness use from 0.4" to 2.4".
  • 【Space Saving & Keep Organized】Desk cable management tray holds all your power cords, outlet strips, USB hubs and computer transformers hidden from your feet, and the data cables will not enter the vacuum cleaner to keep your desk clean and tidy. Desk wire organizer is also suitable for use in the kitchen and outdoors.
  • 【Reduce Safety Risks】Cable tray under desk keeps all plugs away from your kids, no more worry about tripping. Using 2 holes wire tray saves extra space, helps you easily cabling and wire protection. The mesh design is not easy to accumulate dust, but avoids safety accidents caused by messy wires.

Use a repeatable release and rollback procedure

Every release should be observable and reversible. A practical sequence is:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  1. Record the current revision so it can be restored.
  2. Fetch the new revision into the application directory and check it out.
  3. Install the locked dependency set into the existing virtual environment or a new release-specific environment.
  4. Run reviewed database migrations with the production environment loaded.
  5. Run an import check or application test that exercises the new code.
  6. Reload Gunicorn gracefully: sudo systemctl reload flaskapp. If your unit does not define a reload action, use sudo systemctl restart flaskapp during a planned window.
  7. Check systemctl status flaskapp, the service journal, sudo nginx -t, and an HTTPS request to the health endpoint.
  8. Keep the previous revision and dependency information until the new release has passed its observation period.

Never treat a successful command as proof of a successful deployment. Verify process status, nginx configuration, application logs, database connectivity and an external HTTPS request. If the release fails, restore the previous code and compatible dependencies, reverse only migrations that have a reviewed downgrade path, and restart the service.

Back up PostgreSQL and test recovery

Backups are an operational requirement, not an optional add-on. Schedule regular logical or physical backups, copy them off the VPS, protect them from the application account, and define retention. A simple logical dump can be a component of that plan:

sudo -u postgres pg_dump -Fc app_db > /var/backups/app_db-$(date +%F).dump

Store production backups on separate infrastructure; a backup left on the same failed disk is not a complete recovery plan. Perform restore drills into an isolated database and record how long restoration and application verification take. Ubuntu’s PostgreSQL guidance explicitly recommends regular backups.

Plan the next scaling step

Keep the application stateless so additional Gunicorn workers or another application host can serve requests without local-session or uploaded-file surprises. Move user uploads to durable object or shared storage before adding multiple hosts, and centralize logs so a request can be traced across instances.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

When CPU or memory is the constraint, resize the VPS or tune Gunicorn workers after measuring. When database I/O, storage or maintenance is the constraint, move PostgreSQL to a dedicated or managed service and update only the protected connection configuration. Recheck firewall rules, TLS, allowed source addresses, backups and migration timing after the move.

Troubleshoot the failures you are most likely to see

Symptom Checks and fixes
ModuleNotFoundError or import failure Confirm WorkingDirectory, the virtual-environment path, package installation and the Gunicorn module:app target. Reproduce the import as the flaskapp user.
nginx returns 502 Run systemctl status flaskapp, inspect journalctl -u flaskapp, and compare nginx’s proxy_pass address with Gunicorn’s bind address or socket. For sockets, verify ownership and permissions.
Database authentication fails Check the exact DATABASE_URL, role password and privileges, the matching pg_hba.conf rule, and whether PostgreSQL is listening on the intended address. Test with the same host, role and database outside Flask.
Static files are missing Verify the nginx alias, filesystem traversal permissions and the application’s asset build output. Do not route large static assets through Flask unnecessarily.
HTTPS redirect loop or insecure URLs Inspect X-Forwarded-Proto, the nginx proxy configuration and Flask’s proxy settings. Ensure only the trusted proxy can reach Gunicorn and that secure-cookie settings match HTTPS.
Service starts manually but not at boot Run systemctl daemon-reload, confirm systemctl enable flaskapp, inspect unit paths and environment-file permissions, then reboot during a maintenance window to verify recovery.

Production readiness criteria

Your deployment is ready when Flask is no longer exposed through its development server, Gunicorn runs as flaskapp, nginx is the only public application entry point, PostgreSQL uses a dedicated role, secrets are outside version control, debug mode is disabled, migrations are reviewed, HTTPS renews successfully, and backups have passed a restore test. This arrangement gives a small Flask application a secure operational baseline while leaving clear options for managed PostgreSQL, separate hosts and horizontal scaling.

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.