优化Dockerfile、缩小镜像大小,加快容器的启停速度

在上一篇文章《docker-compose部署Rails应用》中,用docker-compose配置了应用集,镜像的构建用了centos:6.10,使用rbenv安装了ruby环境,这样的方式多此一举,而且严重影响镜像的大小,容器的性能,下面我们用更好的方式再做一次。

镜像对比


首先对比下几个基础镜像的大小:

23 MB ruby2.5-alpine

70 MB centos6.10

之前构建的镜像大小是780MB,所以基础镜像之间的差别不会很大,而错误的构建步骤会让镜像的大小天差地别。

下面是此次的大小:

WX20190119-145907@2x

镜像构建


文件目录如下:

WX20190119-150246@2x

FROM ruby:2.5-alpine

WORKDIR /app
COPY code /app/

RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/g' /etc/apk/repositories && \
    apk add --no-cache make gcc g++ tzdata libc-dev libxml2 libxslt postgresql-dev nodejs && \
    cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \
    gem sources --add https://gems.ruby-china.com/ --remove https://rubygems.org/ && \
    gem install bundler -N && \
    bundle config mirror.https://rubygems.org https://gems.ruby-china.com && \
    bundle install --without development test && \
    apk del make gcc g++ tzdata

docker-compose相关配置


WX20190119-152949@2x

docker-compose.yml

version: "3"
services:
  rails-app:
    image: rails-app
    command: puma -C config/puma.rb
    volumes:
      # 共享文件需要外挂出来,和以前cap部署的shared差不多。
      # 配置文件在调试过程中一般挂出来,修改完重启服务方便调试,不用每次重新打包。
      - ./app/logs:/app/logs
      - ./app/config:/app/config
      - ./app/public:/app/public
    depends_on:
      - nginx
      - db

  nginx:
    image: nginx
    volumes:
      - ./nginx/logs:/var/log/nginx
    ports:
      - "80:80"
    volumes:
      - ./nginx/configs/app.conf:/etc/nginx/nginx.conf
      - ./app/public:/app/public

  db:
    image: postgres:10-alpine
    restart: always
    ports:
      - 5432:5432
    environment:
      # 在.env文件中设置
      - POSTGRES_DB=${POSTGRES_DB}
      - POSTGRES_USER=${POSTGRES_USER}
      - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
    volumes:
      - ./postgres:/var/lib/postgresql/data

.env

POSTGRES_DB=postgres
POSTGRES_USER=postgres
POSTGRES_PASSWORD=123456

app/config/puma.rb

directory '/app'
rackup "/app/config.ru"
environment 'production'

tag ''

pidfile "/app/public/puma.pid"
state_path "/app/public/puma.state"
stdout_redirect '/app/logs/puma_error.log', '/app/logs/puma_access.log', true

threads 4,16

bind 'unix:///app/public/puma.sock'

workers 1

preload_app!


on_restart do
  puts 'Refreshing Gemfile'
  ENV["BUNDLE_GEMFILE"] = ""
end

这里用了socket方式没有暴露端口,nginx做反向代理。

app.conf

upstream railsapp {
    server unix:/app/public/puma.sock fail_timeout=0;
}

 server {
  listen 80;
  server_name localhost; # change to match your URL
  root   /app/public;

  location / {
    proxy_pass http://railsapp;
    proxy_set_header Host $host:88;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    client_max_body_size    1024m;
    # add_header Access-Control-Allow-Origin *;
  }

  location ~* ^/(uploads|assets|public)/ {
    expires 1y;
    add_header Cache-Control public;
    gzip_static on;
    add_header Last-Modified "";
    add_header ETag "";
    break;
  }
}

数据库相关

pg_hba.conf

# "local" is for Unix domain socket connections only
local   all             all                                     trust
# IPv4 local connections:
host    all             all             0.0.0.0/0               trust
# IPv6 local connections:
host    all             all             0.0.0.0/0               trust

app/config/database.yml

default: &default
  adapter: postgresql
  encoding: unicode
  host: db
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>

production:
  <<: *default
  database: app_production
  username: postgres
  password: <%= Rails.application.credentials.db[:password] %>

初始化数据库

docker-compose run rails-app rake db:create RAILS_ENV=production
docker-compose run rails-app rake db:migrate RAILS_ENV=production
docker-compose run rails-app rake db:seed RAILS_ENV=production

完成

WX20190119-154134@2x