Кэш ресурсов rails не очищается - docker, rails, nginx

В настоящее время я использую комбинацию Rails, Docker, Nginx (как Rails, так и Nginx используются как образы Docker). Честно говоря, я не знаю, что в этом случае не так. Rails обслуживает старые и несуществующие файлы JavaScript и CSS в процессе производства. Это определенно проблема с кешем. Откуда я знаю? Я загрузил предыдущий образ Docker (который работал), скопировал и вставил старый URL-адрес в последний образ, и они сработали! Даже если их вообще нет в проекте!

Я провел небольшое исследование и не нашел проблемы:

Вот что я сделал:

  • Удалил всю систему (docker system prune -a -p).
  • Правильно вытащил последние образы Docker.
  • Удалил папку /tmp/cache/assets из Rails
  • Использованы следующие команды: RAILS_ENV='production' rails assets:precompile, rails assets:precompile, RAILS_ENV='production' rails assets:clean, rails assets:clean, rails assets:clobber, RAILS_ENV='production' rails assets:clobber
  • Удалил вручную папку public/assets. И все еще ничего
  • Я даже отключил хранилище кеша, сделав config.assets.cache_store = :null_store

Что у меня есть:

  • Рельсы 5.1.5
  • Nginx 1.13.1
  • Docker Compose 3.2

Вот часть Nginx, обслуживающая активы:

  # We enable gzip as a compression mechanism.
  location ~ ^/(assets|images|javascripts|stylesheets)/   {    
      try_files $uri @rails;     
      access_log off;    
      gzip_static on; 

      # to serve pre-gzipped version     
      expires max;    
      add_header Cache-Control public;     

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

Любые идеи? Я получаю ошибку 500 на новом CSS и JavaScript.

Редактировать: Еще кое-что. Rails действительно показывает правильный URL для новых ресурсов, но они получают ошибку сервера 500.

Edit x2 (добавлены файлы Docker Compose) *: Этот используется в разработке:

# WARNING!! Indentation is important! Be careful how you indent.
# All paths that point to the actual disk (not the Docker image) 
# are relative to the location of *this* file! 
# This is the development version of the file. The production one, the
# one that you need to upload is in ./docker-server/docker-compose.yml.
version: '3'
services:
  db:
    image: mariadb:10.3.5
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: "rootPassword"
      MYSQL_USER: "ruby"
      MYSQL_PASSWORD: "userPassword"
      MYSQL_DATABASE: "dev"
    ports:
    - "3306:3306"
    volumes:
      - db-data:/var/lib/mysql/data
      - ./db/rails_cprint.sql:/docker-entrypoint-initdb.d/rails_cprint.sql:ro
    networks: 
      - db
  pma:
    image: phpmyadmin/phpmyadmin
    depends_on:
      - db
    ports:
      - "4000:80"
    networks:
      - db
  app:
    build: .
    depends_on:
      - db
    environment:
      RAILS_ENV: development
      LOGSTASH_HOST: localhost
      SECRET_MYSQL_HOST: 'db'
      SECRET_MYSQL_DATABASE: 'dev'
      SECRET_MYSQL_USERNAME: 'ruby'
      SECRET_MYSQL_PASSWORD: 'userPassword'
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3001 -b '0.0.0.0'"
    stdin_open: true
    tty: true
    links:
      - db
    volumes:
      - "./:/var/www/cprint"
    ports:
      - "3001:3001"
      - "1234:1234"
    expose:
      - "3001"
    networks:
      - elk
      - db
  ipmask:
    build: ./reverse_proxy .
    restart: always
    command: "npm run debug"
    ports:
      - "5050:5050"
      - "9229:9229"
    volumes:
      - "./reverse_proxy/:/var/www/cprint"
    networks:
      - db
      - elk
    # Only on development!!
    depends_on:
      - db

# Volumes are the recommended storage mechanism of Docker. 
volumes:
  db-data:
    driver: local
  elasticsearch:
    driver: local

networks:
    elk:
      driver: bridge
    db:
      driver: bridge

Это тот, который используется в производстве:

# This is the production docker-compose.ymlf ile. 
# This is a docker compose file that will pull from the private
# repo and will use all the images. 
# This will be an equivalent for production.

# The version is super important.
version: '3.2'
services:
  app:
    image: #The private rails URL rails:latest
    restart: always
    environment:
      RAILS_ENV: production
      RAILS_PRODUCTION_FULL_DEBUG: 'true'
      RAILS_LOG_TO_STDOUT: 'true'
    # https://github.com/docker/compose/issues/1393
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -e production -p 5000 -b '0.0.0.0'"
    volumes:
      - /var/www/app
    ports:
      - "5000:5000"
    expose:
      - "5000"
    networks:
      - elk
    links:
      - logstash
  # Uses Nginx as a web server
  # https://stackoverflow.com/questions/30652299/having-docker-access-external-files
  # 
  web:
    image: # the private NGINX image URL 
    # Runs it in debug
    # command: [nginx-debug, '-g', 'daemon off;']
    depends_on:
      - elasticsearch
      - kibana
      - app
      - ipmask
    restart: always
    # Maps the SSL at the same exact location in the server.
    volumes:
      # https://stackoverflow.com/a/48800695/1057052
      # - "/etc/ssl/:/etc/ssl/"
      - type: bind
        source: /etc/ssl/certs
        target: /etc/ssl/certs
      - type: bind
        source: /etc/ssl/private/
        target: /etc/ssl/private
      - type: bind
        source: /etc/nginx/.htpasswd
        target: /etc/nginx/.htpasswd
      - type: bind
        source: /etc/letsencrypt/
        target: /etc/letsencrypt/
    ports:
      - "80:80"
      - "443:443"
    networks:
      - elk
      - nginx
    links:
      - elasticsearch
      - kibana
  # Defining the ELK Stack! 
  # If you're moving servers, check the nmap issue.
  # https://www.elastic.co/guide/en/elasticsearch/reference/current/vm-max-map-count.html
  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:6.2.3
    restart: always
    container_name: elasticsearch
    networks:
      - elk
    # Default config from elastic.co
    environment:
      - cluster.name=docker-cluster
      - bootstrap.memory_lock=true
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
    # Default config from elastic.co
    ulimits:
      memlock:
        soft: -1
        hard: -1
    volumes:
      - elasticsearch:/usr/share/elasticsearch/data
    ports:
      - 9200:9200
  logstash:
    image: docker.elastic.co/logstash/logstash:6.2.3
    restart: always
    container_name: logstash
    volumes:
      - ./elk/logstash/config/logstash.yml:/usr/share/logstash/config/logstash.yml
      - ./elk/logstash/pipeline/logstash.conf:/etc/logstash/conf.d/logstash.conf
    command: logstash -f /etc/logstash/conf.d/logstash.conf
    ports:
      - "5228:5228"
    environment:
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
    networks:
      - elk
    links:
      - elasticsearch
    depends_on:
      - elasticsearch
  kibana:
    image: docker.elastic.co/kibana/kibana:6.2.3
    restart: always
    volumes:
      - ./elk/kibana/config/kibana.yml:/usr/share/kibana/config/kibana.yml
    ports:
      - "5601:5601"
    networks:
      - elk
    links:
      - elasticsearch
    depends_on:
      - elasticsearch
  ipmask:
    image: # the private image URL 
    command: "npm start"
    restart: always
    environment:
      - "NODE_ENV=production"
    expose:
      - "5050"
    ports:
      - "5050:5050"
    links:
      - app
    networks:
      - nginx


# # Volumes are the recommended storage mechanism of Docker. 
volumes:
  elasticsearch:
    driver: local
  rails:
    driver: local

networks:
    elk:
      driver: bridge
    nginx:
      driver: bridge

Ruby Dockerfile:

# Main Dockerfile that contains the Rails application.
# https://docs.docker.com/compose/rails/#define-the-project

FROM ruby:2.5.0
RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs vim

ENV RAILS_ROOT /var/www/app

RUN mkdir -p $RAILS_ROOT

WORKDIR $RAILS_ROOT


COPY Gemfile ./
COPY Gemfile.lock ./

RUN bundle install

COPY . .

Примечание: я вырезал из него всю разумную информацию.

Изменить x 3 Я нашел проблему. Я ищу решения. Я покопался в образе Docker Nginx и увидел в списке общую папку Rails. Я открыл его и обнаружил, что это старые активы. Я отправлю ответ, как только найду правильное решение.

Изменить x 4 Обычная ошибка Nginx 500: enter image description here

Можете ли вы показать результат упомянутой вами ошибки 500?

thesecretmaster 11.08.2018 20:03

@thesecretmasterSure! Это просто страница ошибки Nginx plain 500 - Не удалось загрузить ресурс: сервер ответил статусом 500 ()

Jose A 13.08.2018 13:39

Я имел ввиду ошибку 500 в логах рельсов, но я рад, что вы разобрались!

thesecretmaster 13.08.2018 15:50

@thesecretmaster Большое вам спасибо :) и, кстати, Rails ни разу не получил ошибку 500! Я проверил журналы и ничего не обнаружил (что было очень подозрительно) ... В любом случае, здесь виноват объем Docker.

