BLOG POSTS
Installing and Using PostgreSQL on Ubuntu 24

Installing and Using PostgreSQL on Ubuntu 24

PostgreSQL, often called “Postgres,” stands as one of the most powerful open-source relational database management systems available today, offering advanced features like JSONB support, full-text search, and extensibility that make it a go-to choice for everything from small web applications to enterprise-grade systems. With Ubuntu 24’s release bringing improved performance and updated package repositories, setting up PostgreSQL has become even more straightforward, though there are still plenty of configuration gotchas and optimization opportunities that can make or break your database performance. This guide will walk you through the complete installation process, cover essential configuration tweaks, troubleshoot common issues, and show you how to get PostgreSQL running optimally on Ubuntu 24.

How PostgreSQL Works on Ubuntu 24

PostgreSQL operates as a client-server database system where the server process manages database files, accepts connections, and performs database actions on behalf of client applications. On Ubuntu 24, PostgreSQL integrates seamlessly with systemd for service management, uses the standard APT package manager for installation and updates, and follows Linux filesystem hierarchy standards for data and configuration file placement.

The default Ubuntu installation creates a dedicated ‘postgres’ user account that owns all database processes and files. This security model ensures database operations run with minimal privileges while maintaining proper file permissions. PostgreSQL listens on port 5432 by default and can handle multiple concurrent connections through its multi-process architecture.

Ubuntu 24 ships with PostgreSQL packages that include automatic service startup, logrotate configuration, and integration with Ubuntu’s security updates. The package system handles dependencies, creates necessary directories, and sets up basic configuration files automatically.

Step-by-Step Installation Guide

Let’s start with the straightforward installation process. Ubuntu 24’s repositories include PostgreSQL packages, but you might want to use the official PostgreSQL APT repository for the latest versions.

Installing from Ubuntu Repositories

First, update your package list and install PostgreSQL:

sudo apt update
sudo apt install postgresql postgresql-contrib

The ‘postgresql-contrib’ package includes additional utilities and extensions that you’ll likely need later. Check the installation:

sudo systemctl status postgresql
psql --version

Installing from Official PostgreSQL Repository

For the latest PostgreSQL version (recommended for production), add the official repository:

# Install required packages
sudo apt install wget ca-certificates

# Add PostgreSQL signing key
wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -

# Add repository
echo "deb http://apt.postgresql.org/pub/repos/apt/ $(lsb_release -cs)-pgdg main" | sudo tee /etc/apt/sources.list.d/pgdg.list

# Update and install
sudo apt update
sudo apt install postgresql-15 postgresql-contrib-15

Replace ’15’ with your desired version number. PostgreSQL maintains several versions simultaneously, so you can be specific about which version to install.

Post-Installation Configuration

After installation, PostgreSQL creates a system user called ‘postgres’. Switch to this user to perform initial database operations:

sudo -i -u postgres
psql

You’re now in the PostgreSQL interactive terminal. Set a password for the postgres user:

ALTER USER postgres PASSWORD 'your_secure_password';
\q

Exit back to your regular user account:

exit

Essential Configuration

PostgreSQL’s main configuration files live in ‘/etc/postgresql/[version]/main/’ on Ubuntu. The two most important files are ‘postgresql.conf’ for server settings and ‘pg_hba.conf’ for authentication rules.

Basic PostgreSQL Configuration

Edit the main configuration file:

sudo nano /etc/postgresql/15/main/postgresql.conf

Key settings to modify for better performance:

# Connection settings
listen_addresses = 'localhost'  # Change to '*' for remote connections
port = 5432
max_connections = 100

# Memory settings (adjust based on your system)
shared_buffers = 256MB          # 25% of total RAM is a good starting point
effective_cache_size = 1GB      # 75% of total RAM
work_mem = 4MB                  # Memory per query operation
maintenance_work_mem = 64MB     # Memory for maintenance operations

# Write-ahead logging
wal_level = replica
max_wal_size = 1GB
min_wal_size = 80MB

