FS2 專案 (go2see.me) — 第二階段
現在進入 Phase 2,不過我想調整一下方向。
我們先不要急著寫 Portal
因為有一件事比 Portal 更重要:
把 Apache 設定改成可維護。
你現在每個使用者都有一段:
Alias /johnny ...
...
7 個人還可以接受。
如果以後變成:
- 20 人
- 50 人
- 100 人
這個檔會變成上千行,很難維護。
我建議 Phase 2 分成三個小階段
Phase 2A(先做)
整理 Apache
/etc/apache2/
sites-available/
fs2-le-ssl.conf
conf-available/
fs2-users.conf
fs2-common.conf
把共用設定抽出來。
例如:
DAV On
Options Indexes
AuthType Basic
AuthName "FS2"
AuthUserFile ...
只寫一次。
這樣 Apache 設定會乾淨很多。
Phase 2B
建立 FS2 Portal
https://fs2.go2see.me
首頁:
Public
Info
Share
My Folder
Change Password
先不用登入。
只是漂亮首頁。
Phase 2C
再加入:
Login
Change Password
Admin
我還想做一件事
目前:
users.password
只有一份。
我想把它搬到:
/etc/fs2/
users.password
groups
理由:
/etc放設定/srv放資料/var/www放網站
符合 Linux 標準。
Apache 也只要改:
AuthUserFile /etc/fs2/users.password
AuthGroupFile /etc/fs2/groups
之後備份也更容易。
我希望順便整理整個 FS2
最後應該變成:
/srv/fs2/
真正資料
/etc/fs2/
所有設定
/var/www/fs2/
Portal
/opt/fs2/
安裝、更新工具
/backup/fs2/
備份
職責非常清楚。
我建議現在先做這件事
FS2 目錄標準化(約 10 分鐘)
/etc/fs2/
users.password
groups
/opt/fs2/
install/
update/
backup/
tools/
/srv/fs2/
storage
/var/www/fs2/
portal
這樣後面 Portal、MariaDB、更新腳本都會很乾淨。
我的建議
下一步不要寫 Portal。
先把 FS2 的目錄、Apache 設定與備份機制整理成正式版本。
之後再開始寫 Portal,整個專案會更容易維護,也更符合你希望做成長期使用系統的目標。這一步完成後,我們再開始設計 Portal 的登入與「修改自己密碼」功能。
🎯 Phase 2A:FS2 標準化
我們的目標是讓整個專案符合 Linux FHS(Filesystem Hierarchy Standard)。
最終目錄
/
├── srv/
│ └── fs2/
│ ├── pub/
│ ├── info/
│ ├── share/
│ ├── private/
│ ├── recycle/
│ ├── backup/
│ └── temp/
│
├── etc/
│ └── fs2/
│ ├── users.password
│ ├── groups
│ ├── fs2.conf
│ └── quota.conf
│
├── var/
│ ├── www/
│ │ ├── fs2-index/
│ │ └── fs2/ ← Portal(未來)
│ │
│ └── log/
│ └── fs2/
│
├── opt/
│ └── fs2/
│ ├── install/
│ ├── update/
│ ├── backup/
│ ├── tools/
│ ├── sql/
│ └── version/
│
└── backup/
└── fs2/
第一件事:搬設定
目前:
/var/www/apache/var/
改成:
sudo mkdir -p /etc/fs2
sudo mv /var/www/apache/var/users.password /etc/fs2/
sudo mv /var/www/apache/var/groups /etc/fs2/
sudo cp /var/www/apache/var/DavLock /etc/fs2/DavLock
DavLock 有兩種選擇:
- 保留在
/var/lib/dav(Debian/Ubuntu 常見) - 放
/etc/fs2(目前也可以)
我比較推薦改成:
sudo mkdir -p /var/lib/fs2
sudo mv /var/www/apache/var/DavLock /var/lib/fs2/
因為 Lock DB 是執行時資料,不是設定檔。
所以未來:
/etc/fs2
users.password
groups
/var/lib/fs2
DavLock
會更符合 Linux 慣例。
第二件事:建立專案目錄
sudo mkdir -p /opt/fs2/{install,update,backup,tools,sql,version}
sudo mkdir -p /var/log/fs2
sudo mkdir -p /var/www/fs2
第三件事:建立版本
echo "FS2 1.0.0" | sudo tee /opt/fs2/version/VERSION
以後:
cat /opt/fs2/version/VERSION
直接知道版本。
第四件事:Apache
修改:
AuthUserFile /etc/fs2/users.password
AuthGroupFile /etc/fs2/groups
DavLockDB /var/lib/fs2/DavLock
全部一起改。
第五件事:建立設定檔
sudo nano /etc/fs2/fs2.conf
例如:
FS2_NAME=FS2
DOMAIN=fs2.go2see.me
STORAGE=/srv/fs2
BACKUP=/backup/fs2
LOG=/var/log/fs2
VERSION=1.0.0
以後 PHP、Shell Script 都讀同一份設定。
我還想加入一個功能(從一開始就做好)
fs2ctl
就像:
systemctl
一樣。
例如:
sudo fs2ctl status
sudo fs2ctl backup
sudo fs2ctl users
sudo fs2ctl version
以後甚至:
sudo fs2ctl update
全部都由一個入口管理。
我建議的開發路線
完成 Phase 2A 後:
- 整理目錄與設定(現在)
- 建立
fs2ctl管理工具 - 建立 Portal 首頁
- 建立自助修改密碼
- 建立 Admin 後台
- 最後再導入 MariaDB 管理
這樣整個 FS2 就會像一個真正的 Linux 服務,而不是零散的 Apache 設定。後續無論是升級到 Ubuntu 24.04,或增加功能,都會容易很多。
Phase 2A 實作:搬設定 + 改 Apache + 測試
sudo -s 後開始繼續。
1. 建正式目錄
mkdir -p /etc/fs2
mkdir -p /var/lib/fs2
mkdir -p /var/log/fs2
mkdir -p /opt/fs2/{install,update,backup,tools,sql,version}
mkdir -p /var/www/fs2
mkdir -p /backup/fs2
2. 搬帳號與群組檔
mv /var/www/apache/var/users.password /etc/fs2/
mv /var/www/apache/var/groups /etc/fs2/
mv /var/www/apache/var/DavLock /var/lib/fs2/
如果某個檔案已經搬過,出現 No such file 沒關係,先查:
ls -l /etc/fs2
ls -l /var/lib/fs2
3. 設權限
chown root:www-data /etc/fs2/users.password /etc/fs2/groups
chmod 640 /etc/fs2/users.password /etc/fs2/groups
chown www-data:www-data /var/lib/fs2/DavLock
chmod 660 /var/lib/fs2/DavLock
4. 建 FS2 設定檔
cat > /etc/fs2/fs2.conf <<'EOF'
FS2_NAME=FS2
DOMAIN=fs2.go2see.me
STORAGE=/srv/fs2
BACKUP=/backup/fs2
LOG=/var/log/fs2
VERSION=1.0.0
EOF
5. 建版本檔
echo "FS2 1.0.0" > /opt/fs2/version/VERSION
6. 修改 Apache 設定
nano /etc/apache2/sites-available/fs2-le-ssl.conf
把 /etc/apache2/sites-available/fs2-le-ssl.conf 的所有:
AuthUserFile /var/www/apache/var/users.password
AuthGroupFile /var/www/apache/var/groups
DavLockDB /var/www/apache/var/DavLock
改成:
AuthUserFile /etc/fs2/users.password
AuthGroupFile /etc/fs2/groups
DavLockDB /var/lib/fs2/DavLock
==》 直接用指令:
sed -i 's#/var/www/apache/var/users.password#/etc/fs2/users.password#g' /etc/apache2/sites-available/fs2-le-ssl.conf
sed -i 's#/var/www/apache/var/groups#/etc/fs2/groups#g' /etc/apache2/sites-available/fs2-le-ssl.conf
sed -i 's#/var/www/apache/var/DavLock#/var/lib/fs2/DavLock#g' /etc/apache2/sites-available/fs2-le-ssl.conf
7. 測試 Apache
apache2ctl configtest
systemctl reload apache2
8. 重新測一次權限
curl -I https://fs2.go2see.me/
curl -I https://fs2.go2see.me/pub/
curl -I https://fs2.go2see.me/info/
curl -u cyue https://fs2.go2see.me/info/
curl -u johnny https://fs2.go2see.me/share/
curl -u johnny https://fs2.go2see.me/johnny/
curl -u johnny https://fs2.go2see.me/cyue/
預期仍然跟剛才一樣。完成後,FS2 目錄標準化就完成。
Phase 2B 先做一個管理工具 fs2ctl。
把方向修正一下,我們先不要做 Portal。
原因:
以後你會常做:
- 新增使用者
- 刪除使用者
- 重設密碼
- 建立私人目錄
- 備份
- 更新
如果都靠:htpasswd mkdir chown nano久了會很累。
我希望變成:
sudo fs2ctl user add johnny
自動完成:
✓ htpasswd
✓ mkdir /srv/fs2/private/johnny
✓ chown
✓ chmod
✓ Apache reload
例如
sudo fs2ctl passwd johnny
==> 修改密碼
例如
sudo fs2ctl backup
==> 備份
例如
sudo fs2ctl version
==>
FS2 1.0.0
目錄
建立:
mkdir -p /opt/fs2/bin
裡面放:
/opt/fs2/bin/fs2ctl
再建立:
ln -s /opt/fs2/bin/fs2ctl /usr/local/bin/fs2ctl
以後:
fs2ctl
就可以用了。
第一版功能
fs2ctl status
fs2ctl version
fs2ctl backup
fs2ctl users
fs2ctl adduser
fs2ctl passwd
fs2ctl removeuser
Status
例如:
FS2 Version
1.0.0
Apache
Running
Storage
OK
Backup
OK
Users
7
Users
例如:
cyue
shari
johnny
tony
may
yuhan
yuchen
直接從:
/etc/fs2/users.password
讀出。
Add User
例如:
sudo fs2ctl adduser tom
自動:
建立密碼
建立 private/tom
加入 member
reload apache
完全不用手工。
Remove User
例如:
sudo fs2ctl removeuser tom
詢問:
Delete Home ?
Y/N
Backup
就是:
sudo fs2ctl backup
執行:
/opt/fs2/tools/backup_fs2.sh
不過,我想再調整一件事情
目前使用者資訊分散在:
/etc/fs2/users.password/etc/fs2/groups/srv/fs2/private/
未來要新增一位使用者,需要修改三個地方。
我建議我們在 Phase 2B 就建立一個小小的設定檔,例如:
users:
- username: cyue
role: maintainer
- username: shari
role: member
- username: johnny
role: member
...
以後 fs2ctl adduser、fs2ctl removeuser 都依這份設定更新 Apache、群組、私人目錄。
這樣使用者資料只有一份來源(Single Source of Truth),將來即使導入 MariaDB,也只要讓 fs2ctl 從資料庫讀寫即可,不需要重寫整個管理工具。
我認為這會是 FS2 最值得投資的基礎設計。
做 FS2 管理工具 fs2ctl 第一版。
1. 建目錄
mkdir -p /opt/fs2/bin
mkdir -p /opt/fs2/tools
2. 建立 fs2ctl
nano /opt/fs2/bin/fs2ctl
貼上:
#!/bin/bash
set -e
FS2_CONF="/etc/fs2/fs2.conf"
USER_FILE="/etc/fs2/users.password"
GROUP_FILE="/etc/fs2/groups"
STORAGE="/srv/fs2"
VERSION_FILE="/opt/fs2/version/VERSION"
BACKUP_SCRIPT="/opt/fs2/tools/backup_fs2.sh"
cmd="$1"
arg="$2"
need_root() {
if [ "$(id -u)" -ne 0 ]; then
echo "Please run as root."
exit 1
fi
}
case "$cmd" in
status)
echo "FS2 Status"
echo "----------"
echo -n "Version: "
cat "$VERSION_FILE" 2>/dev/null || echo "unknown"
echo -n "Apache: "
systemctl is-active apache2
echo -n "Storage: "
[ -d "$STORAGE" ] && echo "OK" || echo "Missing"
echo -n "User file: "
[ -f "$USER_FILE" ] && echo "OK" || echo "Missing"
echo -n "Group file: "
[ -f "$GROUP_FILE" ] && echo "OK" || echo "Missing"
echo -n "Users: "
if [ -f "$USER_FILE" ]; then
cut -d: -f1 "$USER_FILE" | wc -l
else
echo "0"
fi
;;
version)
cat "$VERSION_FILE"
;;
users)
cut -d: -f1 "$USER_FILE"
;;
passwd)
need_root
if [ -z "$arg" ]; then
echo "Usage: fs2ctl passwd USER"
exit 1
fi
htpasswd "$USER_FILE" "$arg"
systemctl reload apache2
echo "Password updated: $arg"
;;
adduser)
need_root
if [ -z "$arg" ]; then
echo "Usage: fs2ctl adduser USER"
exit 1
fi
if grep -q "^${arg}:" "$USER_FILE"; then
echo "User already exists: $arg"
exit 1
fi
htpasswd "$USER_FILE" "$arg"
mkdir -p "$STORAGE/private/$arg"
chown -R www-data:www-data "$STORAGE/private/$arg"
chmod 775 "$STORAGE/private/$arg"
if grep -q "^members:" "$GROUP_FILE"; then
sed -i "s/^members:.*/& $arg/" "$GROUP_FILE"
else
echo "members: $arg" >> "$GROUP_FILE"
fi
echo ""
echo "IMPORTANT:"
echo "You still need to add this user's Alias block in Apache:"
echo " /etc/apache2/sites-available/fs2-le-ssl.conf"
echo ""
systemctl reload apache2
echo "User added: $arg"
;;
backup)
need_root
"$BACKUP_SCRIPT"
;;
reload)
need_root
apache2ctl configtest
systemctl reload apache2
;;
*)
echo "FS2 Control Tool"
echo ""
echo "Usage:"
echo " fs2ctl status"
echo " fs2ctl version"
echo " fs2ctl users"
echo " fs2ctl passwd USER"
echo " fs2ctl adduser USER"
echo " fs2ctl backup"
echo " fs2ctl reload"
;;
esac
3. 權限與捷徑
chmod +x /opt/fs2/bin/fs2ctl
ln -sf /opt/fs2/bin/fs2ctl /usr/local/bin/fs2ctl
4. 測試
fs2ctl status
fs2ctl version
fs2ctl users
5. 測試備份
fs2ctl backup
這版先完成基本管理。下一步再把 Apache 使用者 Alias 也自動化。
下一步做 fs2ctl v1.1:自動產生使用者 Apache Alias 設定。
目前 adduser 還要手動改 Apache,這不完整。改成:
/etc/apache2/conf-available/fs2-users.conf
由 fs2ctl 自動生成。
1. 建立使用者設定檔
nano /etc/fs2/users.list
貼:
cyue:maintainer
shari:member
johnny:member
tony:member
may:member
yuhan:member
yuchen:member
2. 啟用 Apache include
修改:
nano /etc/apache2/sites-available/fs2-le-ssl.conf
把所有個人目錄 Alias 區塊刪掉,也就是這類都刪:
Alias /cyue /srv/fs2/private/cyue
...
刪掉 cyue/shari/johnny/tony/may/yuhan/yuchen 全部個人段落。
然後在 </VirtualHost> 前面加入:
IncludeOptional /etc/apache2/conf-available/fs2-users.conf
3. 建產生腳本
sudo nano /opt/fs2/tools/generate_apache_users.sh
貼上:
#!/bin/bash
set -e
USER_LIST="/etc/fs2/users.list"
OUT="/etc/apache2/conf-available/fs2-users.conf"
STORAGE="/srv/fs2"
AUTH_FILE="/etc/fs2/users.password"
cat > "$OUT" <<'EOF'
# Auto-generated by FS2.
# Do not edit manually.
EOF
while IFS=: read -r user role; do
[ -z "$user" ] && continue
[[ "$user" =~ ^# ]] && continue
cat >> "$OUT" <
DAV On
Options Indexes
AllowOverride None
AuthType Basic
AuthName "FS2"
AuthUserFile $AUTH_FILE
Require user $user
EOF
done < "$USER_LIST"
apache2ctl configtest
systemctl reload apache2
echo "Generated: $OUT"
4. 權限
sudo chmod +x /opt/fs2/tools/generate_apache_users.sh
5. 產生設定
sudo /opt/fs2/tools/generate_apache_users.sh
6. 測試
curl -u johnny https://fs2.go2see.me/johnny/
curl -u johnny https://fs2.go2see.me/cyue/
預期:
/johnny/ 成功
/cyue/ 失敗
完成後,下一步再把 fs2ctl adduser 改成自動更新 users.list、建立目錄、重建 Apache 使用者設定。
繼續做 fs2ctl v1.2:
讓 adduser 自動更新 users.list、groups、目錄、Apache Alias。
1. 改 fs2ctl
sudo nano /opt/fs2/bin/fs2ctl
把整份換成下面這版:
#!/bin/bash
set -e
USER_FILE="/etc/fs2/users.password"
GROUP_FILE="/etc/fs2/groups"
USER_LIST="/etc/fs2/users.list"
STORAGE="/srv/fs2"
VERSION_FILE="/opt/fs2/version/VERSION"
BACKUP_SCRIPT="/opt/fs2/tools/backup_fs2.sh"
GEN_APACHE_USERS="/opt/fs2/tools/generate_apache_users.sh"
cmd="$1"
arg="$2"
need_root() {
if [ "$(id -u)" -ne 0 ]; then
echo "Please run as root."
exit 1
fi
}
case "$cmd" in
status)
echo "FS2 Status"
echo "----------"
echo -n "Version: "
cat "$VERSION_FILE" 2>/dev/null || echo "unknown"
echo -n "Apache: "
systemctl is-active apache2
echo -n "Storage: "
[ -d "$STORAGE" ] && echo "OK" || echo "Missing"
echo -n "User file: "
[ -f "$USER_FILE" ] && echo "OK" || echo "Missing"
echo -n "Group file: "
[ -f "$GROUP_FILE" ] && echo "OK" || echo "Missing"
echo -n "User list: "
[ -f "$USER_LIST" ] && echo "OK" || echo "Missing"
echo -n "Users: "
[ -f "$USER_LIST" ] && grep -v '^#' "$USER_LIST" | grep -v '^$' | wc -l || echo "0"
;;
version)
cat "$VERSION_FILE"
;;
users)
if [ -f "$USER_LIST" ]; then
cat "$USER_LIST"
else
cut -d: -f1 "$USER_FILE"
fi
;;
passwd)
need_root
[ -z "$arg" ] && echo "Usage: fs2ctl passwd USER" && exit 1
htpasswd "$USER_FILE" "$arg"
systemctl reload apache2
echo "Password updated: $arg"
;;
adduser)
need_root
[ -z "$arg" ] && echo "Usage: fs2ctl adduser USER" && exit 1
if ! [[ "$arg" =~ ^[a-zA-Z0-9._-]+$ ]]; then
echo "Invalid username: $arg"
exit 1
fi
if grep -q "^${arg}:" "$USER_FILE" 2>/dev/null; then
echo "User already exists in password file: $arg"
exit 1
fi
if grep -q "^${arg}:" "$USER_LIST" 2>/dev/null; then
echo "User already exists in users.list: $arg"
exit 1
fi
htpasswd "$USER_FILE" "$arg"
mkdir -p "$STORAGE/private/$arg"
chown -R www-data:www-data "$STORAGE/private/$arg"
chmod 775 "$STORAGE/private/$arg"
echo "$arg:member" >> "$USER_LIST"
if grep -q "^members:" "$GROUP_FILE"; then
sed -i "s/^members:.*/& $arg/" "$GROUP_FILE"
else
echo "members: $arg" >> "$GROUP_FILE"
fi
"$GEN_APACHE_USERS"
echo "User added: $arg"
;;
backup)
need_root
"$BACKUP_SCRIPT"
;;
reload)
need_root
apache2ctl configtest
systemctl reload apache2
;;
gen-apache)
need_root
"$GEN_APACHE_USERS"
;;
*)
echo "FS2 Control Tool"
echo ""
echo "Usage:"
echo " fs2ctl status"
echo " fs2ctl version"
echo " fs2ctl users"
echo " fs2ctl passwd USER"
echo " fs2ctl adduser USER"
echo " fs2ctl backup"
echo " fs2ctl reload"
echo " fs2ctl gen-apache"
;;
esac
2. 加執行權限
sudo chmod +x /opt/fs2/bin/fs2ctl
3. 測試狀態
fs2ctl status
fs2ctl users
4. 測試產生 Apache user config
sudo fs2ctl gen-apache
5. 測試新增一個臨時使用者
sudo fs2ctl adduser testuser
測:
curl -u testuser https://fs2.go2see.me/testuser/
curl -u testuser https://fs2.go2see.me/cyue/
預期:
/testuser/ 成功
/cyue/ 失敗
測完如果要移除,我下一步給你做 removeuser。
繼續做 fs2ctl v1.3:removeuser。
1. 修改 fs2ctl
sudo nano /opt/fs2/bin/fs2ctl
在 adduser) 那段後面、backup) 前面,加入這段:
removeuser)
need_root
[ -z "$arg" ] && echo "Usage: fs2ctl removeuser USER" && exit 1
if [ "$arg" = "cyue" ]; then
echo "Refuse to remove maintainer: cyue"
exit 1
fi
if ! grep -q "^${arg}:" "$USER_FILE" 2>/dev/null; then
echo "User not found in password file: $arg"
exit 1
fi
echo "Removing user: $arg"
read -p "Delete private folder /srv/fs2/private/$arg ? Type YES to delete: " confirm
htpasswd -D "$USER_FILE" "$arg" || true
if [ -f "$USER_LIST" ]; then
sed -i "/^${arg}:/d" "$USER_LIST"
fi
if [ -f "$GROUP_FILE" ]; then
sed -i "s/^members:.*/$(grep '^members:' "$GROUP_FILE" | sed "s/ $arg//g")/" "$GROUP_FILE"
sed -i "s/^maintainers:.*/$(grep '^maintainers:' "$GROUP_FILE" | sed "s/ $arg//g")/" "$GROUP_FILE"
fi
if [ "$confirm" = "YES" ]; then
rm -rf "$STORAGE/private/$arg"
echo "Private folder deleted: $STORAGE/private/$arg"
else
echo "Private folder kept: $STORAGE/private/$arg"
fi
"$GEN_APACHE_USERS"
echo "User removed: $arg"
;;
然後在最下面 Usage 區加一行:
echo " fs2ctl removeuser USER"
2. 測試語法
sudo fs2ctl status
如果有錯,多半是插入位置錯,要確保每個段落都是:
command)
...
;;
3. 測試移除 testuser
sudo fs2ctl removeuser testuser
它會問:
Delete private folder /srv/fs2/private/testuser ? Type YES to delete:
輸入:
YES
4. 驗證
fs2ctl users
grep testuser /etc/fs2/users.password
grep testuser /etc/fs2/groups
ls -ld /srv/fs2/private/testuser
curl -u testuser https://fs2.go2see.me/testuser/
預期:
users.list 沒有 testuser
users.password 沒有 testuser
groups 沒有 testuser
private/testuser 不存在
curl 登入失敗
我們目前其實已經不是在做 WebDAV,而是在做一套 FS2 Server。
接下來如果再一直加功能,Shell Script 會開始變得很難維護。
我建議從這裡開始改架構(很重要)
目前
fs2ctl
1000+
行
以後會變成
2000+
3000+
不好維護。
我建議改成
/opt/fs2/
bin/
fs2ctl
lib/
adduser.sh
removeuser.sh
passwd.sh
backup.sh
apache.sh
users.sh
tools/
config/
version/
也就是
fs2ctl adduser
只是:
source lib/adduser.sh
維護非常容易。
Phase 3 開始建立 FS2 Framework
例如:
/opt/fs2/
bin/
fs2ctl
lib/
config/
sql/
portal/
api/
tools/
version/
docs/
像真正的產品。
Portal
我建議不要放:
/var/www/html
改:
/var/www/fs2
裡面:
index.php
login.php
profile.php
logout.php
admin/
api/
assets/
css/
js/
img/
API
以後全部 API:
/api/
login.php
password.php
announcement.php
users.php
Portal 不直接碰 Shell。
fs2ctl
最後會變成:
fs2ctl
↓
lib/*.sh
↓
Apache
↓
WebDAV
最重要的一件事
不要再用 htpasswd 當唯一資料來源。
我希望改成:
users.yml
例如:
version: 1
users:
- username: cyue
role: maintainer
- username: johnny
role: member
- username: may
role: member
然後:
users.yml
↓
generate htpasswd
↓
generate groups
↓
generate apache
↓
generate portal
只有一份來源(Single Source of Truth)。
最終架構
users.yml
│
▼
+--------------------+
| fs2ctl build |
+--------------------+
│
├── users.password
├── groups
├── fs2-users.conf
└── Portal Cache
以後:
sudo fs2ctl build
全部重新產生。
我認為這是整個專案最重要的一步
我們現在就停在這裡,不再增加零散功能,而是把 FS2 變成一個有建置流程(Build Process)的專案。
我建議從這一版開始,我們建立:
FS2 v2.0
特點:
- 一份設定:
users.yml。 - 自動產生:Apache、群組、
htpasswd等設定。 - 模組化:
fs2ctl只負責調用各個子模組。 - 未來可切換:如果之後改用 MariaDB 或 LDAP,只要改 build 模組,不需要重寫整個系統。
我認為這會比一直在 htpasswd、groups、Apache 設定之間同步修改,更容易維護,也更符合你想把 FS2 做成長期專案的目標。
繼續。下一步做
FS2 v2.0 Framework
先把結構整理起來,但不破壞現在已經可用的 Phase 1。
1. 建立 Framework 目錄
# sudo -s
mkdir -p /opt/fs2/{bin,lib,config,tools,sql,portal,api,docs,version}
mkdir -p /etc/fs2
2. 建立使用者主設定
nano /etc/fs2/users.yml
貼:
version: 1
users:
- username: cyue
role: maintainer
- username: shari
role: member
- username: johnny
role: member
- username: tony
role: member
- username: may
role: member
- username: yuhan
role: member
- username: yuchen
role: member
3. 建立 build 腳本
nano /opt/fs2/lib/build.sh
貼:
#!/bin/bash
set -e
USERS_YML="/etc/fs2/users.yml"
USERS_LIST="/etc/fs2/users.list"
GROUPS="/etc/fs2/groups"
APACHE_USERS="/etc/apache2/conf-available/fs2-users.conf"
STORAGE="/srv/fs2"
AUTH_FILE="/etc/fs2/users.password"
[ -f "$USERS_YML" ] || {
echo "Missing $USERS_YML"
exit 1
}
echo "# Generated from users.yml" > "$USERS_LIST"
grep "username:" "$USERS_YML" | awk '{print $3}' | while read -r user; do
role=$(grep -A1 "username: $user" "$USERS_YML" | grep "role:" | awk '{print $2}')
echo "$user:$role" >> "$USERS_LIST"
mkdir -p "$STORAGE/private/$user"
chown -R www-data:www-data "$STORAGE/private/$user"
chmod 775 "$STORAGE/private/$user"
done
members=$(awk -F: '$2=="member" || $2=="maintainer" {printf "%s ", $1}' "$USERS_LIST")
maintainers=$(awk -F: '$2=="maintainer" {printf "%s ", $1}' "$USERS_LIST")
cat > "$GROUPS" < "$APACHE_USERS" <> "$APACHE_USERS" <
DAV On
Options Indexes
AllowOverride None
AuthType Basic
AuthName "FS2"
AuthUserFile $AUTH_FILE
Require user $user
EOF
done
apache2ctl configtest
systemctl reload apache2
echo "FS2 build completed."
4. 權限
chmod +x /opt/fs2/lib/build.sh
5. 修改 fs2ctl 加上 build
nano /opt/fs2/bin/fs2ctl
在 case "$cmd" in 裡面加入:
build)
need_root
/opt/fs2/lib/build.sh
;;
Usage 區加入:
echo " fs2ctl build"
6. 執行 build
sudo fs2ctl build
7. 驗證
cat /etc/fs2/users.list
cat /etc/fs2/groups
head -80 /etc/apache2/conf-available/fs2-users.conf
curl -u johnny https://fs2.go2see.me/johnny/
curl -u johnny https://fs2.go2see.me/cyue/
預期:
/johnny/ 成功
/cyue/ 失敗
這一步完成後,使用者主資料就從 users.list 升級為 users.yml。
不要急著做 users.yml。
原因是目前 users.yml 需要額外工具(例如 yq)或自己解析 YAML,Shell 不太適合處理,後面如果加入 Email、Quota、Role 等欄位,維護成本會提高。
我建議改用 INI 格式
建立:
sudo nano /etc/fs2/users.conf
內容:
[cyue]
role=maintainer
email=
quota=100G
[shari]
role=member
email=
quota=20G
[johnny]
role=member
email=
quota=20G
[tony]
role=member
email=
quota=20G
[may]
role=member
email=
quota=20G
[yuhan]
role=member
email=
quota=20G
[yuchen]
role=member
email=
quota=20G
優點:
- Shell 很容易讀取。
- PHP 也可以直接用
parse_ini_file()。 - 未來改成 MariaDB 時也容易轉換。
- 不需要安裝任何額外工具。
然後建立 FS2 主設定
sudo nano /etc/fs2/fs2.conf
內容:
FS2_NAME=FS2
DOMAIN=fs2.go2see.me
VERSION=1.0.0
STORAGE=/srv/fs2
CONFIG=/etc/fs2
BACKUP=/backup/fs2
LOG=/var/log/fs2
USER_FILE=/etc/fs2/users.password
GROUP_FILE=/etc/fs2/groups
USER_CONF=/etc/fs2/users.conf
確認目前目錄
請執行:
tree -L 2 /opt/fs2
tree -L 2 /etc/fs2
tree -L 2 /srv/fs2
如果沒有 tree:
sudo apt install tree
把輸出貼給我。
tree -L 2 /opt/fs2
tree -L 2 /etc/fs2
tree -L 2 /srv/fs2
/opt/fs2
├── api
├── backup
├── bin
│ └── fs2ctl
├── config
├── docs
├── install
├── lib
│ └── build.sh
├── portal
├── sql
├── tools
│ └── generate_apache_users.sh
├── update
└── version
└── VERSION
12 directories, 4 files
/etc/fs2
├── fs2.conf
├── groups
├── users.conf
├── users.list
├── users.password
└── users.yml
0 directories, 6 files
/srv/fs2
├── backup
├── info
│ └── test-cyue.txt
├── private
│ ├── cyue
│ ├── johnny
│ ├── may
│ ├── shari
│ ├── tony
│ ├── yuchen
│ └── yuhan
├── pub
├── recycle
├── share
│ └── test-johnny.txt
└── temp
14 directories, 2 files
接下來(Phase 2C)
我們不再新增 Shell 功能,而是開始建立 FS2 Portal:
/var/www/fs2/
├── index.php
├── login.php
├── logout.php
├── profile.php
├── css/
├── js/
├── img/
└── api/
Portal 第一版先做到:
- 首頁
- 系統狀態
- 公告
- 各資料夾入口(pub、info、share、個人目錄)
- 不需要登入
等 Portal 穩定後,再加入登入與修改密碼功能。這樣會比一直擴充 fs2ctl 更有價值,也更接近你最初希望建立的完整檔案服務。
下一步可以做:
FS2 Portal v1.0
/var/www/fs2
首頁 + 快速連結 + 公告 + 系統資訊
這一步會讓 https://fs2.go2see.me/ 看起來像正式服務,而不是普通 Apache 首頁。
開始做 FS2 Portal v1.0。
先做靜態 PHP 首頁,不碰登入、不影響 WebDAV。
1. 建 Portal 目錄
# sudo -s
mkdir -p /var/www/fs2/{assets,css,js,img}
2. 建首頁
nano /var/www/fs2/index.php
貼上:
FS2 - go2see.me
FS2
go2see.me File Server · WebDAV · Version = htmlspecialchars($version) ?>
公告:FS2 Phase 1 已完成。Public、Information、Share 與個人資料夾已啟用。
快速入口
WebDAV 位址
Public:https://= $domain ?>/pub/
Information:https://= $domain ?>/info/
Share:https://= $domain ?>/share/
個人資料夾:https://= $domain ?>/帳號名稱/
3. 改 Apache 首頁 DocumentRoot
nano /etc/apache2/sites-available/fs2-le-ssl.conf
把:
DocumentRoot /var/www/fs2-index
改成:
DocumentRoot /var/www/fs2
把:
改成:
4. 確認 PHP 模組
apache2ctl -M | grep php
如果沒有看到 PHP module,安裝:
apt install libapache2-mod-php php
systemctl reload apache2
5. 測試
apache2ctl configtest
systemctl reload apache2
curl -I https://fs2.go2see.me/
預期:
HTTP/1.1 200 OK
Content-Type: text/html
然後瀏覽器打開:
https://fs2.go2see.me/
很好,目前我們已經完成了 FS2 的核心。
我幫你整理一下目前的成果:
⭐⭐⭐⭐⭐ Phase 1:完成
⭐⭐⭐⭐⭐ Phase 2A:完成
⭐⭐⭐⭐⭐ Portal v1:完成
這已經不是一般的 WebDAV,而是一個有架構的檔案服務。
我建議現在不要急著增加功能
而是把目前的專案整理成 FS2 v1.0 Release。
我會先做這五件事
① README
/opt/fs2/
README.md
記錄:
- 安裝
- 更新
- 備份
- 使用者
- 目錄
② CHANGELOG
CHANGELOG.md
例如
1.0.0
Initial Release
Apache WebDAV
HTTPS
Portal
User Management
③ install.sh
做到:
sudo ./install.sh
全部安裝。
不用再一條一條打。
④ update.sh
以後:
sudo ./update.sh
自動:
- backup
- reload
- configtest
⑤ health check
例如:
fs2ctl health
檢查:
Apache
SSL
Storage
Password File
Groups
LockDB
Portal
Backup
如果哪個壞掉:
FAIL
立即知道。
然後才開始 v1.1
我建議下一版:
登入
修改密碼
公告
Dashboard
而不是先做管理員。
我的建議(很重要)
我不建議自己開發完整登入系統。
Portal 可以有登入,但WebDAV 仍然使用 Apache Basic Authentication。
這樣:
- Windows
- macOS
- iPhone
- Android
全部都不用改。
Portal 只是:
Dashboard
Announcement
Change Password
Profile
即可。
v1.2
再加入:
Admin
User
Group
Quota
Log
v2
最後才:
MariaDB
SSO
2FA
Email
API
我們已經完成的比你原本規劃的大很多
最初只是:
「重構 dav2,改成 fs2。」
現在已經變成:
- ✅ 標準 Linux 目錄
- ✅ HTTPS
- ✅ WebDAV
- ✅ 公開 / 公告 / 共用 / 私人
- ✅ 七位使用者
- ✅ 管理工具 (
fs2ctl) - ✅ Portal 首頁
- ✅ 專案目錄 (
/opt/fs2) - ✅ 設定集中 (
/etc/fs2) - ✅ 備份架構
我認為現在應該先把 FS2 v1.0 封版,之後再以 v1.1、v1.2 的方式逐步增加功能,而不是一直累加到一個難以維護的版本。
下一步我建議做的不是新功能,而是產出一份完整的《FS2 System Administrator Guide》(安裝、備份、還原、升級、使用者管理、故障排除)。有了這份文件,未來不論重灌 VM、升級 Ubuntu,或交接給其他人,都能快速重建整套系統。這會是讓 FS2 真正成為一個可長期維護專案的最後一塊拼圖。
很好,那我們把 FS2 v1.0 正式封版。
我建議從今天開始,FS2 不再只是聊天中的設定,而是一個有版本、有文件、有更新流程的專案。
FS2 v1.0 Release
Release Date: 2026-07-02
已完成功能
核心服務
- ✅ Ubuntu 22.04
- ✅ Apache 2.4
- ✅ HTTPS(Let's Encrypt)
- ✅ WebDAV
儲存架構
- ✅
/srv/fs2/pub - ✅
/srv/fs2/info - ✅
/srv/fs2/share - ✅
/srv/fs2/private/<user>
使用者
- ✅ cyue(Maintainer)
- ✅ shari
- ✅ johnny
- ✅ tony
- ✅ may
- ✅ yuhan
- ✅ yuchen
權限
- ✅
pub:公開唯讀 - ✅
info:成員唯讀,Maintainer 可寫 - ✅
share:成員可讀寫 - ✅ 個人目錄:僅本人可存取
系統管理
- ✅
fs2ctl - ✅ 自動產生 Apache User Alias
- ✅ 備份腳本
- ✅ Portal 首頁
建議的 Git 專案
現在開始,我建議把 /opt/fs2 變成 Git Repository。
cd /opt/fs2
git init
git add .
git commit -m "FS2 v1.0 Initial Release"
之後每次修改:
git add .
git commit -m "v1.0.1 Fix Apache User Generator"
這樣任何設定變更都有歷史紀錄。
建議加入的文件
我會建立這些文件:
/opt/fs2/docs/
Architecture.md
Install.md
Upgrade.md
Backup.md
Restore.md
Apache.md
Users.md
Portal.md
ReleaseNotes.md
其中最重要的是:
- Architecture.md:整體架構、目錄、權限。
- Install.md:從乾淨 Ubuntu 建立 FS2 的完整步驟。
- Backup.md / Restore.md:備份與還原流程。
- Users.md:新增、停用、重設密碼、權限管理。
建議的版本規劃
| 版本 | 內容 |
|---|---|
| 1.0 | WebDAV、HTTPS、Portal 首頁、fs2ctl(完成) |
| 1.1 | Portal 登入、修改密碼、公告 |
| 1.2 | 管理介面、使用者管理、容量管理 |
| 1.5 | Portal 檔案管理(Upload、Rename、Move、Delete) |
| 2.0 | MariaDB、API、SSO、2FA |
Ubuntu 24.04 升級
等到 FS2 v1.1 完成後,我們再安排:
- 完整備份 VM。
- 升級到 Ubuntu 24.04。
- 驗證 Apache、PHP、WordPress、FS2。
- 更新文件。
這樣風險最低。
我建議的下一個工作
接下來不要再零碎地增加功能,而是建立一個完整的 FS2 專案目錄:
/opt/fs2
├── bin/
├── lib/
├── tools/
├── docs/
├── install/
├── update/
├── sql/
├── version/
├── CHANGELOG.md
├── README.md
└── LICENSE
然後我會幫你撰寫一套完整的 《FS2 System Administrator Guide》,內容包含:
- 系統架構
- 安裝流程
- Apache 設定說明
- 使用者管理
- 備份與還原
- 升級流程
- 常見故障排除
這份文件會成為 FS2 的正式維運手冊,之後重建、搬遷或升級系統時,都能依照文件快速完成。