Docker, Rails 3.2, dependencies issue
我的任务是维护一个遗留的Rails站点:Rails3.2、Ruby2.4,以及一些依赖于这些遗留版本的Rails和Ruby的gem。
我试图把Rails放在一个Docker容器中,而PostgresDB放在另一个容器中。我准备好了,运行得很好,所以我相信我不是完全无用的。
一切似乎都运行良好,包括运行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | /usr/LOCAL/rvm/rubies/ruby-2.4.1/bin/ruby: warning: shebang line ends WITH may cause a problem /usr/LOCAL/rvm/gems/ruby-2.4.1/gems/sinatra-1.4.6/lib/sinatra/base.rb:1225: warning: constant ::Fixnum IS deprecated /usr/LOCAL/rvm/gems/ruby-2.4.1/gems/sinatra-1.4.6/lib/sinatra/base.rb:1225: warning: constant ::Fixnum IS deprecated /usr/LOCAL/rvm/gems/ruby-2.4.1/gems/sinatra-1.4.6/lib/sinatra/base.rb:1225: warning: constant ::Fixnum IS deprecated /usr/LOCAL/rvm/gems/ruby-2.4.1/gems/builder-3.0.4/lib/builder/xchar.rb:111: warning: constant ::Fixnum IS deprecated /usr/LOCAL/rvm/gems/ruby-2.4.1/gems/sinatra-1.4.6/lib/sinatra/base.rb:1225: warning: constant ::Fixnum IS deprecated /usr/locfrom /usr/LOCAL/rvm/gems/ruby-2.4.1/gems/activesupport-3.2.22.5/lib/active_support/dependencies.rb:251:IN `block in require'e -- guard/guard (LoadError) from /usr/local/rvm/gems/ruby-2.4.1/gems/activesupport-3.2.22.5/lib/active_support/dependencies.rb:251:in `require'endency' FROM /usr/LOCAL/rvm/gems/ruby-2.4.1/gems/bundler-1.16.0.pre.3/lib/bundler/runtime.rb:97:IN `require'' from /usr/local/rvm/gems/ruby-2.4.1/gems/bundler-1.16.0.pre.3/lib/bundler/runtime.rb:74:in `block IN require'n require' FROM /usr/LOCAL/rvm/gems/ruby-2.4.1/gems/bundler-1.16.0.pre.3/lib/bundler/runtime.rb:67:IN `require' from /var/www/html/config/application.rb:13:in `<top (required)>'/bundler.rb:114:in `require' FROM /usr/LOCAL/rvm/gems/ruby-2.4.1/gems/railties-3.2.22.5/lib/rails/commands.rb:53:IN `block in <top (required)>' from /usr/local/rvm/gems/ruby-2.4.1/gems/railties-3.2.22.5/lib/rails/commands.rb:50:in `<top (required)>' from script/rails:6:in `<main>'' |
任何关于如何前进的想法都会受到赞赏;我已经在这方面坚持了很长时间了。
以下是我的gemfile、docker-compose.yml、database.yml和每个docker容器的dockerfiles:
docker-compose.yml:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | version: '3' services: web: build: context: . ports: -"8080:3000" -"4443:443" volumes: - ./:/var/www/html environment: - ALLOW_OVERRIDE=TRUE command: tail -f /dev/NULL container_name: hl_web links: - db db: image: postgres:9.3.17 volumes: -"/var/run/postgres/postgres.sock:/var/run/postgres/postgres.sock" -"db-data:/var/lib/postgresql/data" container_name: hl_db volumes: db-DATA: |
数据库
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | defaults: &defaults adapter: postgresql # template: template_postgis encoding: unicode pool: 5 username: root password: host: db development: <<: *defaults DATABASE: realty_development test: <<: *defaults DATABASE: realty_test staging: <<: *defaults DATABASE: realty_development production: <<: *defaults DATABASE: realty_production |
轨道的Dockerfile:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | # Latest Ubuntu LTS FROM ubuntu:12.04 RUN apt-GET -y UPDATE && apt-GET -y upgrade RUN apt-GET -y install --fix-missing curl git wget libpq-dev node libpq-dev vim # Install mpapis RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys D39DC0E3 RUN \curl -sSL https://GET.rvm.io | bash -s stable --ruby # Need TO ADD RVM TO the path ENV PATH /usr/LOCAL/rvm/bin:/usr/LOCAL/sbin:/usr/LOCAL/bin:/usr/sbin:/usr/bin:/sbin:/bin RUN /bin/bash -l -c 'source /etc/profile.d/rvm.sh' RUN /bin/bash -l -c"rvm install 2.1.2" RUN /bin/bash -l -c"rvm use 2.1.2" RUN /bin/bash -l -c"gem install rails -v 4.2.2" # Copy # Heroku installer TO opt AND run it #COPY ./docker_config/install-ubuntu.sh /opt/install-ubuntu.sh #WORKDIR /opt #RUN sh install-ubuntu.sh # Heroku installer RUN /bin/bash -l -c 'echo"deb http://toolbelt.heroku.com/ubuntu ./"> /etc/apt/sources.list.d/heroku.list' RUN \wget -O- https://toolbelt.heroku.com/apt/release.key | apt-KEY ADD - RUN apt-GET -y UPDATE RUN apt-GET install -y heroku-toolbelt # CHANGE back TO project root AND run bundle #WORKDIR /var/www/html #RUN /bin/bash -l -c"bundle install" # make bundler a DEFAULT gem RUN echo bundler >> /usr/LOCAL/rvm/gemsets/global.gems # SOURCE rvm IN every shell RUN sed -i '3i . /etc/profile.d/rvm.sh ' ~/.profile # setup SOME DEFAULT flags FROM rvm (auto install, auto gemset CREATE, quiet curl) RUN echo"rvm_install_on_use_flag=1 rvm_gemset_create_on_use_flag=1 rvm_quiet_curl_flag=1"> ~/.rvmrc # Copy OVER the site vhosts # COPY ./docker_settings/apache_web.conf /etc/apache2/sites-available/000-asite.com.conf # RUN ln -s /etc/apache2/sites-available/000-asite.com.conf /etc/apache2/sites-enabled/000-asite.com.conf # RUN rm /etc/apache2/sites-enabled/000-DEFAULT.conf # # Link ssl # RUN ln -s /etc/apache2/sites-available/default-ssl.conf /etc/apache2/sites-enabled/default-ssl.conf # # Enable modules # RUN ln -s /etc/apache2/mods-available/rewrite.load /etc/apache2/mods-enabled/rewrite.load # RUN ln -s /etc/apache2/mods-available/ssl.load /etc/apache2/mods-enabled/ssl.load # RUN ln -s /etc/apache2/mods-available/ssl.conf /etc/apache2/mods-enabled/ssl.conf # RUN ln -s /etc/apache2/mods-available/socache_shmcb.load /etc/apache2/mods-enabled/socache_shmcb.load # # CREATE SOME directories so Apache doesn't fallover # RUN mkdir /var/www/html/public # # Restart apache to load changes # RUN service apache2 restart # # We need to make some directories writable by apache before docker mounts it # RUN chown -R www-data:www-data /var/www/html # # Donwload composer. Install to /usr/bin # WORKDIR /opt/composer # RUN curl -sS https://getcomposer.org/installer | php # RUN cp composer.phar /usr/bin/composer # # make the work directory the web root dir # WORKDIR /var/www/html # # interactive shell by default so rvm is sourced automatically #ENTRYPOINT /bin/bash -l CMD ["/bin/bash -l"] |
Postgres的Dockerfile
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | # Latest Ubuntu LTS FROM ubuntu:12.04 RUN apt-GET -y UPDATE #&& apt-GET -y upgrade RUN apt-GET -y install --fix-missing curl git wget libpq-dev node libpq-dev vim #Install postgres RUN locale-gen en_US.UTF-8 RUN sh -c 'echo"deb http://apt.postgresql.org/pub/repos/apt/ precise-pgdg main"> /etc/apt/sources.list.d/postgresql.list' RUN \wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add - RUN apt-GET -y UPDATE RUN apt-GET -y install postgresql-9.3 postgresql-9.3-postgis-2.1 #RUN apt-GET -y install postgis RUN echo"listen_addresses='*'">> /etc/postgresql/9.3/main/postgresql.conf # Expose the PostgreSQL port EXPOSE 5432 # ADD VOLUMEs TO allow backup OF config, logs AND DATABASES VOLUME ["/etc/postgresql","/var/log/postgresql","/var/lib/postgresql"] RUN service postgresql START #ENTRYPOINT /bin/bash #CMD ["/usr/lib/postgresql/9.3/bin/postgres","-D","/var/lib/postgresql/9.3/main","-c","config_file=/etc/postgresql/9.3/main/postgresql.conf","start"] |
Gemfile:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 | SOURCE 'https://rubygems.org' gem 'rails', '~> 3.2.17' # http://rack.github.com/ gem 'rack', '~> 1.4.5' # TO redirect TRAILING slashes TO have no TRAILING slashes gem 'rack-rewrite' platforms :ruby do # Unicorn IS a forking webserver gem 'unicorn' # Terminate out-of-control unicorns gem 'unicorn-worker-killer' END platforms :mswin do gem 'thin' END # dependencies FOR the redirector app: gem 'sinatra-subdomain' gem 'postrank-uri' # Used FOR DATE queries gem 'groupdate' # Used TO inject DATA INTO javascript DOM gem 'gon' # Used TO CONNECT TO Amazon FOR sitemap_generator gem gem 'fog' # Used FOR background workers/concurrent tasks. gem 'sidekiq' gem 'sidekiq-failures' # NEXT two gems are FOR sidekiq monitor gem 'slim', '>= 1.1.0' # IF you require 'sinatra' you GET the DSL extended TO Object gem 'sinatra', '>= 1.3.0', require: nil # Used FOR long running jobs TO display progress gem 'ruby-progressbar' # Cloudinary API - image processing AND CDN gem 'cloudinary' # Performance monitoring / exception tracking gem 'newrelic_rpm' gem 'newrelic-rake' # CONVERT an address INTO lat/lon coordinate pair gem 'geocoder' # Yesmail gem 'yesmail', git: 'git://github.com/apartmentlist/yesmail.git' gem 'yesmail2', git: 'git://github.com/apartmentlist/yesmail2.git' gem 'log_mixin', git: 'git://github.com/apartmentlist/log_mixin.git' # Captcha support through recaptcha gem 'recaptcha', :require => 'recaptcha/rails' # xml generation # IMPORTANT: Put nokogiri BEFORE pg IN your Gemfile # https://github.com/sparklemotion/nokogiri/issues/742 # http://stackoverflow.com/questions/6802410/warning-nokogiri-was-built-against-libxml-version-2-7-8-but-has-dynamically-lo#answer-10912948 # http://stackoverflow.com/questions/11668604/mountain-lion-libxml-nokogiri gem"nokogiri",">= 1.6.7.rc" # Postgres / Postgis gems gem 'pg' # Eventually, this gem needs upgrading AS this branch IS no longer supported gem 'postgis_adapter', git: 'git://github.com/nofxx/postgis_adapter.git' # HTTP/api stuff (lead posting) gem 'httparty', '~> 0.10.0' # HTTP library gem 'faraday' gem 'aws-sdk' gem 'json' gem 'psych', '~> 2.0.5' # hiredis IS a high performance redis driver that supports timeouts ON a socket gem 'hiredis' gem 'redis', require: ['redis/connection/hiredis', 'redis'] gem 'redis-rails' # Templates/Frontend gem 'haml', '>= 3.0.0' gem 'haml-rails' gem 'kramdown' gem 'haml-kramdown' gem 'jquery-rails', '~> 2.1.4' gem 'bourbon' gem 'meta-tags', require: 'meta_tags' # Detect mobile/tablet browsers gem 'mobile-fu' # P3P header generation so IE can LOAD cookies IN remote iFrames gem 'rack-p3p' # TIMESTAMP scopes gem 'timestamp_scopes', '~> 0.0.1' # Twitter bootstrap gem 'bootstrap-sass', '~> 2.3.2.1' gem 'jquery-validation-rails' # Pagination gem"kaminari" # Easy generation OF sitemaps WITH upload TO S3 gem 'sitemap_generator' # SHOW the Rails environment ON the Rails console prompt gem 'marco-polo' # Shorthand FOR update_all IN batches gem 'update_in_batches' # Cleanup HTML TO have a black OR white list OF tags gem 'sanitize' # A/B testing framework designed TO WORK WITH Rails gem 'split', require: 'split/dashboard' # Used TO include wordpress blog site that IS hosted ON a different server gem"rack-reverse-proxy", require:"rack/reverse_proxy" # Heroku specific GROUP :edge, :staging, :production do # Overwrite heroku's rails_log_stdout to support tagged logging gem 'rails_log_stdout', '~> 0.1.1' end # Gems used only for assets and not required # in production environments by default. group :assets do gem 'sass-rails', '3.2.5' gem 'coffee-rails' gem 'uglifier', '>= 1.0.3' end group :development, :test do gem 'awesome_print' gem 'quiet_assets' gem"rspec-rails","~> 2.13.0" gem"capybara","~> 2.1.0" gem"poltergeist","~> 1.3.0" gem 'rspec-given' gem 'rr' gem 'shoulda-matchers' gem 'capybara-screenshot' gem 'factory_girl_rails' gem 'forgery' gem 'simplecov', :require => false gem 'simplecov-rcov', :require => false gem 'dotenv-rails' gem"rspec-instafail","~> 0.2.4" gem"show_me_the_cookies" # Not removing these commented out gem lines so that we can enable profiling # in the near future per instructions at: # http://guides.rubyonrails.org/v3.2.13/performance_testing.html # enable next line for profiling # gem 'ruby-prof' # enable next 2 lines for profiling with rails 4 # gem 'rails-perftest' gem 'test-unit' end group :development do gem 'annotate' gem 'foreman' gem 'guard' gem 'guard-bundler' gem 'guard-livereload' gem 'guard-pow' gem 'guard-rspec' gem 'guard-spork' gem 'spork-rails' gem 'growl' gem 'powify' gem 'yard' gem 'stack_rescue' # gem 'pry-rails' # The heroku toolbelt is required for the heroku rake tasks. # https://toolbelt.heroku.com/ # gem 'heroku' end |
您的配置有很多问题,包括您对Ruby的选择。好的。
错误源于使用Ruby2.4和Rails3.3。支持的Ruby的最高版本是2.2,这是StackOverflow上的一个问题。这里是指向原始答案的链接,这里是应用于您的配置的答案本身。请查看此日志中的引用:好的。
Rails 3.2.22 includes all the commits from the 3-2-stable branch. This
mean that now Rails 3.2 supports Ruby 2.2.Ok.
Rails3.2不再接收错误修复(只有严重的安全修复),我不希望Rails3.2分支的更新能够确保Ruby>2.2的兼容性。此外,当释放Rails 5.0时,Rails 3.2达到使用寿命。所以你应该使用Ruby2.2,这就是我要回答的问题。好的。
在使用Docker时,首先需要了解的是,每个容器都有一个前台进程是最佳实践。这不是一个硬性的规则,但是当使用Docker Compose这样的工具时,这是预期的做法。所以简而言之,你肯定是用了错误的方式。好的。
第二条经验法则是尽可能使用官方图片,除非你有真正特殊的情况。如果你有一个没有被官方图片覆盖的案例,使用一个基于官方图片的维护良好的外景照片,或者将你的修改建立在官方图片之上。例如,在您的案例中,您希望使用PostGIS。官方的Postgres图像不包括这一点,但MDillon/Postgis图像是建立在官方的Postgres图像之上的,维护得很好,并具有更好的支持功能,消除了对自己图像的需求。好的。
另一个基本规则是尽量避免执行到映像中,除非您正在调试它,我不确定此配置是生产配置还是开发配置,但构建开发环境似乎是您希望这样做的,我假定是这样。好的。
还有一件令人费解(难以理解)的事情是,你的docker-compose和dockerfiles之间的分离。例如,您定义自己的Postgres图像,但使用官方Postgres:9.3.17。我知道你可能在使用环境中预先构建的图像,但这不是使用Docker Compose时的标准做法。如果是自定义图像,建议在撰写中使用Dockerfile。这允许您在运行中进行更改,并防止其他人假设您使用官方的Postgres图像。不管怎样,断开连接都会让人困惑。好的。
解决方案好的。
第一步:为您的配置选择基本映像。好的。
- 对于Rails3.2、Ruby2.2,我们可以使用Ruby:2.2图像(因为我认为使用Rails3和Ruby2.4是导致错误的原因)。
- 对于postgres+postgis,我们可以使用mdillon/postgis:9.3图像
第二步:编写dockerfiles好的。
对于Postgres/Postgis设置,不需要按原样使用图像。好的。
对于Rails应用程序,我们需要做很多事情,因为Docker,有些事情我们不需要做。好的。
我们需要:好的。
就是这样。说真的。我们不需要做的是:好的。
下面是一个应该在Rails Dockerfile中的示例。我假设gemfile和dockerfile在同一个文件夹中。应该是这样,因为它是唯一的dockerfile好的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | FROM ruby:2.2 # SET a working directory, I am partial TO /src but choose whatever you LIKE WORKDIR /src # Copy gemfile TO pre-install gems (Allows us TO quickly test IF ALL IS working well) COPY Gemfile /src/Gemfile # Install any library dependencies here LIKE so after which you should # install/UPDATE bundler THEN install gems FROM Gemfile RUN apt-GET -y UPDATE \ && apt-GET -y install curl \ git \ wget \ libpq-dev \ node \ libpq-dev \ vim \ /*whatever else you need*/ \ && rm -rf /var/lib/apt/lists/* \ # To preserve syntax highlighting */ && gem install bundler \ && bundle install # Copy SOURCE files TO image FOR flexibility later ON, FOR example IF you would LIKE TO push a bundled image TO a registry OR run it WITHOUT compose COPY . /src # Define /src AS a volume VOLUME /src # USE expose TO SHOW which port should be exposed TO the host OR other containers EXPOSE 3000 # Run rails s IN the foreground ON container launch CMD ["rails","s","-b 0.0.0.0","-p 3000"] |
这就是Dockerfile的作品。这个特定的dockerfile是源代码的根。这是一个例子,您可能仍然需要安装其他的库依赖项,如libpq,但是这些依赖项可以很容易地用通常的
第三步:定义docker-compose.yml好的。
在这个阶段,我们要做很多事情,其中一些事情是你最初做的正确的:好的。
然后,撰写文件应该与原始文件非常相似。好的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | version: '3' volumes: # We'll define a volume that will store the data from the postgres databases: postgres-data: driver: local services: # Our PostgreSQL service: postgres: image: mdillon/postgis:9.3 ports: # We'll bind our host's port 5432 to postgres's port 5432, so we can USE # our DATABASE IDEs WITH it: - 5432:5432 volumes: # Mount the DB dumps folder INTO the container, TO be able TO CREATE & access DATABASE dumps: - ./db/dumps:/db/dumps # Mount OUT tmp folder, we might want TO have access TO something there during development: - ./tmp:/tmp # We'll mount the 'postgres-DATA' volume into the location Postgres stores it's DATA: - postgres-DATA:/var/lib/postgresql/DATA # We'll mount the postgres socket just like before - /var/run/postgres/postgres.sock:/var/run/postgres/postgres.sock environment: POSTGRES_PASSWORD: password rails: build: context: . dockerfile: Dockerfile entrypoint: rails s -p 3000 -b 0.0.0.0 volumes: # Mount our app code directory (".") into our app containers at the #"/src" folder: - .:/src # Keep the stdin open, so we can attach to our app container's process AND do things such AS # byebug, etc: stdin_open: TRUE # Enable sending signals (CTRL+C, CTRL+P + CTRL+Q) INTO the container: tty: TRUE # Link TO our postgres AND redis containers, so they can be visible FROM our # app containers: links: # We'll include a link to the 'db' (postgres) container, making it visible from the container # using the 'db.local' hostname (which is not necessary, but I'm doing it here TO # illustrate that you can play WITH this): - postgres:db.local environment: # Run the app IN the 'development' environment: RACK_ENV: development RAILS_ENV: development depends_on: - postgres |
使用运行docker compose up的配置,应该无缝运行,但在运行之前,应该首先配置database.yml。好的。
第四步:数据库.yml好的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | defaults: &defaults adapter: postgresql # template: template_postgis encoding: unicode pool: 5 username: root password: password host: db.local development: <<: *defaults DATABASE: realty_development test: <<: *defaults DATABASE: realty_test staging: <<: *defaults DATABASE: realty_development production: <<: *defaults DATABASE: realty_production |
应该就是这样。但实际上,您只需要配置开发设置,因为这是docker-compose.yml中定义的环境,如果愿意,可以编辑它。好的。
结论好的。
请再次阅读docker和docker撰写文档,因为所有这些都是基本用法的一部分,并且在多个教程和存储库中。好的。好啊。