ZAPAnet総合情報局 > ZAPAブログ2.0 > CentOS 8 に Amazon AWS Cloud9 をインストール

CentOS 8 に Amazon AWS Cloud9 をインストール

2020年06月28日 プログラミングTIPS
さくらのVPSの CentOS 8 サーバーに、 Amazon AWS Cloud9 をインストールしたときのメモです。


開発に利用するマシンが複数台ある場合、一般的にはマシンごとに開発環境の設定値が異なり、それだけでストレスがたまります。ローカルファイルやオンラインファイルの同期も必要です。今の時代、開発環境もすべてクラウド上で構築できるなら、そちらの方が楽です。

Cloud9は、WebからアクセスできるオンラインIDE(統合開発環境)です。Webブラウザさえあれば、どのマシンからでもコードを記述、実行、デバッグできます。エディタの操作については、コード補完、コードヒント候補、エラー表示、ドラッグ&ドロップ操作、Ctrl+Sで保存など、まるでPCネイティブのアプリケーションを操作しているような感覚でブラウザから開発できます。ターミナル、プレビュー表示、テーマ、キーボードショートカットなどの機能も備えています。クラウドベースのため、オフィス、自宅、移動中、布団の中…どこでも同じ環境でプログラミングすることができます。Cloud9の初期設定さえ済ませれば、「プログラミングに必要なものはブラウザだけ」という夢の環境を構築できることになります。開発マシンの種類や性能は問われません。

また、Cloud9 IDEは、C 、 C ++ 、PHP、Ruby、Perl、Python 、Node.jsを伴うJavaScript 、Goなどの複数のプログラミング言語をサポートしています。Cloud9自体は、JavaScriptでほぼ完全に記述され、バックエンドでNode.jsが使われています。Cloud9は2016年7月にAmazonが買収しました。AWSユーザーには有名な開発環境となっています。

Cloud9は、実はAWS以外のサーバーでも利用できます。ということで、さくらのVPSの CentOS 8.1 サーバーに、 Amazon AWS Cloud9 をインストールしてみたというわけです。Amazon公式で解説されている「AWS Cloud9 インストーラ」を使えば簡単にインストールできそうですが、実際には難しかったので、手順を追ってログとして残しておきます。

Node.jsのインストール確認

まずは、Cloud9のバックエンドとして動いているNode.jsのインストールから。ターミナルから「node -v」と打って、サーバーにnodejsがインストール済みか確認。
node -v

Node.jsのインストール

バージョン確認で何か表示が出てきたらインストール済み。インストールされていなかったら、以下の方法でCentOS8.1にnodejsをインストールできる。
dnf module list nodejs
dnf module -y install nodejs:12
(あるいは、dnf module -y install nodejs:12/defaultなど)
インストールしたnodeとnpmのバージョン確認。
node -v
→v12.16.1(バージョン確認)

npm --version
→6.13.4(バージョン確認)

Node.jsのアンインストール

上記の方法でnodejsはインストールできるが、npmのパッケージが古いとかいろいろ問題が出てきて、今後のバージョン管理にも不具合が出てきそうだったので、上記方法でのnodejs管理方法はやめ。

いきなりnodejsをアンインストール。
dnf remove nodejs

nodebrewのインストール

nodejsを直接インストールする代わりに、nodebrewをインストール。
dnf -y groupinstall 'Development tools'
curl -L git.io/nodebrew | perl - setup

以下のように表示されれば、nodebrewのインストールに成功。
Fetching nodebrew...
Installed nodebrew in $HOME/.nodebrew

========================================
Export a path to nodebrew:

export PATH=$HOME/.nodebrew/current/bin:$PATH
========================================

環境変数を追加。
echo 'export PATH=$HOME/.nodebrew/current/bin:$PATH' >> ~/.bashrc
source ~/.bashrc

パスが通っているか確認。「nodebrew 1.0.1」等と表示されればOK。
nodebrew help

Node.js公式ページを見て、node.js最新推奨版(LTS)をバイナリでインストールする(バイナリだと、インストールが速い!)。「Installed successfully」と表示されればOK。
nodebrew install-binary v12.18.1

使用するnodejsのバージョンを指定。以下のuseコマンドを打って、「use v12.18.1」等と表示されればOK。インストールするnode.jsと使用するバージョンの切り替えが簡単なので、nodebrewは圧倒的に楽。
nodebrew use v12.18.1

続いて、npmのバージョンを確認。「6.14.5」等と表示されればOK。
npm -v
これでNode.jsとnpmの利用準備は完了。

Python 2.7 をインストール。

Cloud9にはPython3系ではなく、Python2.7を使う。Python 2.7 をインストール。
dnf module -y install python27

gitのインストール確認

次はgitのインストール(すでにインストールされていれば必要なし)。
dnf -y install git

ここが超難関のglibc-staticのインストール。
dnf -y install glibc-static

