Playwright Remote Connect Fails: Exception: Connection closed while reading from the driver (Browserless on Railway)

leolmz59
HOBBY

2 months ago

Hello Railway Team,

I am encountering a persistent error when trying to connect to a Browserless instance running on Railway from a Python worker using Playwright’s remote connection (chromium.connect). The error is:

text

Exception: Connection closed while reading from the driver

Context:

  • Browserless is deployed as a Railway service, running and healthy, listening on the port shown in logs (e.g., 8080).

  • No custom port mappings are set in the Networking/Ports tab.

  • The worker service is a Python app using Playwright (async API) and attempts to connect to Browserless via:

    text

    ws://browserless.railway.internal:8080?token=MY_TOKEN
    
  • Browserless logs show no errors or incoming connections when the error occurs.

What I have tried:

  • Verified that Browserless is running and healthy on Railway.

  • Ensured the correct internal Railway domain and port are used.

  • Used the official Playwright Python Docker image and also tried Python 3.11/3.10 with all Playwright dependencies installed.

  • No firewall or network restrictions between services (both are in the same Railway project).

  • No custom Dockerfile for Browserless; using the official image.

  • The same code works with Browserless on other platforms (locally or on other clouds).

What happens:

  • When the worker tries to connect, Playwright raises:

    text

    Exception: Connection closed while reading from the driver
    
  • No connection attempt is logged on the Browserless side.

  • No other errors or warnings are shown in either service.

What I expect:

  • Playwright should be able to connect to Browserless via the internal Railway network as documented.

  • The connection should succeed, and browser automation should work.

What I need:

  • Please help determine why Playwright’s remote connection to Browserless fails with this error on Railway, despite both services being healthy and correctly configured.

  • Is there a known networking, proxy, or compatibility issue on Railway that could cause this?

  • Are there any additional settings or steps required to enable WebSocket connections between services on Railway?

Thank you for your help!

Solved

17 Replies

2 months ago

How are you trying to connect to playwright?


Status changed to Awaiting User Response railway[bot] 2 months ago


leolmz59
HOBBY

2 months ago

Like this:

 async with async_playwright() as p:
             # Connect to the running Browserless service using the BROWSERLESS_URL
             browser = await p.chromium.connect(browserless_url)
             logger.info("Successfully connected to Browserless and Playwright instance.")
            
             user_agent = random.choice(USER_AGENTS)
             context = await browser.new_context(
                 user_agent=user_agent,
                 viewport={'width': 1920, 'height': 1080},
                 locale='es-ES',
                 timezone_id='Europe/Madrid',
                 geolocation={'longitude': -3.7038, 'latitude': 40.4168},  # Madrid
                 permissions=['geolocation'],
                 storage_state=None, # Pass {} or a path to a state file if you manage cookies/local storage
                 java_script_enabled=True,
                 is_mobile=False,
                 has_touch=False,
                 color_scheme='light',
                 reduced_motion='no-preference',
                 forced_colors='none',
                 accept_downloads=True
             )

Status changed to Awaiting Railway Response railway[bot] 2 months ago


leolmz59
HOBBY

2 months ago

Here's the file of my tasks.py for all details

Attachments


leolmz59
HOBBY

2 months ago

I'm running into a persistent issue trying to get Playwright working inside a Celery worker container deployed on Railway ([Your Service Name/ID if you have it]).

Whenever my Celery task tries to initialize Playwright, it fails with GLIBC errors. I've included the specific error lines below.

The main problem is that I've tried several standard Docker base images for my worker (python:3.11-slim-bullseye, python:3.13-slim-bookworm, and python:3.13-jammy) and cleared the build cache each time, but the exact same GLIBC error occurs regardless of the base image chosen.

Here's the error I consistently see in the worker logs:

text

/opt/venv/lib/python3.13/site-packages/playwright/driver/node: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.38' not found (required by /nix/store/s94fwp43xhzkvw8l8nqslskib99yifzi-gcc-13.3.0-lib/lib/libstdc++.so.6)
/opt/venv/lib/python3.13/site-packages/playwright/driver/node: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.36' not found (required by /nix/store/s94fwp43xhzkvw8l8nqslskib99yifzi-gcc-13.3.0-lib/lib/libstdc++.so.6)

The reference to /nix/store/... in the error message makes me suspect that the Railway Nix-based build environment might be interacting with the standard Docker base images in an unexpected way.

Could you please help me understand: How does the Railway Nix-based build environment interact with standard Docker base images, and how can I ensure GLIBC compatibility for Playwright's pre-compiled components within this environment?

Is there a specific base image or configuration you recommend for using Playwright reliably on Railway?

ps: dockerfile.worker:

# FROM python:3.11-slim-bullseye
# FROM python:3.13-slim-bookworm
FROM python:3.13-jammy

RUN apt-get update && apt-get install -y --no-install-recommends \
    build-essential \
    libpq-dev \
    curl \
    && rm -rf /var/lib/apt/lists/* \
    && apt-get clean

WORKDIR /app

COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
RUN pip install playwright && playwright install --with-deps

COPY . /app/

CMD ["celery", "-A", "comparaplan", "worker", "--loglevel=info", "--concurrency=4"]

2 months ago

You will need to install build-essential or any source libraries within your Dockerfile.


Status changed to Awaiting User Response railway[bot] 2 months ago


angelo

You will need to install build-essential or any source libraries within your Dockerfile.

leolmz59
HOBBY

2 months ago

as you can see in my dockerfile worker build-essential is already installed:
RUN apt-get update && apt-get install -y --no-install-recommends \ build-essential \ libpq-dev \ curl \ && rm -rf /var/lib/apt/lists/* \ && apt-get clean

Do you have any other leads?


Status changed to Awaiting Railway Response railway[bot] 2 months ago


leolmz59
HOBBY

2 months ago

In the build logs from my worker the logs clearly show Railway is using Nixpacks to build my image, not my Dockerfile directly. Dockerfile is being ignored: Because Nixpacks detected a Python project (likely due to requirements.txt), it decided to build the environment using Nix instead of following the instructions in your Dockerfile.


echohack
EMPLOYEE

2 months ago

Oh that's odd. Do you have your Dockerfile in the root of your git repo? It should always detect the Dockerfile and build it by default instead of NIXPACKS.

https://docs.railway.com/reference/config-as-code#config-source-location


Status changed to Awaiting User Response railway[bot] 2 months ago


leolmz59
HOBBY

2 months ago

I put in attachment of the project structure.
I put the details bellow:
Dockerfile:
FROM mcr.microsoft.com/playwright/python:v1.43.0-jammy

RUN apt-get update && apt-get install -y --no-install-recommends \

    libpq-dev \

    && rm -rf /var/lib/apt/lists/* \

    && apt-get clean

WORKDIR /app

COPY requirements.txt .

RUN pip install --no-cache-dir -r requirements.txt

COPY . /app/

CMD ["celery", "-A", "comparaplan", "worker", "--loglevel=info", "--concurrency=4"]

Dockerfile.beat:
FROM python:3.11-slim-bullseye

RUN apt-get update && apt-get install -y --no-install-recommends \

    build-essential \

    libpq-dev \

    && rm -rf /var/lib/apt/lists/* \

    && apt-get clean

ENV DEBIAN_FRONTEND=noninteractive

WORKDIR /app

COPY requirements.txt .

RUN python -m venv /opt/venv && \

    /opt/venv/bin/pip install --no-cache-dir -r requirements.txt

COPY . /app/

CMD ["/opt/venv/bin/celery", "-A", "comparaplan", "beat", "--loglevel=info", "-s", "/tmp/celerybeat-schedule"]

Dockerfile.browserless:


FROM browserless/chrome:latest

WORKDIR /usr/src/app

ENV HOST=0.0.0.0
ENV CONNECTION_TIMEOUT=60000
ENV MAX_CONCURRENT_SESSIONS=10
ENV DEFAULT_LAUNCH_ARGS='["--no-sandbox", "--disable-gpu", "--disable-dev-shm-usage"]'
ENV ENABLE_DEBUG_ENDPOINT=true # Mettre à false en production si désiré
ENV EXIT_ON_HEALTH_FAILURE=true

EXPOSE ${PORT:-3000} # Utilise la variable PORT si elle existe, sinon 3000 par défaut

Attachments


Status changed to Awaiting Railway Response railway[bot] 2 months ago


leolmz59
HOBBY

2 months ago

I have now this workers build logs:

Load More

Apr 28 23:42:11

Apr 28 23:42:14

[Region: europe-west4]

Apr 28 23:42:14

=========================

Apr 28 23:42:14

Using Detected Dockerfile

Apr 28 23:42:14

=========================

Apr 28 23:42:14

Apr 28 23:42:14

context: gn0w-xxHB

Apr 28 23:42:14

[internal] load build definition from Dockerfile

Apr 28 23:42:14

[internal] load build definition from Dockerfile 0ms

Apr 28 23:42:14

[internal] load build definition from Dockerfile

Apr 28 23:42:14

[internal] load build definition from Dockerfile 8ms

Apr 28 23:42:14

[internal] load metadata for mcr.microsoft.com/playwright/python:v1.43.0-jammy

Apr 28 23:42:14

[internal] load metadata for mcr.microsoft.com/playwright/python:v1.43.0-jammy 91ms

Apr 28 23:42:14

[internal] load .dockerignore

Apr 28 23:42:14

[internal] load .dockerignore 0ms

Apr 28 23:42:14

[internal] load .dockerignore

Apr 28 23:42:14

[internal] load .dockerignore 7ms

Apr 28 23:42:14

[6/6] COPY . /app/

Apr 28 23:42:14

[5/6] RUN pip install --no-cache-dir -r requirements.txt

Apr 28 23:42:14

[4/6] COPY requirements.txt .

Apr 28 23:42:14

[internal] load build context

Apr 28 23:42:14

[3/6] WORKDIR /app

Apr 28 23:42:14

[2/6] RUN apt-get update && apt-get install -y --no-install-recommends libpq-dev && rm -rf /var/lib/apt/lists/* && apt-get clean

Apr 28 23:42:14

[1/6] FROM mcr.microsoft.com/playwright/python:v1.43.0-jammy@sha256:153927658c515f20ace339566ba2136444dcdbedd80f1305066ccdb1ae9770ff

Apr 28 23:42:14

[1/6] FROM mcr.microsoft.com/playwright/python:v1.43.0-jammy@sha256:153927658c515f20ace339566ba2136444dcdbedd80f1305066ccdb1ae9770ff

Apr 28 23:42:14

[internal] load build context 0ms

Apr 28 23:42:14

[internal] load build context

Apr 28 23:42:14

[1/6] FROM mcr.microsoft.com/playwright/python:v1.43.0-jammy@sha256:153927658c515f20ace339566ba2136444dcdbedd80f1305066ccdb1ae9770ff 7ms

Apr 28 23:42:14

[1/6] FROM mcr.microsoft.com/playwright/python:v1.43.0-jammy@sha256:153927658c515f20ace339566ba2136444dcdbedd80f1305066ccdb1ae9770ff – CACHED

Apr 28 23:42:14

[1/6] FROM mcr.microsoft.com/playwright/python:v1.43.0-jammy@sha256:153927658c515f20ace339566ba2136444dcdbedd80f1305066ccdb1ae9770ff 1ms – CACHED

Apr 28 23:42:14

[1/6] FROM mcr.microsoft.com/playwright/python:v1.43.0-jammy@sha256:153927658c515f20ace339566ba2136444dcdbedd80f1305066ccdb1ae9770ff

Apr 28 23:42:15

[internal] load build context 219ms

Apr 28 23:42:15

[1/6] FROM mcr.microsoft.com/playwright/python:v1.43.0-jammy@sha256:153927658c515f20ace339566ba2136444dcdbedd80f1305066ccdb1ae9770ff 0ms – CACHED

Apr 28 23:42:15

[2/6] RUN apt-get update && apt-get install -y --no-install-recommends libpq-dev && rm -rf /var/lib/apt/lists/* && apt-get clean 0ms – CACHED

Apr 28 23:42:15

[3/6] WORKDIR /app 0ms – CACHED

Apr 28 23:42:15

✕ [4/6] COPY requirements.txt .

failed to calculate checksum of ref qy6xjhuw0zzchgnz4jkj580a6::z3vtej6nfccinf7cwegd8ozhc: "/requirements.txt": not found

Apr 28 23:42:15

[1/6] FROM mcr.microsoft.com/playwright/python:v1.43.0-jammy@sha256:153927658c515f20ace339566ba2136444dcdbedd80f1305066ccdb1ae9770ff 229ms

Apr 28 23:42:15

✕ [2/6] RUN apt-get update && apt-get install -y --no-install-recommends libpq-dev && rm -rf /var/lib/apt/lists/* && apt-get clean

failed to copy: context canceled: context canceled

Apr 28 23:42:15

Dockerfile:15

Apr 28 23:42:15

-------------------

Apr 28 23:42:15

13 | WORKDIR /app

Apr 28 23:42:15

14 |

Apr 28 23:42:15

15 | >>> COPY requirements.txt .

Apr 28 23:42:15

16 | # Installe tes dépendances Python

Apr 28 23:42:15

17 | RUN pip install --no-cache-dir -r requirements.txt

Apr 28 23:42:15

-------------------

Apr 28 23:42:15

ERROR: failed to solve: failed to compute cache key: failed to calculate checksum of ref qy6xjhuw0zzchgnz4jkj580a6::z3vtej6nfccinf7cwegd8ozhc: "/requirements.txt": not found

Load More


echohack
EMPLOYEE

2 months ago

Alright! Looks like it's detecting the Dockerfile successfully now. That's progress.

https://railway.com/project/cbf6ac5f-77b2-4416-9803-076a8da15cd6/service/913ec1c2-5628-4789-a8fb-4fdec2ccf967?context=2025-04-28T21%3A42%3A15.057663304Z&environmentId=4f2d75d5-3831-41a6-9cb6-1c9adaafb2a3&id=61fb3334-ac2c-4384-8387-916bc9998ce7&forceViewAll=true

Looks like your Dockerfile is trying to reference a Requirements.txt file that doesn't exist or is in the wrong path.


Status changed to Awaiting User Response railway[bot] 2 months ago


leolmz59
HOBBY

2 months ago


This is the structure of my project.
Could you confirm that the Dockerfiles are correclty placed (in the right dir) ?
I see in the main app on railway that the root directory is set to /comparaplan --> should it be the case?

Attachments


Status changed to Awaiting Railway Response railway[bot] 2 months ago


leolmz59

This is the structure of my project. Could you confirm that the Dockerfiles are correclty placed (in the right dir) ? I see in the main app on railway that the root directory is set to /comparaplan --> should it be the case?

leolmz59
HOBBY

2 months ago

I renamed "Dockerfile" into "Dockerfile.worker" and now I don't have the error 502.
However I need a dockerfile name Dockerfile to put the content of Dockerfile.worker. Indeed the worker need a dockerfile named "Dockerfile" to work.
could you explain me what is potentialy wrong please ? I'm realy struggling with railway for the last weeks


echohack
EMPLOYEE

2 months ago

I am seeing the Dockerfile in the root directory, and requirements.txt in `./comparaplan/requirements.txt`

So you'd need to correctly reference that path in your Dockerfile instead of ./requirements.txt


Status changed to Awaiting User Response railway[bot] 2 months ago


leolmz59
HOBBY

2 months ago

Thanks for your answer. I changed that like shows my screenshot of my project structure. My issue is that the worker only accept docker files named "Dockerfile" and not Dockerfile.worker. However if I do this I get a 502 error after deploying. How can I indicate the celery worker to use a specific dockerfile ? I need it to then run playwright automation actions.
From what I understood I absolutly need to rename Dockerfile.worker into Dockerfile to avoid the error: "Connection closed while reading from the driver". Is that right ?


Status changed to Awaiting Railway Response railway[bot] 2 months ago


leolmz59
HOBBY

2 months ago

Hi! Any news concerning this issue ?


2 months ago

Please see our docs on how to set a custom Dockerfile location -

https://docs.railway.com/guides/dockerfiles#custom-dockerfile-path


Status changed to Awaiting User Response railway[bot] 2 months ago


Status changed to Solved leolmz59 about 2 months ago


Playwright Remote Connect Fails: Exception: Connection closed while reading from the driver (Browserless on Railway) - Railway Help Station