October DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsPC HealthRecommendedCrashes, freezes, slowdowns? Check your PC nowSpot repairable issues before they interrupt work.Check PCOctober DealsAmazon USDeal season is back - check today's better picksAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
World desk7 min

How to Run Puppeteer in a Rails Controller Without Killing the Docker Container

Keep Puppeteer out of the Rails request cycle: enqueue browser work, run a monitored worker, cap concurrency, and distinguish Docker OOMs from Chromium launch failures.
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Do not run a long Puppeteer capture synchronously in a Rails controller action. Enqueue a browser job, return an accepted response or job ID, and let a monitored worker run Chromium with concurrency capped to the container’s measured CPU and memory budget. If the container still exits, check for an out-of-memory kill separately from Chromium launch and shared-memory failures.

Why synchronous Puppeteer can take down a Rails container

A Rails web request and a browser automation task have different lifetimes. Navigation, JavaScript execution, and rendering may take long enough to tie up a request process; Chromium also starts child processes and consumes resources alongside Rails. If several captures run concurrently, their combined resource demand can exceed the container’s limits. Docker documents that the kernel kills processes in a container by default when an out-of-memory (OOM) error occurs. Docker’s memory constraints documentation explains this behavior.

As an Amazon Associate I earn from qualifying purchases.

Rails recommends moving long-running or non-critical work out of the HTTP request-response cycle and into a background queue. The Active Job guide documents the framework’s job interface and queue options. A queue is not itself a running worker: the deployed backend must be configured, and a worker must be started and monitored.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

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

Use a controller, queue, and worker

Keep the controller request short

Validate and authorize the request, enqueue a job with serializable arguments such as a record ID, and respond with an accepted status and an identifier your application can use to expose progress or results. Do not pass a live browser, page, or other process object through the queue.

class BrowserTaskJob < ApplicationJob
  queue_as :browser

  def perform(record_id)
    record = Record.find(record_id)
    # Invoke the browser integration here and persist the result.
    # Ensure browser resources are closed on both success and failure.
  end
end

class BrowserTasksController < ApplicationController
  def create
    # Apply the application's authorization and input validation here.
    job = BrowserTaskJob.perform_later(params.require(:record_id))
    render json: { job_id: job.job_id }, status: :accepted
  end
end

This is an architecture sketch, not tested drop-in code for a particular application. Add the authorization, validation, browser wrapper, persistence, and result/status endpoint your application requires.

Configure and run the actual queue backend

Check config.active_job.queue_adapter and the Rails version before copying worker commands. The Active Job guide describes Solid Queue as the default starting with Rails 8.0, while also documenting alternatives such as Sidekiq and GoodJob. Solid Queue’s worker process can be started with bin/jobs start when the application is configured to use it. Adapter-specific services and configuration may be necessary for other backends.

Rank #2
Sale
2 Bay DIY NAS Kit, x86 Home Server, Intel Quad-Core, 16GB RAM,
  • 【Build Your Own NAS & Homelab — Not Just Storage】 More than a traditional NAS, ZimaBlade 7700 is a flexible x86 mini server for building your own homelab, personal cloud, or Docker host. Perfect for DIY NAS, self-hosting, container apps, and even retro systems — not limited like typical ARM-based NAS devices.
  • 【x86 Platform — Broad Compatibility, Real Freedom】 Powered by an Intel quad-core x86 processor, it runs a wide range of operating systems and software with native compatibility. Ideal for Linux, Docker, CasaOS, and more — designed for flexibility and experimentation rather than locked-down appliance use.
  • 【16GB RAM for Smooth Multi-Service Workloads】 Handle file sharing, media streaming, backups, and multiple lightweight services at once. Optimized for low-power, always-on operation — a great fit for home labs and personal servers running 24/7.
  • 【Smooth 4K Media Streaming — Plex Direct Play Ready】 Stream your personal media library smoothly with Plex and similar media servers. Supports 4K playback on compatible devices via direct play, delivering a reliable home media experience without the need for heavy transcoding.
  • 【Complete 2-Bay NAS Kit — Ready to Build】 Includes power supply, 16GB RAM, metal drive cage for 2 HDD/SSD, and dual SATA cables — everything you need to start building your own NAS right out of the box.

