-
Notifications
You must be signed in to change notification settings - Fork 3
Hotfix for fixing PDF generation #1208
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
Note Other AI code review bot(s) detectedCodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review. 📝 WalkthroughWalkthroughUpdates the Dockerfile to add Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR addresses PDF generation failures in staging by configuring Grover (a Ruby PDF generation library) to use Chromium with appropriate containerized environment settings. The changes ensure PDF generation works in Docker containers where sandboxing and resource constraints differ from local development.
Changes:
- Added explicit Chromium executable path and Docker-compatible launch arguments to Grover configuration
- Enhanced Dockerfile with fonts package and cleanup commands for better image optimization
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| config/initializers/grover.rb | Configured Chromium executable path and launch arguments to work in containerized environments |
| Dockerfile | Added fonts-liberation package for proper PDF rendering and cleanup commands to reduce image size |
Comments suppressed due to low confidence (1)
Dockerfile:27
- The Node installation RUN command on lines 25-27 should also include cleanup commands (
apt-get cleanandrm -rf /var/lib/apt/lists/*) to reduce the Docker image size, similar to what was added for the first apt-get command. This is a Docker best practice to minimize layer sizes.
RUN curl -sL https://deb.nodesource.com/setup_22.x | bash - && \
apt-get install -y nodejs && \
npm install -q -g yarn
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
config/initializers/grover.rb
Outdated
| display_url: "https://#{Rails.application.config.x.sofia_host}" | ||
|
|
||
| display_url: "https://#{Rails.application.config.x.sofia_host}", | ||
| executable_path: '/usr/bin/chromium', |
Copilot
AI
Jan 17, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The hardcoded executable path /usr/bin/chromium will break local development environments where developers might have Chromium installed in different locations (e.g., macOS users would have it in a different path). Consider making this path configurable based on the environment, or allowing Grover to auto-detect the executable in development/test environments while only setting it explicitly for production/staging.
config/initializers/grover.rb
Outdated
|
|
||
| display_url: "https://#{Rails.application.config.x.sofia_host}", | ||
| executable_path: '/usr/bin/chromium', | ||
| launch_args: ['--no-sandbox', '--disable-setuid-sandbox', '--disable-dev-shm-usage'] |
Copilot
AI
Jan 17, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The --no-sandbox and --disable-setuid-sandbox flags reduce the security isolation of the Chromium process. While these are often necessary in containerized environments, they should ideally be configured only for production/staging environments and not applied globally. Consider making these launch arguments environment-specific to maintain better security in development and test environments.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@config/initializers/grover.rb`:
- Around line 16-18: The Grover init currently sets executable_path and
launch_args with sandbox-disabling flags unconditionally; change this so the
sandbox-disable flags
('--no-sandbox','--disable-setuid-sandbox','--disable-dev-shm-usage') are only
added when an environment toggle (e.g. ENV['GROVER_DISABLE_SANDBOX'] or
ENV.fetch('GROVER_ALLOW_NO_SANDBOX','false')) is truthy. Update the initializer
that builds the Grover config (the hash with display_url, executable_path,
launch_args) to compute launch_args conditionally: use a safe default (empty or
minimal flags) and append the sandbox-disable flags only when the env toggle is
enabled, and document/validate the env var where appropriate.
config/initializers/grover.rb
Outdated
| display_url: "https://#{Rails.application.config.x.sofia_host}", | ||
| executable_path: '/usr/bin/chromium', | ||
| launch_args: ['--no-sandbox', '--disable-setuid-sandbox', '--disable-dev-shm-usage'] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
# First, find the grover initializer and understand context
fd -name "grover.rb" -o -name "Gemfile*" | head -20Repository: csvalpha/sofia
Length of output: 288
🌐 Web query:
Grover 1.2.4 documentation configuration options executable_path launch_args
💡 Result:
Grover accepts Puppeteer/Chromium launch configuration via options — two relevant ones:
-
executable_path: path to the Chrome/Chromium binary used by Puppeteer. Set this to the absolute path Puppeteer/Chromium should run (useful when system Chrome/AppArmor or a custom Puppeteer-managed binary must be pointed at explicitly). [1][2]
-
launch_args: array of Chromium command-line switches (strings) passed to the browser when launched (e.g. ['--no-sandbox','--disable-features=HttpsUpgrades']). You may also supply launch_args via meta tags in HTML. See Chromium switch docs for available flags. [1][2]
Example (initializer or per-instance):
- global config (initializer)
Grover.configure do |config|
config.options = {
executable_path: '/usr/bin/chromium-browser',
launch_args: ['--no-sandbox', '--disable-features=HttpsUpgrades']
}
end - per-instance
grover = Grover.new(html_or_url, executable_path: '/usr/bin/chromium-browser', launch_args: ['--no-sandbox'])
References:
[1] Studiosity/grover README (GitHub).
[2] Grover 1.2.4 API docs (RubyDoc).
🏁 Script executed:
# Search for how Grover is being used in the codebase
rg -i "grover" --type rb -A 3 -B 3 | head -100Repository: csvalpha/sofia
Length of output: 84
🏁 Script executed:
# Look for Docker or deployment files that might reference chromium
fd -name "Dockerfile*" -o -name "docker-compose*" -o -name ".dockerignore" | xargs cat 2>/dev/null || echo "No Docker files found"Repository: csvalpha/sofia
Length of output: 288
🏁 Script executed:
# Check if there are any references to untrusted content or HTML rendering
rg -i "html|render|untrusted|pdf" config/initializers/ -A 2 -B 2Repository: csvalpha/sofia
Length of output: 13457
🏁 Script executed:
cat config/initializers/grover.rbRepository: csvalpha/sofia
Length of output: 739
🏁 Script executed:
# Look for Docker files more carefully
find . -type f \( -name "Dockerfile*" -o -name "*.dockerfile" -o -name "docker-compose*.yml" -o -name "docker-compose*.yaml" \)Repository: csvalpha/sofia
Length of output: 91
🏁 Script executed:
# Search for how grover is being called to understand what content is rendered
rg "Grover.new|grover\(" --type rb -B 3 -A 5 | head -60Repository: csvalpha/sofia
Length of output: 84
🏁 Script executed:
# Check if there's a .env or similar that might configure chromium paths
find . -type f \( -name ".env*" -o -name "*.env" \) 2>/dev/null | head -10Repository: csvalpha/sofia
Length of output: 72
🏁 Script executed:
cat DockerfileRepository: csvalpha/sofia
Length of output: 1645
🏁 Script executed:
cat docker-compose.ymlRepository: csvalpha/sofia
Length of output: 1015
🏁 Script executed:
# Search for Grover usage without -t rb type
rg "Grover.new" -B 3 -A 5Repository: csvalpha/sofia
Length of output: 2132
🏁 Script executed:
# Also search for .render_pdf or similar methods that call grover
rg "render.*pdf|grover.*render" -i -B 2 -A 5Repository: csvalpha/sofia
Length of output: 1856
Consider gating sandbox-disable flags behind an environment toggle.
Grover 1.2.4 does recognize executable_path and launch_args, and /usr/bin/chromium is correctly available in the Docker image (installed via apt-get). The configuration is valid and functional. However, the current setup disables Chromium's sandbox globally for all environments. While your code today only renders internal application templates (via invoices/show), it's good practice to make sandbox-disable opt-in via an environment variable to preserve the security boundary for use cases that don't require it.
♻️ Example: make sandbox-disable opt-in via env
- launch_args: ['--no-sandbox', '--disable-setuid-sandbox', '--disable-dev-shm-usage']
+ launch_args: begin
+ args = ['--disable-dev-shm-usage']
+ args += ['--no-sandbox', '--disable-setuid-sandbox'] if ENV['CHROMIUM_NO_SANDBOX'] == '1'
+ args
+ end🤖 Prompt for AI Agents
In `@config/initializers/grover.rb` around lines 16 - 18, The Grover init
currently sets executable_path and launch_args with sandbox-disabling flags
unconditionally; change this so the sandbox-disable flags
('--no-sandbox','--disable-setuid-sandbox','--disable-dev-shm-usage') are only
added when an environment toggle (e.g. ENV['GROVER_DISABLE_SANDBOX'] or
ENV.fetch('GROVER_ALLOW_NO_SANDBOX','false')) is truthy. Update the initializer
that builds the Grover config (the hash with display_url, executable_path,
launch_args) to compute launch_args conditionally: use a safe default (empty or
minimal flags) and append the sandbox-disable flags only when the env toggle is
enabled, and document/validate the env var where appropriate.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## staging #1208 +/- ##
========================================
Coverage 77.08% 77.08%
========================================
Files 54 54
Lines 1370 1370
========================================
Hits 1056 1056
Misses 314 314 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
PDF generation did work locally but it did not work on staging
Summary by CodeRabbit
Chores
Configuration
✏️ Tip: You can customize this high-level summary in your review settings.