# Cpanel

> Skill untuk deployment dan manajemen hosting via cPanel/WHM. TRIGGER ketika: user minta deploy ke shared hosting, setup domain/subdomain di cPanel, konfigurasi SSL, email hosting, database MySQL via phpMyAdmin, file manager, cron job, .htaccess, PHP version, backup, DNS zone, addon domain, atau troubleshoot error 500/403/404 di hosting. Juga trigger saat: public_html, cPanel login, WHM, Softaculous, atau shared hosting.

- Skill: `edorabma9304/cpanel` (Agent Skill)
- Install (CLI): `npx skillmds@latest add edorabma9304/cpanel`
- Raw SKILL.md: https://api.skillmd.com/api/skills/edorabma9304/cpanel/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: DevOps & Infra
- Author: edorabma9304 (https://skillmd.com/u/edorabma9304)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/edorabma9304/cpanel

---


# cPanel Hosting Skill

Skill untuk deployment, konfigurasi, dan manajemen aplikasi di shared hosting berbasis cPanel.

---

## Deploy Aplikasi ke cPanel

### React/Vite (Static SPA)

#### Langkah-langkah
```bash
# 1. Build di lokal
npm run build

# 2. Upload isi folder dist/ ke public_html/ via:
#    - File Manager di cPanel
#    - FTP (FileZilla, Cyberduck)
#    - SSH (jika tersedia)
#    - Git (jika hosting support)
```

#### .htaccess untuk SPA (React Router)
Buat file `.htaccess` di `public_html/`:
```apache
<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteBase /

  # Jangan rewrite file & folder yang ada
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d

  # Redirect semua ke index.html (SPA)
  RewriteRule ^ index.html [QSA,L]
</IfModule>

# Cache static assets
<IfModule mod_expires.c>
  ExpiresActive On
  ExpiresByType image/webp "access plus 1 year"
  ExpiresByType image/png "access plus 1 year"
  ExpiresByType image/jpg "access plus 1 year"
  ExpiresByType image/jpeg "access plus 1 year"
  ExpiresByType image/svg+xml "access plus 1 year"
  ExpiresByType text/css "access plus 1 month"
  ExpiresByType application/javascript "access plus 1 month"
  ExpiresByType font/woff2 "access plus 1 year"
</IfModule>

# Gzip compression
<IfModule mod_deflate.c>
  AddOutputFilterByType DEFLATE text/html text/css application/javascript application/json image/svg+xml
</IfModule>

# Security headers
<IfModule mod_headers.c>
  Header set X-Frame-Options "SAMEORIGIN"
  Header set X-Content-Type-Options "nosniff"
  Header set X-XSS-Protection "1; mode=block"
  Header set Referrer-Policy "strict-origin-when-cross-origin"
</IfModule>

# Blokir akses file sensitif
<FilesMatch "\.(env|git|htpasswd|log|sql|bak)$">
  Order Allow,Deny
  Deny from all
</FilesMatch>
```

### Deploy ke Subdirectory
Jika deploy di `example.com/app/` bukan di root:
```apache
# .htaccess di public_html/app/
<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteBase /app/
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteRule ^ index.html [QSA,L]
</IfModule>
```

Dan set base di `vite.config.js`:
```javascript
export default defineConfig({
  base: '/app/',
  plugins: [react()],
})
```

### Node.js App (jika hosting support)

#### Setup Node.js di cPanel
1. cPanel → **Setup Node.js App**
2. Pilih versi Node.js (18+)
3. Application root: `app` (folder di home)
4. Application URL: `example.com`
5. Application startup file: `server.js`
6. Klik **Create**

#### Passenger Config
cPanel pakai Phusion Passenger. File `.htaccess` di `public_html/`:
```apache
PassengerAppRoot /home/username/app
PassengerAppType node
PassengerStartupFile server.js
```

---

## Domain & Subdomain

### Addon Domain
cPanel → **Domains** → **Create A New Domain**
```
Domain: toko.example.com
Document Root: /public_html/toko
```

### Subdomain
cPanel → **Domains** → **Create A New Domain**
```
Domain: api.example.com
Document Root: /public_html/api
```

### Redirect
cPanel → **Redirects**
```
Type: Permanent (301)
From: http://www.example.com
To: https://example.com
```

### DNS Zone Editor
cPanel → **Zone Editor**

| Type | Name | Value | TTL |
|------|------|-------|-----|
| A | example.com | 123.456.789.0 | 14400 |
| CNAME | www | example.com | 14400 |
| A | api | 123.456.789.0 | 14400 |
| MX | example.com | mail.example.com (priority 0) | 14400 |
| TXT | example.com | v=spf1 +a +mx ~all | 14400 |

### Pointing Domain ke cPanel
Di registrar domain (Niagahoster, Namecheap, dll):
```
Nameserver 1: ns1.hostingprovider.com
Nameserver 2: ns2.hostingprovider.com
```
Atau pakai A Record: point ke IP server hosting.

---

## SSL / HTTPS

### AutoSSL (Let's Encrypt — Gratis)
cPanel → **SSL/TLS Status** → **Run AutoSSL**
- Otomatis active untuk semua domain
- Auto-renew setiap 90 hari

### Force HTTPS
Tambahkan di `.htaccess`:
```apache
RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
```

### Install SSL Custom (jika perlu)
cPanel → **SSL/TLS** → **Install and Manage SSL**
- Paste Certificate (CRT)
- Paste Private Key (KEY)
- Paste CA Bundle (CABUNDLE)

---

## Database MySQL

### Buat Database
cPanel → **MySQL Databases**
1. Create database: `username_appdb`
2. Create user: `username_appuser` + password
3. Add user to database → privilege: **ALL PRIVILEGES**

### phpMyAdmin
cPanel → **phpMyAdmin**
- Import: upload `.sql` file
- Export: backup database
- Query: jalankan SQL langsung

### Koneksi dari Aplikasi
```javascript
// Node.js
import mysql from 'mysql2/promise'

const db = await mysql.createConnection({
  host: 'localhost',       // biasanya localhost di shared hosting
  user: 'username_appuser',
  password: 'password',
  database: 'username_appdb',
})
```

```php
// PHP
$pdo = new PDO(
  'mysql:host=localhost;dbname=username_appdb',
  'username_appuser',
  'password'
);
```

### Remote MySQL
Jika aplikasi di server lain perlu akses DB:
cPanel → **Remote MySQL** → tambahkan IP yang diizinkan

---

## Email Hosting

### Buat Email Account
cPanel → **Email Accounts** → **Create**
```
Email: info@example.com
Password: (strong password)
Storage: 1 GB
```

### Akses Email
- **Webmail**: `https://example.com:2096` atau `https://webmail.example.com`
- **Email client** (Outlook, Thunderbird):
  ```
  Incoming (IMAP): mail.example.com, port 993, SSL
  Outgoing (SMTP): mail.example.com, port 465, SSL
  Username: info@example.com
  Password: (password email)
  ```

### Email Forwarder
cPanel → **Forwarders**
```
Forward: order@example.com → personal@gmail.com
```

### SPF, DKIM, DMARC (anti-spam)
cPanel → **Email Deliverability**
- Klik **Repair** untuk auto-fix SPF dan DKIM
- Tambahkan DMARC record manual di Zone Editor:
  ```
  Type: TXT
  Name: _dmarc.example.com
  Value: v=DMARC1; p=quarantine; rua=mailto:admin@example.com
  ```

---

## Cron Jobs

### Setup
cPanel → **Cron Jobs**

| Jadwal | Cron Expression | Contoh |
|--------|----------------|--------|
| Setiap menit | `* * * * *` | Health check |
| Setiap 5 menit | `*/5 * * * *` | Sync data |
| Setiap jam | `0 * * * *` | Cleanup temp |
| Setiap hari jam 2 pagi | `0 2 * * *` | Backup database |
| Setiap Senin jam 6 pagi | `0 6 * * 1` | Weekly report |
| Tanggal 1 setiap bulan | `0 0 1 * *` | Monthly report |

### Contoh Command
```bash
# Backup database harian
0 2 * * * mysqldump -u username_appuser -p'password' username_appdb > /home/username/backups/db_$(date +\%Y\%m\%d).sql

# Hapus file temp > 7 hari
0 3 * * * find /home/username/tmp/ -type f -mtime +7 -delete

# Jalankan PHP script
0 */6 * * * /usr/local/bin/php /home/username/app/cron/sync.php

# Jalankan Node.js script
0 4 * * * cd /home/username/app && /usr/local/bin/node scripts/cleanup.js

# Curl endpoint (trigger API)
*/5 * * * * curl -s https://example.com/api/health > /dev/null
```

---

## File Manager

### Struktur Folder Penting
```
/home/username/
├── public_html/          ← Document root (website utama)
│   ├── index.html        ← Entry point
│   ├── assets/           ← JS, CSS, images (dari build)
│   ├── .htaccess         ← Rewrite rules
│   └── subdomain/        ← Addon domain / subdomain
├── public_ftp/           ← FTP root (biasanya kosong)
├── mail/                 ← Email data
├── logs/                 ← Access & error logs
│   ├── access.log
│   └── error.log
├── ssl/                  ← SSL certificates
├── tmp/                  ← Temporary files
└── app/                  ← Node.js app (jika pakai Setup Node.js)
```

### File Permission
| File/Folder | Permission | Chmod |
|-------------|-----------|-------|
| Folder | rwxr-xr-x | 755 |
| File HTML/CSS/JS | rw-r--r-- | 644 |
| .htaccess | rw-r--r-- | 644 |
| Config berisi password | rw------- | 600 |
| Upload folder | rwxrwxrwx | 777 (hindari, pakai 755 + owner) |

---

## FTP / SFTP

### Buat FTP Account
cPanel → **FTP Accounts** → **Create**
```
Username: deploy@example.com
Password: (strong password)
Directory: /public_html
```

### Koneksi FTP (FileZilla)
```
Host: ftp.example.com (atau IP server)
Port: 21 (FTP) atau 22 (SFTP)
Protocol: SFTP jika tersedia (lebih aman)
Username: deploy@example.com
Password: (password)
```

### Deploy via FTP Script
```bash
# Menggunakan lftp
lftp -u deploy@example.com,password ftp.example.com <<EOF
mirror -R --delete --only-newer dist/ public_html/
quit
EOF
```

---

## PHP Configuration

### Pilih PHP Version
cPanel → **MultiPHP Manager** → pilih versi per domain (7.4, 8.0, 8.1, 8.2, 8.3)

### Edit php.ini
cPanel → **MultiPHP INI Editor**

Setting yang sering diubah:
```ini
upload_max_filesize = 64M
post_max_size = 64M
max_execution_time = 300
max_input_time = 300
memory_limit = 256M
display_errors = Off          ; Off di production
error_reporting = E_ALL & ~E_NOTICE
date.timezone = Asia/Jakarta
```

### Custom php.ini via .htaccess
```apache
php_value upload_max_filesize 64M
php_value post_max_size 64M
php_value max_execution_time 300
```

---

## Backup & Restore

### Full Backup
cPanel → **Backup** → **Download a Full Account Backup**
- Termasuk: files, databases, email, settings
- Biasanya di-download sebagai `.tar.gz`

### Partial Backup
- **Home Directory**: download semua file
- **MySQL Database**: download per database
- **Email Forwarders/Filters**: download konfigurasi

### Automated Backup via Cron
```bash
# Backup database harian, keep 7 hari terakhir
0 2 * * * mysqldump -u user -p'pass' dbname | gzip > /home/username/backups/db_$(date +\%Y\%m\%d).sql.gz
0 3 * * * find /home/username/backups/ -name "db_*.sql.gz" -mtime +7 -delete

# Backup files mingguan
0 4 * * 0 tar -czf /home/username/backups/files_$(date +\%Y\%m\%d).tar.gz /home/username/public_html/ --exclude='*.log'
```

### JetBackup (jika tersedia)
cPanel → **JetBackup** → pilih tanggal → Restore

---

## Troubleshooting

### Error 500 (Internal Server Error)
```bash
# 1. Cek error log
cPanel → Error Pages ATAU tail /home/username/logs/error.log

# 2. Penyebab umum:
# - .htaccess syntax error
# - PHP fatal error
# - File permission salah (harus 644/755, bukan 777)
# - PHP version tidak compatible

# 3. Quick fix: rename .htaccess untuk test
mv .htaccess .htaccess.bak
# Jika website jalan → masalah di .htaccess
```

### Error 403 (Forbidden)
```bash
# Penyebab umum:
# - Tidak ada index.html/index.php di folder
# - File permission terlalu restrictive
# - .htaccess memblokir akses
# - IP diblokir oleh firewall hosting

# Fix permission
chmod 755 public_html/
chmod 644 public_html/index.html
```

### Error 404 (Not Found)
```bash
# Untuk SPA (React Router):
# - Pastikan .htaccess dengan RewriteRule sudah ada
# - Pastikan mod_rewrite aktif

# Untuk file statis:
# - Cek path file benar
# - Case sensitive di Linux (File.jpg ≠ file.jpg)
```

### Website Lambat
```bash
# 1. Cek resource usage
cPanel → Resource Usage

# 2. Optimasi:
# - Enable Gzip compression (.htaccess)
# - Optimize images (WebP)
# - Enable browser caching (Expires header)
# - Minify CSS/JS (otomatis dari Vite build)

# 3. Jika masih lambat → upgrade hosting plan atau pindah ke VPS
```

### Disk Space Penuh
```bash
# Cek di cPanel → Disk Usage
# Penyebab umum:
# - Email inbox penuh → hapus email lama
# - Log files besar → hapus/rotate
# - Backup lama → hapus yang tidak perlu
# - File temporary → bersihkan /tmp

# Cek folder terbesar via SSH
du -sh /home/username/*/ | sort -rh | head -10
```

---

## Aturan cPanel

- Jangan upload `node_modules/` ke hosting — upload hanya hasil `build` (folder `dist/`)
- Selalu test `.htaccess` setelah edit — typo bisa bikin error 500
- Backup sebelum perubahan besar
- Gunakan SFTP/SSH bukan FTP biasa (lebih aman)
- Jangan simpan credentials di file yang bisa diakses public
- Cek error log rutin — banyak masalah terdeteksi di sana
- Set file permission yang benar: 755 folder, 644 file, 600 config sensitif
- Jangan pakai 777 permission — risiko keamanan tinggi

