[Docker] ECS automatic deployment --Docker edition-

References

-[Terraform] [Backends] [v0.9] How to manage tfstate files -Migrate the infrastructure of group companies to ECS/Fargate and look back -[AWS] [Terraform] [Fargate] Put container under ALB with ECS

Tree diagram

docker/dev


├── app
│   ├── Dockerfile
│   ├── nginx
│   │   ├── app.conf
│   │   └── nginx.conf
│   └── supervisor
│       ├── app.conf
│       └── supervisord.conf
├── db
│   ├── data
│   └── mysql_init

Docker command

◆ Delete docker container
$ docker rm -f `docker ps -a -q`
◆ Delete docker image
$ docker rmi `docker images -q`
◆ docker image creation
$ docker build -f docker/dev/app/Dockerfile -t sample_dev .
◆ ECR push command
$ docker tag XXXXXX sample/dev  //Docker hub repository
$ 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
◆ Execution command in docker container
$ bundle install
$ bundle exec rake db:create db:migrate

//Start supervisor
$ /usr/bin/supervisorctl restart app  

//Creating a database for production
$ bundle exec rails db:migrate RAILS_ENV=production

//Asset precompile
$ bundle exec rake assets:precompile RAILS_ENV=production
◆ database.yml command
$ 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 command
//Port confirmation
$ ps -ef | grep nginx
$ ps aux | grep nginx

//nginx stop command
$ nginx -s stop

//PID related commands
$ touch /var/run/nginx.pid
$ touch /run/nginx.pid

//Port occupancy confirmation
$ sudo lsof -i:80
$ ps ax | grep rails

//puma start
$ bundle exec puma -C config/puma.rb
$ bundle exec pumactl start
◆ supervisor command
//Start supervisor
$ /etc/init.d/supervisor start
$ supervisord -c /etc/supervisor/supervisord.conf

//supervisor socket command
$ sudo touch /var/run/supervisor.sock
$ sudo chmod 777 /var/run/supervisor.sock
$ supervisorctl help stop

//"Supervisord settings"/var/"run" to "/dev/change to "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


///Directory creation///
RUN mkdir -p $APP_ROOT
RUN mkdir -p /root/tmp
WORKDIR $APP_ROOT


/// Node.js、Nginx,supervisor installation///
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/*


///Create log directory for supervisor///
RUN mkdir -p /var/log/supervisor


/// nginx.conf, conf.d/app.conf creation///
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 creation///
COPY app/supervisor/supervisord.conf /etc/supervisor/supervisord.conf
COPY app/supervisor/app.conf /etc/supervisor/conf.d/app.conf


///Symbolic link (health check log)///

///Each nginx access log///
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


///Application log(puma log) ///
RUN ln -sf /dev/stdout $APP_ROOT/log/development.log
RUN ln -sf /dev/stdout $APP_ROOT/log/production.log


CMD [ "/usr/bin/supervisord" ]

docker-compose.yml


version: '3'
services:
  app:
    build:
      context: .
      dockerfile: app/Dockerfile
    volumes:
      - ~/sample_dev:/var/www/sample_dev
 

    ///Permission for port 80 is required on the host side///
    ///Set up a virtual host with 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 initialization
      - ./db/mysql_init:/docker-entrypoint-initdb.d
      - ./db/data:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: XXXXXX

Nginx

nginx.conf


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;
}

app.conf


///Access log, error log settings///
  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 path setting///
        location / {

        ///Reverse proxy settings///
        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

config/puma.rb


threads_count = ENV.fetch('RAILS_MAX_THREADS') { 5 }.to_i
threads threads_count, threads_count
#If you do not open the port, socket will not listen
#port        ENV.fetch('PORT') { 3000 }
environment ENV.fetch('RAILS_ENV') { 'development' }
plugin :tmp_restart

app_root = File.expand_path('../..', __FILE__)
#Perform socket communication with nginx http directive
bind "unix://#{app_root}/tmp/sockets/puma.sock"

stdout_redirect "#{app_root}/log/puma.stdout.log", "#{app_root}/log/puma.stderr.log", true

supervisor

supervisord.conf


/// supervisor.sock creation///
[unix_http_server]
file=/var/run/supervisor.sock


[supervisord]
/// nodaemon=true:supervisor is for ground(Foreground)Behave in the process///
nodaemon=true


logfile=/var/log/supervisor/supervisord.log
pidfile=/var/tmp/supervisord.pid


///Enabling rpcinterface enables supervisorctl///
[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface


///Enable process management using supervisorctl///
[supervisorctl]
serverurl=unix:///var/run/supervisor.sock

[include]
files = /etc/supervisor/conf.d/*.conf

app.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

Recommended Posts

[Docker] ECS automatic deployment --Docker edition-
[CircleCI] ECS automatic deployment --CircleCI edition-
[Terraform] ECS automatic deployment --Terraform edition-
[Introduction to Docker x ECS] ECS deployment with docker compose up
Fastest Docker introduction (Windows 10 edition)
Run puppeteer-core on Heroku (Docker edition)