Files
momentry_core/docs/INSTALL_SFTPGO.md
accusys 383201cacd feat: Initial v0.9 release with API Key authentication
## v0.9.20260325_144654

### Features
- API Key Authentication System
- Job Worker System
- V2 Backup Versioning

### Bug Fixes
- get_processor_results_by_job column mapping

Co-authored-by: OpenCode
2026-03-25 14:53:41 +08:00

1062 lines
24 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# SFTPGo 安裝指南 (本地部署)
| 項目 | 內容 |
|------|------|
| 建立者 | Warren |
| 建立時間 | 2026-03-18 |
| 文件版本 | V1.0 |
---
## 版本歷史
| 版本 | 日期 | 目的 | 操作人 | 工具/模型 |
|------|------|------|--------|-----------|
| V1.0 | 2026-03-18 | 創建文件 | Warren | OpenCode / MiniMax M2.5 |
| V1.1 | 2026-03-22 | 添加備份還原、API管理、Hook配置 | opencode | OpenCode |
---
## 更新紀錄
- **2026-03-22**:
- 成功使用統一備份系統還原 SFTPGo 到 20260321_101928 時間點
- 重置 admin 密碼為 `Test3200Test3200`
- 修復 demo 用戶權限格式 (從 `["*"]` 改為 `{" /":["*"]}`)
- 通过 API 创建并配置 `demo` 用户和 `demo`
- 配置 SFTPGo Hook 實現自動化檔案註冊
- 確認 API 認證方式為 Basic Auth (GET `/api/v2/token`)
## 概述
本文檔說明如何在 macOS 上安裝 SFTPGo配置為本地部署用於 SFTP/FTP/WebDAV 檔案傳輸服務。
---
## 當前狀態
| 項目 | 狀態 |
|------|------|
| SFTPGo | ✅ 已安裝 v2.7.0 |
| Port | 8080 (HTTP), 2022 (SFTP) |
| 配置目錄 | /Users/accusys/momentry/etc/sftpgo/ |
| 日誌目錄 | /Users/accusys/momentry/log/ |
| Plist | /Library/LaunchDaemons/com.momentry.sftpgo.plist |
| API 狀態 | ✅ 已啟用 (`enable_rest_api: true`) |
| Hook 狀態 | ✅ 已配置 (執行於檔案上傳時) |
---
## 備份與還原機制
SFTPGo 使用 Momentry 統一備份系統進行完整的配置與數據庫備份。
### 備份內容
```bash
# 備份目錄
/Users/accusys/momentry/backup/daily/sftpgo/
# 備份文件範例
sftpgo_cfg_20260321_101928.tar.gz # 配置文件
sftpgo_db_20260321_101928.sql.gz # PostgreSQL 數據庫
sftpgo_20260321_101928.sha256 # 校驗和
```
### 列出可用備份時間點
```bash
/Users/accusys/momentry/scripts/backup_all.sh list | grep sftpgo
```
### 執行備份
```bash
# 備份 SFTPGo (配置 + 數據庫)
/Users/accusys/momentry/scripts/backup_all.sh sftpgo full
# 手動備份單一服務
/Users/accusys/momentry/scripts/backup_all.sh sftpgo cfg
```
### 執行還原
```bash
# 1. 備份當前狀態 (安全措施)
/Users/accusys/momentry/scripts/backup_all.sh sftpgo full
# 2. 還原到指定時間點
/Users/accusys/momentry/scripts/backup_all.sh restore sftpgo 20260321_101928
# 3. 驗證還原結果
curl http://localhost:8080/api/v2/version
psql -U sftpgo -d sftpgo -c "SELECT username, status FROM admins;"
```
### 還原流程说明
`backup_all.sh``restore_sftpgo()` 函数会执行以下步骤 (第 517-546 行)
1. **停止 SFTPGo** - 使用 `pkill -f sftpgo`
2. **恢复配置文件** - 从 `sftpgo_cfg_*.tar.gz` 恢复到 `/Users/accusys/momentry/etc/sftpgo/`
3. **恢复 PostgreSQL 数据库**:
- 删除现有数据库 (如存在)
- 创建新数据库并设置所有者
-`sftpgo_db_*.sql.gz` 导入数据
4. **重启 SFTPGo** - 手动启动服务
### 備份狀態檢查
```bash
/Users/accusys/momentry/scripts/backup_all.sh status
```
此命令會顯示所有服務的最新備份狀態與大小。
---
## 安裝步驟
### Step 1: 安裝 SFTPGo (使用 brew)
```bash
# 安裝 SFTPGo
brew install sftpgo
```
**驗證**:
```bash
sftpgo --version
# SFTPGo 2.7.0
```
---
### Step 2: 建立目錄
```bash
# 建立配置目錄
mkdir -p /Users/accusys/momentry/etc/sftpgo
# 建立日誌目錄
mkdir -p /Users/accusys/momentry/log
# 建立工作目錄
mkdir -p /Users/accusys/workspace/sftpgo
# 建立日誌文件
touch /Users/accusys/momentry/log/sftpgo.log
touch /Users/accusys/momentry/log/sftpgo.error.log
# 設定權限
chown -R accusys:staff /Users/accusys/momentry/etc/sftpgo
chown -R accusys:staff /Users/accusys/momentry/log
chown -R accusys:staff /Users/accusys/workspace/sftpgo
```
---
### Step 3: 建立設定檔
建立 `/Users/accusys/momentry/etc/sftpgo/sftpgo.json`:
```json
{
"common": {
"idle_timeout": 15,
"upload_mode": 0,
"max_per_host_connections": 20
},
"users": [
{
"username": "accusys",
"password": "",
"public_keys": [],
"home_dir": "/Users/accusys/workspace/sftpgo",
"uid": 501,
"gid": 20,
"permissions": {
"/": ["*"]
}
}
],
"httpd": {
"bind_port": 8080,
"bind_address": "0.0.0.0"
},
"ftpd": {
"bind_port": 21,
"bind_address": "0.0.0.0"
},
"sftpd": {
"bind_port": 2022,
"bind_address": "0.0.0.0"
},
"webdavd": {
"bind_port": 0,
"bind_address": ""
}
}
```
---
### Step 4: 使用 plist 開機自動啟動
```bash
# 複製 plist 到 LaunchDaemons 目錄
sudo cp /Users/accusys/momentry_core_0.1/momentry_runtime/plist/com.momentry.sftpgo.plist /Library/LaunchDaemons/
# 載入並啟動
sudo launchctl bootstrap system /Library/LaunchDaemons/com.momentry.sftpgo.plist
```
#### Plist 環境變量說明
plist 包含以下環境變量用於自動創建 admin 用戶:
| 環境變量 | 值 | 說明 |
|----------|------|------|
| `SFTPGO_DEFAULT_ADMIN_USERNAME` | `admin` | 默認管理員用戶名 |
| `SFTPGO_DEFAULT_ADMIN_PASSWORD` | `Test3200Test3200` | 默認管理員密碼 |
**注意**: 這些變量僅在首次啟動時用於創建 admin 用戶。如果 admin 已存在,則不會覆蓋。
---
## 監控配置
### 添加到監控配置
`monitor/config/monitor_config.yaml` 中添加:
```yaml
service:
services:
- name: "sftpgo"
type: "http"
port: 8080
host: "localhost"
check_url: "http://localhost:8080/api/v2/info"
timeout: 5
enabled: true
```
### API 監控端點
| 端點 | 說明 | 認證 |
|------|------|------|
| `/api/v2/info` | 伺服器資訊 | ❌ 不需要 |
| `/api/v2/healthz` | 健康檢查 | ❌ 不需要 |
| `/api/v2/version` | 版本資訊 | ❌ 不需要 |
| `/api/v2/token` | 獲取 Token | ✅ Basic Auth |
| `/api/v2/admins` | 管理員列表 | ✅ Bearer Token |
| `/api/v2/users` | 用戶列表 | ✅ Bearer Token |
| `/api/v2/groups` | 組列表 | ✅ Bearer Token |
---
---
## 卸載步驟
### 重要: 路徑說明
| 路徑 | 類型 | 說明 |
|------|------|------|
| `/Users/accusys/momentry/etc/sftpgo/` | 配置 | **不要刪除** - SFTPGo 配置 |
| `/Users/accusys/momentry/log/` | 日誌 | **不要刪除** - 日誌目錄 |
| `/Users/accusys/workspace/sftpgo/` | 數據 | **不要刪除** - 上傳檔案目錄 |
| `/opt/homebrew/opt/sftpgo/` | 安裝 | **刪除** - SFTPGo 安裝目錄 |
### Step 1: 停止 SFTPGo
```bash
# 找到 SFTPGo 進程
ps aux | grep sftpgo | grep -v grep
# 停止 SFTPGo
pkill sftpgo
# 確認停止
ps aux | grep sftpgo | grep -v grep || echo "SFTPGo 已停止"
```
---
### Step 2: 卸載 SFTPGo
```bash
# 卸載 SFTPGo
brew uninstall sftpgo
# 移除 plist
sudo launchctl unload /Library/LaunchDaemons/com.momentry.sftpgo.plist
sudo rm /Library/LaunchDaemons/com.momentry.sftpgo.plist
```
---
### Step 3: 刪除專屬檔案
```bash
# 刪除配置目錄 (可選)
rm -rf /Users/accusys/momentry/etc/sftpgo
# 刪除日誌 (可選)
rm -f /Users/accusys/momentry/log/sftpgo.log
rm -f /Users/accusys/momentry/log/sftpgo.error.log
```
**注意: 不要刪除以下目錄**:
```bash
# 這些是重要的,不要刪除!
# /Users/accusys/momentry/etc/sftpgo
# /Users/accusys/momentry/log
# /Users/accusys/workspace/sftpgo
```
---
### Step 4: 卸載後檢查清單
```bash
echo "=== SFTPGo 卸載後檢查 ==="
# 1. 檢查 SFTPGo 進程
echo "1. SFTPGo 進程:"
ps aux | grep sftpgo | grep -v grep && echo " ✗ 仍在運行" || echo " ✓ 已停止"
# 2. Port 8080/2022
echo "2. Port 8080/2022:"
(lsof -i :8080 > /dev/null 2>&1 || lsof -i :2022 > /dev/null 2>&1) && echo " ✗ 仍被佔用" || echo " ✓ 已釋放"
# 3. sftpgo 命令
echo "3. sftpgo 命令:"
which sftpgo > /dev/null 2>&1 && echo " ✗ 仍存在" || echo " ✓ 已移除"
# 4. brew 安裝
echo "4. brew 安裝:"
brew list sftpgo > /dev/null 2>&1 && echo " ✗ 仍存在" || echo " ✓ 已移除"
# 5. launchctl 服務
echo "5. launchctl 服務:"
sudo launchctl list | grep sftpgo > /dev/null 2>&1 && echo " ✗ 仍存在" || echo " ✓ 已移除"
# 6. 配置目錄 (可選刪除)
echo "6. 配置目錄:"
[ -d "/Users/accusys/momentry/etc/sftpgo" ] && echo " ✓ 保留" || echo " ✗ 已刪除"
```
---
## 手動檢查命令
```bash
# 1. 檢查進程
ps aux | grep sftpgo | grep -v grep
# 2. 檢查 Port
lsof -i :8080
lsof -i :2022
# 3. 測試連線
curl http://localhost:8080/
# 4. 查看版本
sftpgo --version
# 5. 驗證配置
sftpgo validate --config /Users/accusys/momentry/etc/sftpgo/sftpgo.json
# 6. 查看日誌
tail -20 /Users/accusys/momentry/log/sftpgo.log
```
---
## 連線資訊
| 項目 | 值 |
|------|-----|
| HTTP/WebDAV | http://localhost:8080 |
| SFTP | localhost:2022 |
| FTP | localhost:21 |
| Admin API | http://localhost:8080/api/v2/info |
---
## 環境變數
`.env` 中:
```env
SFTPGO_CONFIG=/Users/accusys/momentry/etc/sftpgo/sftpgo.json
SFTPGO_DATA_DIR=/Users/accusys/workspace/sftpgo
```
---
## 管理員帳戶修復
### 透過 Web 管理面板重置密碼 (推薦)
1. 前往 **http://localhost:8080/web/admin/login**
2. 點擊 **Forgot password?**
3. 輸入 **Installation Code**: `Test3200Test3200`
4.`admin` 設定新密碼
### 透過 SQL 直接重建管理員帳戶
如果 Web 面板無法使用,可直接操作 PostgreSQL 資料庫:
#### 連線到資料庫
```bash
psql -U accusys -d sftpgo
```
#### 插入管理員帳戶
```sql
INSERT INTO admins (
username,
description,
password,
email,
status,
permissions,
filters,
additional_info,
last_login,
role_id,
created_at,
updated_at
) VALUES (
'admin',
'',
'$2a$10$3Boql8AHoxPXWWmgmJiN5.b8s1Z65gNp1yqKQvZ5SOEv7j8NRA58.',
'',
1,
'["*"]',
'{"require_two_factor":false,"totp_config":{"secret":{}},"preferences":{}}',
'',
0,
NULL,
EXTRACT(EPOCH FROM NOW())::bigint * 1000,
EXTRACT(EPOCH FROM NOW())::bigint * 1000
);
```
**預設密碼**: `Test3200Test3200`
#### 使用 bcrypt 生成密碼哈希
```bash
python3 -c "import bcrypt; print(bcrypt.hashpw(b'Test3200Test3200', bcrypt.gensalt(rounds=10)).decode())"
```
### 使用 CLI 重置密碼
```bash
# 停止 SFTPGo (如果正在运行)
pkill -f sftpgo
# 重置密碼 (互動式)
sftpgo resetpwd --admin admin --config-file /Users/accusys/momentry/etc/sftpgo/sftpgo.json
# 重新啟動 SFTPGo
/opt/homebrew/opt/sftpgo/bin/sftpgo serve --config-file /Users/accusys/momentry/etc/sftpgo/sftpgo.json &
```
### 使用 Expect 自動化密碼重置
如果需要自動化重置,可以創建 expect 腳本:
```bash
# resetpwd.exp
#!/usr/bin/expect -f
set timeout 10
set admin_user [lindex $argv 0]
set new_password [lindex $argv 1]
spawn sftpgo resetpwd --admin $admin_user --config-file /Users/accusys/momentry/etc/sftpgo/sftpgo.json
expect "Enter Password:"
send "$new_password\r"
expect "Enter Password:"
send "$new_password\r"
expect eof
```
執行:
```bash
chmod +x resetpwd.exp
expect resetpwd.exp admin Test3200Test3200
```
---
### 透過 CLI 重置密碼
```bash
# 停止 SFTPGo
kill $(pgrep -f "sftpgo serve")
# 重置密碼 (互動式)
sftpgo resetpwd --admin admin --config-file /Users/accusys/momentry/etc/sftpgo/sftpgo.json
# 重新啟動 SFTPGo
sftpgo serve --config-file /Users/accusys/momentry/etc/sftpgo/sftpgo.json &
```
### 驗證管理員帳戶
```sql
-- 檢查 admin 是否存在
SELECT id, username, status, last_login FROM admins;
-- 檢查使用者是否存在 (SFTP/WebDAV 登入)
SELECT id, username, status, home_dir FROM users;
```
---
## API 管理用戶與組
SFTPGo 提供 RESTful API 用於管理用戶和組,支援自動化運維。
### API 認證方式
1. **獲取 Access Token** (使用 Basic Auth):
```bash
TOKEN=$(curl -s -X GET http://localhost:8080/api/v2/token \
-u "admin:Test3200Test3200" | jq -r '.access_token')
```
2. **使用 Token 調用 API**:
```bash
curl -X GET http://localhost:8080/api/v2/admins \
-H "Authorization: Bearer $TOKEN"
```
**注意**: `/api/v2/token` 端點使用 `GET` 方法,而非 `POST`
### 列出所有用戶
```bash
TOKEN=$(curl -s -X GET http://localhost:8080/api/v2/token -u "admin:Test3200Test3200" | jq -r '.access_token')
curl -s -X GET "http://localhost:8080/api/v2/users?limit=100" \
-H "Authorization: Bearer $TOKEN" | jq -r '.[] | "\(.username) status=\(.status) home=\(.home_dir)"'
```
### 創建用戶
```bash
curl -s -X POST http://localhost:8080/api/v2/users \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"username": "demo",
"password": "demopassword123",
"email": "demo@momentry.local",
"status": 1,
"home_dir": "/Users/accusys/sftpgo_test/demo",
"uid": 501,
"gid": 20,
"permissions": {
"/": ["*"]
}
}'
```
**權限格式注意**: 必須為 map[string][]string 格式,例如:
```json
{
"/": ["*"],
"/upload": ["read", "write"]
}
```
### 修復用戶權限格式
如果權限存儲為數組 `["*"]` 而非 mapAPI 會返回錯誤:
```
unable to deserialize permissions for user "demo": json: cannot unmarshal array into Go value of type map[string][]string
```
修復方法:
```bash
psql -h 127.0.0.1 -p 5432 -U sftpgo -d sftpgo -c \
"UPDATE users SET permissions = '{\" /\":[\"*\"]}'::jsonb WHERE username='demo';"
```
### 創建組
```bash
curl -s -X POST http://localhost:8080/api/v2/groups \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "demo",
"description": "Demo group for SFTP uploads"
}'
```
### 將用戶加入組
查看 User Schema 中的 `groups` 欄位為 `GroupMapping` 數組:
```json
{
"groups": [
{
"name": "demo",
"type": 1 // 1=主要組, 2=次要組, 3=僅成員身份
}
]
}
```
更新用戶組關聯:
```bash
curl -s -X PUT http://localhost:8080/api/v2/users/demo \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"groups": [
{
"name": "demo",
"type": 1
}
],
"permissions": {
"/": ["*"]
}
}'
```
**重要**: 更新用戶時必須提供完整的必要欄位 (如 `permissions`),否則會驗證失敗。
### API 端點對照表
| 功能 | 端點 | 方法 |
|------|------|------|
| 獲取 Token | `/api/v2/token` | GET (Basic Auth) |
| 列出管理員 | `/api/v2/admins` | GET |
| 列出用戶 | `/api/v2/users` | GET |
| 創建用戶 | `/api/v2/users` | POST |
| 獲取用戶 | `/api/v2/users/{username}` | GET |
| 更新用戶 | `/api/v2/users/{username}` | PUT |
| 刪除用戶 | `/api/v2/users/{username}` | DELETE |
| 列出組 | `/api/v2/groups` | GET |
| 創建組 | `/api/v2/groups` | POST |
| 獲取組 | `/api/v2/groups/{name}` | GET |
| 更新組 | `/api/v2/groups/{name}` | PUT |
| 刪除組 | `/api/v2/groups/{name}` | DELETE |
完整的 API 文件請參考: http://localhost:8080/openapi/
---
## Hook 配置
SFTPGo Hook 用於在檔案操作時觸發外部腳本,實現自動化處理。
### 配置文件位置
`/Users/accusys/momentry/etc/sftpgo/sftpgo.json`
### 通用 Actions 配置
`common.actions` 中配置:
```json
{
"common": {
"actions": {
"execute_on": ["add"], // 觸發時機: 檔案上傳完成後
"execute_sync": [], // 同步執行 ([])
"hook": "/path/to/hook.sh" // Hook 腳本路徑
}
}
}
```
### Hook 腳本範例
位置: `/Users/accusys/sftpgo_test/register_hook.sh`
```bash
#!/bin/bash
# SFTPGo Hook - 檔案上傳後自動註冊到 Momentry Core
# SFTPGo 傳遞的環境變數
# ${SFTPGO_ACTION} - 操作類型 (add, delete, etc.)
# ${SFTPGO_USERNAME} - 用戶名
# ${SFTPGO_FILEPATH} - 檔案路徑 (相對首頁目錄)
# ${SFTPGO_FILESIZE} - 檔案大小
# ${SFTPGO_TIMESTAMP} - 操作時間戳
# 絕對路徑轉換
UPLOAD_DIR="/Users/accusys/sftpgo_test/demo"
RELATIVE_PATH="${SFTPGO_FILEPATH#./}"
ABS_PATH="${UPLOAD_DIR}/${RELATIVE_PATH}"
# 日誌記錄
LOG_FILE="/Users/accusys/sftpgo_test/hook.log"
echo "$(date '+%Y-%m-%d %H:%M:%S') - User: ${SFTPGO_USERNAME}, File: ${ABS_PATH}, Size: ${SFTPGO_FILESIZE}" >> "$LOG_FILE"
# 調用 Momentry Core 註冊 API
API_URL="http://localhost:8080/api/v1/register"
RESPONSE=$(curl -s -X POST "$API_URL" \
-H "Content-Type: multipart/form-data" \
-F "file=@${ABS_PATH}" \
--connect-timeout 10 --max-time 300)
echo "$(date '+%Y-%m-%d %H:%M:%S') - API Response: ${RESPONSE}" >> "$LOG_FILE"
```
### Hook 執行權限
```bash
chmod +x /Users/accusys/sftpgo_test/register_hook.sh
```
### Hook 執行時間點
`execute_on` 支援以下值:
| 值 | 觸發時機 |
|-----|----------|
| `add` | 檔案上傳完成後 |
| `delete` | 檔案刪除後 |
| `upload_complete` | 上傳完成 (multipart) |
| `download` | 檔案下載時 |
| `rename` | 檔案重命名後 |
| `mkdir` | 建立目錄後 |
| `rmdir` | 刪除目錄後 |
### Hook 執行模式
- **同步執行** (`execute_sync`): Hook 腳本在 SFTPGo 操作返回客戶端前執行
- **非同步執行** (預設): Hook 腳本在后台執行,不阻塞客戶端
### 重新載入配置
修改 Hook 配置後,需重新載入 SFTPGo:
```bash
# 如果是 plist 啟動的服務
sudo launchctl kickstart -k system/local.sftpgo
# 或手動重啟
pkill -f sftpgo
sftpgo serve --config-file /Users/accusys/momentry/etc/sftpgo/sftpgo.json &
```
### Hook 故障排除
1. **檢查 Hook 日誌**:
```bash
tail -f /Users/accusys/sftpgo_test/hook.log
```
2. **手動測試 Hook 腳本**:
```bash
export SFTPGO_USERNAME=demo
export SFTPGO_FILEPATH="./test.txt"
export SFTPGO_FILESIZE=1024
export SFTPGO_ACTION=add
/Users/accusys/sftpgo_test/register_hook.sh
```
3. **SFTPGo 錯誤日誌**:
```bash
tail -20 /Users/accusys/momentry/log/sftpgo.error.log
```
---
| 資料表 | 用途 | 登入 URL |
|--------|------|----------|
| `admins` | 管理員用戶 | `/web/admin/login` |
| `users` | 檔案傳輸用戶 | `/web/client/login` |
### Demo 用戶與組設置
#### 建立 Demo 目錄
```bash
mkdir -p /Users/accusys/sftpgo_test/demo
```
#### 創建 Demo 組
```bash
TOKEN=$(curl -s -X GET http://localhost:8080/api/v2/token -u "admin:Test3200Test3200" | jq -r '.access_token')
curl -s -X POST http://localhost:8080/api/v2/groups \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "demo",
"description": "Demo group for SFTP uploads"
}'
```
#### 創建 Demo 用戶並加入組
如果 `demo` 用戶不存在:
```bash
curl -s -X POST http://localhost:8080/api/v2/users \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"username": "demo",
"password": "demopassword123",
"email": "demo@momentry.local",
"status": 1,
"home_dir": "/Users/accusys/sftpgo_test/demo",
"uid": 501,
"gid": 20,
"permissions": {
"/": ["*"]
}
}'
```
如果用戶已存在但權限格式錯誤,需修復:
```bash
psql -h 127.0.0.1 -p 5432 -U sftpgo -d sftpgo -c \
"UPDATE users SET permissions = '{\" /\":[\"*\"]}'::jsonb WHERE username='demo';"
```
將用戶加入 `demo` 組 (主要組):
```bash
curl -s -X PUT http://localhost:8080/api/v2/users/demo \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"groups": [
{
"name": "demo",
"type": 1
}
],
"permissions": {
"/": ["*"]
}
}'
```
#### 驗證設置
```bash
# 檢查用戶
curl -s -X GET "http://localhost:8080/api/v2/users/demo" \
-H "Authorization: Bearer $TOKEN" | jq .
# 檢查組
curl -s -X GET "http://localhost:8080/api/v2/groups/demo" \
-H "Authorization: Bearer $TOKEN" | jq .
```
#### SFTP 連接測試
```bash
# 使用 SFTP 連接
sshpass -p "demopassword123" sftp -P 2022 demo@localhost
# 上傳測試文件
sftp> put test.txt
```
#### 預期行為
1. 檔案上傳完成後SFTPGo 觸發 Hook
2. Hook 腳本執行並記錄到 `/Users/accusys/sftpgo_test/hook.log`
3. Hook 調用 Momentry Core API 完成註冊
4. 查看注册狀態: `tail -f /Users/accusys/sftpgo_test/hook.log`
---
## 常見問題
#### "無效的憑證" 即使密碼正確
- PostgreSQL 中的密碼哈希可能不符合 SFTPGo 預期格式
- 使用 Web 面板的 **Forgot password** 功能而非直接 SQL 更新
#### CSRF Token 錯誤
- 清除瀏覽器中 `localhost:8080` 的 cookies
- 使用無痕/私密瀏覽視窗
---
## 端到端測試流程
### 1. 準備工作
```bash
# 確認 SFTPGo 運行中
curl http://localhost:8080/healthz
# 確認 Momentry Core API 運行中
curl http://localhost:8080/api/v1/health
```
### 2. SFTP 上傳測試
```bash
# 連接到 SFTPGo
sshpass -p "demopassword123" sftp -P 2022 demo@localhost
# 上傳測試文件
sftp> put /path/to/video.mp4
```
### 3. 驗證 Hook 執行
```bash
# 查看 Hook 日誌
tail -f /Users/accusys/sftpgo_test/hook.log
# 預期看到類似輸出:
# 2026-03-22 01:30:00 - User: demo, File: /Users/accusys/sftpgo_test/demo/video.mp4, Size: 10485760
# 2026-03-22 01:30:05 - API Response: {"uuid":"abc123","status":"registered"}
```
### 4. 檢查 Momentry Core 註冊狀態
```bash
# 使用 Momentry CLI 檢查
/Users/accusys/momentry/target/debug/momentry list --api-key <your-api-key>
# 或直接查詢資料庫
psql -U accusys -d momentry -c "SELECT uuid, filename, status FROM videos WHERE filename='video.mp4';"
```
### 5. 檢查處理狀態
```bash
# 查看處理佇列
curl http://localhost:8080/api/v1/queue
# 查看 searchable 狀態
curl "http://localhost:8080/api/v1/searchable?filename=video.mp4&user=demo"
```
### 6. 故障排除檢查清單
```bash
# 1. SFTPGo 狀態
ps aux | grep sftpgo
curl http://localhost:8080/healthz
# 2. Hook 腳本權限
ls -l /Users/accusys/sftpgo_test/register_hook.sh
# 3. Hook 日誌
tail -20 /Users/accusys/sftpgo_test/hook.log
# 4. Momentry Core 日誌
tail -20 /Users/accusys/momentry/log/momentry.log
# 5. SFTPGo 日誌
tail -20 /Users/accusys/momentry/log/sftpgo.log
# 6. PostgreSQL 連接
psql -U sftpgo -d sftpgo -c "SELECT 1;"
# 7. 端口可用性
lsof -i :8080 # SFTPGo HTTP
lsof -i :2022 # SFTP
lsof -i :5678 # Momentry Core (Primary)
```
---
## 故障排除
### SFTPGo 無法啟動
```bash
# 檢查日誌
tail -f /Users/accusys/momentry/log/sftpgo.log
# 驗證配置語法
sftpgo validate --config /Users/accusys/momentry/etc/sftpgo/sftpgo.json
# 檢查目錄權限
ls -la /Users/accusys/momentry/etc/sftpgo/
# 重新設定權限
chown -R $(whoami):staff /Users/accusys/momentry/etc/sftpgo
```
### Port 被佔用
```bash
# 檢查哪個程序佔用 port
lsof -i :8080
lsof -i :2022
# 終止佔用程序
kill <PID>
```
### 需要重新載入 plist
```bash
# 卸載舊服務 (如果存在)
sudo launchctl unload /Library/LaunchDaemons/com.momentry.sftpgo.plist 2>/dev/null
# 載入新服務
sudo launchctl load /Library/LaunchDaemons/com.momentry.sftpgo.plist
```
---
## 檔案位置
| 類型 | 路徑 | 說明 |
|------|------|------|
| 安裝 | `/opt/homebrew/opt/sftpgo/` | SFTPGo 安裝目錄 |
| 執行檔 | `/opt/homebrew/opt/sftpgo/bin/sftpgo` | SFTPGo 執行檔 |
| 配置 | `/Users/accusys/momentry/etc/sftpgo/sftpgo.json` | 設定檔 |
| 日誌 | `/Users/accusys/momentry/log/sftpgo.log` | 執行日誌 |
| 錯誤日誌 | `/Users/accusys/momentry/log/sftpgo.error.log` | 錯誤日誌 |
| 工作目錄 | `/Users/accusys/workspace/sftpgo/` | 上傳檔案目錄 |
| plist | `/Library/LaunchDaemons/com.momentry.sftpgo.plist` | 開機啟動 |
| 備份 | `/Users/accusys/momentry/backup/daily/sftpgo/` | 配置與數據庫備份 |
| 備份配置 | `/Users/accusys/momentry/var/sftpgo_backup/` | 實時配置備份 (含 sftpgo.json, sftpgo.db) |
| Hook 腳本 | `/Users/accusys/sftpgo_test/register_hook.sh` | 自動註冊腳本 |
| Hook 日誌 | `/Users/accusys/sftpgo_test/hook.log` | Hook 執行記錄 |
| Demo 目錄 | `/Users/accusys/sftpgo_test/demo` | Demo 用戶首頁目錄 |
---
## 常用指令
```bash
# 驗證配置
sftpgo validate --config /Users/accusys/momentry/etc/sftpgo/sftpgo.json
# 查看版本
sftpgo --version
# 查看可用命令
sftpgo --help
# 重載配置 (熱重載)
sftpgo reload --config /Users/accusys/momentry/etc/sftpgo/sftpgo.json
```
---
## 版本資訊
- 版本: 2.7.0
- HTTP Port: 8080
- SFTP Port: 2022
- FTP Port: 21
- 配置: /Users/accusys/momentry/etc/sftpgo/sftpgo.json
- 工作目錄: /Users/accusys/workspace/sftpgo
- 日誌目錄: /Users/accusys/momentry/log/