【问题标题】:Local changes not reflecting changes in the browser when used docker volumes使用 docker 卷时,本地更改不反映浏览器中的更改
【发布时间】:2020-08-24 11:45:35
【问题描述】:

我有一个 rails 应用程序,我使用 docker 卷来使代码持久化。每当我在本地更改任何内容时,代码都会反映在 docker 容器中,但这些更改会反映在浏览器中。我不确定我是否遗漏了什么。

现在每次代码发生更改时,我都会重新启动容器,这不是正确的做法。 下面是我的 docker-compose 文件

version: '3'
services:
  webapp:
    build: .
    ports:
      - '3001:3001'
    volumes:
      - '.:/data/checklist'
    depends_on:
      - db
      - redis
    environment:
      DB_USERNAME: "root"
      DB_PASSWORD: "Mission2019"
      DB_DATABASE: "list"
      DB_PORT: 3306
      DB_HOST: db
      RAILS_ENV: production 
      RAILS_MAX_THREADS: 5
  db:
    image: mysql:5.7
    restart: always
    environment:
      MYSQL_DATABASE: "list"
      MYSQL_ROOT_PASSWORD: "Mission2019"
      MYSQL_USERNAME: "root"
  redis:
    image: redis:4.0-alpine
    command: redis-server
    ports:
      - '6379:6379'
  sidekiq:
    depends_on:
      - "db"
      - "redis"
    build: .
    command: bundle exec sidekiq -C config/sidekiq.yml

这是我的 dockerfile

FROM ubuntu:16.04


ENV RUBY_MAJOR="2.6" \
    RUBY_VERSION="2.6.3" \
    RUBYGEMS_VERSION="3.0.8" \
    BUNDLER_VERSION="1.17.3" \
    RAILS_VERSION="5.2.1" \
    RAILS_ENV="development" \
    GEM_HOME="/usr/local/bundle"
ENV BUNDLE_PATH="$GEM_HOME" \
    BUNDLE_BIN="$GEM_HOME/bin" \
    BUNDLE_SILENCE_ROOT_WARNING=1 \
    BUNDLE_APP_CONFIG="$GEM_HOME"

ENV PATH="$BUNDLE_BIN:$GEM_HOME/bin:$GEM_HOME/gems/bin:$PATH"

USER root
RUN apt-get update && \
      apt-get -y install sudo
RUN echo "%sudo ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers && \
    addgroup --gid 1024 stars && \
    useradd -G stars,sudo -d /home/user --shell /bin/bash -m user
RUN mkdir -p /usr/local/etc \
    && echo 'install: --no-document' >> /usr/local/etc/gemrc \
    && echo 'update: --no-document' >> /usr/local/etc/gemrc

USER user
RUN sudo apt-get -y install --no-install-recommends vim make gcc zlib1g-dev autoconf build-essential libssl-dev libsqlite3-dev \
    curl htop unzip mc openssh-server openssl bison libgdbm-dev ruby git libmysqlclient-dev tzdata mysql-client
    
