If you want the short version, a production-ready PHP deployment on Ubuntu in 2026 usually means this stack: Ubuntu + Nginx + PHP-FPM + MySQL or MariaDB + UFW + Fail2ban + Let's Encrypt. That setup is fast, simple, and easy to maintain.
This guide skips the fluff and shows the path that saves the most time when you just need to get a PHP app online safely.
What you need before you start
- An Ubuntu 24.04 LTS server
- A sudo user
- A domain name pointed to your server
- A PHP app ready to upload
Step 1: Update the server
Start with a clean update. This avoids weird package conflicts later.
sudo apt update && sudo apt upgrade -y
sudo apt install -y curl unzip git software-properties-common
Step 2: Install Nginx, PHP-FPM, and MySQL
In 2026, this is still the easiest production stack for most PHP apps.
sudo apt install -y nginx mysql-server php-fpm php-cli php-mysql php-curl php-mbstring php-xml php-zip php-intl php-bcmath
Check the PHP version installed on your server:
php -v
You will need that version for the PHP-FPM socket path. On many Ubuntu servers, it will look like /run/php/php8.3-fpm.sock or similar.
Step 3: Create your app directory
A clean convention is to keep projects in /var/www/.
sudo mkdir -p /var/www/my-php-app
sudo chown -R $USER:$USER /var/www/my-php-app
Upload your app, clone it with Git, or copy it with rsync. If your project uses Composer:
cd /var/www/my-php-app
composer install --no-dev --optimize-autoloader
Step 4: Set safe file permissions
Do not use 777. Most apps only need the web server to write to a cache, logs, or uploads directory.
sudo chown -R www-data:www-data /var/www/my-php-app/storage /var/www/my-php-app/bootstrap/cache
sudo find /var/www/my-php-app -type f -exec chmod 644 {} \;
sudo find /var/www/my-php-app -type d -exec chmod 755 {} \;
If your app is plain PHP and does not have storage or bootstrap/cache, adjust those paths.
Step 5: Create the Nginx server block
Point Nginx to your app’s public directory, not the project root, if your framework has a public/ folder.
sudo nano /etc/nginx/sites-available/my-php-app
server {
listen 80;
server_name example.com www.example.com;
root /var/www/my-php-app/public;
index index.php index.html;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
}
location ~ /\.ht {
deny all;
}
}
Enable the site:
sudo ln -s /etc/nginx/sites-available/my-php-app /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
Step 6: Create the database
If your app needs MySQL, create a separate database and user. Never use the MySQL root account inside the app.
sudo mysql
CREATE DATABASE my_php_app;
CREATE USER 'my_php_user'@'localhost' IDENTIFIED BY 'change-this-password';
GRANT ALL PRIVILEGES ON my_php_app.* TO 'my_php_user'@'localhost';
FLUSH PRIVILEGES;
EXIT;
Step 7: Add your environment settings
Set your database credentials, app URL, mail settings, and production environment variables. If your framework uses an .env file, double-check it before going live.
Step 8: Enable HTTPS with Let’s Encrypt
Do this before launch. It takes a few minutes and saves you from fixing mixed content and redirect issues later.
sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d example.com -d www.example.com
Step 9: Open the firewall
sudo ufw allow OpenSSH
sudo ufw allow 'Nginx Full'
sudo ufw enable
sudo ufw status
Step 10: Test the app like a real user
Before you call it done, test:
- Homepage loads
- Forms submit correctly
- Database writes work
- Uploads work
- HTTPS redirects correctly
- Error logs stay quiet
Useful logs:
sudo tail -f /var/log/nginx/error.log
sudo tail -f /var/log/php8.3-fpm.log
Common mistakes that waste time
- Using the wrong PHP-FPM socket path
- Pointing Nginx to the wrong directory
- Giving write permission to the whole project
- Forgetting to reload Nginx after config changes
- Deploying over HTTP first and fixing SSL later
What to do next
If you are deploying a framework app, read How to Deploy a Symfony App with Nginx and PHP-FPM. If you have not hardened the server yet, go next to How to Secure a Fresh Ubuntu Server Before Going Live.
Quick FAQ
Should I use Apache instead of Nginx?
For most new deployments, Nginx is the simpler default. If you want a direct comparison, read Nginx vs Apache in 2026: What Developers Should Really Choose.
Do I need Docker for a small PHP app?
No. Docker can help, but a direct Ubuntu deployment is often faster to ship and easier to debug for a small or medium project.
What is the safest PHP deployment model?
A non-root deploy workflow, isolated database credentials, a firewall, HTTPS, and only the minimum writable directories.