Skip to content

Instantly share code, notes, and snippets.

@jaysson
Last active December 30, 2023 05:38
Show Gist options
  • Save jaysson/597e9bd3d6baec2f2b71b13393339cb6 to your computer and use it in GitHub Desktop.
Save jaysson/597e9bd3d6baec2f2b71b13393339cb6 to your computer and use it in GitHub Desktop.
Laravel server setup

This assumes root is logged in via SSH to the latest Ubuntu server, with the root SSH authorized keys stored in /root/authorized_keys. Another assumption is that you use postgres and redis hosted on different database servers, so we don't install those on the app server.

Server setup

Edit the SSH config and disable password login. Update the SSH port to something random.

vim /etc/ssh/sshd_config
systemctl reload sshd

Install nginx and PHP, create a user for deployments.

apt-get upgrade
apt-get update
apt-get install ca-certificates apt-transport-https software-properties-common nginx gnupg supervisor
add-apt-repository ppa:ondrej/php
apt-get update
apt-get install php8.3 php8.3-fpm php8.3-xml php8.3-curl php8.3-mbstring php8.3-zip php8.3-pgsql php8.3-redis php8.3-intl
adduser laravel -G sudo,www-data
mkdir /home/laravel/.ssh
cp ~/.ssh/authorized_keys /home/laravel/.ssh
chown -R laravel:laravel /home/laravel/.ssh

Install nodejs.

mkdir -p /etc/apt/keyrings
curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | sudo gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg
NODE_MAJOR=20
echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_MAJOR.x nodistro main" | sudo tee /etc/apt/sources.list.d/nodesource.list
apt-get update
apt-get install nodejs -y

Setup firewall.

ufw app list
ufw allow 'Nginx HTTP'
ufw allow your-ssh-port
ufw enable

Clone your git repo. Fix ownership and permissions.

cd /var/www
rm -rf html
git clone your-repository-url html
chown -R laravel:www-data html
find /var/www/html -type d -print0 | xargs -0 chmod 0775
find /var/www/html -type f -print0 | xargs -0 chmod 0664

Edit /etc/nginx/sites-available/default and replace its contents with the following after updating the server_name with your domain. Restart nginx.

server {
    listen 80;
    listen [::]:80;
    server_name example.com;
    root /var/www/html/public;
 
    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-Content-Type-Options "nosniff";
 
    index index.php;
 
    charset utf-8;
 
    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }
 
    location = /favicon.ico { access_log off; log_not_found off; }
    location = /robots.txt  { access_log off; log_not_found off; }
 
    error_page 404 /index.php;
 
    location ~ \.php$ {
        fastcgi_pass unix:/var/run/php/php8.2-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        include fastcgi_params;
    }
 
    location ~ /\.(?!well-known).* {
        deny all;
    }
}
vim /etc/nginx/sites-available/default
nginx -t
systemctl reload nginx

Create /etc/supervisor/conf.d/horizon.conf with the following contents and restart supervisor.

[program:horizon]
process_name=%(program_name)s
command=php /var/www/html/artisan horizon
autostart=true
autorestart=true
user=laravel
redirect_stderr=true
stdout_logfile=/var/www/html/storage/logs/horizon.log
stopwaitsecs=3600
vim /etc/supervisor/conf.d/horizon.conf
supervisorctl reread
supervisorctl update
supervisorctl start horizon

That's it for the root user. From now on, use the laravel user. Once you are logged in as laravel, setup cron to run laravel schedule. You can use crontab -e to edit the cron.

* * * * * cd /var/www/html && php artisan schedule:run >> /dev/null 2>&1

Deployments

Every time you need to deploy, you can run these commands

cd /var/www/html
git pull origin main
npm install
find node_modules/.bin/ -type f -exec chmod +x {} \;
npm run build
composer install --optimize-autoloader --no-dev
php artisan config:cache
php artisan event:cache
php artisan route:cache
php artisan view:cache
php artisan migrate --force --isolated
php artisan horizon:terminate
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment