使用docker构建ruby、rails镜像,docker-compose配置应用集并一键启动

安装docker


#官方脚本自动安装
curl -fsSL get.docker.com -o get-docker.sh
sh get-docker.sh --mirror Aliyun

安装docker-compose


#官方脚本自动安装
sudo curl -L "https://github.com/docker/compose/releases/download/1.22.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose

docker镜像制作


ruby环境镜像Dockerfile

FROM centos:6.10

RUN yum update -y && yum install -y epel-release git openssl-devel readline-devel zlib-devel libxml2-devel libxslt-devel libvirt-devel tar gcc-c++ pcre-devel unzip mysql-server mysql-client mysql-devel nodejs \
         && yum clean all \
         && rm -rf /var/cache/yum/* \
         && git clone git://github.com/sstephenson/rbenv.git ~/.rbenv \
         && git clone git://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build \
         && git clone https://github.com/andorchen/rbenv-china-mirror.git ~/.rbenv/plugins/rbenv-china-mirror \
         && /root/.rbenv/plugins/ruby-build/install.sh
ENV PATH /root/.rbenv/bin:$PATH
RUN echo 'eval "$(rbenv init -)"' >> ~/.bashrc \
         && echo 'eval "$(rbenv init -)"' >> /etc/profile \
         && echo 'gem: --no-rdoc --no-ri' >> ~/.gemrc \
         && source /etc/profile \
         && rbenv install 2.5.1 \
         && rbenv rehash \
         && rbenv global 2.5.1 \
         && gem source -r https://rubygems.org \
         && gem source -a https://gems.ruby-china.com
docker build -t ruby2.5.1 .

安装完的软件包需要清理干净,多用&&减少层数,使image尽可能小。

Rails app环境镜像Dockerfile

FROM ruby2.5.1

ENV PATH /root/.rbenv/bin:$PATH
WORKDIR /railsapp
COPY /code/railsapp /railsapp/
RUN rbenv exec gem install bundler \
  && rbenv exec bundle install \
  && /bin/cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
  && echo 'Asia/Shanghai' >/etc/timezone
docker build -t railsapp .

分成2个镜像便于app代码更新,只要重新构建railsapp即可。

配置docker-compose.yml


version: "3"
services:
  db:
    image: mysql:5.7
    restart: always
    ports:
      - "3306:3306"
    volumes:
      - ./mysql/data:/var/lib/mysql
      - ./mysql/logs:/logs
      - ./mysql/conf:/etc/mysql/conf.d
    environment:
      MYSQL_ROOT_PASSWORD: root

  redis:
    image: redis:3.2
    restart: always
    ports:
      - "6379:6379"
    volumes:
      - ./redis/data:/data
    command: >
      --requirepass "root"
      --appendonly yes

  web:
    image: railsapp
    environment:
      PATH: /root/.rbenv/bin:$PATH
    command: bash -lc "source /etc/profile && rbenv exec bundle exec sidekiq --index 0 --pidfile tmp/sidekiq-0.pid --environment production --logfile log/sidekiq.log --daemon && rbenv exec bundle exec puma -C config/puma.rb"
    volumes:
      - ./web/logs:/railsapp/log
      - ./web/config:/railsapp/config
      - ./web/public:/railsapp/public
    ports:
      - "81:81"
    depends_on:
      - db
      - redis

  nginx:
    image: nginx
    ports:
      - "80:80"
    volumes:
      - ./nginx/conf/nginx.conf:/etc/nginx/nginx.conf
      - ./nginx/logs:/var/log/nginx
      - ./web/public:/railsapp/public
    depends_on:
      - web
 docker-compose run web run bash
 
#进入容器终端
rake assets:precompile RAILS_ENV=production
bundle exec rake db:create RAILS_ENV=production
bundle exec rake db:migrate RAILS_ENV=production
bundle exec rake db:seed RAILS_ENV=production
exit

#启动
docker-compose up

总结


  1. volumes通常需要配置:保存的数据、配置文件、共享文件、日志。
  2. rails容器中的public文件夹需要通过配置volumes共享到nginx容器中。
  3. 各容器中的配置文件如果需要指向其他容器的ip,要填写docker-compose.yml中的配置的services名称(web,db,nginx)
    production:
      adapter: mysql2
      encoding: utf8
      pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 20 } %>
      #填写db会自动生成db容器的地址
      host: db
      username: root
      password: "root"
    
  4. compose配置中的command项,如果填写的是容器应用的启动命令,不能使用deamon守护进程的方式运行,容器会exit 0退出。