部署 Docker+Rails5+Puma+Nginx 本地部署时,出现错误:bash: bundle: command not found

Sylor-huang · 2019年11月23日 · 最后由 reducm 回复于 2019年12月04日 · 6626 次阅读

我现在用的环境是: Ruby 2.5.1,Rails-5.2.4, mysql 5.7, 当我在本地练习docker部署时,出现了错误,导致 docker 的 web,app,和 mysql 都没启动,麻烦大家帮我看下,非常感谢。

错误日志:

Starting marine_drug_db_1 ... done
Recreating marine_drug_app_1 ... done
Recreating marine_drug_web_1 ... done
Attaching to marine_drug_db_1, marine_drug_app_1, marine_drug_web_1
db_1   | 2019-11-23 12:07:03+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 5.7.28-1debian9 started.
db_1   | 2019-11-23 12:07:03+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql'
app_1  | Puma starting in single mode...
app_1  | * Version 4.3.0 (ruby 2.5.1-p57), codename: Mysterious Traveller
app_1  | * Min threads: 5, max threads: 5
web_1  | bash: bundle: command not found   #这里报错
db_1   | 2019-11-23 12:07:03+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 5.7.28-1debian9 started.
app_1  | * Environment: development
db_1   | 2019-11-23 12:07:03+00:00 [Note] [Entrypoint]: Initializing database files
db_1   | 2019-11-23T12:07:03.544450Z 0 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp server option (see documentation for more details).
db_1   | 2019-11-23T12:07:03.546435Z 0 [ERROR] --initialize specified but the data directory has files in it. Aborting.   #这里报错
db_1   | 2019-11-23T12:07:03.546500Z 0 [ERROR] Aborting
marine_drug_db_1 exited with code 1
app_1  | * Listening on tcp://0.0.0.0:3000
app_1  | Errno::ENOENT: No such file or directory - connect(2) for /marine_drug/tmp/sockets/puma.sock
app_1  |   /usr/local/bundle/gems/puma-4.3.0/lib/puma/binder.rb:327:in `initialize'
app_1  |   /usr/local/bundle/gems/puma-4.3.0/lib/puma/binder.rb:327:in `new'
app_1  |   /usr/local/bundle/gems/puma-4.3.0/lib/puma/binder.rb:327:in `add_unix_listener'
app_1  |   /usr/local/bundle/gems/puma-4.3.0/lib/puma/binder.rb:151:in `block in parse'
app_1  |   /usr/local/bundle/gems/puma-4.3.0/lib/puma/binder.rb:90:in `each'
app_1  |   /usr/local/bundle/gems/puma-4.3.0/lib/puma/binder.rb:90:in `parse'
app_1  |   /usr/local/bundle/gems/puma-4.3.0/lib/puma/runner.rb:161:in `load_and_bind'
app_1  |   /usr/local/bundle/gems/puma-4.3.0/lib/puma/single.rb:98:in `run'
app_1  |   /usr/local/bundle/gems/puma-4.3.0/lib/puma/launcher.rb:172:in `run'
app_1  |   /usr/local/bundle/gems/puma-4.3.0/lib/puma/cli.rb:80:in `run'
app_1  |   /usr/local/bundle/gems/puma-4.3.0/bin/puma:10:in `<top (required)>'
app_1  |   /usr/local/bundle/bin/puma:23:in `load'
app_1  |   /usr/local/bundle/bin/puma:23:in `<top (required)>'
app_1  | bundler: failed to load command: puma (/usr/local/bundle/bin/puma)   #这里报错
marine_drug_web_1 exited with code 127
marine_drug_app_1 exited with code 1

puma.rb:

threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 }.to_i
threads threads_count, threads_count
port        ENV.fetch("PORT") { 3000 }
environment ENV.fetch("RAILS_ENV") { "development" }
plugin :tmp_restart

app_root = File.expand_path("../..", __FILE__)
bind "unix://#{app_root}/tmp/sockets/puma.sock"

stdout_redirect "#{app_root}/log/puma.stdout.log", "#{app_root}/log/puma.stderr.log", true

nginx.conf:

upstream marine_drug {

   server unix://$RAILS_ROOT/tmp/sockets/puma.sock;
}

server {
   listen 80;
   # define your domain or IP
   server_name localhost;

   # define the public application root
   root   $RAILS_ROOT/public;
   index  index.html;

   # define where Nginx should write its logs
   access_log $RAILS_ROOT/log/nginx.access.log;
   error_log $RAILS_ROOT/log/nginx.error.log;

   # deny requests for files that should never be accessed
   location ~ /\. {
      deny all;
   }

   location ~* ^.+\.(rb|log)$ {
      deny all;
   }

   # serve static (compiled) assets directly if they exist (for rails production)
   location ~ ^/(assets|images|javascripts|stylesheets|swfs|system)/   {

      try_files $uri @rails;
      # close access log
      access_log off;
      # to serve pre-gzipped version
      gzip_static on;

      expires max;
      add_header Cache-Control public;

      add_header Last-Modified "";
      add_header ETag "";
      break;
   }

   # send non-static file requests to the app server
   location / {
      try_files $uri @rails;
   }

   location @rails {
      internal; 
      proxy_set_header  X-Real-IP  $remote_addr;
      proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header Host $http_host;
      proxy_redirect off;
      proxy_pass http://rails_app; 
   }
}

Dockerfile:

FROM ruby:2.5.1
RUN  sed -i s@/archive.ubuntu.com/@/mirrors.aliyun.com/@g /etc/apt/sources.list
RUN  apt-get clean

RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs
RUN apt-get install -y imagemagick
RUN apt-get install -y vim
ENV RAILS_ROOT /marine_drug
RUN mkdir -p $RAILS_ROOT
RUN mkdir -p $RAILS_ROOT/tmp/pids
RUN mkdir -p $RAILS_ROOT/tmp/sockets
WORKDIR $RAILS_ROOT

COPY Gemfile Gemfile
COPY Gemfile.lock Gemfile.lock

RUN gem install bundler
RUN bundler install
RUN bundle install

COPY . .

RUN bundle exec rake RAILS_ENV=$RAILS_ENV assets:precompile
EXPOSE 3000

Nginx 的 Dockerfile:

FROM ruby:2.5.1
RUN  sed -i s@/archive.ubuntu.com/@/mirrors.aliyun.com/@g /etc/apt/sources.list
RUN  apt-get clean

RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs
RUN apt-get install -y imagemagick
RUN apt-get install -y vim
ENV RAILS_ROOT /marine_drug
RUN mkdir -p $RAILS_ROOT
RUN mkdir -p $RAILS_ROOT/tmp/pids
RUN mkdir -p $RAILS_ROOT/tmp/sockets
WORKDIR $RAILS_ROOT

COPY Gemfile Gemfile
COPY Gemfile.lock Gemfile.lock

RUN gem install bundler
RUN bundler install
RUN bundle install

COPY . .

RUN bundle exec rake RAILS_ENV=$RAILS_ENV assets:precompile
EXPOSE 3000

docker-compose.yml:

version: '3'
services:
  app:
    build:
      context: .
    env_file:
      - ./environments/db.env
    command: bundle exec puma -C config/puma.rb
    volumes:
      - .:/marine_drug
      - public-data:/marine_drug/public
      - tmp-data:/marine_drug/tmp
      - log-data:/marine_drug/log
    depends_on:
      - db
  db:
    image: mysql:5.7
    env_file:
      - ./environments/db.env
    volumes:
      - ./tmp/db:/var/lib/mysql/data
    command: --innodb-use-native-aio=0
  web:
    build:
      context: .
      dockerfile: containers/nginx/Dockerfile
    command: bash -c "rm -f tmp/pids/server.pid && RAILS_ENV=development bundle exec rails s -p 3000 -b '0.0.0.0'"
    ports:
      - 80:80
      - 443:443
    depends_on:
      - app
volumes:
  public-data:
  tmp-data:
  log-data:
  db-data:

网上查询了好长时间,但是按照网上说的,添加sockets文件夹,但这好像没有成功。麻烦大家帮我指点下,非常感谢。

docker-compose.yml:

为啥要在 nginx 里跑 rails s

Nginx 的 Dockerfile 和 Dockerfile 是一个

Sylor-huang 关闭了讨论。 11月25日 09:57
Sylor-huang 重新开启了讨论。 11月25日 09:58

@lidashuang 谢谢您的指正,是粘贴错了的。。。我后续修改下。这个方法我发现有问题后,后来就改成了:docker 镜像一个 ubuntu 系统,然后全部的代码都在这个 ubuntu 系统里,然后再打包这个容器。不知道会不会有问题。。。

RUN bundler install => CMD ["bundle", "install"],还有既然是用了 compose, 命令可以写在外面

command:
- /biin/sh
- c
- |
  bundle install
  bundle exec rails db:migrate
  bundle exec rails assets:precompile
  bundle exec puma -C config/puma.rb

一般用 compose,就没必要 nginx 跑在一起了,外部配一个反向代理到暴露的端口就行

需要 登录 后方可回复, 如果你还没有账号请 注册新账号