The in-process async adapter is not the same as a durable independent worker: its jobs are held in memory, and outstanding work can be lost if the process crashes or the machine resets. For work whose completion matters, verify that the chosen backend and worker deployment match the reliability you need.

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

Close browser resources and reap child processes

Scope browser lifecycle to the job. Close pages and the browser in cleanup paths that run on both success and failure, and make sure the job does not leave Chromium processes behind. Puppeteer’s Docker guide recommends using an init process to manage child processes; Docker’s --init option is one documented way to provide one.

Choose a browser image and safe concurrency

Use an image that satisfies Chromium’s requirements

Puppeteer’s official Docker image includes Chrome for Testing and its dependencies. Its documented setup runs in sandbox mode and requires the SYS_ADMIN capability for that image. If you build a custom image instead, ensure it has the browser’s required Linux libraries, a compatible browser installation, the intended sandbox configuration, and writable locations for Chrome’s profile and cache. See the Puppeteer Docker guide and Puppeteer troubleshooting guide rather than assuming that installing the Puppeteer package alone installs everything a container needs.

Start with low concurrency and measure

Rails web processes and Chromium processes share the deployment’s resource budget unless you isolate them. Begin with conservative browser-job concurrency, then tune worker threads or process counts using the workload’s observed memory and CPU use. Solid Queue supports worker thread and process settings as well as per-job concurrency controls; appropriate values depend on your workload and resource limit, not a universal rule.

Rank #4
Dell PowerEdge R730xd Server 24B SFF 2U, 2X Intel Xeon E5-2690 v4 2.6Ghz (28-cores Total), 128GB DDR4 RAM, 4X 1.2TB 10K SAS 2.5” 12Gb/s HDD, H730P 2GB RAID, NIC 10Gb + I350 1Gb (Renewed)
  • Dell PowerEdge R730xd 24B SFF 2U Server
  • 2x Intel Xeon E5-2690 v4 2.6Ghz 14-Core (28-cores Total)
  • 128GB DDR4 RAM – 4x 1.2TB 10K SAS 2.5” 12Gb/s
  • Dell H730P mini 2GB 12Gb/s RAID
  • 2x 750W PSU - 2x 10Gb SFP+ 2x 1Gb (RJ45) NIC

If browser work competes with web requests or repeatedly exhausts the same limit, consider a separate worker service or container with its own resource allocation. That adds deployment and queue operations but can isolate browser failures and let you size web and browser capacity independently. Keep browser work in the web container only when you can cap its concurrency and its resource use fits the measured budget.

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

Find out whether the cause is OOM, launch failure, or shared memory

  1. Check the container’s termination reason and logs. Look for OOM or termination evidence from the host or platform, inspect the configured memory limit, and review application and Chromium logs. A container exit alone does not prove that memory pressure was the cause.
  2. Compare usage with limits. Use docker stats while reproducing the workload and compare memory and CPU use against the container’s configured constraints. Docker notes that its Linux CLI memory display subtracts cache usage, so interpret the reported figure accordingly. See Docker container stats and Docker resource constraints.
  3. Check Chromium’s actual launch error. Missing shared libraries, browser/image incompatibility, sandbox settings, user permissions, or unwritable profile and cache paths can prevent launch without an OOM kill. Match the error to the Puppeteer troubleshooting guide instead of changing memory settings by guesswork.
  4. Check /dev/shm if the logs point to shared-memory trouble. Puppeteer documents Docker’s default shared-memory allocation as 64 MB and gives --disable-dev-shm-usage as a workaround that redirects these files to /tmp. Use it only when diagnosing this class of issue, and ensure /tmp is writable. It does not raise the container’s total memory limit or fix an OOM budget problem. See Puppeteer troubleshooting.
  5. Check process cleanup. If Chromium children linger, configure an init process such as Docker’s --init, as described in the Puppeteer Docker guide. This is process management, not a substitute for adequate memory.
  6. Account for platform-specific CPU behavior. Puppeteer’s troubleshooting guide discusses Google Cloud Run as an example where CPU allocation can change after a response. Treat that as a platform-specific behavior, not a general property of Docker hosts.

