ruby-on-rails - 为什么Rails应用程序在Docker中的加载速度非常慢?

标签 ruby-on-rails ruby docker

我正在探索Docker的世界,并决定对其进行测试以测试一个空的Rails应用程序。

这是我的Dockerize文件:

FROM ruby:alpine

RUN apk add --update build-base postgresql-dev tzdata nodejs yarn
RUN gem install rails -v '5.1.6'

WORKDIR /app
ADD Gemfile Gemfile.lock /app/
RUN bundle install
RUN yarn install

这是docker-compose.yml文件:
version: '3.6'

services:
  web:
    build: .
    volumes:
      - ./:/app
    working_dir: /app
    command: puma
    ports:
      - 3003:3003
    depends_on:
      - db
    environment:
      DATABASE_URL: postgres://postgres@db
  db:
    image: postgres:10.3-alpine

这里是Gemfile:
source 'https://rubygems.org'

git_source(:github) do |repo_name|
  repo_name = "#{repo_name}/#{repo_name}" unless repo_name.include?("/")
  "https://github.com/#{repo_name}.git"
end

gem 'rails', '~> 5.1.6'
gem 'pg', '>= 0.18', '< 2.0'
gem 'puma', '~> 3.7'
gem 'sass-rails', '~> 5.0'
gem 'uglifier', '>= 1.3.0'

gem 'webpacker'

gem 'coffee-rails', '~> 4.2'
gem 'turbolinks', '~> 5'

gem 'jbuilder', '~> 2.5'
gem 'react-rails'

group :development, :test do
  gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
  gem 'capybara', '~> 2.13'
  gem 'selenium-webdriver'
end

group :development do
  gem 'web-console', '>= 3.3.0'
  gem 'listen', '>= 3.0.5', '< 3.2'
  gem 'spring'
  gem 'spring-watcher-listen', '~> 2.0.0'
end

# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]

当我想启动Rails应用程序时,我已经习惯了在终端选项卡中运行以下命令:rails s -p 3003。现在,使用Docker,我运行以下命令:docker-compose updocker-compose up -d并转到0.0.0.0:3003,并在20-50秒(!)之后加载此页面。为什么加载时间这么慢?我可以以某种方式加快速度吗?

该应用程序实际上是空的,仅连接到PSQL,并且有一个带有Hello World Action 的 Controller 。

最佳答案

我在Mac上毫无问题地运行docker,并怀疑这是您的Dockerfile运行 bundle 程序,并且每次您运行docker-compose up时都重新安装了gemlist。分别复制gemfile和复制应用程序的其余部分,因为Docker会缓存该文件,从而防止您每次更改并重建应用程序时重新复制gemfile。仅当您更改gemfile并重建时,它才会重新安装gem。另外,请尽可能使用“COPY”而不是“ADD”,因为“ADD”具有一些额外的魔力,例如解压缩Tar文件和从远程URL提取文件等。

RUN gem install bundler
COPY Gemfile Gemfile.lock ./
RUN bundle install --binstubs

#Left dot signifies copies everything from workstation in current directory of the Dockerfile.  Right dot means it will be copied into the current containers working directory.  It also checks for a file called .dockerignore and will skip copying anything inside those folders.
COPY . .

作为引用,我为我构建的本地应用程序注释了一个dockerfile。
FROM ruby:2.3-slim

MAINTAINER Brian <wasup@gmail.com>

#Always run apt-get update and apt-get install in same line because the update can be cached and thus may not run on second build.
RUN apt-get update && apt-get install -qq -y build-essential wkhtmltopdf libxrender1 libxext6 libfontconfig1 imagemagick nodejs libpq-dev postgresql-client-9.4 --fix-missing --no-install-recommends

ENV INSTALL_PATH /kunzig

#the p flag allows for installing into a sub-path which isnt necessary here
RUN mkdir -p $INSTALL_PATH

#All commands run after this run in the context of this work path
WORKDIR $INSTALL_PATH

#Left hand side is gemfile from workstation, right hand side is path in docker container (in this case kunzig/Gemfile since workdir is /kunzig already we can just do Gemfile)
RUN gem install bundler
COPY Gemfile Gemfile.lock ./
RUN bundle install --binstubs

#Left dot signifies copies everything from workstation in current directory of the Dockerfile.  Right dot means it will be copied into the current containers working directory (kunzig).  It also checks for a file called .dockerignore and will skip copying anything inside those folders.
COPY . .

#Note:  Always separate copying the gemfile and copying the rest because Docker will cache it thus preventing recopying the gemfile everytime you make a change and rebuild the app. and only reinstall gems when you change the gemfile and rebuild!

#When running this from Docker it needs dummy filler for the db and token so just made some stuff up so it doesnt error...
RUN bundle exec rake RAILS_ENV=production DATABASE_URL='postgresql://kunzig:bjkbjk@postgres:5432/kunzig?encoding=utf8&pool=5&timeout=5000' SECRET_KEY_BASE=somejdfkpicksomething assets:precompile

#This volume will allow us to expose our assets in the public folder to nginx since nginx will be sitting in front of the rails app and serve our assets.  Volume creation must go LAST on the dockerfile since everything after isn't run except CMD.
VOLUME ["$INSTALL_PATH/public"]

#Can swap in Puma via this one line if desired
CMD bundle exec puma -C config/puma.rb

关于ruby-on-rails - 为什么Rails应用程序在Docker中的加载速度非常慢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57136538/

相关文章:

css - 如何使用 CSS 和 Rails i18n 分别格式化日期元素(年、月、日)?

ruby-on-rails - Mongoid - 同一个外域的两个逆域

ruby-on-rails - 使用 Carrierwave 调整条件图像大小

ruby - 如何将字符串变成元素调用

docker - 在Docker容器的镜像构建上设置值

docker - Docker 中的 WSL2 Caddy 反向代理

ruby-on-rails - select_tag 正在排序(奇怪地)[Rails]

ruby-on-rails - 销毁后不被要求销毁协会?

ruby-on-rails - 从 Rails 日期时间列中查询一天中的时间(带时区)

php - 如何使用 Dockerfile 以基于 Ubuntu 镜像的 php-fpm 启动 Nginx?