LoginSignup
2
0

More than 1 year has passed since last update.

AWS本番環境のdockerで rails assets:precompile がimageに反映されずハマった件

Posted at

AmazonLinux2のDocker環境に対し、gitlabでbuild、ECRにpush、eb deploy でデプロイするフロー。

build時にDockerfileで rails assets:precompile を実行していたが、なぜかデプロイされて起動したコンテナ内にはassetが作成されていない、つまり docker imageに反映されていない。

色々調べたが、docker-compose.ymlのvolumeにファイルを置いているディレクトリを書いていたからだった。
開発環境ではないので、ホストのディレクトリとコンテナをマウントする必要がなかった。
ちなみに railsのversionは6.1.3.1
最終的に、以下のようなファイルとなった。

Dockerfile_production
FROM ruby:3.0.1
ENV RAILS_ENV="production"
ENV NODE_ENV="production"

RUN \
  apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs vim && \
  wget https://dl.yarnpkg.com/debian/pubkey.gpg && \
  apt-key add pubkey.gpg && \
  echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list && \
  apt-get update -qq && apt-get install -y yarn && \
  mkdir /work_dir

WORKDIR /work_dir
COPY Gemfile Gemfile.lock /work_dir/
RUN \
  echo 'gem: --no-document' >> ~/.gemrc && \
  cp ~/.gemrc /etc/gemrc && \
  chmod uog+r /etc/gemrc && \
  bundle config --global build.nokogiri --use-system-libraries && \
  bundle config --global jobs 4 && \
  bundle config git.allow_insecure true && \
  bundle install

COPY . /work_dir

RUN SECRET_KEY_BASE=<rails_master_key> bundle exec rails assets:precompile assets:clean && \
  yarn cache clean && \
  rm -rf node_modules tmp/cache
docker-compose.prod.yml
version: '3'
services:
  web:
    image: "<web-sha256>"
    volumes:
      # - .:/work_dir  ←コイツがどこかのタイミングでprecompileしたassetを消してたよう。
      - ${EB_LOG_BASE_DIR}/web:/var/log/app
    command:
      ["sh", "-c", "rm -f tmp/pids/server.pid; bin/rails server -p 3000 -b 0.0.0.0"]
    ports:
      - 3000:3000
    env_file:
      - .env
    mem_limit: 768m
  nginx:
    image: "nginx"
    ports:
      - 80:80
    volumes:
      - "./nginx/conf.d:/etc/nginx/conf.d:ro"
      - ${EB_LOG_BASE_DIR}/nginx:/var/log/nginx
    mem_limit: 128m
  jobworker:
    image: "<web-sha256>"
    command: ["sh", "-c", "bundle exec bin/rails jobs:work"]
    volumes:
      - .:/work_dir
      - ${EB_LOG_BASE_DIR}/jobworker:/var/log/app
    env_file:
      - .env
    mem_limit: 256m
gitlab-ci.yml
before_script:
  - pwd
  - if [ $CI_BUILD_REF_NAME = "master" ]; then
  -    ENV=production
  -    EB_ENV_NAME=[サービス名]-production
  - else
  -    ENV=$CI_BUILD_REF_NAME
  -    EB_ENV_NAME=[サービス名]-staging
  - fi
  - export AWS_ACCESS_KEY_ID=$(eval echo \${AWS_ACCESS_KEY_ID})
  - export AWS_SECRET_ACCESS_KEY=$(eval echo \${AWS_SECRET_ACCESS_KEY})
  - ECR_REPO=$(eval echo \${ECR_REPO})
  - PROJECT_NAME=${PROJECT_NAME}
  - RAILS_MASTER_KEY=$(eval echo \${RAILS_MASTER_KEY})
  - PWD=$PWD
  - $(aws ecr get-login --no-include-email)

stages:
  - build
  - push
  - deploy

build:
  stage: build
  script:
    - sed -i -e "s|<rails_master_key>|${RAILS_MASTER_KEY}|g" ./Dockerfile_production
    - docker build -t ${PROJECT_NAME}:${ENV} -f Dockerfile_production .
  only:
    - master
    - staging
  tags:
    - docker

push:
  stage: push
  script:
    - docker tag ${PROJECT_NAME}:${ENV} ${ECR_REPO}/${PROJECT_NAME}:${ENV}
    - docker push ${ECR_REPO}/${PROJECT_NAME}:${ENV}
  only:
    - master
    - staging
  tags:
    - docker

deploy_eb:
  stage: deploy
  script:
    - cp -f docker-compose.prod.yml docker-compose.yml
    - SHA256=${ECR_REPO}/${PROJECT_NAME}:${ENV}`docker inspect --format='{{index .RepoDigests 0}}' ${PROJECT_NAME}:${ENV} | awk '{print substr($0, index($0, "@"))}'`
    - sed -i -e "s|<web-sha256>|${SHA256}|g" ./docker-compose.yml #Buildしたイメージのsha256をdocker-compose(.prod).ymlへ置換
    - zip -qr deploy.zip . -x *.git*  #デプロイ対象ファイルをZipにする
    - eb deploy ${EB_ENV_NAME}
  only:
    - master
    - staging
  tags:
    - docker

参考

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