😊

作成したアプリケーションを公開する(Railway)

2023/01/05に公開

はじめに

herokuが有料化してしまったことにより、
無料で公開する先の候補を検討していたところ、
Railwayが近い構成で出来そうなので、試してみました。

載せるアプリはLaravel、DBはMySQLの構成です。

https://railway.app/

手順

アカウント作成

トップページから「Start New Project」

「Deploy from GitHub repo」を選び

Githubにログイン

この後何かあったかもしれませんが、残してなく不明

プロジェクト作成

トップページからNew Project

色々選べそうですが、Githubから進めます。

別窓が開くので、Githubのアカウントを選択します。

リポジトリの選択

All repositories:アカウントが持っているリポジトリすべてをRailwayに許可します。
Only select repositories:リポジトリを個別に選んで許可します。

リポジトリを選択したら、「Install & Authorize」 ボタンをクリックします。
別窓が閉じるので、先ほどのNew ProjectでGithubを選択すると、
選んだリポジトリが表示されますので、選択します。

環境変数の設定

valiableのタブで環境変数を設定します。
後々の設定で.env.exampleから.envファイルをコピーしますので、
.env.exampleから値を変える必要があるものは最低限設定が必要です。

今回のリポジトリでは、DB関係とAWS関係だけで動作しました。
「RAW Editor」を選ぶとenvファイルのように書けるのでまとめて設定可能です。

他に設定しておいた方がよさそうなもの
APP_ENV:環境に応じた設定に変更
APP_DEBUG:エラー時に原因特定できるのは良いですが、公開する前提であればデバッグはオフで

env関係以外で、下記の値を追加します。

COMPOSER_ALLOW_SUPERUSER=1

これがないと、後で実行するcomposerのコマンドがエラーになるので設定しておきます。

データベースの作成

一旦アプリの設定は×で閉じてデータベースを作成します。
左上の「New」をクリックし、表示されたダイアログから「Database」を選択

ローカル同様MySQLを選択します。

すぐに作成されます。

データベースの作成についてはこれだけで終了です。
結構一瞬過ぎて驚きですね。
まだテーブルは作成されていませんが、ビルド時にartisanコマンドでマイグレーションします。

データベースの設定変更

作成したデータベースに接続するため、先ほど追加した環境変数を変更していきます。
アプリを選択し、「Valiables」を開き、一番下にスクロールすると、
データベースの変数が追加されています。

開くと1つ1つの値を確認することが出来るので、先ほど張り付けたLaravelのデータベース設定を置き換えていきます。

# 設定例
DB_USERNAME=root
DB_PASSWORD=password
DB_HOST=containers-xxxxxxxxx.railway.app
DB_PORT=9999
DB_DATABASE=railway

上記のように直接値を設定してもよいのですが、
Railway上で設定されている環境変数を参照する方法があります。
${{ 環境変数名 }}
とすることで他の環境変数を設定することが可能です。

DB_USERNAME=${{ MYSQLUSER }}
DB_PASSWORD=${{ MYSQLPASSWORD }}
DB_HOST=${{ MYSQLHOST }}
DB_PORT=${{ MYSQLPORT }}
DB_DATABASE=${{ MYSQLDATABASE }}

ビルドコマンドの設定

RailwayのビルダーとしてNixpacksというものが使われており、
Nixpacksによって、package.jsonやcomposer.jsonが含まれていると、
自動的にnpm installやcomposer installを行ってくれます。

ですが、Laravel用のセットアップは行ってくれません。
それを解決する方法も用意されており、
ビルド時に別途コマンドを指定することができます。

「Settings」の「Build Command」

下記のコマンドを設定します。

npm run prod && composer dump-autoload && composer run-script post-root-package-install && composer run-script post-create-project-cmd && php artisan migrate --force

1つにまとめたスクリプトなり用意すればスッキリしそうですが、
ひとまずありもので動いたので一旦OKかなと思います。
npm run prod:jsとcssをpackしています。
dump-autoloadは不要かもしれない。
post-root-package-install:.env.exampleから.envファイルをコピー
post-create-project-cmd:.envのAPI_KEYの値を生成します。
php artisan migrate:DBのマイグレーション

