Deploy Selenium with flask
[Jun'26] Deploy Flask API with remote Selenium for web scraping
Just deployed
selenium
Just deployed
Deploy and Host Selenium with Flask on Railway
What is Selenium with Flask?
Selenium with Flask is a lightweight browser automation stack for Railway. This template runs as two connected services: a Flask REST API service and a Selenium Standalone Chrome service.
The Flask service exposes HTTP endpoints that trigger browser automation tasks, while the Selenium service runs the remote Chrome browser environment. Communication between both services uses Selenium Remote WebDriver, making the setup cleaner, more scalable, and easier to maintain than bundling Chrome, ChromeDriver, and the API server into a single container.
About Hosting Selenium with Flask
Hosting Selenium with Flask on Railway gives you a ready-to-use setup for building browser automation APIs, scraping workers, and internal automation tools.
This template separates the application layer and browser automation layer into two services:
-
Flask REST API Handles incoming HTTP requests, API routes, scraping logic, and response formatting.
-
Selenium Standalone Chrome Runs headless Chrome and exposes a Remote WebDriver endpoint for browser sessions.
Instead of installing ChromeDriver directly inside the Flask container, the Flask app connects to the Selenium service through a remote URL. When both services run inside Railway, you can use Railway private networking for internal service-to-service communication.
Example internal Remote WebDriver URL:
http://standalone-chrome.railway.internal:4444/wd/hub
If you access Selenium from outside Railway, use the public Selenium service URL instead.
Example public Remote WebDriver URL:
https://your-selenium-service.up.railway.app/wd/hub
This architecture keeps the Flask API lightweight while allowing Selenium to run as a dedicated browser automation service.
How to Use
After deploying this template, Railway will create two services:
- Flask REST API
- Selenium Standalone Chrome
Open the generated Railway domain for the Flask service to test the starter API.
The Flask service connects to Selenium using a Remote WebDriver URL. In a Railway-to-Railway setup, use the private internal Railway URL for faster and private service communication.
Example environment variable for the Flask service:
SELENIUM_REMOTE_URL=http://standalone-chrome.railway.internal:4444/wd/hub
If you run the Flask app locally on your computer, you cannot use the .railway.internal URL. Use the public Selenium Railway URL instead:
SELENIUM_REMOTE_URL=https://your-selenium-service.up.railway.app/wd/hub
Test the Scrape Endpoint
This template already includes a sample scrape endpoint in the Flask REST API service.
After deployment, test the Flask service using:
https://your-flask-service.up.railway.app/scrape
You can also test it with curl:
curl https://your-flask-service.up.railway.app/scrape
If the Flask service can connect to the Selenium Standalone Chrome service correctly, the endpoint should return a JSON response from the sample scraping task.
How to Check Selenium Status
You can verify the Selenium service by opening its status endpoint.
Private Railway network:
http://standalone-chrome.railway.internal:4444/status
Public Railway URL:
https://your-selenium-service.up.railway.app/status
If the Selenium service is running correctly, it should return a JSON response showing the Selenium node status.
Customization
If you want to customize the source code, use one of the workflows below.
Via Railway CLI
Use this workflow if you want to edit the project locally and redeploy changes directly from your machine using Railway CLI.
- Deploy the template.
- Clone the repository from Source Repo or Upstream Repo in the Railway dashboard.
- Enter the project directory:
cd your-project-directory
- Link your local project directory to the deployed Railway project:
railway link
- Check the linked project, environment, service, and repository information:
railway status
- Edit the code locally.
- Redeploy your local changes to Railway:
railway up
Railway will upload the current local directory and deploy it to the linked service.
Via Git / GitHub
Use this workflow if you want to manage changes through GitHub and let Railway automatically redeploy after every push.
- Deploy the template.
- Open Source Repo or Upstream Repo from the Railway dashboard.
- Fork the repository to your own GitHub account.
- Clone your fork locally:
git clone your-fork-url
cd your-project-directory
- Edit the code locally.
- Commit and push your changes to your fork:
git add .
git commit -m "Customize Selenium Flask template"
git push origin main
- In Railway, change the service Source Repo to your fork if Railway does not automatically create or link it.
- After the service is connected to your fork, future pushes to the repository can trigger automatic redeployments.
Common Use Cases
- Trigger automated browser tasks via REST API
- Scrape JavaScript-heavy websites
- Build internal scraping workers
- Run scheduled browser automation jobs
- Create lightweight data extraction APIs
- Test browser flows through remote Chrome sessions
- Integrate browser automation with n8n, cron jobs, webhooks, or backend systems
Dependencies for Selenium with Flask Hosting
Flask REST API Service
- Python
- Flask
- Selenium Python package
- Gunicorn or another Python WSGI server
Selenium Service
- Selenium Standalone Chrome
- Headless Chrome
- Remote WebDriver endpoint
Deployment Dependencies
This template uses two Railway services:
- Flask REST API service
- Selenium Standalone Chrome service
Recommended Selenium image:
selenium/standalone-chrome
Recommended Remote WebDriver endpoint:
http://standalone-chrome.railway.internal:4444/wd/hub
Environment Variables
Flask Service
PORT=5000
SELENIUM_REMOTE_URL=http://standalone-chrome.railway.internal:4444/wd/hub
Use the public Selenium Railway URL if running Flask locally:
SELENIUM_REMOTE_URL=https://your-selenium-service.up.railway.app/wd/hub
Selenium Standalone Chrome Service
PORT=4444
START_XVFB=true
SE_SCREEN_WIDTH=1920
SE_SCREEN_HEIGHT=1080
SE_SESSION_TIMEOUT=300
SE_NODE_CHROME_ARGS="--disable-dev-shm-usage --no-sandbox --disable-gpu --disable-extensions --disable-infobars --window-size=1920,1080 --headless=new --remote-allow-origins=*"
SE_NODE_MAX_SESSIONS=4
SE_NODE_SESSION_TIMEOUT=300
SE_NODE_OVERRIDE_MAX_SESSIONS=true
Implementation Details
The Flask service connects to Selenium using Remote WebDriver. The remote URL is configured through the SELENIUM_REMOTE_URL environment variable.
Recommended Railway internal URL:
http://standalone-chrome.railway.internal:4444/wd/hub
For each scraping request, the Flask API should create a remote Selenium browser session, run the automation logic, close the browser session, and return a JSON response.
A good request lifecycle is:
- Receive HTTP request in Flask.
- Create remote Selenium browser session.
- Open target page.
- Extract required data.
- Close the browser session.
- Return JSON response.
Keep browser sessions short-lived and always close them after each request to avoid memory buildup or stuck Chrome sessions.
Private vs Public URL
Use Railway private networking when the Flask service and Selenium service are deployed inside the same Railway project.
Private Railway URL:
http://standalone-chrome.railway.internal:4444/wd/hub
Use the public Selenium Railway URL when connecting from your local machine or from outside Railway.
Public Railway URL:
https://your-selenium-service.up.railway.app/wd/hub
The .railway.internal domain is only reachable from services running inside Railway. It is not accessible from your local computer.
Why Deploy Selenium with Flask on Railway?
Railway is a singular platform to deploy your infrastructure stack. Railway will host your infrastructure so you do not have to deal with complex server configuration, while still allowing you to scale services vertically and horizontally.
By deploying Selenium with Flask on Railway, you get a clean two-service architecture for browser automation. The Flask API stays lightweight, while Selenium runs separately as a dedicated remote browser service.
This makes the template practical for scraping APIs, automation workers, internal tools, webhook-based browser tasks, and integrations with platforms like n8n or other backend systems.
Template Content