在 A2hosting 用 AppImage deploy Rust rocket 這個 framework 的 app

Rust 的 Rocket 是一個後端框架 (framework)。除了有靜態型別語言的好處(比如減少runtime error)外,還有一個binary檔包全部,免除裝其他太多 library 或是框架 library 的問題。

因為自己的是網路租用的A2 site hosting 空間(Linux),想說為了物盡其用,所以想要把產生的 web app binary 放在上面執行,但想當然爾,還是缺相依性(空間提供的函式庫版本太舊)。後來想,既然 AppImage 可以包一個執行檔的諸多相依軟體或是函式庫,為何不用之包呢?

以下以放在 /path/to/exampleapp 這個 app 為例,講述我 deploy 的方法。

製作原始二進位檔 (binary file)

進入 /path/to/exampleapp,輸入下列 Linux 指令,編譯可執行檔:

1
2
3
4
cargo +nightly build --release # 假設app需要 nightly 的 rust 版本

cargo +nightly run --release

最後應該會在/path/to/exampleapp/target/release找到taikoothong

複製到 AppDir

創立新的/path/to/AppDir,然後把exampleapp複製到這裡:

1
2
3
mkdir /path/to/AppDir

cp /path/to/exampleapp/target/release/exampleapp /path/to/AppDir

安裝appimage

1
2
3
4
5
6
wget -O appimage-builder-x86_64.AppImage https://github.com/AppImageCrafters/appimage-builder/releases/download/v1.1.0/appimage-builder-1.1.0-x86_64.AppImage

chmod +x appimage-builder-x86_64.AppImage


sudo mv appimage-builder-x86_64.AppImage /usr/local/bin/appimage-builder #可以自己另外指定安裝目錄

打包appimage

進去/path/to/,產生appimage 的打包設定檔,依指示設定:

1
2
3
4
5
6
7
8
9
10
11
12
13
cd /path/to

appimage-builder --generate

> Basic Information :
> ? ID [Eg: com.example.app] : com.example.exampleapp
> ? Application Name : Example
> ? Icon : (直接依照預設值,按enter就好)
> ? Version : 0.0.0
> ? Executable path relative to AppDir [usr/bin/app] : exampleapp (執行檔在目錄裡面的相對位置)
> ? Arguments [Default: $@] : $@
> ? Update Information [Default: guess] : guess
> ? Architecture : amd64(請依照平臺所屬的 CPU 架構修改)

最後生成 /path/to/AppImageBuilder.yml,檢視裡面的設定有沒有問題,刪除不必要的sourceline內項目,增加必要的include內 ubuntu 套件等等。

最後輸入指令打包

1
2
3
4
5
6
appimage-builder --recipe AppImageBuilder.yml

mv Example-0.0.0-x86_64.AppImage Example #把可執行檔包起來
cp /path/to/exampleapp/templates -r . #把templates複製過來,如果有其他的檔案一併複製

tar -zcf examplearchive.tar templates Example # 有其他檔案也要包起來

然後把 examplearchive.tar 上傳到site-hosting

解壓縮然後執行

因為我的 site-hosting 空間不支援 Linux 的 FUSE,所以在遠端的 site-hosting 空間需要解壓縮AppImage裡面的檔案,然後執行裡面的可執行檔:

1
2
3
4
5
6
7
8
9
10
11
12
13
cd /path/to/archive #進去 examplearchive.tar 所在的目錄

tar -xvf examplearchive.tar

cd examplearchive

./Example --appimage-extract

cd squashfs-root

nohup ./AppRun & 執行app,用 nohup 確保app在離線後繼續執行

# 預設會於 http://127.0.0.1:8000/ 執行

修改 .htaccess

因為a2hosting使用 .htaccess 轉網頁地址假設我們要把 我的網址/example和其下的網頁,轉址到 app 的 http://127.0.0.1:8000/處理,參考 a2hosting 建議的方式設置如下:

1
2
3
4
5
6
7
8
<IfModule mod_rewrite.c>

DirectoryIndex disabled
RewriteEngine On
RewriteRule ^example$ http://127.0.0.1:8000/ [P,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^example/(.*)$ http://127.0.0.1:8000/$1 [P,L]

這樣打我的網址/example就能進入自己的app了。

參考