ECS+EC2のヘルスチェックエラーを解決したい
解決したいこと
以下の構成図でAWS上で動かそうとしているのですが、"GET / HTTP/1.1" 500 1635 "-" "ELB-HealthChecker/2.0"
というヘルスチェックエラーがnginxのコンテナのログから出ていているため、コンテナが起動と停止を繰り返しています。ステータスコード500
という情報しかないため手がかりが掴めずにいます。解決方法を教えていただきたいです。
エラー画面
ソースコード
nginxとrailsのDockerfile及びterraformの設定ファイルは以下のようになります。
rails用Dockerfile
app/docker/rails/Dockerfile
FROM ruby:2.6.5-alpine
WORKDIR /app
ENV RAILS_ENV="production"
ENV NODE_ENV="production"
# 依存パッケージのインストール
COPY Gemfile Gemfile.lock /app/
RUN apk add --no-cache -t .build-dependencies \
build-base \
libxml2-dev\
libxslt-dev \
&& apk add --no-cache \
zsh \
vim \
file \
imagemagick \
libpq \
libxml2 \
libxslt \
nodejs \
mysql-client \
mysql-dev \
tini \
tzdata \
yarn \
&& gem install bundler:2.0.2 \
&& bundle install \
&& apk del --purge .build-dependencies
# アプリケーションコードのコピー
COPY . /app
# アセットのプリコンパイル
RUN bundle exec rails assets:precompile \
&& yarn cache clean \
&& rm -rf tmp/cache
ENV RAILS_SERVE_STATIC_FILES="true"
ENTRYPOINT ["/sbin/tini", "--"]
CMD ["bundle", "exec", "rails", "server", "-b", "0.0.0.0", "-p", "3000"]
EXPOSE 3000
nginx用Dockerfile
app/docker/nginx/dockerfile
FROM nginx:1.19.6-alpine
RUN rm -f /etc/nginx/conf.d/*
# nginx.confを次に載せます。
COPY ./docker/nginx/nginx.conf /etc/nginx/conf.d/bike_app.conf
CMD /usr/sbin/nginx -g 'daemon off;' -c /etc/nginx/nginx.conf
nginx設定ファイル(nginx.conf)
app/docker/nginx/nginx.conf
# プロキシ先の指定
# Nginxが受け取ったリクエストをバックエンドのpumaに送信
upstream app {
# ソケット通信したいのでpuma.sockを指定
server unix:///app/tmp/sockets/puma.sock;
}
server {
listen 80;
server_name touringtaro.work;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
# ドキュメントルートの指定
root /app/public;
# リバースプロキシ設定
location / {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Client-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_redirect off;
proxy_pass http://app;
}
client_max_body_size 100m;
error_page 404 /404.html;
error_page 505 502 503 504 /500.html;
try_files $uri/index.html $uri @app;
keepalive_timeout 5;
}
terrraformの設定ファイル
こちらに関しましてはヘルスチェックエラーに関連のあると思われる、alb
、albのターゲットグループ
、albのリスナー
、セキュリティグループ
について載せたいと思います。
alb関連の設定
alb.tf
# albの定義
resource "aws_lb" "lb" {
name = "sample-lb"
internal = false
load_balancer_type = "application"
security_groups = [
"${aws_security_group.alb.id}",
]
subnets = [
"${data.terraform_remote_state.vpc.outputs.public_subnet_1_id}",
"${data.terraform_remote_state.vpc.outputs.public_subnet_2_id}",
]
}
# ターゲットグループの定義
resource "aws_lb_target_group" "http" {
name = "sample-http"
port = 80
protocol = "HTTP"
vpc_id = "${data.terraform_remote_state.vpc.outputs.vpc_id}"
health_check {
interval = 30
path = "/"
port = "traffic-port"
protocol = "HTTP"
timeout = 10
healthy_threshold = 3
unhealthy_threshold = 3
}
depends_on = [aws_lb.lb]
}
# リスナーの定義
resource "aws_lb_listener" "http" {
load_balancer_arn = "${aws_lb.lb.arn}"
port = "80"
protocol = "HTTP"
default_action {
type = "redirect"
redirect {
port = "443"
protocol = "HTTPS"
status_code = "HTTP_301"
}
}
}
resource "aws_lb_listener" "https" {
load_balancer_arn = "${aws_lb.lb.arn}"
port = "443"
protocol = "HTTPS"
certificate_arn = "${aws_acm_certificate.touringtaro.arn}"
ssl_policy = "ELBSecurityPolicy-2016-08"
default_action {
type = "forward"
target_group_arn = "${aws_lb_target_group.http.arn}"
}
}
セキュリティグループの設定
security_group.tf
resource "aws_security_group" "instance" {
name = "instance"
description = "instance sg"
vpc_id = "${data.terraform_remote_state.vpc.outputs.vpc_id}"
ingress {
from_port = 0
to_port = 0
protocol = "-1"
security_groups = [
"${aws_security_group.alb.id}",
]
}
ingress {
from_port = 22
to_port = 22
protocol = "TCP"
cidr_blocks = [
"0.0.0.0/0",
]
}
ingress {
from_port = 80
to_port = 80
protocol = "TCP"
cidr_blocks = [
"0.0.0.0/0",
]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
resource "aws_security_group" "alb" {
name = "sample-rails-alb"
description = "http and https"
vpc_id = "${data.terraform_remote_state.vpc.outputs.vpc_id}"
ingress {
from_port = 80
to_port = 80
protocol = "TCP"
cidr_blocks = [
"0.0.0.0/0",
]
}
ingress {
from_port = 443
to_port = 443
protocol = "TCP"
cidr_blocks = [
"0.0.0.0/0",
]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
# 手動でRDS作成後に設定する
resource "aws_security_group" "db" {
name = "sample-db2"
description = "DB"
vpc_id = "${data.terraform_remote_state.vpc.outputs.vpc_id}"
ingress {
from_port = 3306
to_port = 3306
protocol = "tcp"
security_groups = [
"${aws_security_group.instance.id}",
]
}
}
その他状況
① 開発環境ではコンテナを立ち上げ、動作を確認できる。
② 同じterraformの設定ファイルでsinatraのアプリを動かすことには成功した。
③ EC2にssh接続後,docker exec
コマンドでコンテナに入ることはできる。その後、rails db:create
とすると、「railsコマンドが見つかりません」と言われる。
仮説
・ sinatraのアプリは動いたので,dockerfileに問題がある。
・ 開発環境下でlocalhost80
でPostリクエストをするとActionController::InvalidAuthenticityToken
というエラーが出た。このエラー自体はこちらの記事を参考にnginx.conf
を修正したところ解決したが、本番環境で考慮すべき「何か」が抜けている。
最後に
ソースコード等、情報が少ないといった場合、気になった箇所があった場合にはコメントしていただけますと助かります。
0