Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.

Set Wicked PDF’s global wkhtmltopdf executable in config/initializers/wicked_pdf.rb, using an absolute path that the Rails runtime can execute:

WickedPdf.configure do |c|
  c.exe_path = '/usr/local/bin/wkhtmltopdf'
  c.enable_local_file_access = true
end

Restart the Rails process after changing the initializer. The path must point to a real executable visible to the same user, filesystem, and environment that runs Rails in production. If you need a different binary for one render, pass a wkhtmltopdf: option on that render instead.

What the path setting controls

Wicked PDF starts wkhtmltopdf as a separate operating-system process. Rails does not render the PDF itself; it hands HTML and options to that executable. Consequently, a path that works in your shell may fail when the application runs under a service account, container, release directory, or job worker.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

exe_path is the global Wicked PDF setting. Put it in the initializer so it is loaded when Rails boots:

#1 Best Overall
# config/initializers/wicked_pdf.rb
WickedPdf.configure do |c|
  c.exe_path = '/usr/local/bin/wkhtmltopdf'
  c.enable_local_file_access = true
end

Use the actual absolute path on your host. Do not leave a shell alias, a relative path, or a path that exists only in your development workstation.

Install the executable before configuring Rails

Adding exe_path only tells Wicked PDF where to look; it does not install the binary. Install wkhtmltopdf using your operating system package manager, an image-build step, or the wkhtmltopdf-binary gem. The Wicked PDF README identifies that gem as a convenient distribution for many Linux and macOS systems. A system package can be preferable when your operations team manages native packages centrally.

Option 1: a system package

Install the package during machine or container provisioning, then locate the executable and use its absolute path. Common locations include /usr/local/bin/wkhtmltopdf and /usr/bin/wkhtmltopdf, but the location is installation-specific; verify it rather than assuming it.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Option 2: the wkhtmltopdf-binary gem

Add the gem to your application and run Bundler:

# Gemfile
gem 'wicked_pdf'
gem 'wkhtmltopdf-binary'
bundle install

Deploy the resulting bundle and confirm that the production bundle includes the binary gem. A local bundle can succeed while production fails if the gem is excluded by a deployment group, omitted from the lockfile, or unavailable to the process that launches Rails.

Configure Wicked PDF globally

  1. Add Wicked PDF. Put gem 'wicked_pdf' in the Gemfile and run bundle install.
  2. Install wkhtmltopdf. Choose a system package or wkhtmltopdf-binary, and make the executable available in the deployment environment.
  3. Create or edit the initializer. Use config/initializers/wicked_pdf.rb.
  4. Set an absolute path. Assign the executable location to c.exe_path. Enable local file access only when your templates require local assets.
  5. Restart Rails. Initializers are evaluated during application boot, so a running web or job process will not pick up the change until restarted.

A minimal production-oriented initializer is:

WickedPdf.configure do |c|
  c.exe_path = '/usr/local/bin/wkhtmltopdf'
  c.enable_local_file_access = true
end

enable_local_file_access affects whether the external renderer may read local files. Treat it as a deliberate setting: enable it for local stylesheets, images, or other file URLs that your PDF requires, and avoid granting access unnecessarily when all assets are served over controlled URLs.

Override the path for one render

Use a render-level option when a particular job needs another executable, when you are migrating versions, or when different workers expose different paths:

render pdf: 'file_name',
       wkhtmltopdf: '/opt/wkhtmltopdf/bin/wkhtmltopdf'

This override applies to that render rather than changing the application-wide initializer. Keep the path absolute and executable just as you would for exe_path.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Verify the path from the Rails runtime

Wicked PDF has an internal discovery method that is useful when automatic detection chooses the wrong binary. From a Rails console, inspect the path:

WickedPdf.new.send(:find_wkhtmltopdf_binary_path)

Then check all of the following:

  • The returned path names an existing file.
  • The file has execute permission.
  • The Rails deployment user can traverse every parent directory and execute the file.
  • The path is present in the same release, container, chroot, or host where the web process runs.
  • Workers that generate PDFs use the same bundle and environment as the web process.

If discovery returns an unexpected location, set exe_path explicitly or use the per-render override. A documented project issue describes failures caused by incorrect discovery and by Bundler not including wkhtmltopdf-binary; checking the resolved path and production bundle addresses both classes of problem.

Make assets work outside the Rails process

Because wkhtmltopdf runs externally, browser-relative assumptions can break even when the HTML looks correct in a normal browser. Relative CSS, image, and JavaScript URLs may resolve differently, and a renderer process may not share the same filesystem context as Rails.

Prefer explicit asset URLs

Use absolute, reachable asset URLs when possible. For local Rails assets, Wicked PDF provides helpers designed for PDF rendering:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
<%= wicked_pdf_stylesheet_link_tag 'application' %>
<%= wicked_pdf_image_tag 'logo.png' %>
<%= wicked_pdf_javascript_include_tag 'charts' %>

