10
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

オンラインIDEを無料で作ろう

Last updated at Posted at 2018-12-07

:golf: はじめに

HerokuにCloud9をデプロイして無料オンラインIDEを使おうと頑張ってます。
その努力の経過をまとめています。

GithubもHerokuも知ってるよ。
過程は良いから、Dockerfileが早く見たい。って人は、GitHubに公開しているので、リンクを参照してください。

なぜ、始めたのか?

友人のAWS Cloud9が13ヶ月目に入り、お金がかかってきたので、無料でやる方法を模索していて思いつきました。

無料オンライン開発環境についてぐぐってみた

レガシーなCloud9のアカウントを持ってるなら、Cloud9使えばいいんですが、持っていない場合、、、

cloud9

HTML, CSS, JSだけでいいなら、Thimbleが良さげ。

thimble

Pythonでデータの処理とか、機械学習系をするなら、Jupitor Notebookとか、Google Colabになるのかな。

google colab

jupitor Notebook

JSONを返すだけとか、静的なファイルを置くだけなら、myjsonとか、GASがいいかも。

GAS

myjson

あと、オンラインのコンパイラとかは、言語ごとに探せばあるって感じですね。

やり方をググってみた。

ない。。。

Cloud9から、Herokuにデプロイする方法は引っかかるが、
HerokuにCloud9をデプロイする方法は見つからない。。。

具体的に何がしたいかというと、、、

とりあえず、思いついた方法、3つ

1. GithubにあるCloud9のリポジトリをフォークして、Herokuにデプロイ

2. Cloud9のDockerfileを使って、コンテナをHerokuにデプロイ

3. ローカルでCloud9を動かし、SSHトンネリング(ポートフォワーディング )でアクセスさせる

実現可能性は高いが、 オンプレ のサーバを置く時点で、無料ではない

1. GitHubからデプロイ

GitHubのアカウントHeroku のアカウント, CLIはすでに持っているものとして、話を進めます。
「なんだそれ?」ってひとは、上のリンクにアクセスするか、よしなにぐぐってください。

a. シンプルにフォークして、デプロイしてみる

Cloud9のGitHubページ にアクセスしてForkする

Herokuにアクセスして、Create new app をする

Create appを押す(App nameは入力しなくていい)

GitHubにつなぐ

Forkしたリポジトリを探して、Connectする

Deploy Branchする

すると、Buildが進んで、

“Your app was successfully deployed”と表示されたら、Viewをクリックする。

全然Successfullyじゃないじゃん。

アプリの設定ページに戻って、Activity → View build logをクリック

ログを見てみると

    -----> Node.js app detected
           
    -----> Creating runtime environment
           
           NPM_CONFIG_LOGLEVEL=error
           NODE_ENV=production
           NODE_MODULES_CACHE=true
           NODE_VERBOSE=false
           
    -----> Installing binaries
           engines.node (package.json):  unspecified
           engines.npm (package.json):   unspecified (use default)
           
           Resolving node version 10.x...
           Downloading and installing node 10.14.1...
           Using default npm version: 6.4.1
           
    -----> Building dependencies
           Prebuild detected (node_modules already exists)
           Rebuilding any native modules
           c9@0.1.0 /tmp/build_75f4baa91a3c7c165659cc801c15ba00/node_modules/c9
           kaefer@0.1.0 /tmp/build_75f4baa91a3c7c165659cc801c15ba00/node_modules/kaefer
           amd-loader@0.0.5 /tmp/build_75f4baa91a3c7c165659cc801c15ba00/node_modules/amd-loader
           architect@0.1.11 /tmp/build_75f4baa91a3c7c165659cc801c15ba00/node_modules/architect
           connect-architect@0.2.0 /tmp/build_75f4baa91a3c7c165659cc801c15ba00/node_modules/connect-architect
           frontdoor@0.0.1 /tmp/build_75f4baa91a3c7c165659cc801c15ba00/node_modules/frontdoor
           msgpack-js@0.1.5 /tmp/build_75f4baa91a3c7c165659cc801c15ba00/node_modules/msgpack-js
           smith@0.1.22 /tmp/build_75f4baa91a3c7c165659cc801c15ba00/node_modules/smith
           treehugger@0.0.2 /tmp/build_75f4baa91a3c7c165659cc801c15ba00/node_modules/treehugger
           Installing any new modules (package.json)
           added 183 packages from 273 contributors, removed 9 packages and audited 253 packages in 11.329s
           found 40 vulnerabilities (11 low, 10 moderate, 18 high, 1 critical)
             run `npm audit fix` to fix them, or `npm audit` for details
           
    -----> Caching build
           - node_modules
           
    -----> Pruning devDependencies
           audited 253 packages in 1.963s
           found 40 vulnerabilities (11 low, 10 moderate, 18 high, 1 critical)
             run `npm audit fix` to fix them, or `npm audit` for details
           
    -----> Build succeeded!
    -----> Discovering process types
           Procfile declares types     -> (none)
           Default types for buildpack -> web
    -----> Compressing...
           Done: 39.6M
    -----> Launching...
           Released v3
           アプリ名 deployed to Heroku

