はじめに
ECS を運用していると、コンテナ内で Go コマンドが見つからない (go: not found) という問題に直面することがあります。
本記事では、その原因と解決方法を詳しく解説します。
個人の備忘録程度の走り書きとなっておりますが、温かい目で見守っていただければ幸いです。
書こうと思ったきっかけ
最近、ECS 上で Go を用いたアプリケーションのマイグレーションを行おうとした際に、go コマンドが実行できず困った経験がありました。
その過程で、ECS 内で Go を使用する際のベストプラクティスを学びました。
同じ問題で悩む方の参考になればと思い、本記事を投稿しました。
ECS コンテナ内で go が見つからない場合の解決方法
ECS のコンテナ内で go コマンドが見つからない (go: not found) 場合、以下のいずれかが原因です。
- コンテナに Go がインストールされていない
- Go のパスが
PATHに含まれていない - ECS のコンテナイメージが golang ベースではなく、Go 実行環境を含んでいない
解決策
① コンテナに Go がインストールされているか確認
まず、以下のコマンドで Go がインストールされているか確認します。
ls /usr/local/go/bin
もし go というファイルが存在しない場合、Go がコンテナに入っていません。
② コンテナに Go をインストール
Alpine Linux ベースの場合
apk add --no-cache go
Debian / Ubuntu ベースの場合
apt update && apt install -y golang
Go をインストール後、バージョンを確認:
go version
③ Go の PATH を修正
もし go が /usr/local/go/bin/go にある場合、PATH に追加してください。
export PATH=$PATH:/usr/local/go/bin
その後、再度 go version を確認:
go version
④ Go を含む Docker イメージを使用
本番環境や ECS では、go run を使わず、事前に Go バイナリをビルドしてデプロイするのが一般的です。
ローカルで Go バイナリをビルド
ECS のコンテナで go を直接実行しないように、事前に Go バイナリを作成し、それをデプロイします。
GOOS=linux GOARCH=amd64 go build -o migrate_app migrate/migrate.go
Dockerfile を修正
以下のように Go のビルドステージを追加し、ECS でバイナリを実行できるようにします。
# Go を使ってビルド
FROM golang:1.20 AS builder
WORKDIR /app
COPY . .
RUN go build -o migrate_app migrate/migrate.go
# 軽量なコンテナにバイナリのみコピー
FROM alpine:latest
WORKDIR /app
COPY --from=builder /app/migrate_app .
ENTRYPOINT ["/app/migrate_app"]
⑤ go run を使わずに ECS でマイグレーション
上記の Dockerfile でイメージを ECS にデプロイした後、以下のコマンドで ECS 内で実行します。
aws ecs execute-command \
--cluster my-ecs-cluster \
--task <TASK_ID> \
--container my-app-repo \
--interactive \
--command "/app/migrate_app"
もしくは、ECS タスクの command を変更し、直接 migrate_app を実行するように設定することも可能です。
まとめ
ls /usr/local/go/bin で Go があるか確認
apk add go や apt install golang で Go をインストール
export PATH=$PATH:/usr/local/go/bin で PATH を修正
go build -o migrate_app migrate/migrate.go でバイナリを作成し ECS で実行
ECS では Go を直接インストールするより、事前にビルドしたバイナリをデプロイする方法が推奨されます!