Coffee Break Point

iPadだけでプログラミング環境を整えた話[VPS+Coder]

はじめに

GithubCodespacesがまだ無かった時代。

なんとかiPadを開発デバイスにしたく、試行錯誤した末にたどり着いた当時の開発環境を公開します。


なお、現在はこちらの記事のとおりCodespacesを使っています。

とても便利でオススメ。


Coderとは

Coder とは、Codespacesと同じく、ブラウザ上でVSCodeライクな操作感で開発をすることができるサービスです。

クラウドサービスですが、セルフホストで使うことも出来て、その場合は無料です。


サービス公開用のVPSを既に借りていたので、そこでホストすればいいやということで、今回はセルフホストすることにしました。



実際にこんな感じで開発をしていました。

(その後、色々辛いところが出てきてvimでの開発に移行しましたが。。。)


運用するまでにやったこと

インストール

詳しい手順は忘れてしまったのですが、当時と今(2023年2月)とはまた話が違いそうなので、 github を参照ください。


ドメインの取得

当方webアプリを開発したかったので、開発中の画面を確認できる必要がありました。

なので、Coder用とpreview用の2つのサブドメインを作成していました。

ローカル環境を立ち上げる際のポート番号を固定して、ポートフォワーディングすることで実現していました。

Codespacesも似たような仕組みですね。


セキュリティ周りの設定

流石に開発環境と開発画面が誰でも見られる状態だとヤバいので、最低限の認証でbasic認証を入れました。

が、webkitの昔からある現象?で、 websocket使用時にbasic認証がうまく動かないらしく。



Coderはwebsocketを使用していて、iPadのブラウザはすべてwebkitなのでbasic認証が効かず、しばらく頭を抱えました。

仕方ないので、code-server側は当時もう一つ気になっていたAuth0でOAuth化することにしました。

oauth2を導入する手順はこちらのサイト様がとてもわかり易かったです。



メンバを絞るなら、

  1. rules -> create rule-> whitelistでemailを絞る

  2. Users&roles ->Users->create Usersでユーザ作成

  3. Connections->Database->Disable SignUpsを有効

という手順でできそう。


SSL化

SSL化もします。おなじみLet’s Encryptですが、設定頻度が高くないので毎回やり方を忘れがちです。

使い方は下記サイト様が分りやすかったです。


nginx設定

上記を踏まえたnginxの設定がこちらです。

ポート番号1111がOAuth認証用、2222がCoder用、3333がpreview用として使い分けています。


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 map $http_upgrade $connection_upgrade { default upgrade; '' close; } server { server_name code.domain.com; location /oauth2/ { proxy_pass http://localhost:1111; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Scheme $scheme; proxy_set_header X-Auth-Request_Redirect $request_uri; } location = /oauth2/auth { proxy_pass http://localhost:1111; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Scheme $scheme; proxy_set_header Content-Length ""; proxy_pass_request_body off; } location / { #oauth2 auth_request /oauth2/auth; error_page 401 = /oauth2/sign_in; auth_request_set $user $upstream_http_x_auth_request_user; auth_request_set $email $upstream_http_x_auth_request_email; proxy_set_header X-User $user; proxy_set_header X-Email $email; auth_request_set $auth_cookie $upstream_http_set_cookie; add_header Set-Cookie $auth_cookie; proxy_pass http://127.0.0.1:2222; #websocket proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-NginxX-Proxy true; proxy_set_header X-Forwarded-Proto $scheme; proxy_http_version 1.1; proxy_redirect off; } listen 443 ssl; # managed by Certbot ssl_certificate /etc/letsencrypt/live/code.from-garage.work/fullchain.pem; # managed by Certbot ssl_certificate_key /etc/letsencrypt/live/code.from-garage.work/privkey.pem; # managed by Certbot include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot } server { server_name preview.domain.com; location /webhook { proxy_pass http://127.0.0.1:3333; proxy_set_header Host $http_host; proxy_redirect off; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } location / { #Basic auth auth_basic "Restricted"; # 認証時に表示されるメッセージ auth_basic_user_file /etc/nginx/.htpasswd; proxy_pass http://127.0.0.1:3333; proxy_set_header Host $http_host; proxy_redirect off; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } listen 443 ssl; # managed by Certbot ssl_certificate /etc/letsencrypt/live/preview.from-garage.work/fullchain.pem; # managed by Certbot ssl_certificate_key /etc/letsencrypt/live/preview.from-garage.work/privkey.pem; # managed by Certbot include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot } server { if ($host = code.domain.com) { return 301 https://$host$request_uri; } # managed by Certbot listen 80; server_name code.domain.com; return 404; # managed by Certbot } server { if ($host = preview.domain.com) { return 301 https://$host$request_uri; } # managed by Certbot listen 80; server_name preview.domain.com; return 404; # managed by Certbot }

1プロジェクトの構成

だいたいこんな感じの構成になっていました。

紹介程度に。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 ├── code_config_root │ └── config.yaml ├── docker │ ├── code-server │ │ ├── app │ │ ├── config │ │ ├── config_backup │ │ ├── Dockerfile │ │ └── ssh │ ├── mysql │ │ ├── docker-entry-point-init.db │ │ └── my.cnf │ └── Dockerfile ├── docker-compose.yml ├── nginx.conf ├── src │ ├── app1 │ └── app2 └── volume └── mysql ├── auto.cnf └── …

試して没になったもの

browser preview

Coderで入れたが単体では動かず、google-chromeとchrome driverがホスト内に必要だとわかったので入れてみましたが、

dockerを立ち上げてからbrowser-previewが動くようになるまで数分かかったのと、スクロールできない致命的な現象を確認したので断念しました。

今入れたらどうかはわかりません。もしかしたらVPSのスペックの問題かも知れません。


  • google-chrome

    1 2 3 4 RUN wget -q -O – https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add && \ echo ‘deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main’ | tee /etc/apt/sources.list.d/google-chrome.list && \ apt-get update && \ apt-get install -y google-chrome-stable
  • ChromeDriver

    1 2 3 ADD https://chromedriver.storage.googleapis.com/77.0.3865.10/chromedriver_linux64.zip /opt/chrome/ RUN cd /opt/chrome/ && \ unzip chromedriver_linux64.zip

終わりに

現在はより便利なCodespacesに移ってしまっていますが、実際にこの構成でアプリを作って(少額ながらも)お金が発生したので、とても思い入れが有ります。

セルフホストするためにいろんなサービスや設定を網羅しないといけなかったので、大変でしたがとても良い勉強になったと思っています!




← Back to home

©from-garage 2022 All Rights Reserved.

powered by