HerokuのCLIで heroku logs -- tail -a アプリ名を実行して、ログをみると、

    $ heroku logs --tail -a safe-shelf-96289
    
    2018-12-07T04:04:02.738118+00:00 app[api]: Release v1 created by user ユーザー名
    省略
    2018-12-07T04:05:20.248779+00:00 heroku[web.1]: State changed from starting to crashed
    2018-12-07T04:05:20.250837+00:00 heroku[web.1]: State changed from crashed to starting
    2018-12-07T04:05:20.222517+00:00 heroku[web.1]: Process exited with status 1
    2018-12-07T04:05:19.969827+00:00 app[web.1]: 
    2018-12-07T04:05:19.969850+00:00 app[web.1]: > c9@3.1.5000 start /app
    2018-12-07T04:05:19.969851+00:00 app[web.1]: > node server.js
    2018-12-07T04:05:19.969853+00:00 app[web.1]: 
    2018-12-07T04:05:20.124000+00:00 app[web.1]: internal/modules/cjs/loader.js:582
    2018-12-07T04:05:20.124004+00:00 app[web.1]: throw err;
    2018-12-07T04:05:20.124005+00:00 app[web.1]: ^
    2018-12-07T04:05:20.124007+00:00 app[web.1]: 
    2018-12-07T04:05:20.124009+00:00 app[web.1]: Error: Cannot find module 'amd-loader'
    省略
    2018-12-07T04:05:20.130850+00:00 app[web.1]: npm ERR! code ELIFECYCLE
    2018-12-07T04:05:20.131414+00:00 app[web.1]: npm ERR! errno 1
    2018-12-07T04:05:20.133176+00:00 app[web.1]: npm ERR! c9@3.1.5000 start: `node server.js`
    2018-12-07T04:05:20.133438+00:00 app[web.1]: npm ERR! Exit status 1
    2018-12-07T04:05:20.133806+00:00 app[web.1]: npm ERR!
    2018-12-07T04:05:20.134072+00:00 app[web.1]: npm ERR! Failed at the c9@3.1.5000 start script.
    2018-12-07T04:05:20.134327+00:00 app[web.1]: npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
    2018-12-07T04:05:20.158427+00:00 app[web.1]: 
    2018-12-07T04:05:20.158771+00:00 app[web.1]: npm ERR! A complete log of this run can be found in:
    2018-12-07T04:05:20.159000+00:00 app[web.1]: npm ERR!     /app/.npm/_logs/2018-12-07T04_05_20_136Z-debug.log
    2018-12-07T04:05:10.873607+00:00 app[api]: Release v3 created by user ユーザー名
    2018-12-07T04:05:12.000000+00:00 app[api]: Build succeeded
    2018-12-07T04:05:10.895893+00:00 app[api]: Scaled to web@1:Free by user ユーザー名
    2018-12-07T04:05:10.873607+00:00 app[api]: Deploy c4d1c59d by user ユーザー名
    2018-12-07T04:05:26.277205+00:00 heroku[web.1]: Starting process with command `npm start`
    2018-12-07T04:05:30.026512+00:00 heroku[web.1]: State changed from starting to crashed
    2018-12-07T04:05:29.989756+00:00 heroku[web.1]: Process exited with status 1
    2018-12-07T04:05:29.665053+00:00 app[web.1]: 
    2018-12-07T04:05:29.665073+00:00 app[web.1]: > c9@3.1.5000 start /app
    2018-12-07T04:05:29.665075+00:00 app[web.1]: > node server.js
    2018-12-07T04:05:29.665076+00:00 app[web.1]: 
    2018-12-07T04:05:29.856720+00:00 app[web.1]: internal/modules/cjs/loader.js:582
    2018-12-07T04:05:29.856725+00:00 app[web.1]: throw err;
    2018-12-07T04:05:29.856726+00:00 app[web.1]: ^
    2018-12-07T04:05:29.856728+00:00 app[web.1]: 
    2018-12-07T04:05:29.856729+00:00 app[web.1]: Error: Cannot find module 'amd-loader'
    2018-12-07T04:05:31.263257+00:00 heroku[router]: at=error code=H10 desc="App crashed" method=GET path="/" 省略

