Linux server todo, first things, first 5 minutes on HTTP server

On Ubuntu 20 LTS

uname -a ; lsb_release -a
apt update && apt upgrade -y
apt install fail2ban unattended-upgrades apt-listchanges git zip software-properties-common
ufw allow 80
ufw allow 443
ufw allow 22
ufw enable

apt-get install unattended-upgrades
nano /etc/apt/apt.conf.d/10periodic
APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Download-Upgradeable-Packages "1";
APT::Periodic::AutocleanInterval "7";
APT::Periodic::Unattended-Upgrade "1";

nano /etc/apt/apt.conf.d/50unattended-upgrades
Unattended-Upgrade::Allowed-Origins {
        "Ubuntu lucid-security";
//      "Ubuntu lucid-updates";
};
Unattended-Upgrade::Automatic-Reboot "true";


sudo dpkg-reconfigure -plow unattended-upgrades
sudo unattended-upgrades --dry-run

reboot

nginx

apt install nginx
sudo unlink /etc/nginx/sites-enabled/default
mkdir /var/www/TODO-ENTER-YOUR-DOMAIN.com
nano /etc/nginx/sites-available/TODO-ENTER-YOUR-DOMAIN.com
# paste and use nginx domain config bellow
ln -s /etc/nginx/sites-available/TODO-ENTER-YOUR-DOMAIN.com /etc/nginx/sites-enabled/
nginx -t
sudo systemctl reload nginx

nginx basic

server {
    listen 80;
    server_name TODO-ENTER-YOUR-DOMAIN.com;
    root /var/www/TODO-ENTER-YOUR-DOMAIN.com/public;

    index index.html index.htm index.php;
    
    location ~ /\. {
        deny all;
    }
    location ^~ /.well-known/ {
        allow all;
    }

    location / {
        index index.html index.php; ## Allow a static html file to be shown first
        try_files $uri $uri/ @handler; ## If missing pass the URI to Magento's front handler
        expires 30d; ## Assume all files are cachable
    }

    location @handler {
        rewrite / /index.php;
    }

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php8.1-fpm.sock;
     }

    location ~ /\.ht {
        deny all;
    }

}

nginx with HTTP auth

generate .htpasswd:

sudo apt install apache2-utils && sudo htpasswd -c /etc/apache2/.htpasswd user

nginx config with http auth

server {
    listen 80;
    server_name TODO-ENTER-YOUR-DOMAIN.com;
    root /var/www/TODO-ENTER-YOUR-DOMAIN.com/public;

    index index.html index.htm index.php;
    
    location ~ /\. {
        deny all;
    }
    location ^~ /.well-known/ {
        allow all;
    }

    location / {
        satisfy any;
        allow 127.0.0.1;
        deny  all;
        auth_basic           "HTTP auth";
        auth_basic_user_file /etc/apache2/.htpasswd; 
    
        index index.html index.php;
        try_files $uri $uri/ @handler;
        expires 30d;
    }

    location @handler {
        rewrite / /index.php;
    }

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php8.1-fpm.sock;
     }

    location ~ /\.ht {
        deny all;
    }

}

HTTPS

apt install certbot python3-certbot-nginx
certbot --nginx -d TODO-ENTER-YOUR-DOMAIN.com
systemctl status certbot.timer
certbot renew --dry-run

PHP

sudo add-apt-repository ppa:ondrej/php -y
apt install php8.1 php8.1-fpm php8.1-common php8.1-pdo php8.1-pgsql php8.1-intl php8.1-mbstring php8.1-xml php8.1-dom php8.1-xml  php8.1-curl php8.1-gd php8.1-imagick php8.1-cli php8.1-dev php8.1-imap php8.1-opcache php8.1-zip php8.1-redis php8.1-intl

composer

php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
php -r "if (hash_file('sha384', 'composer-setup.php') === '906a84df04cea2aa72f40b5f787e49f22d4c2f19492ac310e8cba5b96ac8b64115ac402c8cd292b8a03482574915d1a8') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
php composer-setup.php
php -r "unlink('composer-setup.php');"
sudo mv composer.phar /usr/local/bin/composer

Symfony

wget https://get.symfony.com/cli/installer -O - | bash
mv /root/.symfony/bin/symfony /usr/local/bin/symfony
symfony check:requirements

node

curl -fsSL https://deb.nodesource.com/setup_16.x | sudo -E bash -
apt-get install -y nodejs
npm install
npm install --global yarn

PostgreSQL

sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list'
wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -
apt update && apt upgrade
sudo apt install postgresql-14 postgresql-client-14
sudo -u postgres psql
CREATE DATABASE yourdbname;
CREATE USER youruser WITH ENCRYPTED PASSWORD 'yourpass';
GRANT ALL PRIVILEGES ON DATABASE yourdbname TO youruser;
exit

mySQL

CREATE DATABASE example_database;
CREATE USER 'example_user'@'%' IDENTIFIED WITH mysql_native_password BY 'password';
GRANT ALL ON example_database.* TO 'example_user'@'%';

to install mysql 5.7: https://www.vultr.com/docs/how-to-install-mysql-5-7-on-ubuntu-20-04/

git global

git config --global user.name "YOUR-SERVER-DOMAIN.COM"
git config --global user.email "[email protected]"

deploy

ssh-keygen -t ed25519 -C "[email protected]"
cat /root/.ssh/id_ed25519.pub
# add public ssh key to your repo config, at least read only
cd /var/www/TODO-ENTER-YOUR-DOMAIN.com
git clone enterYourGitRepoAddress /var/www/TODO-ENTER-YOUR-DOMAIN.com
composer install --no-dev --classmap-authoritative --no-interaction
composer dump-env prod
php bin/console doctrine:database:create
php bin/console doctrine:migrations:migrate --all-or-nothing --no-interaction
php bin/console app:execute-one-time
npm install
yarn encore production

permissions

chmod -R 750 /var/www/YOUR-DOMAIN.COM/var
chown -R www-data:www-data /var/www/YOUR-DOMAIN.COM
chmod +x ./bin/console;

DB backup

sudo -u postgres -i pg_dump database_name > /var/zzzz_database_backup/database_name_"$(date +%Y-%m-%d_%H%M%S)".sql

other

rm -r ./var/cache/prod

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

composer install --optimize-autoloader --no-dev --no-interaction # for testing and fast updates, autoloader without cache

sudo lsof -i -P | grep LISTEN | grep :$PORT # check ports usage