# Hướng Dẫn Deploy: SQLite → PostgreSQL

## Tóm Tắt Các Bước

1. **Cài đặt PostgreSQL trên server**
2. **Cấu hình database trong settings.py**
3. **Cài đặt dependencies (psycopg2-binary)**
4. **Chạy migrations**
5. **Cập nhật Django settings cho production**
6. **Thu thập static files**
7. **Cấu hình environment variables**

---

## 1. Cài Đặt PostgreSQL Trên Server

### Trên Ubuntu/Linux:

```bash
# Cài PostgreSQL
sudo apt-get update
sudo apt-get install postgresql postgresql-contrib

# Khởi động service
sudo systemctl start postgresql
sudo systemctl enable postgresql

# Đăng nhập vào PostgreSQL
sudo -u postgres psql

# Tạo database và user
CREATE DATABASE bmc;
CREATE USER bmc_user WITH PASSWORD 'your_secure_password_here';
ALTER ROLE bmc_user SET client_encoding TO 'utf8';
ALTER ROLE bmc_user SET default_transaction_isolation TO 'read committed';
ALTER ROLE bmc_user SET default_transaction_deferrable TO on;
ALTER ROLE bmc_user SET default_transaction_deferrable TO on;
GRANT ALL PRIVILEGES ON DATABASE bmc TO bmc_user;
\q
```

### Trên Windows Server:

```
# Download from: https://www.postgresql.org/download/windows/
# Cài đặt và tạo database, user trong pgAdmin hoặc psql
```

---

## 2. Cập Nhật settings.py Để Dùng PostgreSQL

### File: `BMC/settings.py`

**TRƯỚC (SQLite):**
```python
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': BASE_DIR / 'db.sqlite3',
    }
}
```

**SAU (PostgreSQL):**
```python
# ✓ Sử dụng environment variables (an toàn hơn)
import os
from dotenv import load_dotenv

load_dotenv()

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': os.getenv('DATABASE_NAME', 'bmc'),
        'USER': os.getenv('DATABASE_USER', 'bmc_user'),
        'PASSWORD': os.getenv('DATABASE_PASSWORD', ''),
        'HOST': os.getenv('DATABASE_HOST', 'localhost'),
        'PORT': os.getenv('DATABASE_PORT', '5432'),
    }
}
```

---

## 3. Tạo File .env Cho Server

### File: `.env` (trên server, không push lên git)

```env
# Database
DATABASE_ENGINE=django.db.backends.postgresql
DATABASE_NAME=bmc
DATABASE_USER=bmc_user
DATABASE_PASSWORD=your_secure_password_here
DATABASE_HOST=localhost
DATABASE_PORT=5432

# Django
DEBUG=False
SECRET_KEY=your_production_secret_key_here_generate_new_one
ALLOWED_HOSTS=your-domain.com,www.your-domain.com,127.0.0.1

# Email (optional)
EMAIL_BACKEND=django.core.mail.backends.smtp.EmailBackend
EMAIL_HOST=smtp.gmail.com
EMAIL_PORT=587
EMAIL_USE_TLS=True
EMAIL_HOST_USER=your-email@gmail.com
EMAIL_HOST_PASSWORD=your-email-password

# Security
SECURE_SSL_REDIRECT=True
SESSION_COOKIE_SECURE=True
CSRF_COOKIE_SECURE=True
```

### Cập Nhật settings.py Để Dùng .env:

```python
# Thêm ở đầu file settings.py
import os
from pathlib import Path
from dotenv import load_dotenv

BASE_DIR = Path(__file__).resolve().parent.parent
load_dotenv(BASE_DIR / '.env')

# Sau đó sử dụng os.getenv() cho tất cả sensitive values

DEBUG = os.getenv('DEBUG', 'True') == 'True'
SECRET_KEY = os.getenv('SECRET_KEY', 'django-insecure-default-key')
ALLOWED_HOSTS = os.getenv('ALLOWED_HOSTS', 'localhost').split(',')

# Security Settings cho Production
if not DEBUG:
    SECURE_SSL_REDIRECT = True
    SESSION_COOKIE_SECURE = True
    CSRF_COOKIE_SECURE = True
    SECURE_BROWSER_XSS_FILTER = True
    SECURE_CONTENT_SECURITY_POLICY = {
        'default-src': ("'self'",),
    }
```

---

## 4. Cài Đặt Dependencies

### On Server:

```bash
# Điều hướng đến project
cd /path/to/website-bmc

# Tạo virtual environment (nếu chưa có)
python3 -m venv venv
source venv/bin/activate  # Linux/Mac
# hoặc
venv\Scripts\activate     # Windows

# Cài đặt requirements (psycopg2-binary sẽ được cài)
pip install -r requirements.txt

# Cài python-dotenv nếu chưa có
pip install python-dotenv
```

---

## 5. Chạy Migrations Trên Server

```bash
# Kích hoạt venv
source venv/bin/activate

# Chạy migrations để tạo tables trên PostgreSQL
python manage.py migrate

# Tạo superuser
python manage.py createsuperuser

# Thu thập static files
python manage.py collectstatic --noinput
```

---

## 6. Xử Lý Dữ Liệu (Nếu Cần Migrate Data)

### Option A: Đã Có Dữ Liệu Trên SQLite - Migrate Sang PostgreSQL

```bash
# Trên máy dev (còn SQLite)
python manage.py dumpdata > data.json

# Upload file data.json lên server

# Trên server (PostgreSQL)
python manage.py loaddata data.json
```

### Option B: Bắt Đầu Từ Trống (Recommended)

