### Dockerfile for Chrome Installation Source: https://context7.com/excid3/ferrum_pdf/llms.txt Install Google Chrome stable in a Dockerfile. This is a prerequisite for running FerrumPdf in a production Docker environment. ```dockerfile FROM ruby:3.3 # Install Chrome RUN apt-get update && apt-get install gnupg wget -y && \ wget --quiet --output-document=- https://dl-ssl.google.com/linux/linux_signing_key.pub \ | gpg --dearmor > /etc/apt/trusted.gpg.d/google-archive.gpg && \ sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" \ >> /etc/apt/sources.list.d/google.list' && \ apt-get update && \ apt-get install google-chrome-stable -y && \ rm -rf /var/lib/apt/lists/* # Configure FerrumPdf for Docker (use seccomp or --no-sandbox) # In config/initializers/ferrum_pdf.rb: # FerrumPdf.configure do |config| # config.browser_options = { "no-sandbox" => true } # end ``` -------------------------------- ### Install FerrumPdf Gem Source: https://context7.com/excid3/ferrum_pdf/llms.txt Add the FerrumPdf gem to your application's Gemfile. Ensure Chrome is installed on the host system. ```ruby gem "ferrum_pdf" # Or via bundler CLI: # bundle add "ferrum_pdf" ``` -------------------------------- ### Add Chrome to Docker Image Source: https://github.com/excid3/ferrum_pdf/blob/main/README.md This Dockerfile snippet demonstrates how to install Google Chrome stable on a Debian-based image, which is necessary for running FerrumPdf in a Dockerized environment. ```dockerfile RUN apt-get update && apt-get install gnupg wget -y && \ wget --quiet --output-document=- https://dl-ssl.google.com/linux/linux_signing_key.pub | gpg --dearmor > /etc/apt/trusted.gpg.d/google-archive.gpg && \ sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list' && \ apt-get update && \ apt-get install google-chrome-stable -y && \ rm -rf /var/lib/apt/lists/* ``` -------------------------------- ### Auto-Created Browser Instance Source: https://github.com/excid3/ferrum_pdf/blob/main/README.md FerrumPdf automatically creates a single browser instance per Ruby process when needed. This example shows the basic usage of rendering a PDF without explicit browser management. ```ruby # Browser is auto-created on first use FerrumPdf.render_pdf(url: "https://example.org") ``` -------------------------------- ### Render PNG Screenshot from Rails Controller Source: https://github.com/excid3/ferrum_pdf/blob/main/README.md Use the `ferrum_screenshot` renderer in Rails controllers to render a PDF from the current action. This example shows how to render a PNG. ```ruby def show respond_to do |format| format.html format.png { render ferrum_screenshot: {}, disposition: :inline, filename: "example.png" } end end ``` -------------------------------- ### Install Chrome Dependencies in Dockerfile Source: https://github.com/excid3/ferrum_pdf/blob/main/FLY_HOSTING_GUIDE.md Add these dependencies to your Dockerfile to ensure Chrome is installed and available for FerrumPdf. The DOCKER_BUILD environment variable is set to skip the initializer during the build process. ```dockerfile ENV DOCKER_BUILD=1 RUN apt-get update -qq && \ DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ chromium chromium-sandbox fonts-liberation libappindicator3-1 xdg-utils && \ rm -rf /var/lib/apt/lists/* /var/cache/apt ``` -------------------------------- ### Render PDF from Rails Controller Source: https://github.com/excid3/ferrum_pdf/blob/main/README.md Use the `ferrum_pdf` renderer in Rails controllers to render a PDF from the current action. This example shows basic rendering with inline disposition and a filename. ```APIDOC ## Render PDF from Rails Controller ### Description Use the `ferrum_pdf` renderer in Rails controllers to render a PDF from the current action. ### Method ```ruby respond_to do |format| format.html format.pdf { render ferrum_pdf: {}, disposition: :inline, filename: "example.pdf" } end ``` ``` -------------------------------- ### Add FerrumPdf Gem Source: https://github.com/excid3/ferrum_pdf/blob/main/README.md Add the ferrum_pdf gem to your project's Gemfile to install the library. ```ruby bundle add "ferrum_pdf" ``` -------------------------------- ### Render PDF with Custom Options in Rails Controller Source: https://github.com/excid3/ferrum_pdf/blob/main/README.md Customize PDF rendering in Rails controllers by specifying options like header/footer templates, layout, and template. This example includes display header/footer options. ```APIDOC ## Render PDF with Custom Options in Rails Controller ### Description Customize PDF rendering in Rails controllers by specifying options like header/footer templates, layout, and template. This example includes display header/footer options. ### Method ```ruby render ferrum_pdf: { display_header_footer: true, header_template: FerrumPdf::DEFAULT_HEADER_TEMPLATE, footer_template: FerrumPdf::DEFAULT_FOOTER_TEMPLATE }, layout: "pdf", template: "pdf", disposition: :inline, filename: "example.pdf" ``` ``` -------------------------------- ### Run Test Suite Source: https://github.com/excid3/ferrum_pdf/blob/main/README.md Execute the project's test suite using the provided bash command. ```bash bin/test ``` -------------------------------- ### Render PDF from URL Source: https://github.com/excid3/ferrum_pdf/blob/main/README.md Use this to render a PDF from a given URL. A new browser instance is automatically created if none is provided. ```ruby FerrumPdf.render_pdf(url: "https://example.org") ``` -------------------------------- ### Render PDF with a Specific Browser Instance Source: https://github.com/excid3/ferrum_pdf/blob/main/README.md Render a PDF using a pre-existing browser instance. This is useful if you need to manage multiple browser instances or reuse an existing one. ```ruby other_browser = Ferrum::Browser.new FerrumPdf.render_pdf(url: "https://example.org", browser: other_browser) ``` -------------------------------- ### Configure Browser Options for FerrumPdf Source: https://github.com/excid3/ferrum_pdf/blob/main/README.md Set default browser options, such as window size, process timeout, and browser path, using the `configure` block. This is useful for customizing how Ferrum interacts with the browser. ```ruby FerrumPdf.configure do |config| config.window_size = [1920, 1080] # config.process_timeout = 30 # defaults to 10 # config.browser_path = '/usr/bin/chromium' # For use with Docker, but ensure you trust any sites visited # config.browser_options = { # "no-sandbox" => true # } end ``` -------------------------------- ### Configure FerrumPdf Globally Source: https://context7.com/excid3/ferrum_pdf/llms.txt Set default browser, page-load, PDF, and screenshot options in an initializer. These options are passed directly to Ferrum::Browser.new and Chrome DevTools Protocol methods. ```ruby # config/initializers/ferrum_pdf.rb FerrumPdf.configure do |config| # --- Browser options (passed directly to Ferrum::Browser.new) --- config.window_size = [1920, 1080] config.process_timeout = 30 # seconds to wait for Chrome to start config.browser_path = "/usr/bin/chromium" # Docker: use seccomp instead of --no-sandbox where possible config.browser_options = { "no-sandbox" => true } # Disable headless for local debugging # config.headless = false # --- Page-load defaults --- config.page_options.authorize = { user: "admin", password: "secret" } config.page_options.wait_for_idle_options = { connections: 0, duration: 0.05, timeout: 90 } config.page_options.timeout_if_open_connections = true config.page_options.retries = 3 config.page_options.viewport = { width: 1280, height: 800, scale_factor: 2 } # --- PDF defaults --- config.pdf_options.margin_top = 0.4 # inches config.pdf_options.margin_bottom = 0.4 config.pdf_options.margin_left = 0.4 config.pdf_options.margin_right = 0.4 config.pdf_options.print_background = true # --- Screenshot defaults --- config.screenshot_options.format = :png config.screenshot_options.full = true end ``` -------------------------------- ### Configure Default FerrumPdf Options Source: https://github.com/excid3/ferrum_pdf/blob/main/README.md Set default values for page loads, PDF renders, and screenshot renders using the `configure` block. This allows for consistent settings across your application. ```ruby FerrumPdf.configure do |config| config.page_options.authorize = { user: "username", password: "password" } config.page_options.wait_for_idle_options = { timeout: 90 } config.page_options.retries = 3 config.page_options.viewport = { width: 1200, height: 800, scale_factor: 3 } config.pdf_options.margin_top = 0.2 config.pdf_options.margin_bottom = 0.2 config.pdf_options.margin_left = 0.2 config.pdf_options.margin_right = 0.2 config.screenshot_options.format = :png config.screenshot_options.full = false end ``` -------------------------------- ### Full PDF Rendering Options Source: https://github.com/excid3/ferrum_pdf/blob/main/README.md Configure detailed PDF generation options including URL, HTML content, authentication, network idle settings, viewport, and extensive PDF-specific settings like margins, headers, and footers. ```ruby FerrumPdf.render_pdf( url: "https://example.com/page", # Provide a URL to the content html: content, # or provide HTML display_url: request.original_url, # When supplying content via :html its best to give Chrome a hint of the current url so that it can process relative paths in the document. If you don't provide this, http://example.com will be used instead. authorize: { user: "username", password: "password" }, # Used for authenticating with basic auth wait_for_idle_options: { connections: 0, duration: 0.05, timeout: 5 }, # Used for setting network wait_for_idle options timeout_if_open_connections: true, viewport: { width: 1200, height: 800, scale_factor: 3 } # Used for setting the viewport dimensions and device scale factor (DPR) when rendering the page pdf_options: { landscape: false, # paper orientation scale: 1, # Scale of the webpage rendering format: nil, paper_width: 8.5, # Paper width in inches paper_height: 11, # Paper height in inches page_ranges: nil, # Paper ranges to print "1-5, 8 11-13" # Margins (in inches, defaults to 1cm) margin_top: 0.4, margin_bottom: 0.4, margin_left: 0.4, margin_right: 0.4, # Header, footer, and background options # # Variables can be used with CSS classes. For example # * date: formatted print date # * title: document title # * url: document location # * pageNumber: current page number # * totalPages: total pages in the document display_header_footer: false, print_background: false, # Print background graphics header_template: "", # HTML template for the header footer_template: "", # HTML template for the footer } ) ``` -------------------------------- ### Advanced Screenshot Rendering Options Source: https://github.com/excid3/ferrum_pdf/blob/main/README.md Provides a comprehensive set of options for rendering screenshots, including specifying URLs, HTML content, display URLs for relative path resolution, and detailed screenshot configurations. ```ruby FerrumPdf.render_screenshot( url: "https://example.com/page", # Provide a URL to the content html: content, # or provide HTML display_url: request.original_url, # When supplying content via :html its best to give Chrome a hint of the current url so that it can process relative paths in the document. If you don't provide this, http://example.com will be used instead. screenshot_options: { format: "png" # or "jpeg" quality: nil # Integer 0-100 works for jpeg only full: true # Boolean whether you need full page screenshot or a viewport selector: nil # String css selector for given element, optional area: nil # Hash area for screenshot, optional. {x: 0, y: 0, width: 100, height: 100} scale: nil # Float zoom in/out background_color: nil # Ferrum::RGBA.new(0, 0, 0, 0.0) } ) ``` -------------------------------- ### FerrumPdf.configure Source: https://context7.com/excid3/ferrum_pdf/llms.txt Globally configures default browser, page-load, PDF, and screenshot options for all FerrumPdf render calls. This should be called once in an initializer. ```APIDOC ## FerrumPdf.configure ### Description Sets default browser, page-load, PDF, and screenshot options applied to every render call. Called once in an initializer. ### Usage ```ruby FerrumPdf.configure do |config| # Browser options config.window_size = [1920, 1080] config.process_timeout = 30 config.browser_path = "/usr/bin/chromium" config.browser_options = { "no-sandbox" => true } # config.headless = false # Page-load defaults config.page_options.authorize = { user: "admin", password: "secret" } config.page_options.wait_for_idle_options = { connections: 0, duration: 0.05, timeout: 90 } config.page_options.timeout_if_open_connections = true config.page_options.retries = 3 config.page_options.viewport = { width: 1280, height: 800, scale_factor: 2 } # PDF defaults config.pdf_options.margin_top = 0.4 config.pdf_options.margin_bottom = 0.4 config.pdf_options.margin_left = 0.4 config.pdf_options.margin_right = 0.4 config.pdf_options.print_background = true # Screenshot defaults config.screenshot_options.format = :png config.screenshot_options.full = true end ``` ``` -------------------------------- ### Configure FerrumPdf for Fly.io Production Source: https://github.com/excid3/ferrum_pdf/blob/main/FLY_HOSTING_GUIDE.md Configure FerrumPdf to use Chrome without the sandbox, which is required by Fly.io. This initializer also sets a longer process timeout and specifies the Chrome browser path for production environments. ```ruby # config/initializers/ferrum.rb return if ENV['DOCKER_BUILD'] options = { process_timeout: 30, browser_options: { 'no-sandbox' => nil } } options = options.merge(browser_path: '/usr/bin/chromium') if Rails.env.production? FerrumPdf.browser(options) ``` -------------------------------- ### Set Custom Browser Instance Source: https://github.com/excid3/ferrum_pdf/blob/main/README.md Allows setting a custom `Ferrum::Browser` instance for FerrumPdf to use. All subsequent calls will utilize this configured browser, providing more control over browser options. ```ruby # Set a custom browser with specific options custom_browser = Ferrum::Browser.new(window_size: [800, 600], headless: false) FerrumPdf.browser = custom_browser # All subsequent calls will use this browser FerrumPdf.render_pdf(url: "https://example.org") ``` -------------------------------- ### Render PDF from URL or HTML String Source: https://context7.com/excid3/ferrum_pdf/llms.txt Use `render_pdf` for generating PDF binaries from a URL or an HTML string. It supports custom PDF options and can be used in background jobs or mailers. ```ruby # --- From a URL --- pdf_binary = FerrumPdf.render_pdf(url: "https://example.org/report") ``` ```ruby # --- From an HTML string --- html = ApplicationController.render( template: "reports/annual", layout: "pdf", assigns: { year: 2024 } ) pdf_binary = FerrumPdf.render_pdf( html: html, display_url: "https://myapp.example.com/reports/annual", # helps Chrome resolve relative asset paths pdf_options: { landscape: true, format: "A4", print_background: true, display_header_footer: true, header_template: FerrumPdf::DEFAULT_HEADER_TEMPLATE, footer_template: FerrumPdf::DEFAULT_FOOTER_TEMPLATE, margin_top: 0.4, margin_bottom: 0.4, margin_left: 0.4, margin_right: 0.4, page_ranges: "1-5" # only render pages 1 through 5 } ) ``` ```ruby # Save to disk File.binwrite(Rails.root.join("tmp", "annual-report-2024.pdf"), pdf_binary) ``` ```ruby # Attach via ActiveStorage report = Report.find(1) report.file.attach( io: StringIO.new(pdf_binary), filename: "annual-report-2024.pdf", content_type: "application/pdf" ) ``` ```ruby # Send from a background job class GenerateInvoicePdfJob < ApplicationJob def perform(invoice_id) invoice = Invoice.find(invoice_id) html = ApplicationController.render( template: "invoices/show", layout: "pdf", assigns: { invoice: invoice } ) pdf = FerrumPdf.render_pdf( html: html, display_url: Rails.application.routes.url_helpers.invoice_url(invoice), pdf_options: { print_background: true } ) invoice.pdf.attach(io: StringIO.new(pdf), filename: "invoice-" + invoice.id.to_s + ".pdf", content_type: "application/pdf") end end ``` -------------------------------- ### Render PDF from HTML or URL Source: https://github.com/excid3/ferrum_pdf/blob/main/README.md Generate a PDF directly using `FerrumPdf.render_pdf` by providing either an HTML string or a URL. This method is versatile for on-demand PDF creation. ```ruby FerrumPdf.render_pdf(html: content) ``` ```ruby FerrumPdf.render_pdf(url: "https://google.com") ``` -------------------------------- ### FerrumPdf.render_pdf Options Source: https://github.com/excid3/ferrum_pdf/blob/main/README.md Detailed options available for `FerrumPdf.render_pdf` to customize PDF generation, including URL/HTML source, authentication, network idle options, viewport settings, and extensive PDF-specific options like margins, headers, and footers. ```APIDOC ## FerrumPdf.render_pdf Options ### Description Detailed options available for `FerrumPdf.render_pdf` to customize PDF generation, including URL/HTML source, authentication, network idle options, viewport settings, and extensive PDF-specific options like margins, headers, and footers. ### Method ```ruby FerrumPdf.render_pdf( url: "https://example.com/page", # Provide a URL to the content html: content, # or provide HTML display_url: request.original_url, # When supplying content via :html its best to give Chrome a hint of the current url so that it can process relative paths in the document. If you don't provide this, http://example.com will be used instead. authorize: { user: "username", password: "password" }, # Used for authenticating with basic auth wait_for_idle_options: { connections: 0, duration: 0.05, timeout: 5 }, # Used for setting network wait_for_idle options timeout_if_open_connections: true, viewport: { width: 1200, height: 800, scale_factor: 3 } # Used for setting the viewport dimensions and device scale factor (DPR) when rendering the page pdf_options: { landscape: false, # paper orientation scale: 1, # Scale of the webpage rendering format: nil, paper_width: 8.5, # Paper width in inches paper_height: 11, # Paper height in inches page_ranges: nil, # Paper ranges to print "1-5, 8 11-13" # Margins (in inches, defaults to 1cm) margin_top: 0.4, margin_bottom: 0.4, margin_left: 0.4, margin_right: 0.4, # Header, footer, and background options # # Variables can be used with CSS classes. For example # * date: formatted print date # * title: document title # * url: document location # * pageNumber: current page number # * totalPages: total pages in the document display_header_footer: false, print_background: false, # Print background graphics header_template: "", # HTML template for the header footer_template: "", # HTML template for the footer } ) ``` ``` -------------------------------- ### render ferrum_screenshot: Source: https://context7.com/excid3/ferrum_pdf/llms.txt Renders the current controller action or a named template to a PNG/JPEG screenshot and streams it to the client. Accepts Ferrum screenshot options. ```APIDOC ## render ferrum_screenshot: ### Description Renders the current controller action (or a named template) to a PNG/JPEG screenshot and streams it to the client. Accepts Ferrum screenshot options as keys. ### Usage (PNG) ```ruby class DashboardsController < ApplicationController def show @dashboard = current_user.dashboard respond_to do |format| format.html format.png do render ferrum_screenshot: { format: "png", full: true, scale: 1.5, selector: "#chart" }, layout: "pdf", disposition: :attachment, filename: "dashboard-#{Date.today}.png" end # ... other formats end end end ``` ### Usage (JPEG) ```ruby class DashboardsController < ApplicationController def show @dashboard = current_user.dashboard respond_to do |format| format.html # ... other formats format.jpeg do render ferrum_screenshot: { format: "jpeg", quality: 85, full: false }, disposition: :inline, filename: "dashboard-preview.jpg" end end end end ``` ### Route Example `GET /dashboards/show.png` → streams full-page PNG attachment. ``` -------------------------------- ### Debug Rendering with a Block Source: https://context7.com/excid3/ferrum_pdf/llms.txt Use a block with `render_pdf` or `render_screenshot` to access the `Ferrum::Browser` and `Ferrum::Page` objects for debugging. This allows inspecting page state, evaluating JavaScript, or opening DevTools. ```ruby # Open remote DevTools and pause before rendering FerrumPdf.render_pdf(url: "https://example.org/invoice/1") do |browser, page| puts "Page title: #{page.title}" puts "Current URL: #{page.current_url}" # Evaluate JavaScript on the page total = page.evaluate("document.querySelector('.total').innerText") puts "Invoice total: #{total}" # Open Chrome DevTools (non-headless mode required) # browser.debug # Drop into IRB REPL to poke around # binding.irb end ``` ```ruby # Run Chrome in non-headless mode for visual debugging FerrumPdf.configure { |c| c.headless = false } FerrumPdf.render_pdf(html: "