なんかamd-loaderモジュールが無いのが問題らしいけど、ぐぐっても、いまいちどうしたらいいかわからん。

とりあえずローカル環境にCloud9をインストールしてみる。

    $ git clone フォークしたリポジトリのURL
    $ cd core/
    $ scripts/install-sdk.sh
    $ node server.js

できた。

そういや、install-sdk.shスクリプトって、herokuデプロイの時、実行してないな。

Herokuで使われている言葉がよく分からなかったので、調べてみると、 Procfile ってのが、重要そう。

b. Procfileを作ってみる

Procfile
    web: scripts/install-sdk.sh
    web: node server.js --port $PORT --listen 0.0.0.0 -a name:password

→ デプロイ → 失敗 😭
エラーのログにも変化がないし、
script/install-sdk.shが実行されてる様子がないな。

c. インストールコマンドと起動コマンドを一つのファイルにまとめる

Procfileを変更

Procfile
    web: scripts/install-sdk.sh
install-sdk.sh
    # 追記
    node server.js --port $PORT --listen 0.0.0.0 -a name:password

→ 失敗
g++が無いから、インストールに失敗してるのかな?

d. cedar-14っていうスタック に変えてみる

    # stackを指定してherokuのアプリをcreate
    $ heroku create --stack cedar-14
    # ディレクトリを移動
    $ cd cloud9のディレクトリ
    # herokuをリモートに追加
    $ git heroku git:remote -a アプリ名
    # herokuにpush
    $ git push heroku master

-> 失敗

うん、、、わからん。ここで力尽きました。(泣)

2. Dockerでデプロイ

Docker のアカウントを持っていて、パソコンにDockerが入っているものとして話を進めます。
「なんだそれ?」ってひとは、上のリンクにアクセスするか、よしなにぐぐってください。

Cloud9コンテナをローカルのDocker上に置く

    # docker イメージをダウンロードし、コンテナをつくる
    $ docker pull kdelfour/cloud9-docker
    # コンテナにbashで入る
    $ docker exec -it コンテナID bash
    # コンテナ内でcloud9を起動
    $ node server.js --port 8080

→ 出来た

Heroku Docker のチュートリアルを進めてみる

    # herokuにログイン
    $ heroku container:login
    # gitからcloneする
    $ git clone https://github.com/heroku/alpinehelloworld.git
    # herokuのアプリをcreate
    $ heroku create
    # ディレクトリを移動
    $ cd alpinehelloworld
    # イメージをherokuにアップロード
    $ heroku container:push web -a アプリ名
    # herokuにデプロイ
    $ heroku container:release web -a アプリ名
    # ページを開く
    $ heroku open -a アプリ名

→ 出来た

a. Cloud9のコンテナをHerokuの上に送る