These helpers make the intended asset references explicit for the external renderer. If you construct URLs yourself, ensure the host, protocol, and port are accessible from the machine running wkhtmltopdf, not merely from a developer’s browser.

Check local-file requirements

When templates use file:// references or local generated files, confirm that the renderer can read those files and that your initializer’s local-file-access policy matches the template design. A file existing inside the Rails container does not help if wkhtmltopdf executes in another container or under a user without permission.

Choose between a system binary and wkhtmltopdf-binary

Consideration System package wkhtmltopdf-binary gem
Installation model Managed by the host or container image Delivered through Bundler with the application
Reproducibility Depends on image or operating-system package pinning Can travel with the locked Ruby dependency set, provided deployment includes it
Permissions Must be executable by the Rails service user The bundled executable and its directories must be accessible to that user
Updates Handled through operating-system or image maintenance Handled through dependency updates and bundle deployment
Compatibility evidence No current compatibility matrix is established here No current compatibility matrix is established here
Performance comparison No benchmark figure is established here No benchmark figure is established here

Make the choice based on how your team builds and patches production images, then verify the executable under the real deployment user. Neither option removes the need to test your templates and asset loading in the target environment.

Troubleshoot common failures

“No wkhtmltopdf executable found”

  • Cause: The binary is not installed, the path is wrong, or automatic discovery cannot see it.
  • Fix: Inspect WickedPdf.new.send(:find_wkhtmltopdf_binary_path), set an explicit absolute exe_path, and verify the file in the running environment.

Works locally, fails after deployment

  • Cause: Production uses a different user, container, release path, or Bundler group.
  • Fix: Log into the deployment environment as the service user, check the file and execute bit, and confirm wkhtmltopdf-binary is in the production bundle if you selected that gem.

Permission denied

  • Cause: The executable lacks its execute bit, or one of its parent directories is inaccessible.
  • Fix: Correct ownership and permissions during image or host provisioning, then retry as the exact Rails user. Avoid fixing only your interactive shell’s permissions.

PDF renders without CSS or images

  • Cause: Relative URLs, inaccessible hosts, or local files blocked from the external process.
  • Fix: Use the Wicked PDF asset helpers or absolute URLs, test connectivity from the renderer host, and review the local-file-access setting.

Discovery selects an unintended binary

  • Cause: Multiple installations, a changed PATH, or a Bundler-provided executable.
  • Fix: Set c.exe_path globally or provide wkhtmltopdf: for the affected render, then restart the relevant processes.

PDF generation hangs or fails on user content

wkhtmltopdf is an external process that interprets HTML and JavaScript. The project warns: “Do not use wkhtmltopdf with any untrusted HTML – be sure to sanitize any user-supplied HTML/JS, otherwise it can lead to complete takeover of the server it is running on!” Sanitize user-provided markup and scripts before handing them to the renderer, and isolate rendering where your deployment model permits.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Operational checklist

  • Pin and install one known executable strategy for every deployment target.
  • Use an absolute path in config/initializers/wicked_pdf.rb.
  • Confirm the production bundle contains wkhtmltopdf-binary when you rely on it.
  • Validate the resolved path from a Rails console running in the target environment.
  • Test execute permissions as the web and background-job users.
  • Use explicit asset URLs or Wicked PDF helpers.
  • Decide whether local file access is necessary for each template.
  • Sanitize every user-supplied HTML and JavaScript fragment.
  • Restart web, worker, and job processes after changing the initializer.

Or skip the browser setup

If your goal is a clean website image or PDF rather than a Rails-managed wkhtmltopdf process, ScreenshotNeo provides a single HTTP endpoint. Its cleanup step accepts cookie or consent banners and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each step can be disabled. Bot checks, CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and the response identifies the result with X-Page-Verdict and X-Billed headers. ScreenshotNeo also provides an MCP server with take_screenshot, get_page_info, and capture_pdf for Claude, Cursor, and other MCP clients.

See the complete parameter reference in the ScreenshotNeo documentation. A cURL request is:

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

The same request in Python:

import requests
r = requests.get(
    "https://api.screenshotneo.com/v1/shot",
    params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
    timeout=90,
)
open("shot.webp", "wb").write(r.content)

And in Node.js:

const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

The Free plan includes 1,000 screenshots per month with no card. Paid plans start at $5 for 3,000 shots; every feature is available on every plan. Create a free ScreenshotNeo account.

Frequently Asked Questions

Does changing the initializer affect already running workers?

No. Initializers load during process boot, so restart each web server and background worker that renders PDFs.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Can the Rails process and wkhtmltopdf run in different containers?

Only if the executable, HTML, and every required asset are available in the renderer’s environment; otherwise use a shared image or reachable absolute URLs.

Should I rely on automatic binary discovery in production?

Treat discovery as something to verify. An explicit absolute path is easier to audit when multiple binaries, users, or deployment environments are involved.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.