7 votes

Rails production - toutes les images sont cassées après un nouveau déploiement

J'ai suivi le screencast de Ryan et déployé sur un VPS. J'utilise donc Unicorn + nginx + github + Ubuntu 12.04 LTS + capistrano. J'utilise également i18n pour traduire l'application.

Je tiens également à signaler que j'utilise Carriarewave pour télécharger des photos. Carriarewave conserve les images localement sur le VPS. Lorsque je télécharge des images, tout fonctionne bien et les images téléchargées apparaissent.

Mais à chaque fois que je déploie de nouveaux changements sur le serveur, TOUTES mes images se cassent. C'est vraiment affreux. J'ai essayé de redémarrer nginx manuellement :

sudo service nginx restart

Et j'ai essayé de redémarrer Unicorn :

/etc/init.d/unicorn_Chirch_app restart

Cela ne aide pas non plus.

Quand j'essaie d'ouvrir ma page cassée manuellement, il indique :

La page que vous cherchez n'existe pas.
Vous avez peut-être mal tapé l'adresse ou la page a peut-être été déplacée.

Lorsque j'essaie de trouver des images dans la console :

> Photo.all
> => [#, #, #]

À ce que je comprends, elles devraient être là.

Erreur des journaux :

Début de la requête GET "/ru/uploads%2Fphoto%2Fimage%2F4%2FSeasonscape_by_alexiuss" pour 89.178.205.47 à 2013-01-21 11:31:17 +0000

ActionController::RoutingError (Aucune route ne correspond [GET] "/ru/uploads%2Fphoto%2Fimage%2F4%2FSeasonscape_by_alexiuss"):
  actionpack (3.2.8) lib/action_dispatch/middleware/debug_exceptions.rb:21:in `call'
  actionpack (3.2.8) lib/action_dispatch/middleware/show_exceptions.rb:56:in `call'
  railties (3.2.8) lib/rails/rack/logger.rb:26:in `call_app'
  railties (3.2.8) lib/rails/rack/logger.rb:16:in `call'
  actionpack (3.2.8) lib/action_dispatch/middleware/request_id.rb:22:in `call'
  rack (1.4.4) lib/rack/methodoverride.rb:21:in `call'
  rack (1.4.4) lib/rack/runtime.rb:17:in `call'
  activesupport (3.2.8) lib/active_support/cache/strategy/local_cache.rb:72:in `call'
  rack (1.4.4) lib/rack/lock.rb:15:in `call'
  rack-cache (1.2) lib/rack/cache/context.rb:136:in `forward'
  rack-cache (1.2) lib/rack/cache/context.rb:245:in `fetch'
  rack-cache (1.2) lib/rack/cache/context.rb:185:in `lookup'
  rack-cache (1.2) lib/rack/cache/context.rb:66:in `call!'
  rack-cache (1.2) lib/rack/cache/context.rb:51:in `call'
  railties (3.2.8) lib/rails/engine.rb:479:in `call'
  railties (3.2.8) lib/rails/application.rb:223:in `call'
  railties (3.2.8) lib/rails/railtie/configurable.rb:30:in `method_missing'
  unicorn (4.5.0) lib/unicorn/http_server.rb:552:in `process_client'
  unicorn (4.5.0) lib/unicorn/http_server.rb:628:in `worker_loop'
  unicorn (4.5.0) lib/unicorn/http_server.rb:500:in `spawn_missing_workers'
  unicorn (4.5.0) lib/unicorn/http_server.rb:511:in `maintain_worker_count'
  unicorn (4.5.0) lib/unicorn/http_server.rb:277:in `join'
  unicorn (4.5.0) bin/unicorn:121:in `'
  /home/deployer/apps/My_app/shared/bundle/ruby/1.9.1/bin/unicorn:23:in `load'
  /home/deployer/apps/My_app/shared/bundle/ruby/1.9.1/bin/unicorn:23:in `

Mon config/deploy.rb

require "bundler/capistrano"

server "my_ip_here", :web, :app, :db, primary: true

set :application, "My_app"
set :user, "deployer"
set :deploy_to, "/home/#{user}/apps/#{application}"
set :deploy_via, :remote_cache
set :use_sudo, false

set :scm, "git"
set :repository, "git@github.com:MyName/#{application}.git"
set :branch, "master"

default_run_options[:pty] = true
ssh_options[:forward_agent] = true

after "deploy", "deploy:cleanup" # keep only the last 5 releases

namespace :deploy do
  %w[start stop restart].each do |command|
    desc "#{command} unicorn server"
    task command, roles: :app, except: {no_release: true} do
      run "/etc/init.d/unicorn_#{application} #{command}"
    end
  end

  task :setup_config, roles: :app do
    sudo "ln -nfs #{current_path}/config/nginx.conf /etc/nginx/sites-enabled/#{application}"
    sudo "ln -nfs #{current_path}/config/unicorn_init.sh /etc/init.d/unicorn_#{application}"
    run "mkdir -p #{shared_path}/config"
    put File.read("config/database.example.yml"), "#{shared_path}/config/database.yml"
    puts "Now edit the config files in #{shared_path}."
  end
  after "deploy:setup", "deploy:setup_config"

  task :symlink_config, roles: :app do
    run "ln -nfs #{shared_path}/config/database.yml #{release_path}/config/database.yml"
  end
  after "deploy:finalize_update", "deploy:symlink_config"

  desc "Make sure local git is in sync with remote."
  task :check_revision, roles: :web do
    unless `git rev-parse HEAD` == `git rev-parse origin/master`
      puts "WARNING: HEAD is not the same as origin/master"
      puts "Run `git push` to sync changes."
      exit
    end
  end
  before "deploy", "deploy:check_revision"
end

8voto

ExiRe Points 1982

D'accord, j'ai trouvé la solution. Le problème est apparu parce que je n'ai pas changé le dossier par défaut pour stocker les images. Vous pouvez trouver votre dossier par défaut dans public/uploads. Cela signifie que chaque cap deploy va créer un nouveau dossier vide qui ne contient pas vos anciens fichiers.

Pour résoudre ce problème, vous devriez créer un autre dossier qui ne se trouve pas dans votre application. J'ai choisi la manière la plus simple. J'ai créé un lien symbolique.

Mes étapes:

1) Sur votre serveur, allez dans le dossier partagé de votre application (il a été généré automatiquement via Capistrano). Ensuite, créez votre dossier pour stocker les nouvelles images :

$ mkdir uploads

2) Donnez les droits nécessaires pour le dossier créé :

$ sudo chmod 775 uploads

3) Sur votre machine locale dans config/deploy.rb ajoutez :

tâche :symlink_config, rôles: :app faire
  ...
  run "ln -nfs #{shared_path}/uploads #{release_path}/public/uploads"
end

4) Ensuite, poussez git et déployez :

$ git push
$ cap deploy:symlink
$ cap deploy

Maintenant tout fonctionne correctement.

2voto

Gustavo Schmidt Points 133

Bien joué! J'ai étendu votre recette capistrano.

# config/recipes/carrierwave.rb

namespace :carrierwave do 
  task :uploads_folder do
    run "mkdir -p #{shared_path}/uploads"
    run "#{sudo} chmod 775 #{shared_path}/uploads"
  end
  after 'deploy:setup', 'carrierwave:uploads_folder'

  task :symlink do 
    run "ln -nfs #{shared_path}/uploads #{release_path}/public/uploads"
  end
  after 'deploy', 'carrierwave:symlink'
end

0voto

rksazid Points 23

@ExiRe & @Charlie répondent fonctionne sur Capistrano 2.x. Dans Capistrano 3.x, la commande run a été remplacée par la commande execute.

Donc, j'ai résolu cela avec les étapes suivantes:

  1. Créez un fichier rake dans le répertoire lib/capistrano/tasks/carrierwave.rake avec le contenu:

    namespace :carrierwave do task :uploads_folder do on roles(:app) do execute "mkdir -p #{shared_path}/uploads" execute "#{sudo} chmod 775 #{shared_path}/uploads" end end

    task :symlink do on roles(:app) do execute "ln -nfs #{shared_path}/uploads #{release_path}/public/uploads" end end

  2. Ajoutez la ligne suivante à la fin de votre Capfile si ce n'est pas déjà fait. Dir.glob('lib/capistrano/tasks/*.rake').each { |r| import r }

  3. Ajoutez ces tâches dans config/deploy.rb avec d'autres tâches.

  • after 'deploy:publishing', 'carrierwave:uploads_folder'
  • after 'deploy:publishing', 'carrierwave:symlink'

    namespace :deploy do .. after 'deploy:publishing', 'carrierwave:uploads_folder' after 'deploy:publishing', 'carrierwave:symlink' .. end

  1. Poussez git et déployez

Maintenant, votre image téléchargée restera sauvegardée dans le répertoire shared/uploads même après un nouveau déploiement.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X