Skip to main content

Deploy Symfony

This guide will help you deploy a Symfony application to Deployxa.

Overview

Symfony is a high-performance PHP framework for building robust web applications. Deployxa provides optimized deployments for Symfony with automatic configuration.

Features:

  • Automatic framework detection
  • PHP 8.1+ support
  • Composer dependency management
  • Database migrations
  • Asset management
  • Automatic HTTPS

Prerequisites

  • A Symfony application (version 6 or higher recommended)
  • A GitHub repository with your code
  • A Deployxa account
  • MySQL or PostgreSQL database

Quick Start

1. Create Your Symfony App

If you don't have a Symfony app yet:

symfony new my-symfony-app --full
cd my-symfony-app

Or using Composer:

composer create-project symfony/website-skeleton my-symfony-app
cd my-symfony-app

2. Configure for Production

Update .env:

APP_ENV=prod
APP_SECRET=your-app-secret-here
DATABASE_URL="mysql://user:pass@host:3306/dbname?serverVersion=8.0"

3. Push to GitHub

git init
git add .
git commit -m "Initial commit"
git remote add origin https://github.com/yourusername/my-symfony-app.git
git push -u origin main

4. Deploy to Deployxa

  1. Go to Deployxa Dashboard
  2. Click "New Project"
  3. Select your GitHub repository
  4. Deployxa will automatically detect Symfony
  5. Click "Deploy"

Your app will be live in under 60 seconds!

Configuration

Detected Settings

Deployxa automatically detects these settings:

SettingValue
FrameworkSymfony
Build Commandcomposer install --no-dev --optimize-autoloader
Output Directorypublic
Start Commandphp -S 0.0.0.0:8000 -t public
Port8000

Custom Configuration

If you need to customize settings:

  1. Go to ProjectSettingsBuild
  2. Modify settings as needed
  3. Save changes

Example Custom Settings:

{
"buildCommand": "composer install --no-dev --optimize-autoloader",
"outputDirectory": "public",
"startCommand": "php -S 0.0.0.0:8000 -t public"
}

Environment Variables

Adding Environment Variables

  1. Go to ProjectEnvironment
  2. Click "Add Variable"
  3. Enter key and value
  4. Click "Save"

Required Symfony Environment Variables:

APP_ENV=prod
APP_SECRET=your-app-secret-here
APP_DEBUG=0

# Database
DATABASE_URL=mysql://user:pass@host:3306/dbname?serverVersion=8.0

# Mailer (optional)
MAILER_DSN=smtp://user:pass@smtp.example.com:587

Generating APP_SECRET

Generate a new application secret:

php -r "echo bin2hex(random_bytes(32)) . PHP_EOL;"

Or use Symfony CLI:

symfony console secrets:set APP_SECRET

Database Configuration

Using Managed Database

  1. Go to ProjectSettingsDatabase
  2. Click "Create Database"
  3. Choose database type (MySQL or PostgreSQL)
  4. Configure database settings
  5. Copy connection details to environment variables

Database Migrations

Run migrations automatically on deployment:

Option 1: Post-Deploy Script

Create a deployment script:

#!/bin/bash
php bin/console doctrine:migrations:migrate --no-interaction
php bin/console cache:clear --env=prod
php bin/console assets:install public

Option 2: Manual Migration

Run migrations via SSH or console:

php bin/console doctrine:migrations:migrate --no-interaction

Database Fixtures

Seed your database after migration:

php bin/console doctrine:fixtures:load --no-interaction

Asset Management

Installing Assets

Install assets automatically:

php bin/console assets:install public

This command is automatically run by Deployxa during deployment.

Using Asset Mapper (Symfony 6.3+)

For modern asset management:

composer require symfony/asset-mapper

Configure in config/packages/asset_mapper.yaml:

framework:
asset_mapper:
paths:
- assets/

Using Webpack Encore

For advanced asset management:

composer require symfony/webpack-encore-bundle
npm install

Build assets:

npm run build

Custom Domains

Adding a Custom Domain

  1. Go to ProjectDomains
  2. Click "Add Domain"
  3. Enter your domain (e.g., example.com)
  4. Configure DNS records
  5. Wait for verification

DNS Configuration

For Apex Domain (example.com):

Type: A
Name: @
Value: 76.76.21.21

For Subdomain (www.example.com):

Type: CNAME
Name: www
Value: cname.deployxa.com

Update APP_URL

Update your APP_URL environment variable:

APP_URL=https://example.com

Caching

Clear Cache

Clear cache after deployment:

php bin/console cache:clear --env=prod

Warm Up Cache

Warm up cache for better performance:

php bin/console cache:warmup --env=prod

OPcache

OPcache is enabled by default in Deployxa's PHP runtime.

Performance Optimization

Optimize Autoloader

Optimize Composer autoloader:

composer install --optimize-autoloader --no-dev

This is automatically done by Deployxa.

Enable OPcache

OPcache is enabled by default in Deployxa's PHP runtime.

Use CDN

Serve static assets via CDN:

Configure in config/packages/framework.yaml:

framework:
assets:
base_urls:
- 'https://cdn.example.com'

Database Indexing

Add indexes to frequently queried columns:

// src/Entity/User.php
use Doctrine\ORM\Mapping as ORM;

