Running Symfony Panther in a Docker container provides a consistent, isolated environment for web scraping and browser automation. This guide covers setting up a complete Docker environment with PHP, headless Chrome, and proper network configuration.
Overview
Symfony Panther requires: - PHP application container with Symfony Panther installed - Headless browser (Chrome/Firefox) container - Network connectivity between containers - Proper environment configuration
Step 1: Create the PHP Application Dockerfile
Create a Dockerfile
in your Symfony project root:
FROM php:8.2-fpm
# Install system dependencies
RUN apt-get update && apt-get install -y \
git \
unzip \
curl \
zip \
libpng-dev \
libjpeg-dev \
libfreetype6-dev \
libonig-dev \
libxml2-dev \
libzip-dev \
&& docker-php-ext-configure gd --with-freetype --with-jpeg \
&& docker-php-ext-install -j$(nproc) gd \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
# Install PHP extensions required for Symfony
RUN docker-php-ext-install \
pdo_mysql \
mbstring \
xml \
zip \
bcmath \
opcache
# Install Composer
COPY --from=composer:2.6 /usr/bin/composer /usr/bin/composer
# Set working directory
WORKDIR /var/www/html
# Copy composer files first for better caching
COPY composer.json composer.lock ./
# Install PHP dependencies
RUN composer install --no-dev --optimize-autoloader --no-interaction
# Copy application code
COPY . .
# Set proper permissions
RUN chown -R www-data:www-data /var/www/html \
&& chmod -R 755 /var/www/html
# Create user for running the application
USER www-data
EXPOSE 8000
CMD ["php", "-S", "0.0.0.0:8000", "-t", "public"]
Step 2: Create Docker Compose Configuration
Create a docker-compose.yml
file:
version: '3.8'
services:
app:
build:
context: .
dockerfile: Dockerfile
container_name: symfony_panther_app
ports:
- "8000:8000"
volumes:
- .:/var/www/html:cached
- vendor:/var/www/html/vendor
environment:
- APP_ENV=test
- PANTHER_NO_SANDBOX=1
- PANTHER_CHROME_ARGUMENTS=--disable-dev-shm-usage --no-sandbox --disable-gpu
- PANTHER_WEB_SERVER_PORT=8000
- PANTHER_EXTERNAL_BASE_URI=http://app:8000
depends_on:
- chrome
networks:
- panther_network
chrome:
image: selenium/standalone-chrome:4.15.0
container_name: panther_chrome
ports:
- "4444:4444"
- "7900:7900" # VNC port for debugging
environment:
- SE_VNC_NO_PASSWORD=1
- SE_NODE_MAX_INSTANCES=2
- SE_NODE_MAX_SESSIONS=2
volumes:
- /dev/shm:/dev/shm
networks:
- panther_network
shm_size: 2gb
networks:
panther_network:
driver: bridge
volumes:
vendor:
Step 3: Configure Environment Variables
Create or update your .env.test
file:
# Panther Configuration
PANTHER_NO_SANDBOX=1
PANTHER_CHROME_ARGUMENTS='--disable-dev-shm-usage --no-sandbox --disable-gpu --window-size=1920,1080'
PANTHER_WEB_SERVER_PORT=8000
PANTHER_EXTERNAL_BASE_URI=http://app:8000
PANTHER_CHROME_DRIVER_BINARY=/usr/bin/chromedriver
# If using remote WebDriver (Selenium)
PANTHER_NO_HEADLESS=0
PANTHER_DEVTOOLS=0
Step 4: Create a Panther Test Configuration
Create config/packages/test/panther.yaml
:
panther:
# Use external Chrome instance
external_base_uri: '%env(PANTHER_EXTERNAL_BASE_URI)%'
# Chrome options for Docker environment
chrome:
arguments:
- '--no-sandbox'
- '--disable-dev-shm-usage'
- '--disable-gpu'
- '--window-size=1920,1080'
- '--disable-web-security'
- '--allow-running-insecure-content'
Step 5: Sample Panther Test
Create a test to verify the setup works:
<?php
// tests/PantherTest.php
namespace App\Tests;
use Symfony\Component\Panther\PantherTestCase;
class PantherTest extends PantherTestCase
{
public function testDockerSetup(): void
{
$client = static::createPantherClient([
'external_base_uri' => $_ENV['PANTHER_EXTERNAL_BASE_URI'] ?? 'http://app:8000',
]);
// Test that we can load a page
$crawler = $client->request('GET', '/');
$this->assertSelectorTextContains('title', 'Welcome');
// Take a screenshot (optional)
$client->takeScreenshot('docker-test.png');
}
public function testWebScraping(): void
{
$client = static::createPantherClient();
// Navigate to external site
$crawler = $client->request('GET', 'https://example.com');
// Wait for page to load
$client->waitFor('h1');
// Extract content
$title = $crawler->filter('h1')->text();
$this->assertNotEmpty($title);
}
}
Step 6: Build and Run
Build and start the containers:
# Build images
docker-compose build
# Start services
docker-compose up -d
# Check service status
docker-compose ps
# View logs
docker-compose logs app
docker-compose logs chrome
Step 7: Run Tests
Execute Panther tests inside the container:
# Run all tests
docker-compose exec app ./vendor/bin/phpunit
# Run specific test
docker-compose exec app ./vendor/bin/phpunit tests/PantherTest.php
# Run with verbose output
docker-compose exec app ./vendor/bin/phpunit --verbose tests/PantherTest.php
Advanced Configuration
Using Firefox Instead of Chrome
# In docker-compose.yml, replace chrome service with:
firefox:
image: selenium/standalone-firefox:4.15.0
container_name: panther_firefox
ports:
- "4444:4444"
- "7900:7900"
environment:
- SE_VNC_NO_PASSWORD=1
networks:
- panther_network
shm_size: 2gb
Remote WebDriver Configuration
For using Selenium Grid or remote WebDriver:
# .env.test
PANTHER_CHROME_DRIVER_BINARY=
PANTHER_FIREFOX_DRIVER_BINARY=
PANTHER_WEB_SERVER_ROUTER=
PANTHER_KERNEL_CLASS=App\Kernel
Performance Optimization
Add these Chrome arguments for better performance:
PANTHER_CHROME_ARGUMENTS='--disable-dev-shm-usage --no-sandbox --disable-gpu --disable-extensions --disable-plugins --disable-images --disable-javascript --headless'
Debugging
VNC Access
Access the Chrome container's desktop via VNC:
# Connect to localhost:7900 with any VNC viewer
# Password: secret (if not disabled)
Container Debugging
# Access app container
docker-compose exec app bash
# Access chrome container
docker-compose exec chrome bash
# Check container logs
docker-compose logs -f app
docker-compose logs -f chrome
Common Issues
- Connection refused: Ensure containers are on the same network
- Chrome crashes: Increase
shm_size
or add--disable-dev-shm-usage
- Timeouts: Adjust
PANTHER_CHROME_ARGUMENTS
and network settings - Permission errors: Check file permissions and user configuration
Production Considerations
- Use specific image tags instead of
latest
- Implement proper health checks
- Configure resource limits
- Use multi-stage builds for smaller images
- Implement proper logging and monitoring
This Docker setup provides a robust environment for running Symfony Panther tests and web scraping operations with proper isolation and scalability.