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

Ruby on rails 为什么Rails应用程序在Docker中的加载速度非常慢?,ruby-on-rails,ruby,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的世界,并决定测试一个空的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
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
这里是
docker compose.yml
文件:

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
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]
源代码'https://rubygems.org'
git_源(:github)do | repo_名称|
repo_name=“#{repo_name}/#{repo_name}”除非repo_name.include?(“/”)
"https://github.com/#{repo_name}.git“
结束
gem'rails',“~>5.1.6”
宝石'pg','>=0.18','<2.0'
宝石“彪马”,“大于3.7”
gem'sass-rails',“~>5.0”
gem'uglifier','>=1.3.0'
gem‘webpacker’
gem“咖啡轨”,“~>4.2”
gem“涡轮链接”,“大于5”
gem'jbuilder',“~>2.5”
gem‘反应轨道’
小组:开发,:测试
gem'byebug',平台:[:mri,:mingw,:x64_mingw]
宝石“水豚”,“大于2.13”
gem“selenium webdriver”
结束
小组:发展怎么办
gem“web控制台”,“>=3.3.0”
gem'listen','>=3.0.5','<3.2'
宝石“春天”
gem‘SpringWatcherListen’,“~>2.0.0”
结束
#Windows不包括zoneinfo文件,因此捆绑tzinfo数据
gem'tzinfo data',平台:[:mingw,:mswin,:x64_mingw,:jruby]
我已经习惯了,当我想启动Rails应用程序时,我在终端选项卡中运行了以下命令:
Rails s-p3003
。现在,使用Docker,我运行以下命令:
docker compose up
docker compose up-d
并转到
0.0.0:3003
,20-50秒(!)后加载此页面。为什么装载时间这么慢?我能加快速度吗


该应用程序基本上是空的,它只连接到PSQL,并且有一个带有
Hello World
操作的控制器。

我在Mac上运行docker时没有任何问题,我怀疑是你的docker文件运行捆绑程序,每次运行
docker compose up
时都会重新安装gemlist。单独复制gemfile和复制应用程序的其余部分,因为Docker将缓存它,从而防止每次更改和重建应用程序时重新复制gemfile。只有在您更改gemfile并重新生成时,它才会重新安装gems。此外,尽可能使用“复制”而不是“添加”,因为“添加”具有一些额外的魔力,如解压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:2.3-slim的

维修工布莱恩
#始终在同一行中运行apt get update和apt get install,因为更新可以缓存,因此可能不会在第二次生成时运行。
运行apt get update&&apt get install-qq-y build ESTANCE wkhtmltopdf libxrender1 libxext6 libfontconfig1 imagemagick nodejs libpq dev postgresql-client-9.4--修复缺失--不建议安装
环境安装路径/kunzig
#p标志允许安装到此处不需要的子路径中
运行mkdir-p$INSTALL\u路径
#在此工作路径的上下文中,所有命令在此运行之后运行
WORKDIR$INSTALL\u路径
#左侧是工作站中的gemfile,右侧是docker容器中的路径(在本例中是kunzig/gemfile,因为workdir已经是/kunzig了,所以我们可以只做gemfile)
运行gem安装bundler
复制Gemfile Gemfile.lock/
运行bundle安装--binstubs
#左点表示从Dockerfile当前目录中的工作站复制所有内容。右点表示它将被复制到当前容器工作目录(kunzig)中。它还检查名为.dockrignore的文件,并将跳过复制这些文件夹中的任何内容。
复制
#注意:始终将复制gemfile和复制其余的分开,因为Docker将缓存它,从而防止每次您进行更改和重建应用程序时重新复制gemfile。并且只有在您更改gemfile并重新生成时才能重新安装gems!
#当从Docker运行这个时,它需要为db和令牌使用虚拟填充符,所以只需要编一些东西,这样它就不会出错。。。
运行bundle exec rake RAILS\u ENV=production DATABASE\u URL='postgresql://kunzig:bjkbjk@postgres:5432/kunzig?encoding=utf8&pool=5&timeout=5000'SECRET\u KEY\u BASE=somejdfkpicksomething资产:预编译
#此卷将允许我们向nginx公开公用文件夹中的资产,因为nginx将坐在rails应用程序前面并为我们的资产提供服务。卷创建必须在dockerfile上最后进行,因为除CMD之外,后面的所有操作都不会运行。
卷[“$INSTALL\u PATH/public”]
#如果需要的话,可以通过这一条线交换Puma
CMD bundle exec puma-C config/puma.rb

我在Mac上运行docker时没有任何问题,我怀疑是您的docker文件在运行bundler,并在每次运行
docker compose时重新安装您的gemlist
。单独复制gemfile和复制应用程序的其余部分,因为Docker将缓存它,从而防止每次更改和重建应用程序时重新复制gemfile。只有在您更改gemfile并重新生成时,它才会重新安装gems。此外,尽可能使用“复制”而不是“添加”,因为“添加”具有一些额外的魔力,如解压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:2.3-slim的

维修工布莱恩
#始终在同一行中运行apt get update和apt get install,因为更新可以缓存,因此可能不会在第二次生成时运行。
运行apt get update&&apt get install-qq-y build ESTANCE wkhtmltopdf libxrender1 libxext6 libfontconfig1 imagemagick nodejs libpq dev postgresql-client-9.4--修复缺失--不建议安装
环境安装路径/kunzig
#p标志允许安装到此处不需要的子路径中
运行mkdir-p$INSTALL\u路径
#在此工作路径的上下文中,所有命令在此运行之后运行
WORKDIR$INSTALL\u路径
#左侧是工作站中的gemfile,右侧是docker容器中的路径(在本例中是kunzig/gemfile,因为workdir已经是/kunzig了,所以我们可以只做gemfile)
运行gem安装bundler
复制Gemfile Gemfile.lock/
运行bundle安装--binstubs
#左点表示以当前目录从工作站复制所有内容