# Logging
log_destination = 'stderr'
logging_collector = on
log_directory = '/var/log/postgresql'
log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log'
log_statement = 'error'         # Change to 'all' for debugging

Authentication Configuration

Configure client authentication by editing pg_hba.conf:

sudo nano /etc/postgresql/15/main/pg_hba.conf

The file controls who can connect and how they authenticate. Common configurations:

# Local connections
local   all             postgres                                peer
local   all             all                                     md5

# IPv4 local connections
host    all             all             127.0.0.1/32            md5

# IPv6 local connections  
host    all             all             ::1/128                 md5

# For remote connections (be careful with security)
host    all             all             192.168.1.0/24          md5

After making configuration changes, restart PostgreSQL:

sudo systemctl restart postgresql

Creating Databases and Users

Now let’s create a practical setup with a new database and user. Connect as the postgres user:

sudo -u postgres psql

Create a new database and user:

-- Create a new database
CREATE DATABASE myapp_production;

-- Create a new user with password
CREATE USER myapp_user WITH ENCRYPTED PASSWORD 'secure_password123';

-- Grant privileges
GRANT ALL PRIVILEGES ON DATABASE myapp_production TO myapp_user;

-- Grant schema privileges (PostgreSQL 15+)
\c myapp_production
GRANT ALL ON SCHEMA public TO myapp_user;
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO myapp_user;
GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO myapp_user;

-- Exit
\q

Test the new user connection:

psql -h localhost -U myapp_user -d myapp_production

Performance Optimization and Tuning

PostgreSQL performance depends heavily on proper configuration. Here’s a comparison of default vs. optimized settings for different system sizes:

Setting Default Small System (2GB RAM) Medium System (8GB RAM) Large System (32GB RAM)
shared_buffers 128MB 512MB 2GB 8GB
effective_cache_size 4GB 1.5GB 6GB 24GB
work_mem 4MB 8MB 16MB 32MB
maintenance_work_mem 64MB 128MB 512MB 2GB
max_connections 100 50 100 200

Use the pg_tune utility for automated configuration recommendations:

sudo apt install pgtune
pgtune -i /etc/postgresql/15/main/postgresql.conf -o postgresql.conf.tuned

Monitoring and Maintenance

Set up basic monitoring with these queries:

-- Check database sizes
SELECT 
    datname as database_name,
    pg_size_pretty(pg_database_size(datname)) as size
FROM pg_database
ORDER BY pg_database_size(datname) DESC;

-- Check active connections
SELECT 
    count(*) as active_connections,
    state,
    application_name
FROM pg_stat_activity 
WHERE state IS NOT NULL 
GROUP BY state, application_name;

-- Check slow queries (enable log_min_duration_statement first)
SELECT 
    query,
    mean_time,
    calls,
    total_time
FROM pg_stat_statements 
ORDER BY mean_time DESC 
LIMIT 10;

Common Issues and Troubleshooting

Here are the most frequent problems you’ll encounter and their solutions:

Connection Issues

Problem: “psql: error: connection to server on socket failed”

# Check if PostgreSQL is running
sudo systemctl status postgresql

# Check listening ports
sudo netstat -plunt | grep 5432

# Restart service if needed
sudo systemctl restart postgresql

# Check logs
sudo tail -f /var/log/postgresql/postgresql-15-main.log

Authentication Problems

Problem: “FATAL: password authentication failed”

  • Verify pg_hba.conf settings match your connection method
  • Ensure you’re using the correct username and password
  • Check if the database exists: sudo -u postgres psql -l
  • Reset postgres user password if necessary

Permission Errors

Problem: “ERROR: permission denied for schema public”

-- Connect as superuser and fix permissions
sudo -u postgres psql
\c your_database
GRANT ALL ON SCHEMA public TO your_user;
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO your_user;
GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO your_user;

Performance Issues

Problem: Slow query performance

# Enable query logging
sudo nano /etc/postgresql/15/main/postgresql.conf

