0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

AWSにGoアプリケーションをデプロイしてみた!Apacheをリバースプロキシとして使用

Posted at

はじめに

こんにちは、Shioです。
インフラ学習の一環として、自作のGoアプリケーションをAWSにデプロイしました。
サーバーにはApacheを利用しましたが、個人的に設定が大変でした💦

PHPやPythonのようなインタプリタ言語は、Apacheのモジュール(例: mod_phpmod_wsgi)で簡単にサポートされます。しかし、Goはスタンドアロンで動作するバイナリのため、Apacheのモジュールでは直接対応できません。そのため、今回はApacheをリバースプロキシとして設定し、公開しました。

本来、リバースプロキシには軽量かつシンプルなNginxがよく選ばれますが、今回は認証の学習も目的として、Digest認証を標準でサポートするApacheを使いました。

本記事が少しでも皆さんのお役に立てれば嬉しいです🙇!

環境構成

  • サーバー: AWS EC2(HTTPアクセスがセキュリティグループで許可されていることが前提)
  • OS: Amazon Linux 2023 AMI
  • Webサーバー: Apache
  • アプリケーション: Go言語APIサーバー(フロントエンドは用意していません)
    • Dockerfileは使用せず、アプリケーションを転送後、直接ビルドしました。
  • データベース: SQLite(簡単に動作確認を行うため採用)
    ※ 本記事では、アプリケーションで使用するデータベースの設定や動作には触れません。

リモートサーバーにログインした状態から手順を開始します👀

1. 基本パッケージのインストール

Apache HTTPサーバーのインストール

httpd はApache HTTP Serverのパッケージ名です。-y オプションは全ての問い合わせに「yes」として応答します。

sudo yum install httpd -y

必要なモジュールの確認(proxy関連)

以下のコマンドで現在ロードされているApacheモジュールを確認し、mod_proxymod_proxy_http があることを確認します。

httpd -M | grep proxy

出力例:

proxy_module (shared)
…
proxy_http_module (shared)
…
  • mod_proxy: Apacheをリバースプロキシとして動作させるために必要なモジュール
  • mod_proxy_http: HTTPリクエストをリバースプロキシとして処理するために必要なモジュール

Go言語のインストール

sudo yum install golang -y

2. Apacheの設定

リバースプロキシの設定

Apache設定ファイル(/etc/httpd/conf/httpd.conf)に以下の内容を追加します。
⚠️ 管理者権限でファイルを開き編集します。

sudo vim /etc/httpd/conf/httpd.conf

以下の設定を追加:

<VirtualHost *:80>
    ServerName example.com  # EC2のパブリックIPやドメイン名に変更
    
    ProxyPreserveHost On
    
    # /v1/ へのリクエストをGoアプリケーションへ転送
    ProxyPass /v1/ http://127.0.0.1:8080/v1/
    ProxyPassReverse /v1/ http://127.0.0.1:8080/v1/
</VirtualHost>

設定の詳細

  1. <VirtualHost *:80>
    ポート80で受けた全リクエストに対して、この仮想ホストの設定を適用します。* は全IPアドレスを意味します。

  2. ServerName example.com
    仮想ホストの対象となるIPアドレスまたはドメインを指定します。

  3. ProxyPreserveHost On
    クライアントからのリクエストヘッダーの Host フィールドをそのままGoアプリケーションに渡します。

  4. ProxyPass /v1/ http://127.0.0.1:8080/v1/
    Apacheが受け取った /v1/ へのリクエストをローカルの8080番ポートにあるGoアプリケーションへ転送します。

  5. ProxyPassReverse /v1/ http://127.0.0.1:8080/v1/
    Goアプリケーションからのレスポンスで Location ヘッダー等が適切に修正されるようにします。

Apacheの起動と有効化

設定ファイルの構文チェックを行います。

sudo httpd -t

Syntax OKと表示されたら、Apacheを起動し、サーバー起動時に自動的にApacheが起動するよう設定します。

sudo systemctl start httpd  # Apacheの起動
sudo systemctl enable httpd  # 自動起動を有効化

3. Goアプリケーションのデプロイ

アプリケーションの転送

ローカルPCからEC2インスタンスにアプリケーションを転送します。scpコマンドを使用します。

scp -i <秘密鍵> -r ./myapp ec2-user@<EC2のIP>:/home/ec2-user/

