前言
其實並沒有隨時隨地寫 code 的需求XD 不過透過搭建自己的 coding server,可以練習非常多關於 docker 以及網路的使用方法,對於容器化技術當道的現在,是個相當不錯的開始。我們也可以應用相似的方式將基於網頁應用的 JupyterLab 搭建在 VPS 上,只要連上網路就能隨時將移動設備(包含筆電)快速接入已經搭好的環境中開始寫程式。優點是不用在自己的本機裝環境,也不用擔心本機的環境版本不統一。缺點當然是 VPS 的性能以及價格的 tradeoff,不過在我們小型的 coding project 中,使用 AWS EC2 的免費 12 個月方案是綽綽有餘的。就算 RAM 不夠,也可以透過 SWAP 來假裝我們有足夠的 RAM,跑一些原本在 512 MB RAM 上跑不太動的應用。
準備
要搭建 RStudio Server,我們需要先準備好:
- AWS EC2 linux instance 並安裝 docker
- 在 AWS EC2 control panel 中開啟 port 8787
- 在 iPad 上安裝 termux 或 iSH 等用以使用 ssh 連接虛擬主機
- 使用 termux 建立 ssh 連線的話可能需要透過電腦將 .pem file (ssh key) 存在 iPad 特定的資料夾下。我自己嘗試使用 iPad 的檔案管理系統將 .pem file 存在各個目錄,但 termux 找不到,只能夠過 itunes 將 key 放在 termux 自身的資料夾中才行。
Pull Image from docker hub
docker hub 有許多打包好的 image 可以直接使用,我們可以使用 rocker 的包含 r-base 的 rstudio image:
https://hub.docker.com/r/rocker/rstudio
rocker 也有提供已經安裝好 tidyverse 的 image,接下來我們會使用這個 image:
https://hub.docker.com/r/rocker/tidyverse
透過 docker pull rocker/tidyverse
將這個 image 下載到 VPS 中,接著可以使用使用:
docker run --rm -p 8787:8787 -e PASSWORD=yourpasswordhere rocker/tidyverse
就可以從 image 建立一個 container ,並跑在 port 8787 上,所以對於 VPS 自己來說,可以從 127.0.0.1:8787 來接入 rstudio server,不過我們自己沒辦法從 VPS 的視角來使用 port 8787,所以我們是把 VPS 對外的 port 8787 映射到自己 localhost 的 port 8787 上。這時只要在你的 ipad 或其他設備上的瀏覽器訪問 YOUR_VPS_IP_ADDRESS:8787 就可以看到 rstudio 的登入介面:
預設的帳號是 rstudio,密碼則是你在下 docker run
後設定的 password
使用
為什麼我沒辦法「存檔」?
這裡有幾點使用上的注意事項,注意到 rocker 提供的 quick start command 有一個 tag —-rm
意思是當我們的容器(container)停止執行後,會被移除。並且另外注意到 docker run
指令會從 image 建立一個全新的 container ,所以不管我們是否保留上次 docker run
後使用的容器,我們只要下的是 docker run
指令,且沒有 commit 的話,便沒辦法保存上一次在 rstudio 中的任何操作,包含建立 R script 或者是安裝 packages。
一種方式是每次 docker run
完之後 commit ,去更新 image,不過這不是 “docker way”(見此篇的討論),因此我們用更為簡便的方式,僅使用 container 本身即可。
第一次建立 container 時,我們透過以下指令:
docker run —-name rserver -p 8787:8787 -e PASSWORD=YOUR_PASSWD -d rocker/tidyverse
—-name
表示我們接下來幫由此 image 建立出來的 container 標記一個名為 rserver 的 tag。如果不透過—-name
來標記 tag 的話,docker 會隨機 assign tag。
接著我們可以檢查現在 VPS 上有哪些 container:
# list running containers docker container ls # or docker ps
如果要列出全部的 container (包含已被停止的 container ),只要加 -a
就可以了
可以看到正在跑的 container 是我們從 tidyverse image 建立出來的,name tag 是 rserver,ID=6ad29361d190
如果我們使用 docker stop rserver
指令,再次列出容器的話,會發現同一個 ID=6ad29361d190
的容器處於 stopped 的狀態,但依舊存在。如果當時是以 docker run —rm ...
建立的話,那該容器就會自動刪除。所以怎麼保留在 rstudio 變更的內容呢?當 VPS 重啟或者是我們暫時性地關閉容器(避免長時間把 port 打開讓 VPS 有被攻擊的機會),只要使用 docker start rserver
或者 docker restart rserver
就可以重新啟動容器,並回到上一次存取後的狀態了。
最後是在 ipad 使用上的一個小小問題:在 studio 中的 control 鍵映射在 Safari 瀏覽器是沒有問題的,直接使用 command 代替即可。但在 iOS 上的 chrome 瀏覽器則無法正確映射。使用 control 鍵可以使用如 CTRL + S 的組合鍵存檔,但不能使用 CTRL + ENTER 來執行 script 。
使用 docker 的小結:
docker run
接 image namedocker start
接 container name