first commit
This commit is contained in:
952
AAPANEL_DEPLOYMENT.md
Normal file
952
AAPANEL_DEPLOYMENT.md
Normal file
@@ -0,0 +1,952 @@
|
||||
# IRT Bank Soal - AaPanel Deployment Guide
|
||||
|
||||
**Document Version:** 1.1
|
||||
**Date:** March 21, 2026
|
||||
**Project:** IRT-Powered Adaptive Question Bank System v1.2.0
|
||||
**Updated:** Clarified PostgreSQL setup using Databases > PgSQL menu
|
||||
|
||||
---
|
||||
|
||||
## Table of Contents
|
||||
|
||||
1. [Prerequisites](#1-prerequisites)
|
||||
2. [AaPanel Installation](#2-aapanel-installation)
|
||||
3. [Install Required Software via AaPanel](#3-install-required-software-via-aapanel)
|
||||
4. [PostgreSQL Setup](#4-postgresql-setup)
|
||||
5. [Python Manager Setup](#5-python-manager-setup)
|
||||
6. [Project Deployment](#6-project-deployment)
|
||||
7. [Environment Configuration](#7-environment-configuration)
|
||||
8. [Database Migration](#8-database-migration)
|
||||
9. [Running the Application](#9-running-the-application)
|
||||
10. [Nginx Reverse Proxy Configuration](#10-nginx-reverse-proxy-configuration)
|
||||
11. [SSL Configuration](#11-ssl-configuration)
|
||||
12. [Post-Deployment Verification](#12-post-deployment-verification)
|
||||
13. [Troubleshooting](#13-troubleshooting)
|
||||
|
||||
---
|
||||
|
||||
## 1. Prerequisites
|
||||
|
||||
### Server Requirements
|
||||
|
||||
| Requirement | Minimum | Recommended |
|
||||
|-------------|---------|-------------|
|
||||
| OS | Ubuntu 20.04 / CentOS 7+ | Ubuntu 22.04 LTS |
|
||||
| RAM | 2 GB | 4 GB+ |
|
||||
| Storage | 20 GB | 50 GB+ |
|
||||
| CPU | 1 vCPU | 2+ vCPU |
|
||||
|
||||
### Domain Requirements
|
||||
|
||||
- A domain name pointed to your server IP
|
||||
- Subdomain recommended (e.g., `api.yourdomain.com`)
|
||||
|
||||
---
|
||||
|
||||
## 2. AaPanel Installation
|
||||
|
||||
### Step 2.1: Install AaPanel
|
||||
|
||||
**For Ubuntu/Debian:**
|
||||
|
||||
```bash
|
||||
# Login to your server via SSH
|
||||
ssh root@your-server-ip
|
||||
|
||||
# Install AaPanel
|
||||
wget -O install.sh http://www.aapanel.com/script/install-ubuntu_6.0_en.sh && bash install.sh
|
||||
```
|
||||
|
||||
**For CentOS:**
|
||||
|
||||
```bash
|
||||
# Install AaPanel
|
||||
yum install -y wget && wget -O install.sh http://www.aapanel.com/script/install_6.0_en.sh && sh install.sh
|
||||
```
|
||||
|
||||
### Step 2.2: Access AaPanel
|
||||
|
||||
1. After installation completes, note the panel URL and credentials
|
||||
2. Access AaPanel via browser: `http://your-server-ip:8888`
|
||||
3. Login with provided credentials
|
||||
4. **Important:** Change default port and password after first login
|
||||
|
||||
---
|
||||
|
||||
## 3. Install Required Software via AaPanel
|
||||
|
||||
### Step 3.1: Install Nginx
|
||||
|
||||
1. In AaPanel, go to **App Store**
|
||||
2. Find **Nginx** and click **Install**
|
||||
3. Select version (recommended: 1.24+)
|
||||
4. Click **Submit** and wait for installation
|
||||
|
||||
### Step 3.2: Install Python Manager
|
||||
|
||||
1. Go to **App Store**
|
||||
2. Search for **Python Manager** (or **PM2 Manager**)
|
||||
3. Click **Install**
|
||||
|
||||
### Step 3.3: Install Redis (Optional, for Celery)
|
||||
|
||||
1. Go to **App Store**
|
||||
2. Find **Redis** and click **Install**
|
||||
3. Click **Submit**
|
||||
|
||||
---
|
||||
|
||||
## 4. PostgreSQL Setup
|
||||
|
||||
> **IMPORTANT:** Use **Databases > PgSQL** menu from AaPanel sidebar.
|
||||
>
|
||||
> This menu supports both:
|
||||
> - **Local server** - PostgreSQL installed on your AaPanel server
|
||||
> - **Remote server** - External PostgreSQL (Supabase, Neon, AWS RDS, etc.)
|
||||
|
||||
### Step 4.1: Choose Your Database Type
|
||||
|
||||
You have two options:
|
||||
|
||||
| Option | Description | Best For |
|
||||
|--------|-------------|----------|
|
||||
| **Remote Database** | External PostgreSQL service (Supabase, Neon, etc.) | Easy setup, managed, free tier available |
|
||||
| **Local Database** | PostgreSQL on your AaPanel server | Full control, no external dependency |
|
||||
|
||||
---
|
||||
|
||||
### Option A: Remote PostgreSQL Database (RECOMMENDED)
|
||||
|
||||
Use an external PostgreSQL service:
|
||||
- **Supabase** - https://supabase.com (free tier: 500MB)
|
||||
- **Neon** - https://neon.tech (free tier: 3GB)
|
||||
- **AWS RDS** - https://aws.amazon.com/rds/postgresql/
|
||||
- **DigitalOcean** - https://www.digitalocean.com/products/managed-databases-postgresql
|
||||
- **Railway** - https://railway.app
|
||||
|
||||
#### Step 4.A.1: Create Database on Provider
|
||||
|
||||
1. Sign up on your chosen provider
|
||||
2. Create a new PostgreSQL project/database
|
||||
3. Note down the connection details from dashboard:
|
||||
- **Host** (e.g., `db.xxxxx.supabase.co` or `ep-xxx.us-east-2.aws.neon.tech`)
|
||||
- **Port** (usually `5432`, Supabase uses `6543` for pooler)
|
||||
- **Database name** (e.g., `postgres` or `neondb`)
|
||||
- **Username** (e.g., `postgres.xxxxx`)
|
||||
- **Password**
|
||||
|
||||
#### Step 4.A.2: Add Remote Server to AaPanel PgSQL
|
||||
|
||||
1. In AaPanel, go to **Databases** > **PgSQL**
|
||||
2. Click **Remote DB** button
|
||||
3. Fill in the form:
|
||||
- **Server Name:** `my-remote-db` (any name you like)
|
||||
- **Server Address:** `db.xxxxx.supabase.co` (your host)
|
||||
- **Port:** `5432` or `6543` (check your provider)
|
||||
- **Root User:** `postgres` or your username
|
||||
- **Root Password:** your password
|
||||
4. Click **Submit**
|
||||
|
||||
#### Step 4.A.3: Sync Databases from Remote Server
|
||||
|
||||
1. After adding remote server, click **Get DB from server**
|
||||
2. Select your remote server from dropdown
|
||||
3. Click **Submit**
|
||||
4. Your remote databases will appear in the list
|
||||
|
||||
#### Step 4.A.4: Note Your Connection String
|
||||
|
||||
Your connection string format:
|
||||
```
|
||||
postgresql+asyncpg://username:password@host:port/database_name
|
||||
```
|
||||
|
||||
**Example (Supabase):**
|
||||
```
|
||||
postgresql+asyncpg://postgres.xxxxx:YourPassword@aws-0-ap-southeast-1.pooler.supabase.com:6543/postgres
|
||||
```
|
||||
|
||||
**Example (Neon):**
|
||||
```
|
||||
postgresql+asyncpg://neondb_owner:YourPassword@ep-xxxx.us-east-2.aws.neon.tech/neondb?sslmode=require
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Option B: Local PostgreSQL Database
|
||||
|
||||
Install PostgreSQL directly on your AaPanel server.
|
||||
|
||||
#### Step 4.B.1: Install PostgreSQL via Terminal
|
||||
|
||||
```bash
|
||||
# SSH into your server
|
||||
ssh root@your-server-ip
|
||||
|
||||
# Ubuntu/Debian
|
||||
apt update
|
||||
apt install -y postgresql postgresql-contrib
|
||||
|
||||
# Start and enable PostgreSQL
|
||||
systemctl start postgresql
|
||||
systemctl enable postgresql
|
||||
|
||||
# Check status
|
||||
systemctl status postgresql
|
||||
```
|
||||
|
||||
#### Step 4.B.2: Create Database and User via Terminal
|
||||
|
||||
```bash
|
||||
# Switch to postgres user
|
||||
su - postgres
|
||||
|
||||
# Enter PostgreSQL CLI
|
||||
psql
|
||||
|
||||
# Run SQL commands:
|
||||
CREATE DATABASE irt_bank_soal;
|
||||
|
||||
CREATE USER irt_user WITH ENCRYPTED PASSWORD 'your_secure_password_here';
|
||||
|
||||
GRANT ALL PRIVILEGES ON DATABASE irt_bank_soal TO irt_user;
|
||||
|
||||
# Connect to database and grant schema
|
||||
\c irt_bank_soal
|
||||
GRANT ALL ON SCHEMA public TO irt_user;
|
||||
|
||||
# Exit
|
||||
\q
|
||||
exit
|
||||
```
|
||||
|
||||
#### Step 4.B.3: Add Local Server to AaPanel PgSQL
|
||||
|
||||
1. In AaPanel, go to **Databases** > **PgSQL**
|
||||
2. Click **Root Password** to view/change postgres password
|
||||
3. If your local PostgreSQL is not showing, click **Get DB from server**
|
||||
4. Select **Local server**
|
||||
5. Click **Submit**
|
||||
|
||||
#### Step 4.B.4: Create Additional Database via AaPanel (Optional)
|
||||
|
||||
1. In **Databases** > **PgSQL**
|
||||
2. Click **Add DB**
|
||||
3. Fill in:
|
||||
- **Database name:** `irt_bank_soal`
|
||||
- **Username:** `irt_user` (or same as DB name)
|
||||
- **Password:** (click generate or enter custom)
|
||||
- **Add to:** `Local server`
|
||||
4. Click **Submit**
|
||||
|
||||
#### Step 4.B.5: Note Your Connection String
|
||||
|
||||
```
|
||||
postgresql+asyncpg://irt_user:your_password@127.0.0.1:5432/irt_bank_soal
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4.1 Test Database Connection
|
||||
|
||||
Before proceeding, verify your database connection works.
|
||||
|
||||
### For Remote Database:
|
||||
|
||||
```bash
|
||||
# Install psql client if needed
|
||||
apt install -y postgresql-client
|
||||
|
||||
# Test connection (replace with your details)
|
||||
psql "postgresql://username:password@host:port/database_name" -c "SELECT version();"
|
||||
```
|
||||
|
||||
### For Local Database:
|
||||
|
||||
```bash
|
||||
# Test connection
|
||||
psql -U irt_user -d irt_bank_soal -h 127.0.0.1 -c "SELECT version();"
|
||||
|
||||
# If prompted for password, enter it
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4.2 Connection String Quick Reference
|
||||
|
||||
| Database Type | Connection String Format |
|
||||
|---------------|-------------------------|
|
||||
| **Remote (Supabase)** | `postgresql+asyncpg://postgres.xxxx:password@aws-0-region.pooler.supabase.com:6543/postgres` |
|
||||
| **Remote (Neon)** | `postgresql+asyncpg://user:password@ep-xxxx.region.aws.neon.tech/neondb?sslmode=require` |
|
||||
| **Local** | `postgresql+asyncpg://irt_user:password@127.0.0.1:5432/irt_bank_soal` |
|
||||
|
||||
> **Note:** We use `postgresql+asyncpg://` because our app uses async SQLAlchemy with `asyncpg` driver.
|
||||
|
||||
---
|
||||
|
||||
## 5. Python Manager Setup
|
||||
|
||||
### Step 5.1: Open Python Manager
|
||||
|
||||
1. In AaPanel, go to **App Store**
|
||||
2. Find **Python Manager** and click **Settings**
|
||||
|
||||
### Step 5.2: Install Python Version
|
||||
|
||||
1. Click **Version Management**
|
||||
2. Select **Python 3.11** (or latest stable)
|
||||
3. Click **Install**
|
||||
4. Wait for installation to complete
|
||||
|
||||
---
|
||||
|
||||
## 6. Project Deployment
|
||||
|
||||
### Step 6.1: Create Project Directory
|
||||
|
||||
```bash
|
||||
# Create project directory
|
||||
mkdir -p /www/wwwroot/irt-bank-soal
|
||||
|
||||
# Navigate to directory
|
||||
cd /www/wwwroot/irt-bank-soal
|
||||
```
|
||||
|
||||
### Step 6.2: Upload Project Files
|
||||
|
||||
**Option A: Upload via File Manager**
|
||||
|
||||
1. In AaPanel, go to **Files**
|
||||
2. Navigate to `/www/wwwroot/irt-bank-soal`
|
||||
3. Upload your project ZIP file
|
||||
4. Extract the archive
|
||||
|
||||
**Option B: Clone from Git (if applicable)**
|
||||
|
||||
```bash
|
||||
cd /www/wwwroot/irt-bank-soal
|
||||
|
||||
# If using Git
|
||||
git clone https://github.com/your-repo/irt-bank-soal.git .
|
||||
|
||||
# Or copy from local
|
||||
# scp -r /Users/dwindown/Applications/tryout-system/* root@your-server-ip:/www/wwwroot/irt-bank-soal/
|
||||
```
|
||||
|
||||
### Step 6.3: Verify Project Structure
|
||||
|
||||
```bash
|
||||
# Expected structure:
|
||||
ls -la /www/wwwroot/irt-bank-soal/
|
||||
# app/
|
||||
# app/models/
|
||||
# app/routers/
|
||||
# app/services/
|
||||
# app/core/
|
||||
# tests/
|
||||
# requirements.txt
|
||||
# .env.example
|
||||
# alembic/
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. Environment Configuration
|
||||
|
||||
### Step 7.1: Create Virtual Environment via Python Manager
|
||||
|
||||
1. In AaPanel **Python Manager**, click **Add Project**
|
||||
2. Configure:
|
||||
- **Project Name:** `irt-bank-soal`
|
||||
- **Project Path:** `/www/wwwroot/irt-bank-soal`
|
||||
- **Python Version:** `Python 3.11`
|
||||
- **Framework:** `FastAPI`
|
||||
- **Startup Method:** `uvicorn`
|
||||
3. Click **Submit**
|
||||
|
||||
### Step 7.2: Create Environment File
|
||||
|
||||
```bash
|
||||
# Copy example file
|
||||
cp /www/wwwroot/irt-bank-soal/.env.example /www/wwwroot/irt-bank-soal/.env
|
||||
|
||||
# Edit .env file
|
||||
nano /www/wwwroot/irt-bank-soal/.env
|
||||
```
|
||||
|
||||
### Step 7.3: Configure .env File
|
||||
|
||||
```env
|
||||
# Database Configuration
|
||||
# For Remote Database (Supabase example):
|
||||
# DATABASE_URL=postgresql+asyncpg://postgres.xxxx:password@aws-0-ap-southeast-1.pooler.supabase.com:6543/postgres
|
||||
# For Remote Database (Neon example):
|
||||
# DATABASE_URL=postgresql+asyncpg://neondb_owner:password@ep-xxxx.us-east-2.aws.neon.tech/neondb?sslmode=require
|
||||
# For Local Database:
|
||||
DATABASE_URL=postgresql+asyncpg://irt_user:your_secure_password_here@127.0.0.1:5432/irt_bank_soal
|
||||
|
||||
# Security
|
||||
SECRET_KEY=your-production-secret-key-min-32-characters-random-string
|
||||
|
||||
# Environment
|
||||
ENVIRONMENT=production
|
||||
DEBUG=false
|
||||
|
||||
# API Configuration
|
||||
API_V1_STR=/api/v1
|
||||
PROJECT_NAME=IRT Bank Soal
|
||||
PROJECT_VERSION=1.2.0
|
||||
|
||||
# CORS - Add your WordPress domains
|
||||
ALLOWED_ORIGINS=https://yourdomain.com,https://www.yourdomain.com
|
||||
|
||||
# OpenRouter API (for AI Generation)
|
||||
OPENROUTER_API_KEY=your-openrouter-api-key-here
|
||||
OPENROUTER_API_URL=https://openrouter.ai/api/v1
|
||||
OPENROUTER_MODEL_QWEN=qwen/qwen-2.5-coder-32b-instruct
|
||||
OPENROUTER_MODEL_LLAMA=meta-llama/llama-3.3-70b-instruct
|
||||
OPENROUTER_TIMEOUT=60
|
||||
|
||||
# WordPress Integration
|
||||
WORDPRESS_API_URL=https://yourdomain.com/wp-json
|
||||
WORDPRESS_AUTH_TOKEN=your-wordpress-jwt-token
|
||||
|
||||
# Redis (for Celery task queue)
|
||||
REDIS_URL=redis://127.0.0.1:6379/0
|
||||
|
||||
# Admin Panel
|
||||
ADMIN_USER=admin
|
||||
ADMIN_PASSWORD=your-secure-admin-password
|
||||
|
||||
# Normalization Defaults
|
||||
DEFAULT_RATAAN=500
|
||||
DEFAULT_SB=100
|
||||
MIN_SAMPLE_FOR_DYNAMIC=100
|
||||
```
|
||||
|
||||
### Step 7.4: Generate Secret Key
|
||||
|
||||
```bash
|
||||
# Generate a secure secret key
|
||||
python3 -c "import secrets; print(secrets.token_urlsafe(32))"
|
||||
|
||||
# Copy the output and paste into SECRET_KEY in .env
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. Database Migration
|
||||
|
||||
### Step 8.1: Activate Virtual Environment
|
||||
|
||||
```bash
|
||||
# Via Python Manager, the venv is usually at:
|
||||
source /www/wwwroot/irt-bank-soal/venv/bin/activate
|
||||
|
||||
# Or check Python Manager for exact venv path
|
||||
```
|
||||
|
||||
### Step 8.2: Install Dependencies
|
||||
|
||||
```bash
|
||||
# Ensure you're in project directory
|
||||
cd /www/wwwroot/irt-bank-soal
|
||||
|
||||
# Install dependencies
|
||||
pip install -r requirements.txt
|
||||
|
||||
# Verify installation
|
||||
pip list | grep -E "fastapi|sqlalchemy|numpy|scipy|httpx|openpyxl"
|
||||
```
|
||||
|
||||
### Step 8.3: Initialize Alembic (First Time Setup)
|
||||
|
||||
```bash
|
||||
# Initialize Alembic if not already done
|
||||
alembic init alembic
|
||||
|
||||
# Generate initial migration
|
||||
alembic revision --autogenerate -m "Initial migration"
|
||||
|
||||
# Apply migration
|
||||
alembic upgrade head
|
||||
```
|
||||
|
||||
### Step 8.4: Verify Database Tables
|
||||
|
||||
```bash
|
||||
# Check tables were created
|
||||
psql -U irt_user -d irt_bank_soal -h 127.0.0.1 -c "\dt"
|
||||
|
||||
# Expected output: websites, users, tryouts, items, sessions, user_answers, tryout_stats
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 9. Running the Application
|
||||
|
||||
### Step 9.1: Configure Python Project in AaPanel
|
||||
|
||||
1. In **Python Manager**, find your project `irt-bank-soal`
|
||||
2. Click **Settings**
|
||||
3. Configure startup:
|
||||
- **Startup File:** `app/main.py`
|
||||
- **Startup Method:** `uvicorn`
|
||||
- **Port:** `8000`
|
||||
- **Modules:** `uvicorn[standard]`
|
||||
|
||||
### Step 9.2: Set Startup Command
|
||||
|
||||
In Python Manager settings, set the startup command:
|
||||
|
||||
```bash
|
||||
# Startup command
|
||||
uvicorn app.main:app --host 127.0.0.1 --port 8000 --workers 4
|
||||
|
||||
# Or for development:
|
||||
uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload
|
||||
```
|
||||
|
||||
### Step 9.3: Start the Application
|
||||
|
||||
1. In Python Manager, click **Start** on your project
|
||||
2. Check logs for any errors
|
||||
3. Verify the application is running:
|
||||
|
||||
```bash
|
||||
# Test health endpoint
|
||||
curl http://127.0.0.1:8000/
|
||||
|
||||
# Expected response:
|
||||
# {"status": "healthy", "project_name": "IRT Bank Soal", "version": "1.2.0"}
|
||||
```
|
||||
|
||||
### Step 9.4: Configure Auto-Start on Boot
|
||||
|
||||
1. In Python Manager, enable **Auto-start on boot**
|
||||
2. Or manually via terminal:
|
||||
|
||||
```bash
|
||||
# Using systemd (create service file)
|
||||
nano /etc/systemd/system/irt-bank-soal.service
|
||||
```
|
||||
|
||||
```ini
|
||||
[Unit]
|
||||
Description=IRT Bank Soal FastAPI Application
|
||||
After=network.target
|
||||
# Uncomment below if using LOCAL PostgreSQL:
|
||||
# After=network.target postgresql.service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=www
|
||||
Group=www
|
||||
WorkingDirectory=/www/wwwroot/irt-bank-soal
|
||||
Environment="PATH=/www/wwwroot/irt-bank-soal/venv/bin"
|
||||
ExecStart=/www/wwwroot/irt-bank-soal/venv/bin/uvicorn app.main:app --host 127.0.0.1 --port 8000 --workers 4
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
|
||||
```bash
|
||||
# Enable and start service
|
||||
systemctl daemon-reload
|
||||
systemctl enable irt-bank-soal
|
||||
systemctl start irt-bank-soal
|
||||
systemctl status irt-bank-soal
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 10. Nginx Reverse Proxy Configuration
|
||||
|
||||
### Step 10.1: Create Website in AaPanel
|
||||
|
||||
1. In AaPanel, go to **Website**
|
||||
2. Click **Add Site**
|
||||
3. Configure:
|
||||
- **Domain:** `api.yourdomain.com` (or your subdomain)
|
||||
- **PHP Version:** Pure Static (not needed)
|
||||
- **Database:** None (already created)
|
||||
4. Click **Submit**
|
||||
|
||||
### Step 10.2: Configure Reverse Proxy
|
||||
|
||||
1. Click **Settings** on the newly created website
|
||||
2. Go to **Reverse Proxy**
|
||||
3. Click **Add Reverse Proxy**
|
||||
4. Configure:
|
||||
- **Proxy Name:** `irt-api`
|
||||
- **Target URL:** `http://127.0.0.1:8000`
|
||||
5. Click **Submit**
|
||||
|
||||
### Step 10.3: Manual Nginx Configuration (Alternative)
|
||||
|
||||
```bash
|
||||
# Edit Nginx config
|
||||
nano /www/server/panel/vhost/nginx/api.yourdomain.com.conf
|
||||
```
|
||||
|
||||
```nginx
|
||||
server {
|
||||
listen 80;
|
||||
server_name api.yourdomain.com;
|
||||
|
||||
# Access and error logs
|
||||
access_log /www/wwwlogs/api.yourdomain.com.log;
|
||||
error_log /www/wwwlogs/api.yourdomain.com.error.log;
|
||||
|
||||
# Client body size (for Excel uploads)
|
||||
client_max_body_size 50M;
|
||||
|
||||
# Proxy to FastAPI
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:8000;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
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_connect_timeout 60s;
|
||||
proxy_send_timeout 60s;
|
||||
proxy_read_timeout 60s;
|
||||
}
|
||||
|
||||
# Static files (if any)
|
||||
location /static/ {
|
||||
alias /www/wwwroot/irt-bank-soal/static/;
|
||||
expires 30d;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Step 10.4: Test and Reload Nginx
|
||||
|
||||
```bash
|
||||
# Test Nginx configuration
|
||||
nginx -t
|
||||
|
||||
# Reload Nginx
|
||||
nginx -s reload
|
||||
|
||||
# Or via AaPanel: Website > Settings > Config > Save
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 11. SSL Configuration
|
||||
|
||||
### Step 11.1: Install SSL Certificate
|
||||
|
||||
1. In AaPanel, go to **Website**
|
||||
2. Click **Settings** on your site
|
||||
3. Go to **SSL**
|
||||
4. Choose method:
|
||||
- **Let's Encrypt:** Free, auto-renewal
|
||||
- **Own Certificate:** Upload your own
|
||||
- **Buy:** Purchase through AaPanel
|
||||
|
||||
### Step 11.2: Configure Let's Encrypt
|
||||
|
||||
1. Click **Let's Encrypt**
|
||||
2. Enter your email
|
||||
3. Select domain `api.yourdomain.com`
|
||||
4. Click **Apply**
|
||||
5. Enable **Force HTTPS**
|
||||
|
||||
### Step 11.3: Update .env for HTTPS
|
||||
|
||||
```bash
|
||||
# Edit .env
|
||||
nano /www/wwwroot/irt-bank-soal/.env
|
||||
|
||||
# Update CORS to use HTTPS
|
||||
ALLOWED_ORIGINS=https://yourdomain.com,https://www.yourdomain.com
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 12. Post-Deployment Verification
|
||||
|
||||
### Step 12.1: Test API Endpoints
|
||||
|
||||
```bash
|
||||
# Test health endpoint
|
||||
curl https://api.yourdomain.com/
|
||||
|
||||
# Test detailed health
|
||||
curl https://api.yourdomain.com/health
|
||||
|
||||
# Test API documentation
|
||||
# Open in browser: https://api.yourdomain.com/docs
|
||||
```
|
||||
|
||||
### Step 12.2: Test Database Connection
|
||||
|
||||
```bash
|
||||
# Via API
|
||||
curl https://api.yourdomain.com/health
|
||||
|
||||
# Expected response includes database status:
|
||||
# {"status": "healthy", "database": "connected", "api_version": "v1"}
|
||||
```
|
||||
|
||||
### Step 12.3: Test Admin Panel
|
||||
|
||||
```bash
|
||||
# Access admin panel
|
||||
# Open in browser: https://api.yourdomain.com/admin
|
||||
# Login with credentials from .env
|
||||
```
|
||||
|
||||
### Step 12.4: Load Test Data (Optional)
|
||||
|
||||
```bash
|
||||
# SSH into server
|
||||
ssh root@your-server-ip
|
||||
|
||||
# Navigate to project
|
||||
cd /www/wwwroot/irt-bank-soal
|
||||
|
||||
# Activate venv
|
||||
source venv/bin/activate
|
||||
|
||||
# Run test data script
|
||||
python3 -c "
|
||||
import asyncio
|
||||
from app.database import init_db
|
||||
asyncio.run(init_db())
|
||||
print('Database initialized successfully')
|
||||
"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 13. Troubleshooting
|
||||
|
||||
### Issue: Python Manager Not Starting Application
|
||||
|
||||
**Solution:**
|
||||
|
||||
```bash
|
||||
# Check logs
|
||||
tail -f /www/wwwroot/irt-bank-soal/logs/error.log
|
||||
|
||||
# Check if port is in use
|
||||
lsof -i :8000
|
||||
|
||||
# Manually test startup
|
||||
cd /www/wwwroot/irt-bank-soal
|
||||
source venv/bin/activate
|
||||
uvicorn app.main:app --host 127.0.0.1 --port 8000
|
||||
```
|
||||
|
||||
### Issue: Database Connection Failed
|
||||
|
||||
**For Remote Database:**
|
||||
|
||||
```bash
|
||||
# Test connection from server
|
||||
apt install -y postgresql-client
|
||||
psql "postgresql://username:password@remote-host:port/database" -c "SELECT 1;"
|
||||
|
||||
# Check if firewall allows outbound connection
|
||||
# Most remote DBs use port 5432 or 6543
|
||||
|
||||
# Verify DATABASE_URL in .env
|
||||
cat /www/wwwroot/irt-bank-soal/.env | grep DATABASE_URL
|
||||
|
||||
# Common issues:
|
||||
# - Wrong port (Supabase pooler uses 6543, direct uses 5432)
|
||||
# - Missing sslmode=require (Neon requires this)
|
||||
# - IP not whitelisted (check provider dashboard)
|
||||
```
|
||||
|
||||
**For Local Database:**
|
||||
|
||||
```bash
|
||||
# Check PostgreSQL status
|
||||
systemctl status postgresql
|
||||
|
||||
# Test connection manually
|
||||
psql -U irt_user -d irt_bank_soal -h 127.0.0.1 -W
|
||||
|
||||
# Check pg_hba.conf allows connections
|
||||
cat /etc/postgresql/*/main/pg_hba.conf | grep -v "^#" | grep -v "^$"
|
||||
|
||||
# Verify DATABASE_URL in .env
|
||||
cat /www/wwwroot/irt-bank-soal/.env | grep DATABASE_URL
|
||||
```
|
||||
|
||||
### Issue: 502 Bad Gateway
|
||||
|
||||
**Solution:**
|
||||
|
||||
```bash
|
||||
# Check if FastAPI is running
|
||||
ps aux | grep uvicorn
|
||||
|
||||
# Check Nginx error logs
|
||||
tail -f /www/wwwlogs/api.yourdomain.com.error.log
|
||||
|
||||
# Verify proxy configuration
|
||||
cat /www/server/panel/vhost/nginx/api.yourdomain.com.conf | grep proxy_pass
|
||||
```
|
||||
|
||||
### Issue: CORS Errors
|
||||
|
||||
**Solution:**
|
||||
|
||||
```bash
|
||||
# Check ALLOWED_ORIGINS in .env
|
||||
cat /www/wwwroot/irt-bank-soal/.env | grep ALLOWED_ORIGINS
|
||||
|
||||
# Ensure WordPress domain is included
|
||||
# Example: ALLOWED_ORIGINS=https://site1.com,https://site2.com
|
||||
|
||||
# Restart application after changes
|
||||
# Via Python Manager: Stop > Start
|
||||
```
|
||||
|
||||
### Issue: SSL Certificate Not Working
|
||||
|
||||
**Solution:**
|
||||
|
||||
```bash
|
||||
# Check certificate
|
||||
openssl s_client -connect api.yourdomain.com:443
|
||||
|
||||
# Force HTTPS in Nginx config
|
||||
# Add to server block:
|
||||
# return 301 https://$host$request_uri;
|
||||
|
||||
# Reload Nginx
|
||||
nginx -s reload
|
||||
```
|
||||
|
||||
### Issue: Large File Upload Failed
|
||||
|
||||
**Solution:**
|
||||
|
||||
```bash
|
||||
# Increase Nginx client body size
|
||||
nano /www/server/panel/vhost/nginx/api.yourdomain.com.conf
|
||||
|
||||
# Add/modify:
|
||||
# client_max_body_size 100M;
|
||||
|
||||
# Also check PHP settings if using PHP
|
||||
# In AaPanel: PHP > Settings > Upload Max Filesize
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Quick Reference Commands
|
||||
|
||||
```bash
|
||||
# Application Management
|
||||
systemctl start irt-bank-soal
|
||||
systemctl stop irt-bank-soal
|
||||
systemctl restart irt-bank-soal
|
||||
systemctl status irt-bank-soal
|
||||
|
||||
# Local Database Management (if using local PostgreSQL)
|
||||
systemctl start postgresql
|
||||
systemctl stop postgresql
|
||||
systemctl restart postgresql
|
||||
systemctl status postgresql
|
||||
|
||||
# Nginx Management
|
||||
nginx -t # Test config
|
||||
nginx -s reload # Reload config
|
||||
systemctl restart nginx # Restart Nginx
|
||||
|
||||
# View Logs
|
||||
tail -f /www/wwwlogs/api.yourdomain.com.log
|
||||
tail -f /www/wwwlogs/api.yourdomain.com.error.log
|
||||
|
||||
# Application Logs (if configured)
|
||||
tail -f /www/wwwroot/irt-bank-soal/logs/app.log
|
||||
|
||||
# Test Database Connection
|
||||
# Local:
|
||||
psql -U irt_user -d irt_bank_soal -h 127.0.0.1 -c "SELECT version();"
|
||||
# Remote:
|
||||
psql "postgresql://user:pass@host:port/db" -c "SELECT version();"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Security Checklist
|
||||
|
||||
- [ ] Changed AaPanel default port and password
|
||||
- [ ] Database user has strong password
|
||||
- [ ] SECRET_KEY is unique and 32+ characters
|
||||
- [ ] SSL certificate installed and forced HTTPS
|
||||
- [ ] CORS restricted to production domains only
|
||||
- [ ] Firewall configured (only 80, 443, 22, 8888 open)
|
||||
- [ ] Admin password is strong
|
||||
- [ ] For local DB: PostgreSQL not exposed to internet
|
||||
- [ ] For remote DB: IP whitelist configured (if supported)
|
||||
- [ ] Regular backups configured
|
||||
|
||||
---
|
||||
|
||||
## Backup Configuration
|
||||
|
||||
### Database Backup
|
||||
|
||||
**For Local Database:**
|
||||
|
||||
```bash
|
||||
# Create backup directory
|
||||
mkdir -p /www/backup
|
||||
|
||||
# Manual backup
|
||||
pg_dump -U irt_user -h 127.0.0.1 irt_bank_soal > /www/backup/irt_bank_soal_$(date +%Y%m%d).sql
|
||||
|
||||
# Automated backup (cron)
|
||||
crontab -e
|
||||
# Add: 0 2 * * * pg_dump -U irt_user -h 127.0.0.1 irt_bank_soal > /www/backup/irt_bank_soal_$(date +\%Y\%m\%d).sql
|
||||
```
|
||||
|
||||
**For Remote Database:**
|
||||
|
||||
Most managed PostgreSQL providers have built-in backup features:
|
||||
- **Supabase:** Dashboard > Database > Backups (daily automatic)
|
||||
- **Neon:** Automatic point-in-time recovery
|
||||
- **AWS RDS:** Automated backups with retention period
|
||||
|
||||
You can also backup manually:
|
||||
|
||||
```bash
|
||||
# Manual backup from remote (requires postgresql-client)
|
||||
pg_dump "postgresql://username:password@host:port/database" > /www/backup/irt_bank_soal_$(date +%Y%m%d).sql
|
||||
|
||||
# Or with SSL for providers like Neon
|
||||
pg_dump "postgresql://username:password@host:port/database?sslmode=require" > /www/backup/irt_bank_soal_$(date +%Y%m%d).sql
|
||||
```
|
||||
|
||||
### Project Backup
|
||||
|
||||
```bash
|
||||
# Backup project files
|
||||
tar -czvf /www/backup/irt_project_$(date +%Y%m%d).tar.gz /www/wwwroot/irt-bank-soal
|
||||
|
||||
# Exclude venv to save space
|
||||
tar -czvf /www/backup/irt_project_$(date +%Y%m%d).tar.gz --exclude='venv' /www/wwwroot/irt-bank-soal
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**Document End**
|
||||
|
||||
**Status:** Ready for Deployment
|
||||
|
||||
**Support:** Refer to TEST.md for testing procedures and PRD.md for requirements.
|
||||
Reference in New Issue
Block a user