# Add these lines:
log_min_duration_statement = 1000  # Log queries taking >1 second
log_statement = 'all'              # Log all statements (for debugging only)

# Restart PostgreSQL
sudo systemctl restart postgresql

# Analyze specific queries
sudo -u postgres psql your_database
EXPLAIN ANALYZE SELECT * FROM your_table WHERE condition;

Real-World Use Cases and Examples

Let’s look at practical applications where PostgreSQL on Ubuntu 24 excels:

Web Application Backend

PostgreSQL works excellently as a backend for web applications. Here’s a typical setup for a Django application:

# Create application-specific database
sudo -u postgres createdb webapp_production
sudo -u postgres createuser webapp_user

# Set up connection pooling with pgbouncer
sudo apt install pgbouncer

# Configure pgbouncer
sudo nano /etc/pgbouncer/pgbouncer.ini

# Add database configuration
[databases]
webapp_production = host=localhost port=5432 dbname=webapp_production

[pgbouncer]
listen_port = 6432
listen_addr = 127.0.0.1
auth_type = md5
auth_file = /etc/pgbouncer/userlist.txt
pool_mode = transaction
max_client_conn = 100
default_pool_size = 25

Analytics and Reporting

PostgreSQL’s advanced features make it perfect for analytics workloads:

-- Enable additional extensions for analytics
sudo -u postgres psql
CREATE EXTENSION IF NOT EXISTS pg_stat_statements;
CREATE EXTENSION IF NOT EXISTS btree_gin;
CREATE EXTENSION IF NOT EXISTS btree_gist;

-- Example analytics query with window functions
SELECT 
    date_trunc('day', created_at) as day,
    count(*) as daily_signups,
    avg(count(*)) OVER (ORDER BY date_trunc('day', created_at) 
                       ROWS 6 PRECEDING) as seven_day_avg
FROM users 
GROUP BY date_trunc('day', created_at)
ORDER BY day;

JSON Document Storage

PostgreSQL’s JSONB support makes it competitive with NoSQL databases:

-- Create table with JSONB column
CREATE TABLE products (
    id SERIAL PRIMARY KEY,
    name VARCHAR(255),
    metadata JSONB,
    created_at TIMESTAMP DEFAULT NOW()
);

-- Insert JSON data
INSERT INTO products (name, metadata) VALUES 
('Widget A', '{"color": "red", "size": "large", "tags": ["electronics", "gadget"]}'),
('Widget B', '{"color": "blue", "size": "small", "tags": ["tool", "utility"]}');

-- Query JSON data
SELECT name, metadata->'color' as color 
FROM products 
WHERE metadata @> '{"size": "large"}';

-- Create index on JSON field
CREATE INDEX idx_products_metadata ON products USING gin(metadata);

Comparing PostgreSQL with Alternatives

Here’s how PostgreSQL stacks up against other database options on Ubuntu:

Feature PostgreSQL MySQL SQLite MongoDB
ACID Compliance Full Full (InnoDB) Full Limited
JSON Support Native JSONB Basic JSON JSON1 extension Native
Full-text Search Built-in Basic FTS5 extension Text indexes
Replication Streaming, logical Master-slave, group None built-in Replica sets
Max DB Size Unlimited 256TB 281TB Unlimited
Concurrent Writers High High 1 High

Security Best Practices

Securing PostgreSQL on Ubuntu 24 requires attention to several areas:

Network Security

# Configure firewall
sudo ufw allow from 192.168.1.0/24 to any port 5432
sudo ufw enable

# Use SSL connections
sudo nano /etc/postgresql/15/main/postgresql.conf
# Enable SSL
ssl = on
ssl_cert_file = '/etc/ssl/certs/ssl-cert-snakeoil.pem'
ssl_key_file = '/etc/ssl/private/ssl-cert-snakeoil.key'

Authentication Security

# Use strong passwords and rotate regularly
ALTER USER postgres PASSWORD 'very_secure_password_123!';

