DevOps
Debian
How to upgrade
sudo apt-get update && sudo apt-get upgrade && sudo apt-get dist-upgrade
sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak
sudo cp -R /etc/apt/sources.list.d /etc/apt/sources.list.d.bak
sudo sed -i 's/buster/bullseye/g' /etc/apt/sources.list
sudo sed -i 's/buster/bullseye/g' /etc/apt/sources.list.d/*
sudo apt-get update && sudo apt-get upgrade
sudo apt-get dist-upgrade
sudo reboot now
Install useful packages
apt-get install sudo curl redis-server imagemagick git wget unzip iptables lsb-release make -y
nginx
wget -O - https://nginx.org/keys/nginx_signing.key | apt-key add -
# Debian
echo "deb https://nginx.org/packages/debian/ $(lsb_release -sc) nginx" > /etc/apt/sources.list.d/nginx.list
# Linux Mint Cinnamon 21
echo "deb [arch=amd64] https://nginx.org/packages/ubuntu/ jammy nginx" | sudo tee /etc/apt/sources.list.d/nginx.list
echo "deb-src https://nginx.org/packages/ubuntu/ jammy nginx" | sudo tee -a /etc/apt/sources.list.d/nginx.list
apt-get update
apt-get install nginx
nano /etc/nginx/nginx.conf
user www-data;
worker_processes 2;
include /etc/nginx/sites-enabled/*;
cd /etc/nginx && mkdir sites-available && mkdir sites-enabled
nginx -t
service nginx reload
nginx -v
# chmod 0644 /var/log/nginx
server {
listen 80;
server_name website.test;
root /var/www/website.test/public;
location /tests/ {
alias /var/www/website.test/tests/_html/;
index index.html;
fastcgi_index index.html;
}
error_page 503 @maintenance;
location @maintenance {
rewrite ^(.*)$ /maintenance.html break;
}
location / {
if (-f /var/www/website.test/public/maintenance.html) {
return 503;
}
try_files $uri /index.php$is_args$args;
}
location ~ ^/index\\.php(/|$) {
fastcgi_pass unix:/run/php/php7.4-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;
}
proxy_buffer_size 512k;
proxy_buffers 4 512k;
proxy_busy_buffers_size 512k;
client_max_body_size 20M;
error_log /var/log/nginx/website.test_error.log;
access_log /var/log/nginx/website.test_access.log;
}
server {
listen 80 default_server;
server_name _ ;
root /var/www/default;
index index.html;
}
<!-- /var/www/default/index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Default page</title>
<link href="https://fonts.googleapis.com/css?family=Lato:300" rel="stylesheet" type="text/css">
<style>
* {
font-size: 24px;
font-family: Lato, sans-serif;
font-weight: 300;
}
#content {
padding-top: 70px;
}
p {
width: 370px;
margin:auto;
text-align: center;
}
</style>
</head>
<body>
<div id="content">
<p>Don't forget to configure your virtual host on nginx.</p>
</div>
</body>
</html>
server {
listen 80 default;
rewrite ^ https://yourhost.com?from=$host$request_uri?;
}
sudo apt-get install apache2-utils -y
sudo htpasswd -c /etc/nginx/.htpasswd username
sudo nano /etc/nginx/sites-available/website.dev
server {
...
location / {
try_files $uri @rewriteapp;
auth_basic "Staging - Private property";
auth_basic_user_file /etc/nginx/.htpasswd;
}
}
sudo service nginx reload
PHP
sudo apt-get install apt-transport-https lsb-release ca-certificates
# Debian
sudo wget -O /etc/apt/trusted.gpg.d/php.gpg https://packages.sury.org/php/apt.gpg
sudo echo "deb https://packages.sury.org/php/ $(lsb_release -sc) main" > /etc/apt/sources.list.d/php.list
# Linux Mint
sudo add-apt-repository ppa:ondrej/php
sudo apt-get update
# Install xdebug & pcov on dev environment only
sudo apt-get install php8.3-{fpm,cli,mysql,curl,intl,imagick,gd,sqlite3,xml,zip,mbstring,redis,msgpack,igbinary,apcu,ldap,bz2,excimer,xdebug,pcov}
# Install xdebug & pcov on dev environment only
sudo apt-get install php8.4-{fpm,cli,mysql,curl,intl,imagick,gd,sqlite3,xml,zip,mbstring,redis,msgpack,igbinary,apcu,ldap,bz2,excimer,xdebug,pcov}
# Install xdebug & pcov on dev environment only
sudo apt-get install php8.5-{fpm,cli,mysql,curl,intl,imagick,gd,sqlite3,xml,zip,mbstring,redis,msgpack,igbinary,apcu,ldap,bz2,excimer,xdebug,pcov}
sudo sed -i.bak 's#;date.timezone =#date.timezone = Europe/Brussels#g' /etc/php/8.*/*/php.ini
cd /var
mkdir www
chown -R www-data:www-data /var/www/
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
php composer-setup.php
php -r "unlink('composer-setup.php');"
sudo mv composer.phar /usr/local/bin/composer && sudo chmod a+x /usr/local/bin/composer
echo 'export PATH="$(composer config -g home)/vendor/bin:$PATH"' >> ~/.bash_profile
x="$(dpkg --list | grep php8.2 | awk '/^ii/{ print $2}')"
sudo apt-get --purge remove $x
sudo update-alternatives --set php /usr/bin/php7.4
sudo update-alternatives --set phar /usr/bin/phar7.4
sudo update-alternatives --set phar.phar /usr/bin/phar.phar7.4
sudo update-alternatives --set phpize /usr/bin/phpize7.4
sudo update-alternatives --set php-config /usr/bin/php-config7.4
sudo sed -i 's/php8.0-fpm/php8.1-fpm/g' /etc/nginx/sites-available/*
xdebug.default_enable = 1
xdebug.remote_autostart = 0
xdebug.remote_enable = 1
xdebug.remote_port = 9000
xdebug.remote_host = 192.168.33.1
xdebug.remote_handler = dbgp
xdebug.max_nesting_level = 500
xdebug.idekey = netbeans-xdebug
echo "alias sf='symfony console'" >> ~/.bash_profile && source ~/.bash_profile
MariaDB
sudo apt-get install mariadb-server mariadb-client
sudo mysql_secure_installation
# comment out bind-address in /etc/mysql/my.cnf, or /etc/mysql/mariadb.conf.d/50-server.cnf
sudo service mysql restart
sudo mysql -u root -p
CREATE USER dev IDENTIFIED BY "dev";
GRANT ALL ON *.* TO dev@"%" WITH GRANT OPTION;
CREATE USER dev@"localhost" IDENTIFIED BY "dev";
GRANT ALL ON *.* TO dev@"localhost" WITH GRANT OPTION;
FLUSH PRIVILEGES;
exit
sudo mysql -u root -p
CREATE DATABASE database_name;
CREATE USER user_name@"localhost" IDENTIFIED BY "password";
GRANT ALL ON database_name.* TO user_name@"localhost";
FLUSH PRIVILEGES;
exit
DROP USER IF EXISTS 'username'@'localhost';
DROP DATABASE IF EXISTS database_name;
Elasticsearch
Setup using Docker Compose
# docker-compose.prod.yaml
version: '3'
services:
elasticsearch_prod:
image: docker.elastic.co/elasticsearch/elasticsearch:8.17.2
environment:
- cluster.name=docker-cluster
- bootstrap.memory_lock=true
- discovery.type=single-node
- xpack.security.enabled=false
- "ES_JAVA_OPTS=-Xms512m -Xmx512m" # 512mo HEAP
ulimits:
memlock:
soft: -1
hard: -1
ports:
- 9201:9200
volumes:
- elasticsearch-prod:/usr/share/elasticsearch/data
volumes:
elasticsearch-prod:
driver: local
Start & stop the container
docker-compose -f docker-compose.prod.yaml up -d
docker-compose -f docker-compose.prod.yaml stop
# docker-compose.staging.yaml
version: '3'
services:
elasticsearch_staging:
image: docker.elastic.co/elasticsearch/elasticsearch:8.4.2
environment:
- cluster.name=docker-cluster
- bootstrap.memory_lock=true
- discovery.type=single-node
- xpack.security.enabled=false
- "ES_JAVA_OPTS=-Xms512m -Xmx512m" # 512mo HEAP
ulimits:
memlock:
soft: -1
hard: -1
ports:
- 9202:9200
volumes:
- elasticsearch-staging:/usr/share/elasticsearch/data
volumes:
elasticsearch-staging:
driver: local
Start & stop the container
docker-compose -f docker-compose.staging.yaml up -d
docker-compose -f docker-compose.staging.yaml stop
Symfony CLI
Installation
curl -1sLf 'https://dl.cloudsmith.io/public/symfony/stable/setup.deb.sh' | sudo -E bash
sudo apt install symfony-cli
Check this page for advanced configuration.
Let's Encrypt
Based on this article.
sudo apt-get update && sudo apt-get install letsencrypt -y
mkdir -p /etc/nginx/snippets
# /etc/nginx/snippets/letsencrypt.conf
location /.well-known/acme-challenge {
allow all;
auth_basic off;
default_type "text/plain";
root /var/www/letsencrypt;
}
# /etc/nginx/snippets/ssl.conf
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;
ssl_protocols TLSv1.2;
ssl_ciphers EECDH+AESGCM:EECDH+AES;
ssl_ecdh_curve secp384r1;
ssl_prefer_server_ciphers on;
ssl_stapling on;
ssl_stapling_verify on;
add_header Strict-Transport-Security "max-age=15768000; includeSubdomains; preload";
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
server {
listen 80;
listen [::]:80;
server_name --url--;
include /etc/nginx/snippets/letsencrypt.conf;
location / {
return 301 https://--url--$request_uri;
}
}
letsencrypt certonly --webroot -w /var/www/letsencrypt -d --url-- --email --email-- --agree-tos
# Append to previous code
server {
server_name --url--;
listen 443 ssl;
listen [::]:443 ssl;
http2 on;
ssl_certificate /etc/letsencrypt/live/--url--/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/--url--/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/--url--/fullchain.pem;
include /etc/nginx/snippets/ssl.conf;
root /var/www/--url--/public;
error_page 503 @maintenance;
location @maintenance {
rewrite ^(.*)$ /maintenance.html break;
}
location / {
if (-f /var/www/--url--/public/maintenance.html) {
return 503;
}
try_files $uri /index.php$is_args$args;
}
location ~ ^/index\.php(/|$) {
fastcgi_pass unix:/run/php/php8.4-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/--url--_error.log;
access_log /var/log/nginx/--url--_access.log;
}
Add the following line to /etc/letsencrypt/cli.ini:
deploy-hook = systemctl reload nginx
Miscellaneous
/etc/init.d/mpt-statusd stop
update-rc.d -f mpt-statusd remove
cd /etc/init.d && wget "https://gist.githubusercontent.com/jmsche/a070134ba2a48cd5cfd84041ab64e45e/raw/b5eab2fb87795bdee15954727d97ee71c1facbfb/firewall.sh" -O "firewall.sh"
chmod 755 firewall.sh && systemctl enable firewall.sh && service firewall.sh start
TCP_SERVICES="22 80 3306 873 443 5666" # SSH HTTP MySQL RSYNC HTTPS NRPE
REMOTE_TCP_SERVICES="80 443 25 22 366" # web browsing sending mail SSH
REMOTE_UDP_SERVICES="53" # DNS
# File location: /etc/supervisor/conf.d/*
Update scripts: supervisorctl update
Status: supervisorctl status
Start/stop script: supervisorctl start/stop dems
git config --global user.name jmsche
git config --global user.email contact+github@jmsche.fr
git config --global core.excludesfile ~/.gitignore
echo ".idea/" >> ~/.gitignore