#[ORM\Entity]
#[ORM\Table(name: 'users')]
#[ORM\Index(name: 'email_idx', columns: ['email'])]
class User
{
// ...
}

Monitoring

Viewing Logs

  1. Go to ProjectLogs
  2. Select log type:
    • Build Logs: Deployment process
    • Runtime Logs: Application output
    • Error Logs: Application errors

Symfony Logging

Configure logging in .env:

MONOLOG_CHANNEL=app

View logs in var/log:

var/log/prod.log

Monitoring Metrics

  1. Go to ProjectAnalytics
  2. View metrics:
    • Request count
    • Response times
    • Error rates
    • Bandwidth usage
    • CPU/RAM usage

Health Checks

Deployxa automatically monitors your application:

  • HTTP health checks every 30 seconds
  • Automatic restart on failure
  • Alerts on consecutive failures

Troubleshooting

500 Internal Server Error

Problem: Application returns 500 error

Solution:

  1. Check runtime logs for errors
  2. Verify environment variables
  3. Check database connection
  4. Ensure APP_SECRET is set
  5. Check file permissions

Database Connection Failed

Problem: An exception occurred in the driver

Solution:

  1. Verify DATABASE_URL is correct
  2. Check database host and port
  3. Ensure database exists
  4. Check firewall rules
  5. Verify database user permissions

Migration Failed

Problem: php bin/console doctrine:migrations:migrate fails

Solution:

  1. Check database connection
  2. Verify migration files
  3. Check for syntax errors
  4. Run migrations locally first
  5. Check database permissions

Assets Not Loading

Problem: CSS/JS files return 404

Solution:

  1. Run php bin/console assets:install public
  2. Check public directory exists
  3. Verify asset paths are correct
  4. Check file permissions

Cache Issues

Problem: Changes not reflected

Solution:

  1. Clear cache: php bin/console cache:clear --env=prod
  2. Warm up cache: php bin/console cache:warmup --env=prod
  3. Check cache directory permissions
  4. Verify APP_ENV is set to prod

Best Practices

Project Structure

my-symfony-app/
├── config/
├── public/
│ └── index.php
├── src/
│ ├── Controller/
│ ├── Entity/
│ └── Repository/
├── templates/
├── var/
│ ├── cache/
│ └── log/
├── vendor/
├── .env
├── .env.example
├── composer.json
├── symfony.lock
└── README.md

Environment Variables

  • Never commit .env file
  • Use .env.example as template
  • Rotate secrets regularly
  • Use different values per environment

Security

  • Keep Symfony updated
  • Use HTTPS only
  • Validate all inputs
  • Use CSRF protection
  • Sanitize user data
  • Use parameterized queries

Performance

  • Enable OPcache
  • Optimize autoloader
  • Use caching (config, route, twig)
  • Use queue for background jobs
  • Use CDN for static assets
  • Minimize HTTP requests

Database

  • Use migrations for schema changes
  • Index frequently queried columns
  • Use transactions for complex operations
  • Backup database regularly
  • Use connection pooling

Advanced Configuration

Custom PHP Configuration

Create php.ini:

upload_max_filesize = 64M
post_max_size = 64M
memory_limit = 256M
max_execution_time = 60
opcache.enable=1
opcache.memory_consumption=256

Custom Nginx Configuration

For advanced routing, create custom Nginx config:

server {
listen 8000;
root /app/public;

location / {
try_files $uri /index.php$is_args$args;
}

location ~ ^/index\.php(/|$) {
fastcgi_pass unix:/var/run/php/php-fpm.sock;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $realpath_root;
internal;
}

location ~ \.php$ {
return 404;
}
}

Multi-Environment Setup

Use different environment variables per environment:

# Production
APP_ENV=prod
APP_DEBUG=0

# Staging
APP_ENV=staging
APP_DEBUG=1

# Development
APP_ENV=dev
APP_DEBUG=1

Examples

Basic Symfony App

// src/Controller/DefaultController.php
namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;

class DefaultController extends AbstractController
{
#[Route('/', name: 'home')]
public function index(): Response
{
return $this->render('default/index.html.twig');
}
}

API Endpoint

// src/Controller/ApiController.php
namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\Routing\Annotation\Route;

class ApiController extends AbstractController
{
#[Route('/api/users', name: 'api_users', methods: ['GET'])]
public function getUsers(): JsonResponse
{
return $this->json(['users' => []]);
}
}

Database Entity

// src/Entity/User.php
namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;

#[ORM\Entity]
#[ORM\Table(name: 'users')]
class User
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
private ?int $id = null;

#[ORM\Column(length: 180, unique: true)]
private ?string $email = null;

#[ORM\Column(length: 255)]
private ?string $name = null;

// Getters and setters...
}

Migration

// migrations/Version20240115120000.php
namespace DoctrineMigrations;

use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;

final class Version20240115120000 extends AbstractMigration
{
public function up(Schema $schema): void
{
$this->addSql('CREATE TABLE users (
id INT AUTO_INCREMENT NOT NULL,
email VARCHAR(180) NOT NULL UNIQUE,
name VARCHAR(255) NOT NULL,
PRIMARY KEY(id)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci ENGINE = InnoDB');
}

public function down(Schema $schema): void
{
$this->addSql('DROP TABLE users');
}
}

Resources


Need Help? Contact support@deployxa.com or join our community Discord.