上記コマンドを打っても、以下のエラーが返ってきてインストールできない。
No match for argument: glibc-static
Error: Unable to find a match: glibc-static

実は、glibc-staticは、Red Hat系OSからは削除されている。インストールは推奨されていない。

それでも無理やりglibc-staticをインストールするなら、以下のコマンドで(自己責任で)。
dnf --enablerepo=PowerTools install glibc-static

GitHubとの連携設定

GitHubと連携するため、SSH認証用の鍵を作る。事前にGitHubのアカウントが必要。アカウントがない場合は、アカウントを作っておく。
ssh-keygen -t rsa -b 4096 -C "GitHubに登録済みのメールアドレス"
Enter file in which to save the key :鍵の置き場所

chmod 600 作った鍵ファイル
eval "$(ssh-agent)"
ssh-add 作った鍵ファイル
ssh-add -l

作った公開鍵を開く。中身の文字列を全てコピーする。
view 作った鍵ファイル(.pubの方)

GitHubの方で、「SSH and GPG keys」を選択し、コピーした文字列をGitHubに登録


コンフィグファイルの作成。
vi 鍵がおいてあるディレクトリ/.ssh/config

configファイルに以下のように記述して保存。
Host github.com
 HostName      github.com
 IdentityFile  作った鍵ファイル
 User          git

動作確認。下記コマンドで、「Hi ユーザー名! You've successfully authenticated,」と表示されればOK。
ssh -T git@github.com

Cloud9のインストール

ようやく、Cloud9のインストールに取りかかる。まずは、Cloud9の作業スペースとインストール場所の作成(場所は各自自由)。
mkdir /opt/workspace
chmod 777 /opt/workspace
cd /usr/local/src
chmod 777 /usr/local/src

インストール。
git clone git://github.com/c9/core.git c9sdk
cd c9sdk
scripts/install-sdk.sh

成功すれば、以下のように表示される(もしうまく行かなかった場合は、エラー内容をよく読んで修正し、install-sdk.shをやり直す)。
Success!
run 'node server.js -p 8080 -a :' to launch Cloud9

ポート、ユーザー名、パスワード、IPアドレスを指定するには、以下のようにする。
node ./server.js -p 8080 -a user:password -w /opt/workspace/ --listen サーバのIPアドレス

firewalldのポートを開けたいときは、以下のようなコマンドを使って解放する。さくらのVPSなど、パケットフィルタでポートが塞がれている場合はそちらも確認する。
firewall-cmd --permanent --add-port 8080/tcp
firewall-cmd --reload
firewall-cmd --list-port
systemctl reload firewalld.service