デプロイコマンドの設定

必要かと思ったのですが特に不要です。
デフォルトの設定のままでビルド完了後に自動的にデプロイされます。

ドメインの発行

「Settings」の「Environment」から「Generate Domain」でドメインが発行されます。

デプロイがうまく行っていれば無事ページが開けます。

テンプレートもある

主要な言語のテンプレートはそろってそうです。
Laravelのもありました。
テンプレートではDockerfileで諸々書いているようでした。
テンプレートを用いる場合、テンプレートのリポジトリを作成することになるので、
そちらを参考に自分のリポジトリに組み込むか、
テンプレートのリポジトリに自分のリポジトリの内容を移す必要があり、
その辺がひと手間かかりそうな印象でした。
https://railway.app/templates

料金について

一応無料ではあるのですが、
毎月、5$分使用か、500時間稼働という制限があります。
1つのサービスを使用している分には1か月稼働し続けても大丈夫な雰囲気です。
https://railway.app/pricing

時間を使いきったらアプリが停止するようです。
月毎に上記の制限は復活する雰囲気はありそう。
実際1か月たっていないので確実に言えないので、この辺は追って情報更新しようと思います。
https://docs.railway.app/reference/pricing
https://docs.railway.app/reference/plans#example-calculation

無料枠を節約する方法として、
アプリの場合は、デプロイを削除することで止められます。
再開したい場合はデプロイを行えば良いです。
一方DBの方は、停止することができないので、DBを削除するしかなさそうです。

※2023/1/28追記
無事?無料枠使い切ったので、確認してみましたが、説明上来月まで使えないよ。
となっていますね。

※2023/2/4追記
無料枠復活していることが確認できました。
これで安心して使えそうですね。

トラブルシューティング

digital envelope routines::unsupported

#15 3.448 Error: error:0308010C:digital envelope routines::unsupported

調べてみるとOpenSSLの互換エラーということらしいですがnodeのダウングレードや下記のオプションの追加での対策が多いようです。
セキュリティ対応的には微妙ではありますが根本対応するには依存関係をすべて最新にする必要がありそうです。

暫定的に下記で対応

package.jsonのprodコマンドに下記を追加

"NODE_OPTIONS='--openssl-legacy-provider'

    "scripts": {
    ~~~ 中略 ~~~
        "prod": "npm run production",
        "production": "NODE_OPTIONS='--openssl-legacy-provider' cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js"
    },

おそらく根本対応

npm audit fix --force

正常動作しなくなる可能性もあるため、実施前にはブランチ切って動作確認した上での適用しましょう。

参考

https://summertree.hatenablog.com/entry/2022/03/22/005754
https://qiita.com/akitkat/items/f455bbc088a408cbc3a5
https://stackoverflow.com/questions/69692842/error-message-error0308010cdigital-envelope-routinesunsupported

Unable to prepare route [api/user] for serialization. Uses Closure.

npmのビルドが通った後にLaravelのエラー

#15 25.30    LogicException  : Unable to prepare route [api/user] for serialization. Uses Closure.

ルーティングにクロージャがあるとダメらしい。
プロジェクト作成時に記載されているapp.phpのルーティングをコメントアウトで解決。
必要なルーティングの場合は、適宜コントローラクラスを用意してクロージャを止めると動作すると思います。

参考

https://programmer-life.work/php/logicexception-unable-to-prepare-route

Composer plugins have been disabled for safety in this non-interactive session.

デフォルトでは、composerが無効にされているようです。
COMPOSER_ALLOW_SUPERUSER=1を設定すればいいよ的な事が書いてあるので、
指定の通り環境変数に設定することで解決します。

#15 2.687 Composer plugins have been disabled for safety in this non-interactive session. Set COMPOSER_ALLOW_SUPERUSER=1 if you want to allow plugins to run as root/super user.
#15 2.687 Do not run Composer as root/super user! See https://getcomposer.org/root for details

No application encryption key has been specified.

デプロイされてやれやれというところで、実行時エラー
API_KEY未設定によるものなので、API_KEYを設定してあげればOK。
本記事ではビルド時のコマンドで指定

K2Oシステムテックブログ

Discussion