# Limit connection attempts
# Add to postgresql.conf
authentication_timeout = 60s

# Use certificate authentication for high-security environments
# In pg_hba.conf:
hostssl all all 192.168.1.0/24 cert

File System Security

# Verify file permissions
ls -la /var/lib/postgresql/15/main/
# Should show postgres:postgres ownership

# Secure backup files
sudo chmod 600 /path/to/backup/files/*
sudo chown postgres:postgres /path/to/backup/files/*

Backup and Recovery

Implement a robust backup strategy from day one:

Logical Backups

# Create backup script
#!/bin/bash
BACKUP_DIR="/var/backups/postgresql"
DATE=$(date +%Y%m%d_%H%M%S)

# Create directory if it doesn't exist
mkdir -p $BACKUP_DIR

# Backup all databases
sudo -u postgres pg_dumpall > $BACKUP_DIR/all_databases_$DATE.sql

# Backup specific database
sudo -u postgres pg_dump myapp_production > $BACKUP_DIR/myapp_production_$DATE.sql

# Compress backups
gzip $BACKUP_DIR/*_$DATE.sql

# Remove backups older than 7 days
find $BACKUP_DIR -name "*.gz" -mtime +7 -delete

Physical Backups

# Set up continuous archiving
# In postgresql.conf:
wal_level = replica
archive_mode = on
archive_command = 'cp %p /var/lib/postgresql/wal_archive/%f'

# Create WAL archive directory
sudo mkdir -p /var/lib/postgresql/wal_archive
sudo chown postgres:postgres /var/lib/postgresql/wal_archive

# Restart PostgreSQL
sudo systemctl restart postgresql

Integration with Development Tools

PostgreSQL integrates well with popular development stacks on Ubuntu:

Python/Django Integration

# Install Python PostgreSQL adapter
pip install psycopg2-binary

# Django settings.py
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'myapp_production',
        'USER': 'myapp_user',
        'PASSWORD': 'your_password',
        'HOST': 'localhost',
        'PORT': '5432',
        'OPTIONS': {
            'connect_timeout': 60,
        }
    }
}

Node.js Integration

# Install pg module
npm install pg

# Connection example
const { Pool } = require('pg');

const pool = new Pool({
  user: 'myapp_user',
  host: 'localhost',
  database: 'myapp_production',
  password: 'your_password',
  port: 5432,
  max: 20,
  idleTimeoutMillis: 30000,
  connectionTimeoutMillis: 2000,
});

// Query example
async function getUsers() {
  const client = await pool.connect();
  try {
    const result = await client.query('SELECT * FROM users');
    return result.rows;
  } finally {
    client.release();
  }
}

PostgreSQL on Ubuntu 24 provides a rock-solid foundation for modern applications, offering enterprise-grade features with the flexibility of open-source software. The combination of Ubuntu’s stability, PostgreSQL’s advanced features, and proper configuration creates a database platform capable of handling everything from small web apps to large-scale analytics workloads. Regular maintenance, monitoring, and following security best practices will ensure your PostgreSQL installation remains performant and secure as your application grows.

For more detailed information, check the official PostgreSQL documentation and the Ubuntu PostgreSQL community guide.



This article incorporates information and material from various online sources. We acknowledge and appreciate the work of all original authors, publishers, and websites. While every effort has been made to appropriately credit the source material, any unintentional oversight or omission does not constitute a copyright infringement. All trademarks, logos, and images mentioned are the property of their respective owners. If you believe that any content used in this article infringes upon your copyright, please contact us immediately for review and prompt action.

This article is intended for informational and educational purposes only and does not infringe on the rights of the copyright owners. If any copyrighted material has been used without proper credit or in violation of copyright laws, it is unintentional and we will rectify it promptly upon notification. Please note that the republishing, redistribution, or reproduction of part or all of the contents in any form is prohibited without express written permission from the author and website owner. For permissions or further inquiries, please contact us.

Leave a reply

Your email address will not be published. Required fields are marked