4 min read

How to Deploy a Symfony App with Nginx and PHP-FPM

Deploy Symfony on Ubuntu with Nginx and PHP-FPM the fast way, including Composer, environment config, migrations, cache warmup, permissions, and SSL.

If you want the fastest reliable way to deploy Symfony in 2026, use Nginx + PHP-FPM + Composer + environment variables + database migrations + cache warmup + HTTPS. That is the stack most teams can maintain without turning deployment into a side project.

This tutorial is written for developers who want a working production setup, not a perfect theoretical diagram.

Before you start

  • An Ubuntu 24.04 server
  • A Symfony app that runs locally
  • SSH access and a sudo user
  • A domain name already pointed to the server

Step 1: Install the server packages

sudo apt update && sudo apt upgrade -y
sudo apt install -y nginx git unzip curl mysql-server php-fpm php-cli php-mysql php-curl php-mbstring php-xml php-zip php-intl php-bcmath

Install Composer if it is not already available:

cd /tmp
curl -sS https://getcomposer.org/installer -o composer-setup.php
php composer-setup.php
sudo mv composer.phar /usr/local/bin/composer

Step 2: Upload or clone the project

cd /var/www
sudo mkdir -p symfony-app
sudo chown -R $USER:$USER symfony-app
git clone your-repository-url symfony-app

Step 3: Install production dependencies

cd /var/www/symfony-app
composer install --no-dev --optimize-autoloader

If your project uses frontend assets, run the matching production build now.

Step 4: Configure the environment

Symfony usually reads environment values from .env, but production should use real server environment variables or a secure .env.local that is not committed to Git.

At minimum, check:

  • APP_ENV=prod
  • APP_SECRET
  • DATABASE_URL
  • Mailer and queue settings if your app uses them

Step 5: Set permissions the right way

Symfony usually needs write access to var/. That is it.

sudo chown -R www-data:www-data /var/www/symfony-app/var
sudo find /var/www/symfony-app -type f -exec chmod 644 {} \;
sudo find /var/www/symfony-app -type d -exec chmod 755 {} \;

Step 6: Create the Nginx config

Symfony should serve from the public/ directory.

sudo nano /etc/nginx/sites-available/symfony-app
server {
    listen 80;
    server_name example.com www.example.com;
    root /var/www/symfony-app/public;
    index index.php;

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

    location ~ ^/index\.php(/|$) {
        fastcgi_pass unix:/run/php/php8.3-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;
    }

    error_log /var/log/nginx/symfony-app_error.log;
    access_log /var/log/nginx/symfony-app_access.log;
}
sudo ln -s /etc/nginx/sites-available/symfony-app /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

Step 7: Run migrations and warm the cache

This is the part many developers forget, then they wonder why production breaks.

cd /var/www/symfony-app
php bin/console doctrine:migrations:migrate --no-interaction
php bin/console cache:clear --env=prod
php bin/console cache:warmup --env=prod

Step 8: Set up the worker processes if needed

If your app uses Messenger, queues, or scheduled jobs, configure them now. Do not wait until users discover that emails or background tasks are not working.

Step 9: Add HTTPS

sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d example.com -d www.example.com

Step 10: Check logs and production behavior

sudo tail -f /var/log/nginx/symfony-app_error.log
sudo tail -f /var/log/nginx/symfony-app_access.log

Also check Symfony logs in var/log/ if your app writes there.

Common mistakes that break Symfony deployments

  • Serving the project root instead of public/
  • Leaving APP_ENV=dev in production
  • Skipping migrations
  • Skipping cache warmup
  • Using a writable permission model that is far too broad

When this setup is enough

For a typical content site, SaaS MVP, internal tool, or API, this stack is enough. You do not need Kubernetes just to launch a Symfony app.

Useful next reads

If you want the more general base server flow, read How to Deploy a PHP App on Ubuntu Step by Step in 2026. If the server is still fresh, harden it with How to Secure a Fresh Ubuntu Server Before Going Live.

Quick FAQ

Should I use Apache for Symfony?

You can, but Nginx plus PHP-FPM is usually the cleaner default in 2026.

Do I need Supervisor?

Only if your app has workers or background jobs. A simple content site may not need it.

Can I deploy Symfony without Composer on the server?

Yes, if your CI pipeline builds the release artifact first. That is often better for larger teams.

Php Mar 28, 2026