ポートが開放できたら、node ./server.js コマンドを打ったときに出てきたアドレスにアクセスする(8080番ポートを指定したのなら、http://IPアドレス:8080など)。このような画面が出てきたら成功。エラーが表示されたら、それをがんばって直す。



hello.phpを作り、Hello,World!を表示するPHPファイル作ってみる(適当に打ったらタイプミスした)。


hello.phpを保存してみる。Windows PCと同じように、Ctrl+Sで保存できる。ブラウザ上で保存すると、サーバーのターミナル側には、以下のようにリアルタイムで処理が表示される。
User saving /hello.php
Successfully saved /hello.php


作成したPHPファイルを外部のWebブラウザから直接表示できるようにする。nginxの場合、nginx.confを編集。
vi /etc/nginx/nginx.conf

Cloud9で8080ポートを使っているので、Nginxでも8080を使おうとすると…(下記設定は各自の環境に合わせて)
    server {
        listen       8080;
        listen       [::]:8080;
        server_name  _;
        root         /opt/workspace;
        include /etc/nginx/default.d/*.conf;

        location / {
        }
    }

nginxを再読込し…
systemctl reload nginx.service

もう一度Cloud9を立ち上げようとすると、怒られる。
Error: listen EADDRINUSE: address already in use IPアドレス:8080
    at Server.setupListenHandle [as _listen2] (net.js:1313:16)
    at listenInCluster (net.js:1361:12)
    at doListen (net.js:1498:7)
    at processTicksAndRejections (internal/process/task_queues.js:85:21)
Emitted 'error' event on Server instance at:
    at emitErrorNT (net.js:1340:8)
    at processTicksAndRejections (internal/process/task_queues.js:84:21) {
  code: 'EADDRINUSE',
  errno: 'EADDRINUSE',
  syscall: 'listen',
  address: 'IPアドレス',
  port: 8080
}

8080はCloud9で使うので、nginxでは使うなということ。Webからページを表示させたいときは、他のポートを使用する。例えば、httpの80やhttpsの443(SSL)。テスト用に自分だけ表示できれば良いのなら、8081ポートとかを適当に使う(公開せず、自分専用の開発環境の表示確認なら、Basic認証を設定しておくとなお良い)。
    server {
        listen       8081;
        listen       [::]:8081;
        server_name  _;
        root         /opt/workspace;
        include /etc/nginx/default.d/*.conf;

        location / {
        }
    }

この場合も、ポート開放を忘れないようにしなくてはいけない。firewalldを設定し、nginxを再起動し、Cloud9の起ち上げまで、一連の動作。

nginxのエイリアスで公開

上記例は8080番ポートでIDE開発環境を構築して、8081番ポートでテストするという設定。もし開発しながら、そのディレクトリで直接Web上に80や443ポートで公開したいのであれば、nginxのlocationディレクトリでalias機能を追加すると楽。
        location /opt/workspace {
               alias /opt/workspace;
        }

「location /opt/workspace」のところは、公開したいディレクトリに自由に設定する。そして「alias /opt/workspace;」を設定すれば、locationで設定したアドレスにアクセスすると「/opt/workspace」以下のファイルが公開される(「/opt/workspace」は、Cloud9で編集したファイルが保存されるように、上の方で設定してある)。

いつでも使えるように、foreverをインストール

コンソールからいちいちCloud9を立ち上げなくても、ずっとCloud9を使えるようにする。それには、foreverをインストール。
npm install -g forever

インストール後、以下のコマンドでCloud9を立ち上げると、コンソールを落とした後も、ずっとCloud9が動き続ける。これでいつでもどこでも、Webブラウザさえあれば開発ができる(以下のコマンドを実行する際は、server.jsの置いてあるディレクトリで打っている)。
forever start ./server.js -p 8080 -a user:password -w /opt/workspace/ --listen サーバのIPアドレス

ずっとCloud9を動かし続ける必要がないときは、以下のコマンドで止める。
forever stopall

foreverでいくつも動かしているプロセスがあって、全てを止めたくない場合は、リストを表示して個別にIDを指定して止める。
forever list

forever stop ID番号

Let's EncryptでSSL証明書を取得してサブドメインでSSL通信

ポート80のhttp通信で開発するのはセキュリティ的に良くないので、ポート443のSSL通信ができるようにする。

取得しているドメインにサブドメインの「c9」を追加して、IPアドレスをサーバーに向ける。DNSの浸透には時間がかかるため、ドメインの設定を変更したら、しばらく待つ。

「http://c9.ドメイン.com」でアクセスできるようになったら、Let's EncryptでSSL証明書を取得する。サブドメインのSSL証明書追加は、「www付きのサブドメインをSSLドメインに転送できなかったときのメモ」を参照。「/etc/nginx/nginx.conf」を編集。Let's Encryptは、「.well-known/acme-challenge」にファイルを書き込みに来るので、特別にこのディレクトリへのアクセスの設定を追加する(.well-known/acme-challengeの書き込み権限を777に設定するのを忘れずに)。その他のファイルへのアクセスは、プロキシでCloud9の立ち上がっている8080ポートに向ける。
        server_name  c9.ドメイン.com;
        location ^~ /.well-known/acme-challenge {
            default_type "text/plain";
            alias         /どこかのディレクトリ/.well-known/acme-challenge;
        }
        location / {
                proxy_pass IPアドレス:8080/;
        }

これでLet's EncryptのSSL証明書を取得すると、「https://c9.ドメイン.com」でSSLアクセスできるようになる。サブドメインでのアクセスではなく、「https://ドメイン.com/opt/workspace」などディレクトリで振り分けても良いが、設定がごちゃごちゃになるのでサブドメインに分けた。実際に使った感想としては、サブドメインを使った方が楽。サブドメインのSSL取得も簡単かつ無料なので問題ない。

注意点として、proxy_passを設定した場合のnginx.confにおけるphp-fmの設定が難しく、そのままではPHPファイルを実行できなくなってしまう恐れがある。WebアクセスのCloud9上から、「PHPファイルだけなぜか開けない(could not open file)」と言われたときは少々焦った(rubyやpythonのファイルは開けるのに)。原因は、NginxのPHPの設定。

落とし穴とよくある間違い | NGINX 日本語訳を参考にする。以下のように設定しているのなら…
fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
下記のように変更する必要があるかもしれない。
fastcgi_param  SCRIPT_FILENAME  $request_filename;
同様に、エイリアスで公開しているディレクトリがあれば、そちらの設定も修正する。Nginxの設定は難しい。

Cloud9構築完了!

以上で、Cloud9の構築は完了です!これで、デスクトップPCだろうがノートPCだろうが、どこからでも全く同じように開発できます。対応ブラウザは、Google Chrome、Mozilla Firefox、Microsoft Edge、MacOS 版 Apple Safariです。ブラウザから開発できるのなら、「iPhoneからでも開発できる!」と最初は思ったりしたのですが、iPhoneからの開発はちょっと難しいです(カーソル移動、文字入力、右クリックなど)。Cloud9はスマホ対応もされれば完璧だと思います。それから、Cloud9のサーバー負荷について。何も操作していないときの待ち受け時のサーバー負荷は、CPU使用率0%です。サーバーに無駄な負荷は与えません。


次回Cloud9とGitHubを連携させる