コマンドの意味

  • scp: セキュアコピーコマンド
  • -r: ディレクトリを再帰的にコピーするオプション
  • -i <秘密鍵>: 秘密鍵を指定
  • ./myapp: ローカルのディレクトリ
  • ec2-user@<EC2のIP>: リモートのEC2インスタンスのユーザー名とIPアドレス
  • /home/ec2-user/: 転送先ディレクトリ

転送が成功したら、再度EC2インスタンスにSSHでログインし、転送されたディレクトリが確認できるはずです👀

Goアプリケーションのビルドと実行

1. アプリケーションのビルド

アプリケーションのソースコードがあるディレクトリに移動して、ビルドします。

cd myapp
go build -o myapp main.go

2. アプリケーションの実行

ビルドしたアプリケーションをバックグラウンドで実行します。

./myapp &

&を付けることでバックグラウンド実行されます。

ブラウザやcurlコマンドでアプリケーションが問題なく動作していることを確認します👀

4. Goアプリケーションのサービス化

バックグラウンド実行は一時的なものなので、サーバー再起動後も自動でアプリケーションを起動させるためにsystemdを使用してサービスとして設定します。その前に使用中の8080ポートを開放します👀

1. プロセスの確認

ps aux | grep myapp

2. プロセスの停止

プロセスIDを指定して停止します。

kill -9 PID

systemdサービスの設定

現在ディレクトリ構成は以下のようになっています。

/home/ec2-user/myapp/      # アプリケーションのディレクトリ
  ├── myapp                # 実行ファイル(Goアプリケーション)
  ├── go.mod               # Goのモジュール設定ファイル
  ├── go.sum               # Goのモジュールチェックサムファイル
  └── その他の設定ファイル

サービスファイルを作成

systemdのサービスユニットファイルを作成し、以下の内容を貼り付けます。

sudo vim /etc/systemd/system/myapp.service

以下を記述:

[Unit]
Description=My Go Application
After=network.target

[Service]
ExecStart=/home/ec2-user/myapp/myapp  # アプリケーションのパスを指定
WorkingDirectory=/home/ec2-user/myapp  # アプリケーションがあるディレクトリ
Restart=always
User=ec2-user  # 実行ユーザー

[Install]
WantedBy=multi-user.target

詳細

[Unit]

  • Description: サービスの説明です。
  • After=network.target: ネットワークが有効になった後に開始する設定です。

[Service]

  • ExecStart=/home/ec2-user/myapp/myapp: 実行するバイナリのパスを指定します。
  • WorkingDirectory=/home/ec2-user/myapp: アプリケーションがあるディレクトリを指定します。
  • Restart=always: サービスが停止した場合に自動で再起動します。
  • User=ec2-user: アプリケーションを実行するユーザーを指定します。
  • EnvironmentFile=/home/ec2-user/myapp/app/.env: (必要に応じて)環境変数を含むファイルを指定します

サービスの起動と自動起動の有効化

1. systemdの設定をリロード

sudo systemctl daemon-reload

2. サービスの起動と自動起動の有効化

sudo systemctl start myapp
sudo systemctl enable myapp

3. サービスのステータス確認

アプリケーションが正しく起動しているかを確認します。

sudo systemctl status myapp

成功していれば以下のようなステータスが表示されます。


● myapp.service - My Go Application
     Loaded: loaded (/etc/systemd/system/myapp.service; enabled; preset: disabled)
     Active: active (running) 

5. トラブルシューティング:hammer_pick:

Apacheログの確認

Apacheのエラーログを確認

sudo tail -f /var/log/httpd/error_log

Goアプリケーションのログ確認

Goアプリケーションのsystemdログを確認

sudo journalctl -u myapp -f

遭遇したエラーと対処方法:fire:

ポート8080がすでに使用中

:star:ポート8080を使用しているプロセスを特定して終了

sudo lsof -i :8080
sudo kill -9 <PID>  # 使用中のプロセスID(PID)を指定して終了

Apacheの設定ファイルミス

:star:Apacheの設定に誤りがないか構文チェック

sudo httpd -t

6. 注意事項

ここまで読んでくださりありがとうございます。本記事はあくまでGoアプリケーションをAWS上でデプロイするまでの手順になります。セキュリティ対策(SSL/TLSの設定やファイアウォール、アクセス制御)については触れていません🙇

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?