shuntagami
@shuntagami (Shun Tagami)

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

ECS+EC2のヘルスチェックエラーを解決したい

解決したいこと

以下の構成図でAWS上で動かそうとしているのですが、"GET / HTTP/1.1" 500 1635 "-" "ELB-HealthChecker/2.0"というヘルスチェックエラーがnginxのコンテナのログから出ていているため、コンテナが起動と停止を繰り返しています。ステータスコード500という情報しかないため手がかりが掴めずにいます。解決方法を教えていただきたいです。

スクリーンショット 2020-12-27 12.58.34.png

エラー画面

スクリーンショット 2020-12-27 13.49.49.png

ソースコード

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の設定ファイル

こちらに関しましてはヘルスチェックエラーに関連のあると思われる、albalbのターゲットグループ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

No Answers yet.

Your answer might help someone💌