本文模仿 vscode-server 效果,藉助 ssh 、反向代理 的方式把原生程式碼對映到外網,透過 Web IDE 開啟。
概述
vscode 推出了一個新的功能 —— vscode-server,可以把本地的程式碼對映到外網(vscode.dev),透過瀏覽器(Web IDE)修改和除錯程式碼。
使用者PC 透過安全隧道與 vscode.dev 通訊,連線成功後,使用者將獲得一個裝置程式碼和 URL,你可以任意的可聯網裝置上開啟這個URL 並驗證 GitHub 帳戶後,就可以透過vscode 的 web 版編輯你的PC上的程式碼。
不足的是瀏覽器上使用時會有點卡頓,主要受到網速的影響,而且需要使用github賬號登入,不太方便。
操作步驟:準備一個github的賬號,然後在 vscode UI 或者 code tunnel命令 生成一個外網url,訪問這個url就可以在任意聯網裝置上透過瀏覽器瀏覽你本機的程式碼,如果需要除錯需要安裝一下vscode 外掛。
分析
本地電腦 與 vscode.dev 連線時採用的安全隧道技術,再透過 vscode.dev 訪問本地電腦的資料夾,具體的安全隧道技術細節比較複雜這裡不展開,不過從實現的角度,還是有現成的技術可以作為解決方案。首先,為了方便和安全對映本地資料夾目錄到容器;然後,把容器的webide、ssh埠對映到外網;最後,就可以在瀏覽器輸入外網地址訪問webide,或者 vscode 的remote ssh功能對原生程式碼進行修改。
解決方案
首先你需要準備 一臺公網的伺服器,以及這臺伺服器對應的公網ip 或者 域名。
- 啟動一個包含開發除錯環境的 webide docker 容器,使用 SmartIDE 在原生程式碼目錄下 執行 smartide start 即可
建立一個容器,檔案對映到你本地資料夾,不直接對映本地會比較安全,也簡單很多,本地作業系統需要對映22會很折騰;另外用 SmartIDE 啟動容器會方便很多,否則你還要自己寫一個映象,環境多了還要維護幾個,乾脆就不折騰了吧。
- 透過 ssh遠端轉發 或者 ngrok內網穿透 的方式把容器的 SSH埠、WebIDE埠對映到外網
- 透過瀏覽器開啟外網地址開啟程式碼視窗,或者 透過 VSCode 的 Remote Development (包含Remote SSH) 外掛進行開發除錯。
準備一臺VM
比較推薦使用 azure 雲,最好是選擇 Ubuntu 系統,包管理更加方便,而且軟體版本也比較新。
建立容器
SmartIDE 建立
## 進入到程式碼目錄
cd CODE_FOLDER
## 執行 smartide start
## 可以到模板庫 https://gitee.com/smartide/smartide-templates.git 檢視您需要的程式碼模板,即開發語言 和 WebIDE型別
## 比如,我是一個 golang 專案,需要使用VSCode 的 webide,指令碼是
smartide start golang --type vscode
檢視 SSH 和 WebIDE 對應的埠,如果命令列視窗關閉,也可以透過docker ps命令檢視。
整個過程不算太快,需要花大改2-3分鐘;看到 “SmartIDE 啟動完畢” 的字眼的時候可以關閉命令列,或者 ctrl + c 退出也不會有影響,應該容器已經安裝到你 PC 的docker上了。
直接使用 docker 建立
相比smartide建立的容器,目測簡單一些,但是實際還是有些麻煩,比如本地埠占用問題,具體的開發語言支援問題 等等,都可能需要自己再編排一下 Dockerfile,而 SmartIDE 把這些坑都踩過了。
- webide 使用 theia,這個WebIDE的特點是擴充套件性強
- 開放ssh服務,方便vscode remote ssh連線
- 需要的開發環境,需要重新編排Dockerfile,這裡暫時略過
## LOCAL_CODE_FOLDER 替換為原生程式碼資料夾路徑
docker run -it --restart always \
-p 8000:3000 \
-p 8022:22 \
-v "LOCAL_CODE_FOLDER:/home/project" \
--name theia \
-d \
brjapon/theia-arm64
SSH 遠端轉發
遠端主機配置
## 首先登入 遠端主機
ssh remote_user@remote_host
## 修改 “/etc/ssh/sshd_config” , GatewayPorts 執行網路連結埠,AllowTcpForwarding 允許tcp轉發,詳情 https://www.jianshu.com/p/e87bb207977c
## GatewayPorts yes
## AllowTcpForwarding yes
vim /etc/ssh/sshd_config
## 複製本地 ~/.ssh 目錄下的 id_rsa、id_rsa.pub 到遠端主機的 ~/.ssh 目錄下
## 重啟服務 / 重啟遠端主機
systemctl restart sshd
遠端轉發
ssh -N -R 0.0.0.0:remote-port:target-host:target-port remote_user@remotehost
例如:ssh -N -R 0.0.0.0:8022:0.0.0.0:6822 -R 0.0.0.0:6800:0.0.0.0:6900 root@test.com
參考:https://wangdoc.com/ssh/port-forwarding#遠端轉發
- remote_port 是你希望連線到遠端主機的埠,如果是雲(比如 Azure)上的主機需要開啟這個埠
- target-host 本地可以訪問的目標 host
- target-port 本地訪問 target-host 使用的埠,比如上面SimpleHTTPServer的 8080
- remote_user 是連線到遠端主機的使用者名稱
- remote_host 是遠端主機的地址
內網穿透
目前比較多人用的內網穿透工具有幾個: NPS 支援tcp、udp,以及http、socket5代理,web管理端比較強大;FRP 高效能的反向代理,支援tcp、udp、http、https等;ngrok 知名度最高,1.7以後閉源,但有公網服務可以使用比較方便。
建議使用FRP,NPS 的管理端太重沒有必要,ngrok 在v1.7後閉源 且 私有化部署非常費勁(按照官方的辦法部署了多次都是失敗),建議大家避坑。
ngrok
以下直接使用 ngrok.com 官網的服務,國內的也有,但不好用。
## 官網 (https://dashboard.ngrok.com/get-started/setup) 註冊賬號,下載客戶端;
## 進入 rgrok 命令列工具所在目錄;
## 複製token,替換“ngrok_token”
ngrok config add-authtoken ngrok_token
## 對映 本地埠 到外網,替換 contarner_binding_port 為本地埠
ngrok tcp localhost:contarner_binding_port
這種效果上最簡單的,藉助公網上的 ngrok 服務,直接對映出去,如圖可以看到內網的資料夾中的內容已經完全對映到了外網,包括隱藏資料夾 bin、obj
frp
從 (releases)[https://github.com/fatedier/frp/releases] 下載作業系統對應的安裝包
├── frpc 客戶端命令列工具
├── frpc.ini 客戶端配置檔案
├── frpc_full.ini 客戶端完整配置示例
├── frps 服務端命令列工具
├── frps.ini 服務端配置檔案
└── frps_full.ini 服務端完整配置示例
服務端
修改配置檔案 frps.ini ,示例可以參考 frps_full.ini,完成後 透過 ./frps -c frps.ini 可以啟動 server
[common]
bind_port = 8088
# token 資訊,客戶端也要保持一致
token=smartide666
# dashboard,可以檢視連線情況
dashboard_addr = 0.0.0.0
dashboard_port = 7500
dashboard_user = admin
dashboard_pwd = admin
在 /lib/systemd/system/ 下建立 frps.service
sudo vim /lib/systemd/system/frps.service
錄入以下內容
[Unit]
Description=frps daemon
[Service]
Type=simple
#此處把 frps_folder_path 替換成 frps的實際安裝目錄
ExecStart=frps_folder_path/frps -c frps_folder_path/frps.ini
[Install]
WantedBy=multi-user.target
伺服器自啟動 / 啟動
# 自啟動
sudo systemctl enable frps
# 啟動
sudo systemctl start frps
客戶端
編輯 frpc.ini 檔案
[common]
server_addr = remote_host
server_port = 8088
token = smartide666
[web]
type = tcp
local_ip = 127.0.0.1
local_port = 6900
remote_port = 6900
[ssh]
type = ssh
local_ip = 127.0.0.1
local_port = 6922
remote_port = 6922
啟動 frpc,如果是 mac/linux 自動的方法可以參考 frp 服務端配置
./frpc -c ./frpc.ini
效果如下