Dockerfile
    # webappディレクトリを削除
    rm -rf ./webapp
    # Dockerfileを編集


    #Grab the latest alpine image
    FROM kdelfour/cloud9-docker
    
    RUN /cloud9/scripts/install-sdk.sh
    
    # Expose is NOT supported by Heroku
    # EXPOSE 5000
    
    # Run the app.  CMD is required to run on Heroku
    # $PORT is set by Heroku
    CMD node server.js --port $PORT --listen 0.0.0.0 --auth name:pass

→ 動いた?

ん?

でも、cloud9 インストールされてない(.c9が無い)のか??

ん?

Terminalが使えない(泣)

b. Dockerfileを編集

Dockerfile
    #Grab the latest alpine image
    FROM kdelfour/cloud9-docker
    
    RUN /cloud9/scripts/install-sdk.sh
    
    RUN C9_DIR=$HOME/.c9
    RUN PATH="$C9_DIR/node/bin/:$C9_DIR/node_modules/.bin:$PATH"
    RUN cd $C9_DIR
    RUN npm install pty.js
    
    # Expose is NOT supported by Heroku
    # EXPOSE 5000
    
    # Run the app.  CMD is required to run on Heroku
    # $PORT is set by Heroku
    CMD node server.js --port $PORT --listen 0.0.0.0 --auth name:pass

例のごとくインストールして、

きたーーーーーーー!!!!

→ 成功!!

GitHubにDockerfileを公開しています

3. トンネリング

あらかじめ、ssh接続先でアプリケーションを実行しておいてください。

接続先で動かす簡易ウェブアプリの例 cloud9を動かしてもOKです)

    # bottleをインストール
    $ pip install bottle
server.py
    from bottle import route, run
    
    @route('/')
    def hello():
        return "Hello World!"
    
    
    run(host='localhost', port=8080, debug=True)


    # バックグラウンドで実行
    python3 server.py &

まず、トンネリングをコマンドラインで動かしてみる

🔗 つながるSSHトンネルが俺の力だ!

    $ ssh example.com -p 22 -L 8080:localhost:8080

0.0.0.0:8080にアクセスしてみる
→ 成功

pythonで実装

🔗 pythonでsshtunnelする

    # sshtunnelライブラリをインストール
    $ pip install sshtunnel
connect.py
    from sshtunnel import SSHTunnelForwarder
    import sys
    
    args = sys.argv
    
    server = SSHTunnelForwarder(
        ('example.com', 22),
        ssh_username="name",
        ssh_password="pass",
        remote_bind_address=('0.0.0.0', 8080),
        local_bind_address=('0.0.0.0', 8080)
    )
    
    server.start()
    # 実行
    $ python3 connect.py

0.0.0.0:8080にアクセスしてみる
→ 成功

Herokuのpythonチュートリアルを進める

    # GitHubからclone
    $ git clone https://github.com/heroku/python-getting-started.git
    # ディレクトリを移動
    $ cd python-getting-started
    # herokuのアプリをcreate
    $ heroku create
    # herokuにpush
    $ git push heroku master
    # デプロイ
    $ heroku ps:scale web=1
    # 開く
    $ heroku open

→ 成功

修正して、Herokuにデプロイ

connect.py
    from sshtunnel import SSHTunnelForwarder
    import sys
    
    args = sys.argv
    
    server = SSHTunnelForwarder(
        ('example.com', 22),
        ssh_username="name",
        ssh_password="pass",
        remote_bind_address=('0.0.0.0', 8080),
        local_bind_address=('0.0.0.0', int(args[1]))
    )
    
    server.start()

→ 成功

というか、これをするなら、AWSで良いんじゃない、、、??

一応、GitHubに上げときます。

まとめと今後の展望

HerokuとDocker、ポートフォワーディングについていい勉強になりました。

今後の展望としては、cloud9 でのプレビュー機能をつけることですね。

今更だけど、heroku dockerって、1日に1回リスタートされるみたいなんで、こまめにgit push remote masterしましょう。

10
12
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?