We're on the easy track, also known as straight forward. To me it means no VM, no docker. In this example, we're using nginx, php-fpm and Ubuntu (commands should also work with debian).
Here is a set of commands you can run on your server to install dependencies
# Install Nginx & PHP 8.3
apt update && apt upgrade -y
add-apt-repository ppa:ondrej/php
apt update
apt install nginx certbot python3-certbot-nginx acl zip unzip php8.3 php8.3-cli php8.3-{bz2,curl,mbstring,intl,zip,xml,pgsql,imagick,fpm}
# Prepare some right management, here I suggest the usage of a deployer user
adduser deployer
usermod -a -G www-data deployer
# We need to setup some keys
mkdir /home/deployer/.ssh
chown -R deployer:deployer /home/deployer/.ssh
touch /home/deployer/.ssh/authorized_keys
chown deployer:deployer /home/deployer/.ssh/authorized_keys
chmod 600 /home/deployer/.ssh/authorized_keys
# Add your public key to authorized keys
echo "Your key" >> /home/deployer/.ssh/authorized_keys
More information about commands:
ppa:ondrej/php
is the most known ppa to get PHP https://launchpad.net/~ondrej/+archive/ubuntu/phpcertbot
is required to setup our SSL certificatecomposer require --dev deployer/deployer
You may run as well vendor/bin/dep init
to create a standard deployment setup. But I suggest you to use directly the following configuration:
<?php
namespace Deployer;
require 'recipe/symfony.php';
// Config
set('repository', 'git@github.com:YourOrganization/your-project.git');
add('shared_files', []);
add('shared_dirs', [/* 'public/media' */]);
add('writable_dirs', [/* 'public/media' */]);
// Tasks
// If you work with AssetMapper
task('assets:install', function () {
run("cd {{release_or_current_path}} && {{bin/console}} asset-map:compile");
})->desc('Install assets');
// Hosts
host('YOUR_IP_OR_HOST')
->set('remote_user', 'deployer')
->set('deploy_path', '~/my-project');
// Hooks
after('deploy:failed', 'deploy:unlock');
// Enables Doctrine migrations
before('deploy:publish', 'database:migrate');
after('deploy:cache:clear', 'assets:install');
You can find information about anything in the previous script on this documentation.
Deploy! You can do so by using vendor/bin/dep deploy
.
Depending how you did your first deploy you may need to adjust some rights on the server, so just in case remember you can use that:
chmod +x /home/deployer/
chmod +x /home/deployer/my-project
chmod +x /home/deployer/my-project/current
But by default deployer will use getfacl
and setfacl
if your server supports it (most does by default those days).
Edit the file /etc/nginx/sites-available/my-project.com.conf
. The .conf
may be important depending on your nginx configuration.
You can use this configuration:
# /etc/nginx/sites-available/my-project.com.conf
server {
server_name my-project.com;
root /home/deployer/my-project/current/public;
location / {
# try to serve file directly, fallback to index.php
try_files $uri /index.php$is_args$args;
}
# optionally disable falling back to PHP script for the asset directories;
# nginx will return a 404 error when files are not found instead of passing the
# request to Symfony (improves performance but Symfony's 404 page is not displayed)
# location /bundles {
# try_files $uri =404;
# }
location ~ ^/index\.php(/|$) {
# when using PHP-FPM as a unix socket
fastcgi_pass unix:/var/run/php/php8.3-fpm.sock;
# when PHP-FPM is configured to use TCP
# fastcgi_pass 127.0.0.1:9000;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
# optionally set the value of the environment variables used in the application
# fastcgi_param APP_ENV prod;
# fastcgi_param APP_SECRET <app-secret-id>;
# fastcgi_param DATABASE_URL "mysql://db_user:db_pass@host:3306/db_name";
# When you are using symlinks to link the document root to the
# current version of your application, you should pass the real
# application path instead of the path to the symlink to PHP
# FPM.
# Otherwise, PHP's OPcache may not properly detect changes to
# your PHP files (see https://github.com/zendtech/ZendOptimizerPlus/issues/126
# for more information).
# Caveat: When PHP-FPM is hosted on a different machine from nginx
# $realpath_root may not resolve as you expect! In this case try using
# $document_root instead.
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $realpath_root;
# Prevents URIs that include the front controller. This will 404:
# http://example.com/index.php/some-path
# Remove the internal directive to allow URIs like this
internal;
}
# return 404 for all other php files not matching the front controller
# this prevents access to other php files you don't want to be accessible.
location ~ \.php$ {
return 404;
}
error_log /var/log/nginx/my_project_error.log;
access_log /var/log/nginx/my_project_access.log;
listen 443 ssl;
ssl_certificate /etc/letsencrypt/live/my-project.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/my-project.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
}
Run certbot first, then enable our previously setup configuration for nginx:
certbot --nginx -d my-project.com
ln -s /etc/nginx/sites-available/my-project.com.conf /etc/nginx/sites-enabled/my-project.com.conf
Test your configuration, restart nginx
nginx -t
systemctl restart nginx