# Cài PostgreSQL trên VPS: chọn cấu hình, tinh chỉnh và sao lưu

URL: https://cloudj.net/vi/blog/postgresql-vps-setup
Published: 2026-11-11 · Updated: 2026-11-11

> Hướng dẫn cài PostgreSQL trên VPS cho môi trường thật: chọn CPU dedicated và RAM, tinh chỉnh bộ nhớ, chỉ mở cổng cho IP ứng dụng và tự động sao lưu ra ngoài.

Cài PostgreSQL trên VPS thường là bước hạ tầng đầu tiên khi một dự án lớn dần và muốn tách database khỏi nền tảng managed hoặc khỏi chung máy với ứng dụng. Bạn có tài nguyên ổn định, toàn quyền cấu hình và cài extension, và đặt được database ngay cạnh ứng dụng. Đổi lại, bạn tự chịu trách nhiệm tinh chỉnh, bảo mật và sao lưu. Bài này đi qua từng việc theo đúng thứ tự bạn sẽ gặp, kèm lệnh cho Ubuntu để chạy trên một máy chủ mới.

## Trước khi thuê VPS: vài câu hỏi cần trả lời

Trả lời mấy câu này trước khi chọn cấu hình. Chúng quyết định nhiều hơn bất kỳ tham số tinh chỉnh nào.