Only reduce concurrency, adjust a resource limit, or isolate the worker after evidence points to resource pressure. A shared-memory workaround and an init process address different failure modes.

Best Value
Sale
Ateco Dough Docker, White , 5.25-Inches wide
  • Ateco #1357 Dough Docker for use with pastry or pizza dough for best baked results
  • Roll over pizza dough, pie dough, pastries before baking, the small depressions help reduce blistering or air pockets from forming while crust bakes
  • Measures 5.25-Inches wide, 2.25-Inch diameter, 8.25-Inches long including handle
  • Hand wash suggested for best results; made from high impact plastic
  • Family owned and operated since 1905, Ateco has produced specialized professional quality baking and decorating tools for professional pastry chefs and discerning home bakers alike
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Or skip the browser setup

ScreenshotNeo is a website screenshot API and MCP server. A single GET request can return a PNG, JPEG, WebP, or PDF. Its clean-shot steps accept cookie and consent banners like a visitor and remove 60+ known consent platforms, newsletter popups, and chat widgets; each step can be turned off. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing, and responses identify the page verdict and billing status in headers. Its MCP server provides take_screenshot, get_page_info, and capture_pdf for AI agents.

For a Rails job or another server-side caller, make the request from the worker and store the returned image or PDF where your application expects it. Keep the key in server-side configuration; do not expose it in browser code. See the ScreenshotNeo API documentation for request options and response handling.

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

ScreenshotNeo offers 1,000 shots a month free with no card; paid plans start at $5 for 3,000 shots. A free account is available at ScreenshotNeo sign-up.

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

Common errors and what to check

Symptom Likely area to inspect Next step
Container exits while browser jobs run Container termination reason, memory limit, and concurrent Rails plus Chromium usage Check OOM evidence and docker stats; reduce simultaneous browser work or adjust resources based on measurements.
Error: spawn ENOMEM Process or memory pressure; the error alone does not identify the root cause Check container limits, observed usage, and worker concurrency before changing launch flags.
Chrome fails to launch Missing libraries, incompatible browser/image, sandbox configuration, permissions, or unwritable paths Compare the full error with Puppeteer’s troubleshooting guide and verify the image setup.
Chromium crashes around shared-memory use /dev/shm capacity or related shared-memory behavior Check the runtime configuration; if appropriate, try --disable-dev-shm-usage with writable /tmp. This does not increase total memory.
Jobs queue but never complete Queue adapter configuration or a missing/stopped worker Verify the adapter and start the matching worker process; enqueueing alone does not execute the job.
Browser processes linger after jobs Missing cleanup or child-process reaping Close pages and browsers on errors as well as success, and use an init process.
Work slows after the HTTP response Runtime-specific CPU allocation behavior Check your hosting platform’s behavior; Puppeteer’s Cloud Run example should not be generalized to every host.

Frequently Asked Questions

Does moving Puppeteer to Active Job guarantee that it will run?

No. The configured queue backend must have a live worker, and the reliability characteristics depend on that backend.

Is --disable-dev-shm-usage a fix for Docker OOM kills?

No. It redirects shared-memory files to /tmp; it does not add memory to the container.

Can I return a Puppeteer page or browser from the controller response?

No. Return a serializable job identifier or application result, not a live browser process object.

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.

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

Leave a Reply

Your email address will not be published. Required fields are marked *

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.

More from the Wire

  1. World desk4 min
    How to Spot an AI Voice Scam Before Sending MoneyDon’t rely on how a caller sounds. Pause, call back through a known number, and verify the emergency with another trusted person before sending money.
  2. Mountain View desk4 min
    Google’s SynthID Detector: How to Check AI-Generated Images, Video and AudioGoogle’s SynthID Detector looks for an embedded watermark in supported images, video and audio. Here is what its results do—and do not—show.
  3. Redmond desk20 min
    How to create a link to File or Folder in Windows 11Windows 11 gives you several ways to point to a file or folder without moving or duplicating it. You can create a desktop shortcut,…
Recommended PC Tool
Recommended PC Tool
Outdated Drivers Are Slowing You DownFree scan - exact matches
PC Slower Than It Used to Be?Free scan - under a minute

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.