Tencent Lighthouse Hong Kong Phone Setup
This runbook sets up a Tencent Cloud Lighthouse instance in Hong Kong as an always-on codewhale host controlled from Feishu/Lark on a phone.
If you are teaching this as the Tencent-native default path, start with docs/TENCENT_CLOUD_REMOTE_FIRST.md. This file is the implementation runbook for the Lighthouse host itself.
Target Architecture
CNB mirror or GitHub branch
-> /opt/whalebro/codewhale
Feishu/Lark mobile app
-> Feishu/Lark long-connection bot
-> codewhale-feishu-bridge systemd service
-> http://127.0.0.1:7878 codewhale serve --http
-> /opt/whalebro
-> codewhale/
Optional public edge:
EdgeOne -> Caddy/Nginx public site on Lighthouse
The runtime API must stay on 127.0.0.1. The bridge is the only phone-facing
control surface. EdgeOne is optional and should only front a deliberate public
HTTP service, not the runtime API.
Remote Whalebro Workspace
Use /opt/whalebro as the VPS workspace root. The first-class checkout is
/opt/whalebro/codewhale.
Create these paths first:
/opt/whalebro/codewhale/opt/whalebro/worktrees
Linux is enough for Rust, Node, and service work. Mac-only release work such
as iOS simulator runs, .app/DMG checks, notarization, and Apple signing
still belongs on the Mac.
Lighthouse Instance
Recommended package for travel:
- Region: Hong Kong (China)
- Image: plain Ubuntu 24.04 LTS or latest Ubuntu LTS
- Size: buy the HK 2 vCPU / 4 GB / 70 GB plan for the first month
- Login: SSH key, not password
- Firewall: SSH open; runtime API on localhost only
Tencent's Lighthouse docs say Linux instances can use SSH keys, and the Lighthouse firewall opens SSH/HTTP/HTTPS by default.
Use 4 GB RAM for compiling Rust and running the bridge comfortably. A 4 vCPU / 8 GB plan is better for multiple parallel agent workers.
Feishu / Lark App
Create an enterprise self-built app in:
- Feishu China:
https://open.feishu.cn/app - Lark international:
https://open.larksuite.com/app
Configure:
- Enable bot capability.
- Copy App ID and App Secret.
- Add permissions for message send/receive. The minimum practical set is:
im:messageim:message:send_as_bot- direct message read permission for your tenant
- group @message read permission only if you intentionally enable group control later
- Add event subscription
im.message.receive_v1. - Use long connection / WebSocket mode.
- Publish the app and add the bot to your Feishu/Lark chat.
Server Bootstrap
SSH into the Lighthouse instance and run:
sudo apt-get update
sudo apt-get install -y git
export DEEPSEEK_BRANCH=main
export DEEPSEEK_REPO_URL=https://cnb.cool/codewhale.net/codewhale.git
git clone --branch "$DEEPSEEK_BRANCH" "$DEEPSEEK_REPO_URL" /tmp/codewhale
cd /tmp/codewhale
sudo DEEPSEEK_REPO_URL="$DEEPSEEK_REPO_URL" \
DEEPSEEK_REPO_BRANCH="$DEEPSEEK_BRANCH" \
bash scripts/tencent-lighthouse/bootstrap-ubuntu.sh
Use an SSH repo URL instead if you want push access from the VPS. If the CNB mirror is unavailable, fall back to:
export DEEPSEEK_REPO_URL=https://github.com/Hmbown/CodeWhale.git
For stable release docs, confirm the CNB mirror has the branch or tag before using it:
export DEEPSEEK_REPO_URL=https://cnb.cool/codewhale.net/codewhale.git
git ls-remote "$DEEPSEEK_REPO_URL" \
refs/heads/main \
refs/tags/v0.8.37
The CNB mirror receives main and release tags. CNB is the default source for
this Lighthouse path; GitHub is the fallback only when the CNB workflow or
credentials are unhealthy.
If this deployment setup has not been pushed to Git yet, either push the branch first or copy this checkout to the VPS before running these commands. A fresh VPS clone cannot see uncommitted local files.
Install Rust 1.88+ for the codewhale user, then build both shipped binaries:
sudo -iu codewhale
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs -o /tmp/rustup-init.sh
sed -n '1,120p' /tmp/rustup-init.sh
sh /tmp/rustup-init.sh -y --profile minimal
. "$HOME/.cargo/env"
rustup default stable
cd /opt/whalebro/codewhale
cargo install --path crates/cli --locked --force
cargo install --path crates/tui --locked --force
exit
Copy and install the bridge/service files:
cd /opt/whalebro/codewhale
sudo bash scripts/tencent-lighthouse/install-services.sh
After editing both env files, validate the bridge/runtime pairing:
sudo -u codewhale node /opt/codewhale/bridge/scripts/validate-config.mjs \
--env /etc/deepseek/feishu-bridge.env \
--runtime-env /etc/deepseek/runtime.env \
--workspace-root /opt/whalebro \
--check-filesystem
Secrets
Generate one runtime token and put the same value in both env files:
openssl rand -hex 32
sudoedit /etc/deepseek/runtime.env
sudoedit /etc/deepseek/feishu-bridge.env
Required values:
/etc/deepseek/runtime.envDEEPSEEK_API_KEYDEEPSEEK_RUNTIME_TOKEN
/etc/deepseek/feishu-bridge.envFEISHU_APP_IDFEISHU_APP_SECRETFEISHU_DOMAIN=feishufor Feishu,larkfor LarkDEEPSEEK_RUNTIME_TOKENFEISHU_ALLOW_GROUPS=falsefor the first deployment
For first pairing, either:
- Temporarily set
DEEPSEEK_ALLOW_UNLISTED=true, message the bot, copy the returnedchat_id, then setDEEPSEEK_CHAT_ALLOWLIST=<chat_id>and turn unlisted access back off. - Or obtain the chat ID from Feishu/Lark event logs and set the allowlist before first start.
Start Services
sudo systemctl start codewhale-runtime
sudo systemctl status codewhale-runtime --no-pager
curl -s http://127.0.0.1:7878/health
sudo systemctl start codewhale-feishu-bridge
sudo journalctl -u codewhale-feishu-bridge -f
Run the Lighthouse doctor after both services are configured:
cd /opt/whalebro/codewhale
sudo bash scripts/tencent-lighthouse/doctor.sh
Enable on boot is done by install-services.sh; if needed:
sudo systemctl enable codewhale-runtime codewhale-feishu-bridge
Phone Commands
DMs can be plain text and are the intended first control path:
check git status and summarize what needs attention
Group chats are disabled by default. If you later set
FEISHU_ALLOW_GROUPS=true, group prompts must start with /ds.
Useful commands:
/status/threads/new/resume <thread_id>/interrupt/compact/allow <approval_id>/deny <approval_id>/allow <approval_id> remember
Use remember only when you intentionally want the runtime thread to flip
toward auto-approval for future tools.
CNB Deploy Button
After the manual Lighthouse setup passes, CNB can become the repeatable deploy button:
- Copy
deploy/tencent-lighthouse/cnb/cnb.yml.exampleto.cnb.ymlin the CNB repo. - Copy
deploy/tencent-lighthouse/cnb/tag_deploy.yml.exampleto.cnb/tag_deploy.yml. - Configure the CNB deploy secrets documented in
deploy/tencent-lighthouse/cnb/README.md. - Trigger the
lighthouse-hkdeployment environment.
Keep this manual until the server is boring. Automatic deploys on every push are convenient later, but they can consume CNB quota and restart the bridge while a phone turn is active.
EdgeOne
EdgeOne is not required for the first Feishu/Lark long-connection setup. Add it only when you need a public HTTPS domain in front of a deliberate public service on the Lighthouse host.
Good EdgeOne uses:
- public docs or tutorial site
- tiny operator status page
- future webhook-mode bridge endpoint
- demo web app hosted on the same Lighthouse instance
Do not use EdgeOne to expose:
http://127.0.0.1:7878/v1/*runtime endpoints- any endpoint that accepts
DEEPSEEK_RUNTIME_TOKEN
End-to-End Validation
From a phone DM to the bot:
- Send
/statusand confirm runtime version, localhost bind, auth state, workspace, git repo, branch, and dirty counts. - Send a harmless prompt such as
summarize git status. - Send
/interruptwhile a turn is active and confirm the turn stops. - Send
/threads, then/resume <thread_id>for one listed thread. - Trigger a tool approval and verify both
/allow <approval_id>and/deny <approval_id>paths. - Restart both services and re-run
/status. - Reboot the instance, then confirm
systemctl status codewhale-runtimeandsystemctl status codewhale-feishu-bridgereturn to active.
Operational Notes
- Bind
codewhale serve --httpto127.0.0.1. - Keep the Lighthouse firewall focused on SSH for this setup.
- Use SSH key auth.
- Use
tmuxfor emergency terminal work from Blink/Termius. - Keep
/opt/whalebro/codewhaleon a personal branch while working from the phone.