- **Ứng dụng chạy ở đâu?** Đặt database cùng thành phố với máy chủ ứng dụng. Mỗi truy vấn đều phải trả giá cho một vòng đi về, và một trang chạy năm mươi truy vấn sẽ nhân con số đó lên năm mươi lần. [Hướng dẫn chọn vị trí đặt VPS](https://cloudj.net/vi/blog/vps-locations-guide) liệt kê đủ 14 quốc gia và các thành phố của Cloudj.
- **Dữ liệu "nóng" lớn cỡ nào?** Phần dữ liệu và index được truy cập thường xuyên nên nằm vừa trong RAM. Database lớn hơn RAM nhiều lần vẫn ổn nếu phần lớn là dữ liệu ít dùng.
- **Tải đều hay theo đợt?** Database rất kỵ tranh chấp CPU. Với tải truy vấn đều đặn, hãy chọn máy chủ **CPU dedicated**, tức có nhân CPU riêng. CPU shared chấp nhận được cho môi trường dev và công cụ nội bộ ít truy cập.
- **Bạn chấp nhận mất bao nhiêu dữ liệu?** Nếu câu trả lời là "vài phút", bạn cần lưu trữ WAL liên tục chứ không chỉ một bản dump mỗi đêm.

Điểm khởi đầu hợp lý cho một database production nhỏ là 2 vCPU dedicated và 4 đến 8 GB RAM, ổ đĩa đủ cho dữ liệu, index, WAL và phần tăng trưởng. Bạn có thể tăng CPU, RAM và mở rộng ổ đĩa sau trong console, nên không cần mua trước cấu hình của năm sau. Tham khảo [các lựa chọn máy chủ cloud](https://cloudj.net/vi/cloud-servers) để biết các loại CPU, và xem [giá hiện hành](https://cloudj.net/vi/pricing) theo từng vị trí.

## Cài PostgreSQL trên VPS Ubuntu

Kho gói của Ubuntu đã có sẵn một phiên bản được hỗ trợ. Nếu muốn bản major mới nhất, hãy dùng kho apt chính thức của PostgreSQL:

```bash
sudo apt update
sudo apt install -y postgresql-common
sudo /usr/share/postgresql-common/pgdg/apt.postgresql.org.sh
sudo apt install -y postgresql
```

Kiểm tra phiên bản và cluster đã cài:

```bash
pg_lsclusters
```

Kết quả hiển thị số phiên bản và thư mục dữ liệu. Các đường dẫn bên dưới dùng phiên bản 16; hãy thay bằng phiên bản của bạn. Tạo role và database cho ứng dụng:

```bash
sudo -u postgres createuser --pwprompt appuser
sudo -u postgres createdb --owner=appuser appdb
```

## Tinh chỉnh bộ nhớ theo cấu hình máy

Giá trị mặc định cố tình để rất dè dặt. Sửa file `/etc/postgresql/16/main/postgresql.conf` (hoặc thêm file vào thư mục `conf.d/`). Các giá trị dưới đây giả định máy 8 GB RAM chỉ chạy PostgreSQL:

```ini
shared_buffers = 2GB              # khoảng 25% RAM
effective_cache_size = 6GB        # khoảng 75% RAM; chỉ là gợi ý cho planner, không cấp phát thật
work_mem = 16MB                   # cho mỗi thao tác sort/hash trong mỗi truy vấn; để vừa phải
maintenance_work_mem = 512MB      # dùng cho VACUUM và tạo index
random_page_cost = 1.1            # ổ SSD
max_connections = 100
```

`work_mem` là tham số hay gây rắc rối nhất: một truy vấn phức tạp có thể dùng nó nhiều lần, và mỗi kết nối đều có thể chạy truy vấn như vậy. Nếu cần hàng trăm kết nối từ client, hãy đặt PgBouncer phía trước thay vì tăng `max_connections`. Khởi động lại và kiểm tra:

```bash
sudo systemctl restart postgresql
sudo -u postgres psql -c "SHOW shared_buffers;"
```

Bật ghi log truy vấn chậm để tinh chỉnh dựa trên số liệu thật:

```ini
log_min_duration_statement = 500ms
```

## Chỉ cho máy chủ ứng dụng kết nối

Đừng bao giờ để cổng 5432 mở ra Internet. Hãy kết hợp ba lớp bảo vệ.

Thứ nhất, chỉ định giao diện mạng mà PostgreSQL lắng nghe. Trong `postgresql.conf`:

```ini
listen_addresses = 'localhost,198.51.100.5'   # IP của chính máy chủ này
```

Thứ hai, chỉ cho phép đúng các client đã biết trong `/etc/postgresql/16/main/pg_hba.conf`, dùng mật khẩu SCRAM và TLS:

```text
hostssl  appdb  appuser  203.0.113.10/32  scram-sha-256
hostssl  appdb  appuser  203.0.113.11/32  scram-sha-256
```

Gói của Ubuntu tự tạo chứng chỉ tự ký và bật `ssl = on` sẵn; [tài liệu PostgreSQL về SSL](https://www.postgresql.org/docs/current/ssl-tcp.html) hướng dẫn cách thay bằng chứng chỉ của bạn.

Thứ ba, lọc ở firewall để chỉ máy chủ ứng dụng chạm được tới cổng:

```bash
sudo ufw allow OpenSSH
sudo ufw allow from 203.0.113.10 to any port 5432 proto tcp
sudo ufw allow from 203.0.113.11 to any port 5432 proto tcp
sudo ufw enable
sudo systemctl reload postgresql
```

Bài [cấu hình firewall UFW](https://cloudj.net/vi/blog/ufw-firewall-vps) giải thích thứ tự rule và cách tránh tự khóa mình ở ngoài.

## Sao lưu: hai lớp, cả hai đều nằm ngoài máy chủ

Bản sao lưu nằm cùng ổ đĩa với database chỉ là một bản copy, chưa phải bản sao lưu. Hãy chuẩn bị hai lớp.

### Dump logic bằng pg_dump

Đơn giản, chuyển được giữa các phiên bản, hợp với database nhỏ hoặc làm thêm một lớp an toàn trước khi migrate:

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

Khôi phục vào một database trống bằng `pg_restore -d appdb file.dump`. Đặt lịch bằng cron và chép file ra ngoài máy chủ.

### Lưu trữ liên tục bằng pgBackRest

Để khôi phục về một thời điểm bất kỳ, pgBackRest tạo bản sao lưu full và incremental, đồng thời đẩy WAL liên tục lên một bucket tương thích S3. Cài bằng `sudo apt install -y pgbackrest` rồi tạo file `/etc/pgbackrest.conf`:

```ini
[global]
repo1-type=s3
repo1-s3-endpoint=s3.example-storage.com
repo1-s3-bucket=db-backups
repo1-s3-region=eu-central
repo1-s3-key=ACCESS_KEY
repo1-s3-key-secret=SECRET_KEY
repo1-path=/pgbackrest
repo1-retention-full=2

[main]
pg1-path=/var/lib/postgresql/16/main
```

Bật lưu trữ WAL trong `postgresql.conf`, khởi động lại rồi tạo bản full đầu tiên:

```ini
archive_mode = on
archive_command = 'pgbackrest --stanza=main archive-push %p'
```

```bash
sudo systemctl restart postgresql
sudo -u postgres pgbackrest --stanza=main stanza-create
sudo -u postgres pgbackrest --stanza=main --type=full backup
sudo -u postgres pgbackrest --stanza=main info
```

Hãy chọn bucket ở vị trí khác với database. Cloudj có trang [object storage](https://cloudj.net/vi/object-storage) để bạn tham khảo; cấu hình trên dùng được với mọi dịch vụ tương thích S3.

### Thử khôi phục thật

Mỗi tháng một lần, tạo một máy chủ thuê theo giờ, khôi phục bản sao lưu mới nhất, chạy vài truy vấn kiểm tra rồi xóa máy. Máy chủ theo giờ bị tính tiền chừng nào còn tồn tại, nên xóa ngay sau khi thử sẽ giữ chi phí chỉ ở số giờ bạn đã dùng.

## Áp dụng vào bài toán thực tế

Hệ thống giao dịch là ví dụ điển hình: một bot ghi lại lệnh khớp và vị thế cần database nằm sát bot, không phải ở bên kia đại dương. Các bài về [bot giao dịch crypto ở Singapore](https://cloudj.net/vi/blog/crypto-trading-bot-vps-singapore), [VPS forex ở London](https://cloudj.net/vi/blog/forex-vps-london) và [VPS forex ở New York](https://cloudj.net/vi/blog/forex-vps-new-york) cho thấy vị trí máy chủ đi theo khối lượng công việc thế nào, và database cũng theo đúng logic đó.

## Câu hỏi thường gặp

### Nên dùng CPU shared hay dedicated cho PostgreSQL?

Dedicated cho production có tải đều, vì độ trễ truy vấn tăng khi phải tranh chấp CPU. Shared ổn cho dev, staging và công cụ nội bộ nhỏ.

### Database managed có tốt hơn PostgreSQL tự cài trên VPS không?

Dịch vụ managed lo phần vá lỗi, failover và sao lưu cho bạn. VPS cho bạn toàn quyền với phiên bản, extension và cấu hình, đổi lại bạn tự làm những việc đó. Nếu trong đội không ai nhận trách nhiệm sao lưu và nâng cấp, dịch vụ managed là lựa chọn an toàn hơn.

### Nên chạy pg_dump bao lâu một lần?

Mỗi ngày một lần là mức cơ bản phổ biến cho database nhỏ. Nếu không chấp nhận mất dữ liệu cả ngày, hãy thêm lưu trữ WAL liên tục bằng pgBackRest.

### Sau này nâng cấu hình máy được không?

Được. Bạn có thể tăng CPU, RAM và mở rộng ổ đĩa trong console. Hãy lên lịch một khoảng bảo trì ngắn cho lần khởi động lại.

## Khởi chạy máy chủ database của bạn

Đặt database cạnh ứng dụng, bắt đầu với CPU dedicated và đủ RAM cho dữ liệu nóng, rồi chứng minh bản sao lưu dùng được bằng một lần khôi phục thật. [Console Cloudj](https://app.cloudj.net) hiển thị giá chính xác cho từng cấu hình trước khi bạn triển khai, và bạn có thể nạp tiền vào số dư bằng chuyển khoản ngân hàng bằng VND.
