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
参考
-
Professional Rails on ECS (rails developer meetup 2017) - joker1007’s diary
「RailsのDocker化における鬼門の一つ」「S3に保存」は、結果的にはミスリードだったかな。。