Limited time30% off all orders with codeHELLO30
← Back to blog

How to Set Up Nginx, PostgreSQL, and Redis on Ubuntu 24.04

Ubuntu 24.04 server setup in 20 minutes — install Nginx 1.24, PostgreSQL 16, and Redis 7, configure UFW, a reverse proxy, and free Let's Encrypt SSL.

TL;DR:

  • Ubuntu 24.04 LTS ships everything in its default repos: Nginx 1.24, PostgreSQL 16, Redis 7.
  • The full Ubuntu server setup — install, firewall, hardening, reverse proxy, SSL — takes about 20 minutes on a fresh VPS.
  • UFW's Nginx Full profile opens ports 80/443; PostgreSQL and Redis stay on localhost by default (keep them there).
  • Certbot adds a free Let's Encrypt certificate with auto-renewal in one command.
  • Verify everything at once: systemctl status nginx postgresql redis-server.

A fresh Ubuntu 24.04 VPS is a blank slate. This Ubuntu server setup guide takes you from first SSH login to Nginx serving requests, PostgreSQL storing data, and Redis handling caching or session state — configured correctly and ready for a production workload, within 20 minutes.

Commands are shown in order. Run them as root or prefix each with sudo.


Before you start

You need a VPS running Ubuntu 24.04 LTS with root or sudo access. If you're still on shared hosting and running into resource limits, the gap between what shared hosting provides and what a VPS gives you is real — moving to a VPS makes sense once your workload demands consistent CPU and memory.

If you're deploying on Arct Cloud, your server is SSH-ready in under 60 seconds. Once you have your IP and root credentials, you're ready to go.


Step 1: Update the system

Start with a full package update before installing anything.

apt update && apt upgrade -y

This ensures you're installing against the latest package index and avoids dependency conflicts from stale metadata.


Step 2: Install Nginx on Ubuntu 24.04

Ubuntu 24.04's default repositories include Nginx 1.24. Install it and enable it to start on boot.

apt install nginx -y
systemctl enable --now nginx

Verify it's running:

systemctl status nginx

You should see active (running). Open your server's IP in a browser and you'll get the default Nginx welcome page.

Configure the firewall

If you're running UFW, allow HTTP and HTTPS traffic:

ufw allow 'Nginx Full'
ufw enable
ufw status

Nginx Full opens ports 80 and 443. If you only need HTTP for now, use Nginx HTTP instead.


Step 3: Install PostgreSQL 16 on Ubuntu 24.04

Ubuntu 24.04 ships with PostgreSQL 16. Install it directly from the default repos:

apt install postgresql postgresql-contrib -y
systemctl enable --now postgresql

Confirm the service is active:

systemctl status postgresql

Create a database and user

PostgreSQL creates a system user called postgres during installation. Switch to it and open the interactive shell:

su - postgres
psql

Inside psql, create a dedicated user and database for your application:

CREATE USER appuser WITH PASSWORD 'your_secure_password';
CREATE DATABASE appdb OWNER appuser;
GRANT ALL PRIVILEGES ON DATABASE appdb TO appuser;
\q

Exit back to root:

exit

Configure remote access (optional)

By default, PostgreSQL only listens on localhost. If your application runs on the same server, leave it that way. If you need remote access, edit postgresql.conf:

nano /etc/postgresql/16/main/postgresql.conf

Find the listen_addresses line and update it:

listen_addresses = '*'

Then edit pg_hba.conf to allow your specific IP:

nano /etc/postgresql/16/main/pg_hba.conf

Add a line at the bottom:

host    appdb    appuser    your.client.ip/32    scrypt

Restart PostgreSQL to apply the changes:

systemctl restart postgresql

Only open remote access if you genuinely need it. A database exposed to the public internet is an unnecessary risk.


Step 4: Install Redis 7 on Ubuntu 24.04

Redis 7 is available in Ubuntu 24.04's repositories.

apt install redis-server -y
systemctl enable --now redis-server

Verify it responds:

redis-cli ping

Expected output: PONG

Harden the Redis configuration

The default Redis config binds to localhost and has no password. For a single-server setup, the localhost binding is correct. Add a password for any environment where Redis handles sensitive session data.

Open the config file:

nano /etc/redis/redis.conf

Find the requirepass line, uncomment it, and set a strong password:

requirepass your_redis_password

Confirm Redis is bound to localhost only — this is the default, but verify it:

