😸
【Docker】ECS自動デプロイ - Docker編 -
参考文献
- [Terraform][Backends][v0.9]tfstateファイルの管理方法
- グループ会社のインフラをECS/Fargateに移行して振り返る
- [AWS][Terraform][Fargate]ECSでコンテナをALB配下に置く
- circleci/aws-ecs@1.4.0
- AWS ECR/ECS へのデプロイ
ツリー図
docker/dev
├── app
│ ├── Dockerfile
│ ├── nginx
│ │ ├── app.conf
│ │ └── nginx.conf
│ └── supervisor
│ ├── app.conf
│ └── supervisord.conf
├── db
│ ├── data
│ └── mysql_init
Dockerコマンド
◆ dockerコンテナ削除
$ docker rm -f `docker ps -a -q`
◆ dockerイメージ削除
$ docker rmi `docker images -q`
◆ dockerイメージ作成
$ docker build -f docker/dev/app/Dockerfile -t sample_dev .
◆ ECRプッシュコマンド
$ docker tag XXXXXX sample/dev //Docker hubリポジトリ
$ docker images
$ docker push sample/dev
$ docker tag sample/dev:latest XXXXXX.dkr.ecr.XXXXXX.amazonaws.com/ecs-sample:latest
$ docker push XXXXXX.dkr.ecr.XXXXXX.amazonaws.com/ecs-sample:latest
◆ dockerコンテナ内実行コマンド
$ bundle install
$ bundle exec rake db:create db:migrate
// supervisor起動
$ /usr/bin/supervisorctl restart app
// production用データベース作成
$ bundle exec rails db:migrate RAILS_ENV=production
// アセットプリコンパイル
$ bundle exec rake assets:precompile RAILS_ENV=production
◆ database.ymlコマンド
$ export RAILS_DATABASE_USERNAME=test
$ export RAILS_DATABASE_PASSWORD=password
$ export RAILS_DATABASE_HOST=rds.XXXXXX.XXXXXX.rds.amazonaws.com
$ export RAILS_DATABASE_PORT=3306
◆ nginx && pumaコマンド
// ポート確認
$ ps -ef | grep nginx
$ ps aux | grep nginx
// nginx停止コマンド
$ nginx -s stop
// PID関連コマンド
$ touch /var/run/nginx.pid
$ touch /run/nginx.pid
// ポート占有確認
$ sudo lsof -i:80
$ ps ax | grep rails
// puma起動
$ bundle exec puma -C config/puma.rb
$ bundle exec pumactl start
◆ supervisorコマンド
// supervisor起動
$ /etc/init.d/supervisor start
$ supervisord -c /etc/supervisor/supervisord.conf
// supervisorのsocketコマンド
$ sudo touch /var/run/supervisor.sock
$ sudo chmod 777 /var/run/supervisor.sock
$ supervisorctl help stop
// supervisordの設定の「/var/run」を「/dev/shm」 に変更する
$ sed -i "s/\/var\/run/\/dev\/shm/g" /etc/supervisor/supervisord.conf
Dockerfile
Dockerfile
FROM ruby:2.7.1
ENV APP_ROOT /var/www/sample_dev
ENV LANG C.UTF-8
ENV TZ Asia/Tokyo
/// ディレクトリ作成 ///
RUN mkdir -p $APP_ROOT
RUN mkdir -p /root/tmp
WORKDIR $APP_ROOT
/// Node.js、Nginx, supervisorインストール ///
RUN apt-get update -y && \
apt-get upgrade -y && \
apt-get install -y --no-install-recommends \
bash \
build-essential \
git \
libcurl4-openssl-dev \
libghc-yaml-dev \
libqt5webkit5-dev \
libxml2-dev \
libxslt-dev \
libyaml-dev \
linux-headers-amd64 \
default-mysql-client \
nginx \
nodejs \
openssl \
ruby-dev \
ruby-json \
tzdata \
vim \
supervisor \
zlib1g-dev && \
apt-get clean -y && \
rm -rf /var/cache/apt/archives/* /var/lib/apt/lists/*
/// supervisor用logディレクトリ作成 ///
RUN mkdir -p /var/log/supervisor
/// nginx.conf, conf.d/app.conf作成 ///
COPY app/nginx/nginx.conf /etc/nginx/nginx.conf
COPY app/nginx/app.conf /etc/nginx/conf.d/app.conf
/// supervisord.conf, conf.d/app.conf作成 ///
COPY app/supervisor/supervisord.conf /etc/supervisor/supervisord.conf
COPY app/supervisor/app.conf /etc/supervisor/conf.d/app.conf
/// シンボリックリンク(ヘルスチェックログ) ///
/// 各nginxアクセスログ ///
RUN ln -sf /dev/stdout /var/log/nginx/access.log
RUN ln -sf /dev/stdout /var/log/nginx/app.access.log
RUN ln -sf /dev/stderr /var/log/nginx/app.error.log
/// アプリケーションログ(pumaログ) ///
RUN ln -sf /dev/stdout $APP_ROOT/log/development.log
RUN ln -sf /dev/stdout $APP_ROOT/log/production.log
CMD [ "/usr/bin/supervisord" ]
version: '3'
services:
app:
build:
context: .
dockerfile: app/Dockerfile
volumes:
- ~/sample_dev:/var/www/sample_dev
/// ホスト側で80番ポートの許可が必要 ///
/// nginxでバーチャルホストを設定する ///
ports:
- 80:80
environment:
MYSQL_ROOT_PASSWORD: XXXXXX
depends_on:
- db
tty: true
stdin_open: true
db:
image: mysql:5.7
ports:
- 3306:3306
volumes:
# mysql初期化
- ./db/mysql_init:/docker-entrypoint-initdb.d
- ./db/data:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: XXXXXX
Nginx
user root;
worker_processes 1;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
keepalive_timeout 65;
include /etc/nginx/conf.d/*.conf;
}
/// アクセスログ、エラーログ設定 ///
access_log /var/log/nginx/access.log main;
error_log /var/log/nginx/error.log warn;
upstream app {
server unix:///var/www/sample_dev/tmp/sockets/puma.sock;
}
server {
listen 80;
server_name dev.sample.com;
/// URLのパス設定 ///
location / {
/// リバースプロキシ設定 ///
proxy_pass http://app;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
}
}
puma
threads_count = ENV.fetch('RAILS_MAX_THREADS') { 5 }.to_i
threads threads_count, threads_count
# ポートを開放しておかないと、socketのlistenが行われない
#port ENV.fetch('PORT') { 3000 }
environment ENV.fetch('RAILS_ENV') { 'development' }
plugin :tmp_restart
app_root = File.expand_path('../..', __FILE__)
# nginxのhttpディレクティブでsocket通信を行う
bind "unix://#{app_root}/tmp/sockets/puma.sock"
stdout_redirect "#{app_root}/log/puma.stdout.log", "#{app_root}/log/puma.stderr.log", true
supervisor
/// supervisor.sock作成 ///
[unix_http_server]
file=/var/run/supervisor.sock
[supervisord]
/// nodaemon=true: supervisorがforground(最前面)プロセスで振舞う ///
nodaemon=true
logfile=/var/log/supervisor/supervisord.log
pidfile=/var/tmp/supervisord.pid
/// rpcinterfaceを有効にすると、supervisorctlが有効になる ///
[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
/// supervisorctlを使ってプロセス管理を可能にする ///
[supervisorctl]
serverurl=unix:///var/run/supervisor.sock
[include]
files = /etc/supervisor/conf.d/*.conf
[program:app]
command=bundle exec puma -C ./config/puma.rb
autostart=true
autorestart=true
stopsignal=TERM
user=root
directory=/var/www/sample_dev/
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
[program:nginx]
command=/usr/sbin/nginx -g "daemon off;"
autostart=true
autorestart=true
stopsignal=TERM
user=root
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
Discussion