```bash
# Chỉ chạy migrations, không cần migrate dữ liệu cũ
python manage.py migrate
python manage.py createsuperuser
```

---

## 7. Cấu Hình Web Server

### Sử Dụng Gunicorn + Nginx

**Cài Gunicorn:**
```bash
pip install gunicorn
```

**Tạo systemd service** (`/etc/systemd/system/bmc.service`):

```ini
[Unit]
Description=BMC Django Application
After=network.target

[Service]
Type=notify
User=www-data
WorkingDirectory=/var/www/website-bmc
Environment="PATH=/var/www/website-bmc/venv/bin"
ExecStart=/var/www/website-bmc/venv/bin/gunicorn \
    --workers 3 \
    --bind unix:/var/www/website-bmc/bmc.sock \
    BMC.wsgi:application

[Install]
WantedBy=multi-user.target
```

**Khởi động service:**
```bash
sudo systemctl daemon-reload
sudo systemctl start bmc
sudo systemctl enable bmc
```

**Cấu hình Nginx** (`/etc/nginx/sites-available/bmc`):

```nginx
server {
    listen 80;
    server_name your-domain.com www.your-domain.com;

    location / {
        proxy_pass http://unix:/var/www/website-bmc/bmc.sock;
        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;
    }

    location /static/ {
        alias /var/www/website-bmc/staticfiles/;
    }

    location /media/ {
        alias /var/www/website-bmc/media/;
    }
}
```

**Kích hoạt Nginx config:**
```bash
sudo ln -s /etc/nginx/sites-available/bmc /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl restart nginx
```

---

## 8. Checklist Trước Deploy

### Database
- [ ] PostgreSQL cài đặt trên server
- [ ] Database và user được tạo
- [ ] Credentials lưu trong .env

### Django
- [ ] settings.py cấu hình đọc từ environment variables
- [ ] DEBUG = False
- [ ] SECRET_KEY được generate mới (unique cho production)
- [ ] ALLOWED_HOSTS cập nhật với domain thực tế
- [ ] requirements.txt chứa psycopg2-binary

### Files
- [ ] .env file trên server (KHÔNG push lên git)
- [ ] .gitignore chứa `.env`
- [ ] static files được collect

### Security
- [ ] SECURE_SSL_REDIRECT = True
- [ ] SESSION_COOKIE_SECURE = True
- [ ] CSRF_COOKIE_SECURE = True
- [ ] Firewall config đúng

### Migrations
- [ ] Tất cả migrations chạy thành công
- [ ] Superuser được tạo
- [ ] Database có dữ liệu cần thiết

---

## 9. Lệnh Deploy Nhanh (Cheat Sheet)

```bash
# Trên server, sau khi pull code

# 1. Kích hoạt virtual environment
source venv/bin/activate

# 2. Cài dependencies
pip install -r requirements.txt

# 3. Chạy migrations
python manage.py migrate

# 4. Thu thập static files
python manage.py collectstatic --noinput

# 5. Restart services
sudo systemctl restart bmc
sudo systemctl restart nginx

# 6. Kiểm tra logs
sudo journalctl -u bmc -f
```

---

## 10. Troubleshooting

### Lỗi: "psycopg2 not found"

```bash
pip install psycopg2-binary
# hoặc
pip install -r requirements.txt --upgrade
```

### Lỗi: "could not connect to server"

```bash
# Kiểm tra PostgreSQL chạy
sudo systemctl status postgresql

# Kiểm tra connection string trong .env
# Đảm bảo HOST, PORT, USER, PASSWORD đúng

# Test kết nối
psql -h localhost -U bmc_user -d bmc
```

### Lỗi: "Permission denied" khi collectstatic

```bash
# Đảm bảo thư mục staticfiles có write permission
chmod -R 755 staticfiles/
sudo chown -R www-data:www-data staticfiles/
```

### Lỗi: 502 Bad Gateway

```bash
# Kiểm tra Gunicorn logs
sudo journalctl -u bmc -n 50

# Kiểm tra socket file
ls -la bmc.sock

# Restart services
sudo systemctl restart bmc
sudo systemctl restart nginx
```

---

## 11. So Sánh SQLite vs PostgreSQL

| Khía Cạnh | SQLite | PostgreSQL |
|-----------|--------|-----------|
| **Dữ liệu** | File .sqlite3 | Server database |
| **Concurrent Users** | 1-2 | Unlimited |
| **Performance** | Chậm khi dữ liệu lớn | Nhanh, optimized |
| **Setup** | Không cần setup | Cần cài + config |
| **Backup** | Copy file | pg_dump |
| **Scaling** | Khó | Dễ |
| **Sử dụng** | Dev, Testing | Production |

---

## 12. Production Checklist Cuối Cùng

- [ ] Tất cả environment variables đã set
- [ ] Database backup được tạo
- [ ] Static files được collect
- [ ] Migrations chạy OK
- [ ] Superuser được tạo
- [ ] SSL/HTTPS cấu hình
- [ ] Domain DNS pointing đúng
- [ ] Logs được monitor
- [ ] Backup schedule được set up
- [ ] Uptime monitoring được cấu hình

---

## Tài Liệu Tham Khảo

- [Django Deployment Checklist](https://docs.djangoproject.com/en/4.0/howto/deployment/checklist/)
- [PostgreSQL Official Docs](https://www.postgresql.org/docs/)
- [Gunicorn Documentation](https://gunicorn.org/)
- [Nginx Django Guide](https://uwsgi-docs.readthedocs.io/en/latest/tutorials/Django_and_nginx.html)

---

**Tạo ngày**: April 18, 2026  
**Status**: ✅ Ready for Deploy
