From 77b2c85fee6eab59f6e48d1cc8bf41bde5b70372 Mon Sep 17 00:00:00 2001 From: Andrew Brown Date: Mon, 29 Sep 2025 00:46:13 -0700 Subject: [PATCH] Fix Tailwind CSS not loading in production MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add stylesheet_pack_tag to load Webpacker's compiled CSS - Create explicit Tailwind imports for asset pipeline fallback - Configure file cache store with size limits to prevent cache buildup - Add cache maintenance rake tasks for automatic cleanup - Create whenever schedule for automated cache maintenance The issue was that Tailwind was only included via Webpacker but the layout wasn't loading Webpacker stylesheets in production. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- app/assets/stylesheets/tailwind.css | 4 + app/views/layouts/application.html.erb | 1 + config/environments/production.rb | 11 +++ config/schedule.rb | 16 ++++ lib/tasks/cache_maintenance.rake | 100 +++++++++++++++++++++++++ 5 files changed, 132 insertions(+) create mode 100644 app/assets/stylesheets/tailwind.css create mode 100644 config/schedule.rb create mode 100644 lib/tasks/cache_maintenance.rake diff --git a/app/assets/stylesheets/tailwind.css b/app/assets/stylesheets/tailwind.css new file mode 100644 index 00000000..69acb647 --- /dev/null +++ b/app/assets/stylesheets/tailwind.css @@ -0,0 +1,4 @@ +/* Tailwind CSS imports */ +@tailwind base; +@tailwind components; +@tailwind utilities; \ No newline at end of file diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index ab5d7ea1..f8f1028d 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -5,6 +5,7 @@ <%= csrf_meta_tags %> <%= stylesheet_link_tag 'application', media: 'all' %> + <%= stylesheet_pack_tag 'application', media: 'all' %> diff --git a/config/environments/production.rb b/config/environments/production.rb index 1d50c10f..ac87d954 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -57,6 +57,17 @@ Rails.application.configure do # Use a different cache store in production. # config.cache_store = :mem_cache_store + # File store cache with size limits and automatic expiration + config.cache_store = :file_store, Rails.root.join("tmp", "cache"), { + size: 256.megabytes, # Maximum cache size (256MB should be plenty) + compress: true, # Compress cached data to save space + compress_threshold: 1.kilobyte # Compress anything over 1KB + } + + # Set cache expiration for fragment caching + config.action_controller.perform_caching = true + config.action_controller.enable_fragment_cache_logging = false + # 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 = "notebook_#{Rails.env}" diff --git a/config/schedule.rb b/config/schedule.rb new file mode 100644 index 00000000..fbea8073 --- /dev/null +++ b/config/schedule.rb @@ -0,0 +1,16 @@ +# This file is for the whenever gem (optional) +# To use: add `gem 'whenever', require: false` to Gemfile +# Then run: whenever --update-crontab + +# If not using whenever gem, add this manually to crontab with: crontab -e +# 0 3 * * * cd /var/www/notebook && RAILS_ENV=production /home/ubuntu/.rbenv/shims/bundle exec rake cache:clear_old >> /var/www/notebook/log/cache_cleanup.log 2>&1 + +# Clean up old cache files daily at 3 AM +every 1.day, at: '3:00 am' do + rake "cache:clear_old" +end + +# Show cache stats weekly (optional - for monitoring) +every :sunday, at: '2:00 am' do + rake "cache:stats" +end \ No newline at end of file diff --git a/lib/tasks/cache_maintenance.rake b/lib/tasks/cache_maintenance.rake new file mode 100644 index 00000000..2a463103 --- /dev/null +++ b/lib/tasks/cache_maintenance.rake @@ -0,0 +1,100 @@ +namespace :cache do + desc "Clear old cache files (older than 7 days)" + task :clear_old => :environment do + cache_dir = Rails.root.join('tmp', 'cache') + + if Dir.exist?(cache_dir) + # Count files before cleanup + count_before = Dir.glob(File.join(cache_dir, '**', '*')).select { |file| File.file?(file) }.count + + # Remove files older than 7 days + cutoff_time = 7.days.ago + removed_count = 0 + + Dir.glob(File.join(cache_dir, '**', '*')).each do |file| + if File.file?(file) && File.mtime(file) < cutoff_time + begin + File.delete(file) + removed_count += 1 + rescue => e + Rails.logger.error "Failed to delete cache file #{file}: #{e.message}" + end + end + end + + # Remove empty directories + Dir.glob(File.join(cache_dir, '**', '*')).reverse.each do |dir| + if File.directory?(dir) && Dir.empty?(dir) + begin + Dir.rmdir(dir) + rescue => e + Rails.logger.error "Failed to remove empty directory #{dir}: #{e.message}" + end + end + end + + count_after = Dir.glob(File.join(cache_dir, '**', '*')).select { |file| File.file?(file) }.count + + puts "Cache cleanup complete:" + puts " Files before: #{count_before}" + puts " Files removed: #{removed_count}" + puts " Files after: #{count_after}" + + Rails.logger.info "Cache cleanup: removed #{removed_count} files older than 7 days" + else + puts "Cache directory does not exist: #{cache_dir}" + end + end + + desc "Clear all cache files (use with caution)" + task :clear_all => :environment do + Rails.cache.clear + puts "All cache files have been cleared" + end + + desc "Show cache statistics" + task :stats => :environment do + cache_dir = Rails.root.join('tmp', 'cache') + + if Dir.exist?(cache_dir) + files = Dir.glob(File.join(cache_dir, '**', '*')).select { |f| File.file?(f) } + + total_files = files.count + total_size = files.sum { |f| File.size(f) rescue 0 } + + # Group by age + now = Time.now + age_groups = { + "< 1 day" => 0, + "1-7 days" => 0, + "7-30 days" => 0, + "> 30 days" => 0 + } + + files.each do |file| + age_days = ((now - File.mtime(file)) / 86400).to_i rescue 999 + + if age_days < 1 + age_groups["< 1 day"] += 1 + elsif age_days <= 7 + age_groups["1-7 days"] += 1 + elsif age_days <= 30 + age_groups["7-30 days"] += 1 + else + age_groups["> 30 days"] += 1 + end + end + + puts "Cache Statistics:" + puts " Total files: #{total_files}" + puts " Total size: #{(total_size / 1024.0 / 1024.0).round(2)} MB" + puts "" + puts "Files by age:" + age_groups.each do |age, count| + puts " #{age}: #{count} files" + end + else + puts "Cache directory does not exist: #{cache_dir}" + end + end +end \ No newline at end of file