bind 127.0.0.1 ::1

Restart Redis:

systemctl restart redis-server

Test authentication:

redis-cli -a your_redis_password ping

Step 5: Configure Nginx as a reverse proxy

For most web applications, Nginx sits in front of your app server (Node.js, Gunicorn, Puma, etc.) and proxies requests to it. Here's a basic server block for an app running on port 3000:

nano /etc/nginx/sites-available/myapp

Paste the following:

server {
    listen 80;
    server_name yourdomain.com www.yourdomain.com;

    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }
}

Enable the site and test the config:

ln -s /etc/nginx/sites-available/myapp /etc/nginx/sites-enabled/
nginx -t

If the test returns syntax is ok and test is successful, reload Nginx:

systemctl reload nginx

Step 6: Verify all 3 services are running

Check everything at once:

systemctl status nginx postgresql redis-server

All 3 should show active (running). If any show failed, check the journal:

journalctl -xeu nginx
journalctl -xeu postgresql
journalctl -xeu redis-server

The journal output will point to the exact config line that caused the failure.


Step 7: Add SSL with Let's Encrypt

Serving over HTTP in production is not acceptable. Install Certbot and get a certificate:

apt install certbot python3-certbot-nginx -y
certbot --nginx -d yourdomain.com -d www.yourdomain.com

Certbot modifies your Nginx config automatically, installs the certificate, and sets up auto-renewal via a systemd timer. Verify the renewal timer is active:

systemctl status certbot.timer

Keeping the stack healthy

A few practices worth following once the stack is live:

  • Monitor disk I/O — PostgreSQL write-heavy workloads benefit from NVMe-backed storage. On Arct Cloud, every VM runs on Gen4 NVMe delivering up to 7,000 MB/s, so disk is rarely the bottleneck.
  • Set Redis maxmemory — Add maxmemory 256mb and maxmemory-policy allkeys-lru to redis.conf if Redis is used for caching. Without a memory limit, Redis will consume all available RAM under load.
  • Enable PostgreSQL logging — Set log_min_duration_statement = 1000 in postgresql.conf to log any query taking over 1 second. Slow query logs are the fastest way to catch performance problems early.
  • Back up your databasepg_dump appdb > appdb_backup.sql gives you a portable snapshot. Automate it with a cron job and store backups off-server.

FAQs

What version of PostgreSQL ships with Ubuntu 24.04? Ubuntu 24.04 LTS ships with PostgreSQL 16 in its default repositories. You can install newer versions from the official PostgreSQL APT repository if your application requires them.

Should Redis bind to localhost or a public IP? Bind Redis to localhost (127.0.0.1) unless your architecture specifically requires Redis to be reachable from another server. Exposing Redis on a public interface without strict firewall rules is a common misconfiguration that leads to data exposure.

How do I connect my application to PostgreSQL? Use the credentials you created in Step 3. Your connection string will follow the pattern postgresql://appuser:your_secure_password@localhost:5432/appdb. Most application frameworks accept this format directly.

Can Nginx serve static files and proxy dynamic requests at the same time? Yes. Add a location /static/ block pointing to your static file directory before the proxy location / block. Nginx serves static files directly without touching your app server, which reduces load significantly.

How do I test that Redis is caching correctly? Run redis-cli monitor while sending requests to your application — you'll see every command Redis receives in real time. For cache hit/miss ratios, run redis-cli info stats and check keyspace_hits and keyspace_misses.

What's the right way to run multiple sites on one Nginx server? Create a separate config file in /etc/nginx/sites-available/ for each site with a unique server_name directive. Symlink each to sites-enabled/, run nginx -t, and reload. Nginx routes requests by matching the Host header against each server_name.

Do I need to open PostgreSQL's port in UFW? Only if your application connects from a different server. For a single-server stack where Nginx, your app, and PostgreSQL all run on the same VPS, PostgreSQL stays on localhost and UFW doesn't need a rule for port 5432.


Your stack is running. Nginx handles incoming traffic, PostgreSQL stores your data, and Redis handles caching or sessions. The next step is deploying your application code and pointing it at these services using the credentials and socket paths configured above.

If you're still deciding where to host, Arct Cloud provisions Ubuntu 24.04 VMs in under 60 seconds with full root access, Gen4 NVMe storage, and a 10 Gbps uplink — everything this stack needs, with no managed-runtime layer in the way.