RUN sudo rm -rf /var/lib/apt/lists/* \
    && sudo curl -fSL -o ruby.tar.gz "http://cache.ruby-lang.org/pub/ruby/$RUBY_MAJOR/ruby-$RUBY_VERSION.tar.gz" \
    && sudo mkdir -p /usr/src/ruby \
    && sudo tar -xzf ruby.tar.gz -C /usr/src/ruby --strip-components=1 \
    && sudo rm ruby.tar.gz

USER root
RUN cd /usr/src/ruby \
    && { sudo echo '#define ENABLE_PATH_CHECK 0'; echo; cat file.c; } > file.c.new && mv file.c.new file.c \
    && autoconf \
    && ./configure --disable-install-doc

USER user
RUN cd /usr/src/ruby \
    && sudo make -j"$(nproc)" \
    && sudo make install \
    && sudo gem update --system $RUBYGEMS_VERSION \
    && sudo rm -r /usr/src/ruby
RUN sudo gem install bundler --version "$BUNDLER_VERSION"

RUN sudo mkdir -p "$GEM_HOME" "$BUNDLE_BIN" \
    && sudo chmod 777 "$GEM_HOME" "$BUNDLE_BIN" \
    && sudo gem install rails --version "$RAILS_VERSION"
RUN mkdir -p ~/.ssh && \
    chmod 0700 ~/.ssh && \
    ssh-keyscan github.com > ~/.ssh/known_hosts
ARG ssh_pub_key
ARG ssh_prv_key
RUN echo "$ssh_pub_key" > ~/.ssh/id_rsa.pub && \
    echo "$ssh_prv_key" > ~/.ssh/id_rsa && \
    chmod 600 ~/.ssh/id_rsa.pub && \
    chmod 600 ~/.ssh/id_rsa
USER root
RUN curl -sL https://deb.nodesource.com/setup_10.x | sudo -E bash -
RUN apt-get install -y nodejs
USER user
WORKDIR /data
RUN sudo mkdir /data/checklist
WORKDIR /data/checklist
ADD Gemfile Gemfile.lock ./

RUN sudo chown -R user /data/checklist
RUN bundle install
ADD . .
RUN sudo chown -R user /data/checklist
EXPOSE 3001
ENV RAILS_ENV production
ENV RAILS_SERVE_STATIC_FILES true
ENV RAILS_LOG_TO_STDOUT true
ENTRYPOINT ["sh", "./config/docker/startup.sh"]
#! /bin/sh

# Wait for DB services

# Prepare DB (Migrate - If not? Create db & Migrate)
kill -9 `cat /data/checklist/tmp/pids/server.pid`
sh ./config/docker/prepare-db.sh

# Pre-comple app assets
sh ./config/docker/asset-pre-compile.sh

# Start Application
rails s -p 3001 -b 0.0.0.0

生产.rb

Rails.application.configure do
  # Settings specified here will take precedence over those in config/application.rb.

  # Code is not reloaded between requests.
  config.cache_classes = true

  # Eager load code on boot. This eager loads most of Rails and
  # your application in memory, allowing both threaded web servers
  # and those relying on copy on write to perform better.
  # Rake tasks automatically ignore this option for performance.
  config.eager_load = true

  # Full error reports are disabled and caching is turned on.
  config.consider_all_requests_local       = false
  config.action_controller.perform_caching = true

  # Ensures that a master key has been made available in either ENV["RAILS_MASTER_KEY"]
  # or in config/master.key. This key is used to decrypt credentials (and other encrypted files).
  # config.require_master_key = true

  # Disable serving static files from the `/public` folder by default since
  # Apache or NGINX already handles this.
  config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present?

  # Compress JavaScripts and CSS.
  config.assets.js_compressor = :uglifier
  # config.assets.css_compressor = :sass

  # Do not fallback to assets pipeline if a precompiled asset is missed.
  config.assets.compile = false

  # `config.assets.precompile` and `config.assets.version` have moved to config/initializers/assets.rb

  # Enable serving of images, stylesheets, and JavaScripts from an asset server.
  # config.action_controller.asset_host = 'http://assets.example.com'

  # Specifies the header that your server uses for sending files.
  # config.action_dispatch.x_sendfile_header = 'X-Sendfile' # for Apache
  # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX

  # Store uploaded files on the local file system (see config/storage.yml for options)
  config.active_storage.service = :local

  # Mount Action Cable outside main process or domain
  # config.action_cable.mount_path = nil
  # config.action_cable.url = 'wss://example.com/cable'
  # config.action_cable.allowed_request_origins = [ 'http://example.com', /http:\/\/example.*/ ]

  # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
  # config.force_ssl = true

  # Use the lowest log level to ensure availability of diagnostic information
  # when problems arise.
  config.log_level = :debug

  # Prepend all log lines with the following tags.
  config.log_tags = [ :request_id ]

  # Use a different cache store in production.
  # config.cache_store = :mem_cache_store

  # Use a real queuing backend for Active Job (and separate queues per environment)
  # config.active_job.queue_adapter     = :resque
  # config.active_job.queue_name_prefix = "Checklist_#{Rails.env}"

  config.action_mailer.perform_caching = false

  # Ignore bad email addresses and do not raise email delivery errors.
  # Set this to true and configure the email server for immediate delivery to raise delivery errors.
  # config.action_mailer.raise_delivery_errors = false

  # Enable locale fallbacks for I18n (makes lookups for any locale fall back to
  # the I18n.default_locale when a translation cannot be found).
  config.i18n.fallbacks = true

  # Send deprecation notices to registered listeners.
  config.active_support.deprecation = :notify

  # Use default logging formatter so that PID and timestamp are not suppressed.
  config.log_formatter = ::Logger::Formatter.new

  # Use a different logger for distributed setups.
  # require 'syslog/logger'
  # config.logger = ActiveSupport::TaggedLogging.new(Syslog::Logger.new 'app-name')
  config.action_mailer.default_url_options = { :host => 'localhost:3000', protocol: 'http' }
  config.action_mailer.smtp_settings = {
    address: "smtp.gmail.com",
    port: 587,
    domain: "example.com",
    authentication: "plain",
    enable_starttls_auto: true,
    user_name: ENV["EMAIL"],
    password: ENV["EMAIL_PASSWORD"]
  }
  if ENV["RAILS_LOG_TO_STDOUT"].present?
    logger           = ActiveSupport::Logger.new(STDOUT)
    logger.formatter = config.log_formatter
    config.logger    = ActiveSupport::TaggedLogging.new(logger)
  end

  # Do not dump schema after migrations.
  config.active_record.dump_schema_after_migration = false
end

【问题讨论】:

  • 可以分享 startup.sh 和 production.rb 文件吗?
  • 生产配置不刷新文件。为此目的使用development。您可能有文件系统侦听器问题。在您的config/development.rb 中尝试评论此行config.file_watcher = ActiveSupport::EventedFileUpdateChecker 看看是否有帮助。
  • 我尝试评论提到的行,它不起作用。 @DannyB
  • 标准的面向生产的 Docker 做法是删除volumes:,重新运行docker build,并在应用程序代码更改时删除并重新创建容器。您可以使用 Bundler 和 rvmrbenv 的某种组合来获得隔离的本地 Ruby 开发环境。您可以显着简化 Dockerfile:不要安装 sudo 或尝试配置 ssh 访问,并考虑使用 ruby Docker Hub 映像作为基础。

标签: ruby-on-rails ruby docker docker-compose docker-volume


【解决方案1】:

一般来说,Rails 不会在生产环境中热重载代码(出于很好的理由,包括安全性、稳定性和速度),所以我会考虑切换到开发 Rails 环境。

接下来要警惕的是,docker 可能不会以 Rails 会“注意到”文件已更改的方式(即使在 development 中)来获取更改。为了解决这个问题,添加一行:

config.file_watcher = ActiveSupport::FileUpdateChecker

到您的 production.rb 文件(或 development.rb 在您切换的情况下)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-11
    • 1970-01-01
    • 2019-02-26
    • 1970-01-01
    • 2017-10-08
    • 2021-03-06
    相关资源
    最近更新 更多