OpenShipの公式クイックスタートは、インストール、初期化、デプロイの3段階で公開する流れを示しています。(openship.io)
症状:デプロイ完了と表示されたのに、ドメインへ接続できない。
最短解決策:再インストールではなく、ローカル構築、SSH転送、コンテナ起動、ドメイン経路、依存サービスの順に証拠を集めてください。
この手順は、初めてOpenShipでAI SaaSを公開する個人開発者向けです。自前サーバーの保守担当者や、Macからデプロイを実行するチームにも使えます。OpenShipの構成や利用場所を変える前に、どの層で止まっているかを確定させることが先です。
障害を五つの層に分ける
OpenShipでは、コードの取得、ビルド、SSH経由の転送、コンテナ起動、ルーティングという複数の処理が連続します。公式説明でも、ビルド済みの成果物をSSHで対象へ送り、新しいコンテナを起動し、ドメインとTLSを接続する流れが示されています。(openship.io)
そのため、「デプロイ失敗」という表示だけでは原因を特定できません。次の表で、最初に確認する場所を決めてください。
| 確認層 | 主な症状 | 先に残す証拠 | 判断 |
|---|---|---|---|
| ローカル構築 | ビルド途中で停止、成果物がない | 完全な構築ログ、終了コード、設定ファイル | コード・依存関係・資源の問題 |
| SSH転送 | 接続拒否、鍵エラー、途中切断 | 接続先、ポート、鍵権限、詳細出力 | 経路または認証の問題 |
| コンテナ起動 | 起動直後に終了、再起動を繰り返す | 起動ログ、状態、ヘルスチェック | 入口、ポート、資源の問題 |
| ドメイン経路 | サーバー内では見えるが外部から開けない | 公開DNS、証明書、HTTP応答 | DNS・TLS・ルーティングの問題 |
| 依存サービス | DB、Redisなどだけ接続できない | サービス状態、接続文字列、データボリューム | 資格情報・ネットワーク・保全の問題 |
構築ログを最後まで保存する
OpenShipの構築失敗では、ログの最後にある「module not found」や「command not found」だけを見てはいけません。依存関係のインストールが失敗した後に、コンパイル処理が連鎖的に失敗している場合があるためです。
識別信号
次のような状態なら、まず構築層を疑います。
- パッケージの取得途中で処理が止まる
- 指定したビルドコマンドが存在しない
- Node.js、Python、Goなどの実行時バージョンが想定と違う
- 環境変数が未設定で、静的生成や型チェックに失敗する
- 成果物ディレクトリが作成されていない
取証動作
完全な構築ログを保存し、次のファイルと照合します。
cat package.json
cat Dockerfile
cat .env.example
git rev-parse HEAD
実際のリポジトリ、ブランチ、コミットIDは伏せずに記録し、秘密情報だけをマスキングしてください。OpenShipはフレームワークやパッケージマネージャーを検出して初期設定を生成しますが、検出結果がプロジェクト固有のビルド要件を完全に代替するわけではありません。(github.com)
処理結論と再確認
ローカルで同じコミットを構築し、同じコマンドで失敗するならコードや設定側の問題です。ローカルでは成功する一方、構築端末だけで停止するなら、メモリ、ディスク、CPU、同時実行処理の不足を確認します。
公式の自己ホスト要件では、最低構成として2コア、RAM 2GB、ディスク20GBが示され、推奨構成は4コア以上、RAM 4GB以上、SSD 50GB以上です。(openship.io) ただし、これはOpenShip本体の目安であり、AI SaaSのビルドに必要な資源を保証する値ではありません。修正後は、同じコミットで構築完了、成果物生成、終了コード成功の3点を記録します。
SSH接続と転送経路を分離する
SSHの問題は、接続前、転送中、接続後の権限不足に分かれます。OpenShipの自前サーバー構成では、対象サーバーへSSHで接続して成果物を転送するため、認証成功とデプロイ成功は同じ意味ではありません。(openship.io)
識別信号
- 初回から接続できない:ホスト名、ポート、鍵、ホスト鍵の問題
- 接続できるが転送途中で切れる:回線、タイムアウト、ファイアウォール、ディスクの問題
- 接続後にコマンドを実行できない:ユーザー権限、作業ディレクトリ、Docker権限の問題
取証動作
実際の値は必ず置き換えてください。
ssh -vvv -p <PORT> -i <KEY_PATH> <USER>@<HOST>
ssh-keygen -lf <KEY_PATH>
nc -vz <HOST> <PORT>
初回接続では、表示されたホスト指紋を管理者が確認します。秘密鍵の権限、接続先ポート、ログインユーザー、対象ディレクトリの所有者も別々に記録してください。
SSHポートをインターネットへ公開する場合は、全送信元を許可せず、許可元IP、鍵認証、不要な管理ポートの閉鎖を組み合わせます。接続確認のためにファイアウォールを全面開放したままにするのは、短時間の検証でも避けるべきです。
処理結論と再確認
sshの対話接続が成功しても、OpenShipが使うユーザーでDockerや作業ディレクトリを操作できるとは限りません。接続ユーザーで次を確認します。
id
docker ps
touch <WORK_DIR>/permission-check
rm <WORK_DIR>/permission-check
転送だけが失敗する場合は、接続ログと転送ログを分けて保存します。再公開時には、転送完了、対象サーバー上のイメージまたは成果物存在、起動処理開始を個別に確認してください。
コンテナの起動状態を実際の応答で確認する
「デプロイ完了」は、イメージの配置やコンテナ作成が終わったという意味に留まる場合があります。アプリが待受していない、誤ったポートを使っている、127.0.0.1だけで待ち受けている場合、外部利用者には停止中と同じです。
識別信号
docker ps -a
docker logs <CONTAINER>
docker inspect <CONTAINER>
起動直後に終了するなら、入口コマンド、必須環境変数、マイグレーション、実行時バージョンを確認します。再起動を繰り返すなら、ヘルスチェックの結果とアプリ自身の起動ログを突き合わせ、ヘルスチェックだけが誤っているのか、プロセス自体が落ちているのかを分けます。
処理結論と再確認
アプリは0.0.0.0で指定ポートを待ち受ける必要があります。ポート番号を変更した場合は、コンテナ設定、OpenShipのサービス設定、ドメイン側の転送先を同時に確認します。
修正後は、サーバー内からの実リクエストを実行します。
curl -i http://<HOST>:<PORT>/health
curl -i https://<DOMAIN>/health
HTTP応答だけでなく、データベースへの読み書きやログイン処理も確認してください。旧バージョンのスナップショットは削除せず、修正後のコンテナが不安定なら直前版へ戻せる状態を維持します。OpenShipは以前のデプロイへ戻すロールバック運用を想定しています。(openship.io)
DNS、HTTPS、外部経路を一つずつ確認する
ドメイン障害では、DNS、証明書、エッジルーティング、アプリ応答を同時に変更しないでください。OpenShipの公式説明では、ドメイン接続と自動TLS、ルーティングをデプロイ経路に含めています。(openship.io)
識別信号と取証動作
まず公開DNSの結果を確認します。
dig <DOMAIN> A
dig <DOMAIN> AAAA
次に証明書とHTTP応答を確認します。
curl -Iv https://<DOMAIN>
curl -i https://<DOMAIN>/health
DNSが意図したサーバーを返さない場合は、証明書を再発行する前にDNSを修正します。DNSが正しく、証明書も有効なのに応答がない場合は、エッジのルール、公開ポート、コンテナの待受アドレスを確認します。
サーバー内のlocalhostでは表示できるのに外部から開けない場合、アプリのコードよりも、ファイアウォール、バインドアドレス、リバースプロキシ、DNSの境界を優先して調べます。静的フロントエンドとAPIを同一ドメインで扱う構成では、パス転送の設定も確認対象です。OpenShipの公式リポジトリには、静的配信とバックエンドへのパス転送を扱うルーティング仕様が記載されています。(github.com)
データベースとバックグラウンドサービスを保全する
データベース接続失敗は、アプリのコードエラー、資格情報の誤り、依存サービスの停止、ネットワーク分離のいずれでも発生します。最初からデータボリュームを削除すると、原因を消したうえでデータまで失うため、復旧手順として一般化してはいけません。
識別信号
- DBコンテナが停止している
- 接続先が検証環境や古いホスト名を指している
- ユーザー名やパスワードだけが拒否される
- アプリとDBが異なる内部ネットワークにいる
- マイグレーションだけが失敗している
取証動作と処理結論
まずサービス状態、ログ、環境変数名、データボリュームの存在を確認します。
docker ps -a
docker logs <DB_CONTAINER>
docker volume ls
printenv | grep -E 'DATABASE|REDIS|MONGO'
資格情報を修正する場合は、アプリとDBのどちらを変更したか記録します。サービス停止が疑われる場合は、先にバックアップまたはスナップショットを取得し、復旧後に読み取りと書き込みの両方を検証します。OpenShipの自己ホスト構成では、データを保持するボリューム設定がインストール例に示されています。(openship.io)
再公開の合格条件を記録する
修正後は「デプロイボタンが成功した」だけで終了しません。次の順番でマイルストーンを記録します。
- 同じコミットの構築が完了している
- 成果物の転送が完了している
- コンテナが安定して起動している
- ヘルスチェックが成功している
- 外部ドメインから実際のリクエストが通る
- データベースの読み書きが成功している
- 旧バージョンへ戻す手順を確認している
同じコードが何度もローカル資源不足で止まる、Macを常時オンラインにできない、チームに安定した公開用ノードがない場合は、プラットフォームを再インストールするより、構築場所を見直す方が合理的です。一方、コード設定や資格情報の誤りであれば、環境を移しても再発します。
ローカルMacからのデプロイを続ける場合は、Macのレンタル環境を確認する前に、必要なビルドコマンド、ログ保存先、SSH鍵の管理方法を整理してください。継続的にログを残せる遠隔のMac構築環境へ移すなら、Kvmkitの案内で接続方法と利用条件を確認し、故障原因が端末側にある場合だけ移行を検討します。
OpenShip障害の証拠テンプレート
チームで再利用するなら、次の項目を1件の障害記録にまとめます。
発生日時:
対象プロジェクト:
コミットID:
実行端末:
OpenShipの実行形態:
失敗した層:
完全なログの保存先:
終了コード:
SSH接続結果:
コンテナ状態:
ヘルスチェック結果:
公開DNS結果:
証明書確認結果:
HTTP応答:
DB・依存サービス状態:
実施した修正:
修正後の検証:
ロールバック確認:
この形式なら、単発のエラーメッセージではなく、次の担当者が同じ環境を再現できます。
FAQ
OpenShipのビルドに失敗したとき、最初にどのログを確認すべきですか?
画面に表示された最後の1行だけではなく、ビルド開始から終了までの完全なログを保存してください。依存関係のインストール、コンパイル、環境変数の読み込み、終了コードの順に確認し、package.jsonやDockerfileなどプロジェクト側の設定と照合すると、資源不足と設定ミスを分けやすくなります。
OpenShipからSSHでサーバーへ接続できない場合はどうしますか?
最初に接続先のホスト名、ポート、秘密鍵のパス、鍵ファイルの権限を個別に確認します。初回接続ならホスト鍵の確認、接続途中で切れるなら経路やファイアウォール、接続後に操作できないならログインユーザーの権限を調べ、各段階の出力を保存してください。
OpenShipでデプロイが成功したのに、ドメインだけ開けない原因は何ですか?
DNSが正しい接続先を返しているか、証明書が発行済みか、エッジ側のルーティングが対象コンテナへ向いているか、アプリが実際に応答しているかを順に確認します。ローカルホストからだけ見える場合は、公開ポート、待受アドレス、ファイアウォールの境界を重点的に調べます。
OpenShipのアプリが起動後に何度も再起動するときの見方を教えてください。
コンテナの再起動回数だけで判断せず、起動直後のログ、ヘルスチェックの結果、実際の待受ポートを突き合わせます。入口コマンドの失敗、127.0.0.1だけでの待受、必須環境変数の欠落、メモリ不足を順に除外し、修正前のバージョンを残してから再デプロイします。
OpenShipでデータベース接続に失敗したとき、安全に復旧する方法はありますか?
まずデータベースの稼働状態とデータボリュームを確認し、接続文字列が本番と検証環境のどちらを指しているかを確認します。資格情報の誤りなら秘密情報だけを修正し、サービス停止や破損が疑われる場合は先にバックアップを取得してください。データボリュームの削除は最後の手段です。
OpenShipのデプロイ失敗がコード設定やサーバー権限に由来するなら、環境を変えても問題は残ります。反対に、ローカルMacのメモリやディスク不足、端末を長時間オンラインにできないことが原因なら、現在の方式は構築処理が端末状態に依存し、ログの保存や再実行も不安定になりやすいです。その場合は、必要な時間だけ遠隔接続でき、ログを保持できるMac環境へ切り替える方が、長期契約やプラットフォーム変更より先に検討しやすい選択肢です。
よくある質問
OpenShipのビルドに失敗したとき、最初にどのログを確認すべきですか?
画面に表示された最後の1行だけではなく、ビルド開始から終了までの完全なログを保存してください。依存関係のインストール、コンパイル、環境変数の読み込み、終了コードの順に確認し、package.jsonやDockerfileなどプロジェクト側の設定と照合すると、資源不足と設定ミスを分けやすくなります。
OpenShipからSSHでサーバーへ接続できない場合はどうしますか?
最初に接続先のホスト名、ポート、秘密鍵のパス、鍵ファイルの権限を個別に確認します。初回接続ならホスト鍵の確認、接続途中で切れるなら経路やファイアウォール、接続後に操作できないならログインユーザーの権限を調べ、各段階の出力を保存してください。
OpenShipでデプロイが成功したのに、ドメインだけ開けない原因は何ですか?
DNSが正しい接続先を返しているか、証明書が発行済みか、エッジ側のルーティングが対象コンテナへ向いているか、アプリが実際に応答しているかを順に確認します。ローカルホストからだけ見える場合は、公開ポート、待受アドレス、ファイアウォールの境界を重点的に調べます。
OpenShipのアプリが起動後に何度も再起動するときの見方を教えてください。
コンテナの再起動回数だけで判断せず、起動直後のログ、ヘルスチェックの結果、実際の待受ポートを突き合わせます。入口コマンドの失敗、127.0.0.1だけでの待受、必須環境変数の欠落、メモリ不足を順に除外し、修正前のバージョンを残してから再デプロイします。
OpenShipでデータベース接続に失敗したとき、安全に復旧する方法はありますか?
まずデータベースの稼働状態とデータボリュームを確認し、接続文字列が本番と検証環境のどちらを指しているかを確認します。資格情報の誤りなら秘密情報だけを修正し、サービス停止や破損が疑われる場合は先にバックアップを取得してください。データボリュームの削除は最後の手段です。
M4 Mac mini で CI/CD を回すのが一番ラク
Xcode, Fastlane, CocoaPods, and SPM are first-class on macOS. Mac mini M4 unified memory keeps signing and archiving smooth; ~4W standby power suits 24/7 build nodes.