Jose A 22.08.2018 18:31
5
4
797
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Нашел решение!

TL; DR

Виновником не был ни Rails, ни Docker ... это был я (рисунки 🙄). Проблема заключалась в том, что я вручную скопировал общую папку при создании образа Docker для контейнера Nginx, но Я никогда не планировал это как общий том между Rails и Nginx.

Объяснение и решение:

Я забыл опубликовать свой файл Nginx Dockerfile. В нем была строка, в которой говорилось:

# copy over static assets
COPY public public/

Которая скопировала общую папку Rails в образ Docker. Предостережение заключалось в том, что при восстановлении образа это запускало Только! Поскольку в Nginx не вносились изменения, перестраивать образ не нужно!

Исправление заключалось в создании общего тома в docker-compose.yml между Rails и Nginx:

# Some lines are omitted 
 app:
    image: rails:latest
    restart: always
    environment:
      RAILS_ENV: production
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -e production -p 5000 -b '0.0.0.0'"
    volumes:
      - public-files:/var/www/app/public
web:
    image: nginx:latest
    # Runs it in debug
    # command: [nginx-debug, '-g', 'daemon off;']
    depends_on:
      - elasticsearch
      - kibana
      - app
      - ipmask
    restart: always
    # Maps the SSL at the same exact location in the server.
    volumes:
      # https://stackoverflow.com/a/48800695/1057052
      # - "/etc/ssl/:/etc/ssl/"
      # We need to map this so Nginx can read the public files
      - public-files:/var/www/app/public:ro

Другие вопросы по теме