Riepilogo post nella categoria PHP Freelance

Nota: questa guida creata da Maurizio Fonte è anche disponibile come Repository GitHub all'indirizzo github.com/mauriziofonte/win11-wsl2-ubuntu22-setup.

Questo progetto è destinato a guidare lo sviluppatore attraverso l'installazione e la configurazione di uno Stack LAMP rivolto a Windows 11 e Windows 10 (versione 1903, build 18362 o successive), tramite l'utilizzo di WSL2 e Ubuntu 22.04, con lo Stack Lamp che opererà tramite servizi systemd nativi al posto di usare container o virtualizzazione.

Ma perché utilizzare Windows 10/11, e perché servizi systemd nativi invece di contenitori?

Durante i miei anni di esperienza sul campo, ho creato un flusso di lavoro di mio gusto personale che permette a uno sviluppatore di:

  • Utilizzare MS Windows quando questo è il sistema operativo usato abitualmente, senza dover migrare su Linux o utilizzare VirtualBox o similari;
  • Utilizzare il terminale Linux con tutte le ottimizzazioni delle prestazioni rese possibili da WSL2, e in particolare utilizzare Ubuntu in quanto la sua base utente è consistente: se incontri un problema, o hai bisogno di un pacchetto specifico, c'è una buona probabilità che troverai informazioni su come risolvere il problema o completare la task in pochi minuti;
  • Utilizzare servizi systemd nativi (Apache e MariaDB) invece di fare affidamento su contenitori come Docker. Anche se, in realtà, le prestazioni di Docker sono quasi identiche alle prestazioni native in Linux, la mia opinione personale è che, se un cliente ha la propria VM o hosting condiviso o server voodoo in cui la "Dockerizzazione" non è tecnicamente fattibile, allora il flusso di lavoro, sviluppo, test e benchmark dovrebbero essere quanto più possibile aderenti a ciò che sarà l'ambiente di produzione.
    Detto ciò, questo significa avere un set di strumenti che permetta allo sviluppatore di implementare, testare e fare benchmark su varie tipologie di versioni e configurazioni PHP che saranno disponibili nel server di produzione.

Come sarà configurato lo Stack LAMP?

Lo stack sarà opportunamente configurato e ottimizzato in modo da:

  • Utilizzare il repository ppa:ondrej/php per PHP, che permette di installare versioni PHP dalla 5.6 fino all'8.2 (Nota: PHP 8.3 è ancora in beta ed è prevista la sua uscita il 23 novembre 2023.);
  • Utilizzare il repository ppa:ondrej/apache2 per il Webserver Apache;
  • Utilizzare lo strumento mfonte/hte-cli per gestire i Virtualhost di Apache. Questo strumento può essere utilizzato per creare, eliminare e elencare virtualhost specificamente ottimizzati per lo sviluppo locale/test;
  • Far funzionare i Virtualhost di Apache tramite PHP-FPM e dare allo sviluppatore comandi di deploy rapidi per configurare un VirtualHost locale nativo situato nella macchina Ubuntu;
  • Lasciare libertà allo sviluppatore riguardo alla scelta della versione PHP target del VirtualHost distribuito localmente;
  • Utilizzare MariaDB 10.6 e utilizzare una opportuna configurazione del server Mysql in modo tale da non avere problemi durante lo sviluppo e i test.

Istruzioni per l'installazione

Le istruzioni sono le medesime sia per Windows 11 sia per Windows 10 (dove cambia solo un flag dello script PowerShell da eseguire)

Installazione automatica su Windows 11

Sebbene non sia consigliata, perchè molti aspetti della configurazione rimarranno oscuri e dovrai documentarti successivamente, per installare tutto il necessario è sufficiente eseguire su una PowerShell elevata a Privilegi di Amministratore (Esegui come amministratore) ed incollare questo snippet:

Set-ExecutionPolicy RemoteSigned -Scope CurrentUser -Force; $desktopPath = [Environment]::GetFolderPath('Desktop'); $url = 'https://raw.githubusercontent.com/mauriziofonte/win11-wsl2-ubuntu22-setup/main/install/win11.ps1'; $outputPath = Join-Path -Path $desktopPath -ChildPath 'install-ubuntu22-wsl2.ps1'; (New-Object System.Net.WebClient).DownloadFile($url, $outputPath); & $outputPath

Installazione automatica su Windows 10

L'installazione automatica su Windows 10 è funzionante a patto che la versione di Windows 10 sia la 1903, build 18362 o successive. Come sopra, eseguire su una PowerShell elevata a Privilegi di Amministratore (Esegui come amministratore) ed incollare questo snippet:

Set-ExecutionPolicy RemoteSigned -Scope CurrentUser -Force; $desktopPath = [Environment]::GetFolderPath('Desktop'); $url = 'https://raw.githubusercontent.com/mauriziofonte/win11-wsl2-ubuntu22-setup/main/install/win11.ps1'; $outputPath = Join-Path -Path $desktopPath -ChildPath 'install-ubuntu22-wsl2.ps1'; (New-Object System.Net.WebClient).DownloadFile($url, $outputPath); & $outputPath -SkipWindowsVersionCheck

Installazione Manuale

Per eseguire una installazione manuale, si riporta la guida completa che è reperibile in italiano sul Repository Github di questo progetto, a questo indirizzo: github.com/mauriziofonte/win11-wsl2-ubuntu22-setup/blob/main/docs/it/SETUP-IT.md

Setup manuale stack LAMP su Windows 11 con WSL2, servizi web nativi, VS Code e Ubuntu 22.04 (senza Microsoft Store)

Ultimo aggiornamento: 04/09/2023. Versione target Ubuntu: 22.04.03

Questa guida illustrerà come installare il supporto al sottosistema Linux nativo di Windows (WSL2), installare Ubuntu 22.04 (senza dover utilizzare il Microsoft Store), creare uno stack LAMP multi-PHP (con servizi nativi tramite systemd) e agganciare Visual Studio Code da Windows 11, per sviluppare e debuggare direttamente sulla macchina virtuale.

Requisiti

  1. Computer con Windows 11, preferibilmente aggiornato tramite Windows Update
  2. 16GB di RAM
  3. Almeno 50GB di spazio libero su C:\ (conterrà il disco virtuale di Ubuntu 22.04)
  4. Un SSD (meglio se NVMe) come disco principale di Windows
  5. Una conoscenza di medio livello del terminale Linux (come usare e cosa sono comandi di base come cd, cp, mv, sudo, nano, etc.)
  6. Il vostro computer dovrebbe essere protetto da password, usare BitLocker, e disporre di supporto a TPM 2.0 per evitare che malintenzionati possano accedere ad informazioni sensibili, se entrassero in possesso del vostro dispositivo. Questo è particolarmente importante se intendete maneggiare informazioni per conto terzi (lavoro). Le vostre politiche di sicurezza sulla rete e i dispositivi che utilizzate dovrebbero essere consone al tipo di uso del PC che intendete effettuare. In linea generale, se usate il vostro PC per lavoro, bisogna porre massima attenzione alla protezione. Prevenire è meglio che curare.

Lo stack LAMP che andremo a configurare supporta https (con certificati autofirmati con scadenza a 30 anni), protocollo http/2 e compressione brotli. Per quanto riguarda la parte PHP, useremo PHP-FPM perchè è più performante e più versatile nella configurazione delle impostazioni per-virtualhost. Per capire le differenze tra l'utilizzo di PHP con Apache in modalità PHP-CGI piuttosto che PHP-FPM, si rimanda a questa guida: https://www.basezap.com/difference-php-cgi-php-fpm/

Installare Ubuntu 22.04 LTS su Windows in virtualizzazione WSL2

Per installare Ubuntu 22.04 su Windows 11, useremo solo la PowerShell di Windows, senza ricorrere al Microsoft Store. Importante: assicurarsi di avviare la powershell in modalità amministratore.

Per prima cosa, scaricare ed installare https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_x64.msi. Questo è importante. E' un pacchetto aggiuntivo che installa l'aggiornamento Linux Kernel Update, necessario per compatibilità con WSL2.

Dopodichè, eseguire su una PowerShell elevata a privilegi di amministratore questi comandi:

dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
Restart-Computer -Force

Attendere il riavvio del PC, dopodichè eseguire su una PowerShell elevata a privilegi di amministratore questi comandi:

wsl --update --web-download
wsl --set-default-version 2
wsl --version
wsl --list --online

Il comando wsl --version ritornerà le informazioni sulla versione del sottosistema linux per windows. Qui un esempio di output aggiornato ad Agosto 2023:

Versione WSL: 1.2.5.0
Versione kernel: 5.15.90.1
Versione WSLg: 1.0.51
Versione MSRDC: 1.2.3770
Versione Direct3D: 1.608.2-61064218
Versione DXCore: 10.0.25131.1002-220531-1700.rs-onecore-base2-hyp
Versione di Windows: 10.0.22621.2134

Dobbiamo assicurarci che la versione WSL sia maggiore o uguale alla 0.67.6. Nell'esempio sopra riportato, è tutto OK.

Il comando wsl --list --online ritornerà le distribuzioni installabili. Qui un esempio di output aggiornato ad Agosto 2023:

NAME                                   FRIENDLY NAME
Ubuntu                                 Ubuntu
Debian                                 Debian GNU/Linux
kali-linux                             Kali Linux Rolling
Ubuntu-18.04                           Ubuntu 18.04 LTS
Ubuntu-20.04                           Ubuntu 20.04 LTS
Ubuntu-22.04                           Ubuntu 22.04 LTS
OracleLinux_7_9                        Oracle Linux 7.9
OracleLinux_8_7                        Oracle Linux 8.7
OracleLinux_9_1                        Oracle Linux 9.1
openSUSE-Leap-15.5                     openSUSE Leap 15.5
SUSE-Linux-Enterprise-Server-15-SP4    SUSE Linux Enterprise Server 15 SP4
SUSE-Linux-Enterprise-15-SP5           SUSE Linux Enterprise 15 SP5
openSUSE-Tumbleweed                    openSUSE Tumbleweed

Noi siamo interessati alla distribuzione Ubuntu-22.04. Quindi, eseguire questo comando su una PowerShell elevata a privilegi di amministratore:

wsl --install -d Ubuntu-22.04

Al termine dell'installazione, in assenza di errori, verrà automaticamente aperta l'istanza della macchina Ubuntu appena installata. Il sistema Ubuntu richiederà di impostare un nome utente (occhio, serve sotto ed è importante) -- consiglio di usare una singola parola corta digitata tutta in minuscolo -- e di specificare una password per questo utente -- consiglio di usare una sola lettera, per comodità quando si eseguiranno comandi da sudoer --

Modificare il resolver DNS di Ubuntu

Per risolvere permanentemente il problema della risoluzione nomi dominio DNS di Ubuntu via WSL2, seguire queste istruzioni. La procedura richiederà sia l'utilizzo della bash di Ubuntu, sia una PowerShell elevata a privilegi di amministratore:

Su Ubuntu 22.04

sudo su -
echo "[network]" | tee /etc/wsl.conf
echo "generateResolvConf = false" | tee -a /etc/wsl.conf

Su Windows, Powershell

wsl --terminate Ubuntu-22.04

Su Ubuntu 22.04 (da avviare nuovamente, perchè il comando precedente lo avrà terminato)

sudo su -
rm -f /etc/resolv.conf
echo "nameserver 9.9.9.9" | tee /etc/resolv.conf
echo "nameserver 1.1.1.1" | tee -a /etc/resolv.conf
echo "nameserver 216.87.84.211" | tee -a /etc/resolv.conf
echo "nameserver 208.67.222.222" | tee -a /etc/resolv.conf
chattr +i /etc/resolv.conf

Su Windows, Powershell

wsl --terminate Ubuntu-22.04
Get-NetAdapter

Ora, leggere l'output del comando Get-NetAdapter. Questo comando listerà tutte le interfacce di rete del PC. Noi siamo interessati alla interfacce che si collegano ad internet.

Ecco un esempio di output:

Name                      InterfaceDescription                    ifIndex Status       MacAddress             LinkSpeed
----                      --------------------                    ------- ------       ----------             ---------
Wi-Fi                     Intel(R) Wi-Fi 6E AX210 160MHz               15 Up           4C-77-CB-79-06-03       1.7 Gbps
Connessione di rete Bl... Bluetooth Device (Personal Area Netw...      12 Disconnected 4C-77-CB-79-06-07         3 Mbps
Ethernet                  Intel(R) Ethernet Connection (14) I2...       9 Disconnected A0-29-19-0B-74-1E          0 bps

Nell'esempio sopra, l'intefaccia utilizzata per collegarsi ad internet è Intel(R) Wi-Fi 6E AX210 160MHz, il cui ifIndex è 15.

Quindi, prendere nota del ifIndex corretto, ed eseguire una PowerShell elevata a privilegi di amministratore:

Set-NetIPInterface -InterfaceIndex [NUMERO_IFINDEX] -InterfaceMetric 6000

Con queste istruzioni la macchina Ubuntu 22.04 non dovrebbe avere nessun problema di risoluzione nomi a dominio.

Abilitare systemd su WSL2

Systemd è una suite di elementi costitutivi di base per un sistema Linux. Fornisce un gestore di sistema e servizi che viene eseguito come PID 1 e avvia il resto del sistema.
Molte distribuzioni popolari eseguono systemd per impostazione predefinita, come Ubuntu e Debian. Questa modifica significa che WSL sarà ancora più simile all'utilizzo delle tue distribuzioni Linux preferite su una macchina bare metal e ti consentirà di utilizzare software che dipende dal supporto systemd.

Abilitare systemd è relativamente semplice. Basterà lanciare questo comando su Ubuntu:

sudo su -
echo "[boot]" | tee -a /etc/wsl.conf
echo "systemd = true" | tee -a /etc/wsl.conf

Su Windows, Powershell

wsl --shutdown

Dopodichè, riavviare la macchina Ubuntu.

Step 1 - Configurare l'ambiente LAMP su Ubuntu

Qui andremo ad installare tutti i servizi e gli eseguibili di sistema per abilitare il supporto a PHP versioni 5.6, 7.0, 7.1, 7.2, 7.3, 7.4, 8.0, 8.1 e 8.2. Abiliteremo anche il web server Apache e il server Mysql.

Perchè installare tante versioni di PHP? E' importante per due motivi:

  1. avere a disposizione un ambiente di sviluppo che consenta, con facilità, di testare la propria applicazione con svariate versioni di PHP. Questo agevolerà il lavoro in caso di constraint specifici sui server di produzione dove andremo ad installare le applicazioni create.
  2. in caso un Cliente o un progetto specifico vi richieda di mantenere e/o modificare una vecchia base di codice funzionante su una specifica versione di PHP, non avrete difficoltà a rendere funzionante l'ambiente di dev&test in locale.

Si presume che la versione di default di PHP che si vorrà utilizzare nel sistema sia la 8.2. Questo è modificabile tramite le righe update-alternatives --set php*** che si troveranno nella lista qui sotto. Ad esempio, se si desidera che la versione di PHP di default (quella che verrà utilizzata digitando semplicemente il comando php e non la sua versione "versionata" es php7.4) basterà specificare update-alternatives --set php /usr/bin/php7.4. (Ad ogni modo, questo comportamento verrà in ogni caso modificato con i Bash Alias che andremo a configurare più tardi)

IMPORTANTE: Lanciare tutti questi comando come l'utente root su Ubuntu (il comando sudo su -). IMPORTANTE: Escludere le linee che iniziano con # in quanto servono solo a differenziare i vari blocchi.

# APACHE + Multi-PHP-FPM + Redis
sudo su -
apt update && apt upgrade
apt install -y net-tools zip unzip git redis-server lsb-release ca-certificates apt-transport-https software-properties-common
LC_ALL=C.UTF-8 add-apt-repository ppa:ondrej/php
LC_ALL=C.UTF-8 add-apt-repository ppa:ondrej/apache2
apt update && apt upgrade
PHPVERS="8.2 8.1 8.0 7.4 7.3 7.2 7.1 7.0 5.6"
PHPMODS="cli fpm common bcmath bz2 curl gd intl mbstring mcrypt mysql opcache sqlite3 redis xml zip"
APTPACKS=$(for VER in $PHPVERS; do echo -n "libapache2-mod-php$VER php$VER "; for MOD in $PHPMODS; do echo -n "php$VER-$MOD "; done; done)
apt install -y apache2 brotli openssl libapache2-mod-fcgid $APTPACKS
a2dismod $(for VER in $PHPVERS; do echo -n "php$VER "; done) mpm_prefork
a2enconf $(for VER in $PHPVERS; do echo -n "php$VER-fpm "; done)
a2enmod actions fcgid alias proxy_fcgi setenvif rewrite headers ssl http2 mpm_event brotli
a2dissite 000-default
systemctl enable apache2.service
systemctl restart apache2.service
systemctl enable redis-server.service
systemctl start redis-server.service
update-alternatives --set php /usr/bin/php8.2
update-alternatives --set phar /usr/bin/phar8.2
update-alternatives --set phar.phar /usr/bin/phar.phar8.2

# MYSQL
sudo su -
apt install mariadb-server
systemctl enable mariadb.service
systemctl start mariadb.service
mysql_secure_installation
[digitare questa sequenza di risposte: ENTER + n + Y + "YOUR-ROOT-PASS" + "YOUR-ROOT-PASS" + Y + Y + Y + Y]
mysql -u root -p
DIGITARE "YOUR-ROOT-PASS"
> GRANT ALL ON *.* TO 'admin'@'localhost' IDENTIFIED BY 'YOUR-ADMIN-PASS' WITH GRANT OPTION;
> GRANT ALL ON *.* TO 'admin'@'127.0.0.1' IDENTIFIED BY 'YOUR-ADMIN-PASS' WITH GRANT OPTION;
> FLUSH PRIVILEGES;
> exit

Eseguiti questi comandi, saranno installati tutti i servizi e gli eseguibili necessari per realizzare uno stack LAMP (Linux, Apache, Mysql, PHP) in modalità multi-PHP (multiple versioni di PHP) con PHP-FPM per incrementare le performance.

Nota: le query mysql relative allo username e password (admin e YOUR-ADMIN-PASS) da creare come utente privilegiato possono essere modificate a piacimento.
Nell'esempio sopra riportato viene creato un utente con username admin e password YOUR-ADMIN-PASS. C'è da dire che stiamo configurando un ambiente di sviluppo locale, e fintanto che questo ambiente non viene esposto in internet, non dobbiamo preoccuparci di usare policy particolari riguardanti i nomi utente e la complessità delle password.
Tuttavia, tengo a precisare che usare nomi utente "facilmente guessabili" e password "ben note" è una bad practice.

Step 2 - Configurare l'ambiente LAMP su Ubuntu

Qui andremo a modificare le configurazioni di base di Apache e Mysql per poter lavorare localmente.

Si riporta il nome del file da modificare, e il contenuto modificato e commentato. Ogni modifica a questi file deve essere eseguita con sudo nano NOME_FILE. E' richiesta dimestichezza con lo strumento nano. In alternativa, usare l'editor di testo più comodo.

A. Modificare gli envvars di Apache

Nome file: /etc/apache2/envvars

Sintesi: modificare APACHE_RUN_USER e APACHE_RUN_GROUP settandoli, al posto che www-data, con il proprio nome utente (dove c'è scritto IL_TUO_NOME_UTENTE)

Contenuto:

# envvars - default environment variables for apache2ctl

# this won't be correct after changing uid
unset HOME

# for supporting multiple apache2 instances
if [ "${APACHE_CONFDIR##/etc/apache2-}" != "${APACHE_CONFDIR}" ] ; then
    SUFFIX="-${APACHE_CONFDIR##/etc/apache2-}"
else
    SUFFIX=
fi

# Since there is no sane way to get the parsed apache2 config in scripts, some
# settings are defined via environment variables and then used in apache2ctl,
# /etc/init.d/apache2, /etc/logrotate.d/apache2, etc.
export APACHE_RUN_USER=IL_TUO_NOME_UTENTE
export APACHE_RUN_GROUP=IL_TUO_NOME_UTENTE

B. Modificare le Porte di Apache

Nome file: /etc/apache2/ports.conf

Sintesi: modificare ogni occorrenza di Listen con Listen 127.0.0.1 (indirizzo ip di loopback + porta: 127.0.0.1:80 127.0.0.1:443)

Contenuto:

# If you just change the port or add more ports here, you will likely also
# have to change the VirtualHost statement in
# /etc/apache2/sites-enabled/000-default.conf

Listen 127.0.0.1:80

<IfModule ssl_module>
    Listen 127.0.0.1:443
</IfModule>

<IfModule mod_gnutls.c>
    Listen 127.0.0.1:443
</IfModule>

C. Modificare la configurazione di Mysql

Nome file: /etc/mysql/mariadb.conf.d/99-custom.cnf

Sintesi: adattare la configurazione di Mysql in modo da usare l'autenticazione nativa, una collation di default adeguata, e una modalità di esecuzione delle query "che non dia problemi di compatibilità" (riferimento: https://dev.mysql.com/doc/refman/8.0/en/sql-mode.html#sqlmode_no_engine_substitution).
Inoltre, imposteremo alcune configurazioni specifiche per aumentare le performance in lettura/scrittura (attenzione: bisogna avere un quantitativo adeguato di RAM a disposizione)

Contenuto:

[mysqld]

bind-address = 127.0.0.1
skip-external-locking
skip-name-resolve
max-allowed-packet = 256M
max-connect-errors = 1000000
default-authentication-plugin=mysql_native_password
sql_mode=NO_ENGINE_SUBSTITUTION
collation-server = utf8_unicode_ci
character-set-server = utf8

# === InnoDB Settings ===
default_storage_engine          = InnoDB
innodb_buffer_pool_instances    = 4
innodb_buffer_pool_size         = 4G
innodb_file_per_table           = 1
innodb_flush_log_at_trx_commit  = 0
innodb_flush_method             = O_DIRECT
innodb_log_buffer_size          = 16M
innodb_log_file_size            = 1G
innodb_sort_buffer_size         = 4M
innodb_stats_on_metadata        = 0
innodb_read_io_threads          = 64
innodb_write_io_threads         = 64

# === MyISAM Settings ===
query_cache_limit               = 4M
query_cache_size                = 64M
query_cache_type                = 1
key_buffer_size                 = 24M
low_priority_updates            = 1
concurrent_insert               = 2

# === Connection Settings ===
max_connections                 = 20
back_log                        = 512
thread_cache_size               = 100
thread_stack                    = 192K
interactive_timeout             = 180
wait_timeout                    = 180

# === Buffer Settings ===
join_buffer_size                = 4M
read_buffer_size                = 3M
read_rnd_buffer_size            = 4M
sort_buffer_size                = 4M

# === Table Settings ===
table_definition_cache          = 40000
table_open_cache                = 40000
open_files_limit                = 60000
max_heap_table_size             = 128M 
tmp_table_size                  = 128M

# === Binary Logging ===
disable_log_bin                 = 1

[mysqldump]
quick
quote_names
max_allowed_packet              = 1024M

D. Riavviare i servizi

Una volta completate le modifiche alle configurazioni di Apache e MariaDB, possiamo riavviare i servizi

sudo su -
systemctl restart apache2.service
systemctl restart mariadb.service

Step 3 - Configurare l'ambiente PHP con Composer e HTE-Cli

Adesso che abbiamo creato e configurato lo stack LAMP, non ce ne facciamo nulla se non creiamo dei VirtualHost per svilupare o testare applicazioni web sulle diverse versioni di PHP installate sul sistema.

Per creare dei VirtualHost utilizzeremo HTE-Cli, un tool di mia creazione pensato per agevolare la configurazione di environment di test su nomi dominio fittizi via modifica del file hosts di Windows.

Il tool HTE-Cli si occuperà di auto-configurare quello che serve sulla base di alcune informazioni basilari per il progetto che vogliamo svlippare o testare.

Inoltre, nel prosieguo del nostro lavoro avremo anche a che fare con Composer. In questa parte andremo a configurare Composer per sfruttarlo non solo per HTE-Cli, ma anche per PHP Code Sniffer e PHP CS Fixer, che ci serviranno per lo sviluppo con VS Code.

NOTA : per saperne di più su HTE-Cli, leggere il README dedicato di HTE-Cli

Installazione di Composer 2 e Composer 1

Per installare l'ultima versione stabile (2.x) di Composer globalmente, eseguire questo comando:

wget -O composer.phar https://getcomposer.org/download/latest-stable/composer.phar && sudo mkdir -p /usr/local/bin && sudo mv composer.phar /usr/local/bin/composer && sudo chmod +x /usr/local/bin/composer

ATTENZIONE : Composer 2 non è compatibile con versioni di PHP minori della 7.2.5. Per usare Composer su progetti che richiedono PHP 7.2, 7.1, 7.0 o 5.6 sarà quindi necessario utilizzare il vecchio binario di Composer 1

Per installare l'ultima versione del vecchio Composer 1.x, (compatibile su PHP 7.2, 7.1, 7.0 e 5.6), eseguire questo comando:

wget -O composer-oldstable.phar https://getcomposer.org/download/latest-1.x/composer.phar && sudo mkdir -p /usr/local/bin && sudo mv composer-oldstable.phar /usr/local/bin/composer1 && sudo chmod +x /usr/local/bin/composer1

NOTA : per mantenere questi binari aggiornati, sarà sufficiente eseguire sudo /usr/local/bin/composer self-update && sudo /usr/local/bin/composer1 self-update

Installare il supporto per HTE-Cli, PHP Code Sniffer e PHP CS Fixer

Per installare il supporto a questi tool, eseguire questi comandi:

composer global require --dev friendsofphp/php-cs-fixer
composer global require --dev "squizlabs/php_codesniffer=*"
composer global require "mfonte/hte-cli=*"
echo 'export PATH="$(composer config -g home)/vendor/bin:$PATH"' >> ~/.bashrc

NOTA : per mantenere questi pacchetti aggiornati, sarà sufficiente eseguire composer global update
ATTENZIONE : la directory di installazione dei pacchetti su Ubuntu 22.04 sarà ~/.config/composer e non ~/.composer come ci si potrebbe aspettare: qui la spiegazione

Configurare gli Alias Bash

Ora che abbiamo installato tutto, non ci resta che creare dei Bash Aliases che velocizzino il lavoro.

Lanciare quindi nano .bash_aliases (oppure vim .bash_aliases) e incollare questi alias:

alias hte="sudo /usr/bin/php8.2 -d allow_url_fopen=1 -d memory_limit=1024M ~/.config/composer/vendor/bin/hte-cli create"
alias hte-create="sudo /usr/bin/php8.2 -d allow_url_fopen=1 -d memory_limit=1024M ~/.config/composer/vendor/bin/hte-cli create"
alias hte-remove="sudo /usr/bin/php8.2 -d allow_url_fopen=1 -d memory_limit=1024M ~/.config/composer/vendor/bin/hte-cli remove"
alias hte-details="sudo /usr/bin/php8.2 -d allow_url_fopen=1 -d memory_limit=1024M ~/.config/composer/vendor/bin/hte-cli details"
alias composer-self-update="sudo /usr/local/bin/composer self-update && sudo /usr/local/bin/composer1 self-update"
alias composer-packages-update="composer global update"
alias composer="/usr/bin/php8.2 -d allow_url_fopen=1 -d memory_limit=1024M /usr/local/bin/composer"
alias composer82="/usr/bin/php8.1 -d allow_url_fopen=1 -d memory_limit=1024M /usr/local/bin/composer"
alias composer81="/usr/bin/php8.1 -d allow_url_fopen=1 -d memory_limit=1024M /usr/local/bin/composer"
alias composer80="/usr/bin/php8.0 -d allow_url_fopen=1 -d memory_limit=1024M /usr/local/bin/composer"
alias composer74="/usr/bin/php7.4 -d allow_url_fopen=1 -d memory_limit=1024M /usr/local/bin/composer"
alias composer73="/usr/bin/php7.3 -d allow_url_fopen=1 -d memory_limit=1024M /usr/local/bin/composer"
alias composer72="/usr/bin/php7.2 -d allow_url_fopen=1 -d memory_limit=1024M /usr/local/bin/composer"
alias 1composer72="/usr/bin/php7.2 -d allow_url_fopen=1 -d memory_limit=1024M /usr/local/bin/composer1"
alias 1composer71="/usr/bin/php7.1 -d allow_url_fopen=1 -d memory_limit=1024M /usr/local/bin/composer1"
alias 1composer70="/usr/bin/php7.0 -d allow_url_fopen=1 -d memory_limit=1024M /usr/local/bin/composer1"
alias 1composer56="/usr/bin/php5.6 -d allow_url_fopen=1 -d memory_limit=1024M /usr/local/bin/composer1"
alias php="/usr/bin/php8.2 -d allow_url_fopen=1 -d memory_limit=1024M"
alias php82="/usr/bin/php8.2 -d allow_url_fopen=1 -d memory_limit=1024M"
alias php81="/usr/bin/php8.1 -d allow_url_fopen=1 -d memory_limit=1024M"
alias php80="/usr/bin/php8.0 -d allow_url_fopen=1 -d memory_limit=1024M"
alias php74="/usr/bin/php7.4 -d allow_url_fopen=1 -d memory_limit=1024M"
alias php73="/usr/bin/php7.3 -d allow_url_fopen=1 -d memory_limit=1024M"
alias php72="/usr/bin/php7.2 -d allow_url_fopen=1 -d memory_limit=1024M"
alias php71="/usr/bin/php7.1 -d allow_url_fopen=1 -d memory_limit=1024M"
alias php70="/usr/bin/php7.0 -d allow_url_fopen=1 -d memory_limit=1024M"
alias php56="/usr/bin/php5.6 -d allow_url_fopen=1 -d memory_limit=1024M"
alias wslrestart="history -a && cmd.exe /C wsl --shutdown"

Una volta finito l'editing del file .bash_aliases, eseguire

source ~/.bash_aliases

Con questa configurazione di .bash_aliases abbiamo:

  1. Aliasato il tool HTE-Cli (che, ricordo, serve per gestire i VirtualHost sul sistema) con 4 differenti comandi: hte, hte-create, hte-remove, hte-details
  2. Creato un alias per aggiornare i binari di Composer (installati come binari di sistema su /usr/local/bin) con il comando composer-self-update. Questo alias aggiornerà sia Composer 2 sia Composer 1 in una volta sola.
  3. Creato un alias per aggiornare i pacchetti di Composer installati globalmente con il comando composer-packages-update
  4. Creato svariati alias per i flavour di utilizzo di Composer corrispondenti alle versioni target di PHP che sono installate sul sistema. In sintesi, il comando composer utilizzerà PHP 8.2, composer81 utilizzerà PHP 8.1, composer80 utilizzerà PHP 8.0, e così via fino a composer72 che utilizzerà PHP 7.2. Parimenti, per utilizzare il vecchio Composer 1 per sviluppare su progetti datati, basterà usare 1composer72, oppure 1composer71, oppure 1composer70, oppure 1composer56
  5. Creato svariati alias per richiamare il binario di PHP su tutte le versioni installate sul sistema, quindi php utilizzerà PHP 8.2, php81 utilizzerà PHP 8.1, e così via fino a php56 che utilizzerà PHP 5.6
  6. Fatto in modo che sia gli alias riguardanti composer sia gli alias riguardanti php lavorino con due configurazioni specifiche: allow_url_fopen settato su 1, cioè attivo, e memory_limit settato su 1024M.
  7. Creato un alias per fare il reset della macchina virtuale Ubuntu con il comando wslrestart

Perchè impostare un limite di memoria per gli alias di PHP e Composer? Perchè di default il limite di memoria sarebbe "nessun limite". Questo è pericoloso, perchè oscura eventuali potenziali problematiche sul binario di Composer stesso, e più in generale sui comandi che lanciamo via command line. Avere un limite di memoria non infinito per l'esecuzione è sempre buona prassi, perchè evita brutte sorprese poi in produzione.

Testare la configurazione creando un VirtualHost per PhpMyAdmin

A mero titolo esemplificativo, verrà mostrata l'intera procedura di creazione di un VirtualHost funzionante, che esponga l'applicativo PhpMyAdmin sulla macchina locale. Questa installazione potrà essere di aiuto nel caso in cui si decida di continuare ad utilizzarla per navigare tra i Database Mysql presenti sul sistema, e i dati contenuti all'interno di essi.

cd ~/
mkdir opt && cd opt/
wget https://files.phpmyadmin.net/phpMyAdmin/5.2.1/phpMyAdmin-5.2.1-all-languages.zip
unzip phpMyAdmin-5.2.1-all-languages.zip && rm -f phpMyAdmin-5.2.1-all-languages.zip && mv phpMyAdmin-5.2.1-all-languages phpmyadmin

Ora abbiamo creato la directory radice per l'installazione di PhpMyAdmin. Non resta che configurare un VirtualHost funzionante.

IMPORTANTE : le istruzioni che seguono si applicano a tutti gli ambienti di staging/test locali che si vorranno abilitare sul sistema tramite il tool HTE-Cli

maurizio:~ $ hte-create
[sudo] password for maurizio:
   __ __ ______ ____      _____ __ _
  / // //_  __// __/____ / ___// /(_)
 / _  /  / /  / _/ /___// /__ / // /
/_//_/  /_/  /___/      \___//_//_/

[H]andle [T]est [E]nvironment Cli Tool version 1.0.5 by Maurizio Fonte
WARNING: THIS TOOL IS *NOT* INTENDED FOR LIVE SERVERS. Use it only on local/firewalled networks.

 ? Enter a valid local Domain Name (suggested .test TLD, as "jane.local.test") []:
 > local.phpmyadmin.test

 ? Enter a valid directory in the filesystem for the DocumentRoot [/home/maurizio]:
 > /home/maurizio/opt/phpmyadmin/

 ? Enter a valid PHP version for PHP-FPM (5.6, 7.0, 7.1, 7.2, 7.3, 7.4, 8.0, 8.1, 8.2) [8.2]:
 > 8.2

 ? Do you need HTTPS support? ["yes", "no", "y" or "n"] [y]:
 > y

 ? Do you want to force HTTPS? ["yes", "no", "y" or "n"] [y]:
 > y

⏳ VirtualHost configuration for local.phpmyadmin.test created at /etc/apache2/sites-available/008-local.phpmyadmin.test.conf
⏳ PHP8.2-FPM configuration for local.phpmyadmin.test created at /etc/php/8.2/fpm/pool.d/local.phpmyadmin.test.conf
⏳ Self-signed SSL certificate script for local.phpmyadmin.test created at /tmp/sscert_local.phpmyadmin.testnPwhL6
?️ Executing the self-signed SSL certificate script for local.phpmyadmin.test...
 > Removing existing previous self-signed certs with pattern local.phpmyadmin.test.*
 > Generating certs for local.phpmyadmin.test
 > Generating RSA private key, 2048 bit long modulus
 > Writing info to /etc/apache2/certs-selfsigned/local.phpmyadmin.test.info
 > Protecting the key with chmod 400 /etc/apache2/certs-selfsigned/local.phpmyadmin.test.key
 > Removing the temporary config file /tmp/openssl.cnf.r60k8l
⏳ Enabling local.phpmyadmin.test on config 008-local.phpmyadmin.test...
⚡ Restarting Apache2...
⚡ Restarting PHP8.2-FPM...
✅ VirtualHost local.phpmyadmin.test created successfully!

Ora, bisogna modificare il file hosts di Windows per inserire il puntamento locale al dominio local.phpmyadmin.test.

Per modificare il file hosts su Windows 11, possiamo:

  1. Usare i PowerToys. Per l'installazione e l'utilizzo, si rimanda alla guida ufficiale di Microsoft
  2. Modificare il file C:\Windows\System32\drivers\etc\hosts (consiglio di utilizzare Notepad++)

Dopodichè, aprire una command line di Windows in modalità privilegiata e lanciare ipconfig /flushdns

Finito!

Complimenti! Se sei arrivato fino a questo punto, hai tutto quello che ti serve per lavorare, ed è possibile navigare sul proprio browser all'indirizzo https://local.phpmyadmin.test/setup/ per proseguire il setup di PhpMyAdmin.

Per creare altri VirtualHost per altri progetti, utilizzare sempre le stesse istruzioni seguite per il setup di PhpMyAdmin. Basterà far puntare il VirtualHost alla directory giusta del proprio progetto, e definire un nome di dominio fittizio che sarà reindirizzato dal file hosts verso 127.0.0.1

NOTE : per eliminare i VirtualHost creati tramite HTE-Cli, utilizzare il comando (Alias) hte-remove.
Per listare tutti i VirtualHost creati tramite HTE-Cli, utilizzare il comando (Alias) hte-details

Step 4 - Installare una shell custom, NVM, e ottimizzare l'esperienza utente (opzionale)

Questi step sono opzionali e servono ad ottimizzare l'esperienza utente sulla console dei comandi di Linux (secondo le mie personali preferenze), oltre che ad installare nvm (Node Version Manager, per lavorare con Node, React, etc).

  1. Seguire le istruzioni di installazione di https://github.com/slomkowski/bash-full-of-colors (o installare ZSH, o qualunque altra shell di gradimento: io mi trovo bene con questa bash colorata super minimale, mia opinione personale è che avere meno aiuto possibile sulla bash sia un ottimo modo per non staccare la testa). Riporto un one-liner per installare Bash full of colors cd ~/ ; git clone https://github.com/slomkowski/bash-full-of-colors.git .bash-full-of-colors ; [ -f .bashrc ] && mv -v .bashrc bashrc.old ; [ -f .bash_profile ] && mv -v .bash_profile bash_profile.old ; [ -f .bash_aliases ] && mv -v .bash_aliases bash_aliases.old ; [ -f .bash_logout ] && mv -v .bash_logout bash_logout.old ; ln -s .bash-full-of-colors/bashrc.sh .bashrc ; ln -s .bash-full-of-colors/bash_profile.sh .bash_profile ; ln -s .bash-full-of-colors/bash_aliases.sh .bash_aliases ; ln -s .bash-full-of-colors/bash_logout.sh .bash_logout ; rm -f bash_logout.old ; rm -f bashrc.old ; rm -f bash_aliases.old
  2. Lanciare wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.4/install.sh | bash per installare NVM (per sviluppo NodeJS/React)
  3. Creare una coppia di chiavi pubblica/privata con il comando ssh-keygen -o -a 100 -t ed25519 -f ~/.ssh/nome_chiave -C "utente@computer" (comunicare il contenuto della chiave pubblica ~/.ssh/nome_chiave.pubal proprio team, che la userà per esempio per abilitare l'accesso ad un repository GIT privato.)
  4. Creare un collegamento alla home directory di Ubuntu raggiungibile dal proprio Desktop per visualizzare la home di Ubuntu tramite l'Esplora risorse di Windows: per farlo, cliccare sul Desktop con il tasto destro del Mouse, Selezionare Nuovo > Collegamento, e immettere nel percorso del collegamento la stringa \\wsl$\Ubuntu-22.04\home\NOME_UTENTE, dove NOME_UTENTE è il nome utente usato su Ubuntu. Opzionale : modificare l'icona del collegamento (consiglio questa: ubuntu-drive-icon.ico)
  5. Creare un collegamento alla Bash di Ubuntu raggiungibile dal proprio Desktop per avviare un nuovo terminale: per farlo, cliccare sul Desktop con il tasto destro del Mouse, Selezionare Nuovo > Collegamento, e immettere nel percorso del collegamento la stringa C:\Windows\System32\wsl.exe -d Ubuntu-22.04 bash -c "cd /home/NOME_UTENTE && bash", dove NOME_UTENTE è il nome utente usato su Ubuntu. Opzionale : modificare l'icona del collegamento (consiglio questa: ubuntu-icon.ico)

Step 5 - Installare VS Code per accedere ai file di progetto su WSL2

VS Code è totalmente integrato e compatibile con WSL2, nativamente.

Questo incrementa la produttività e semplifica tantissimo lo sviluppo.

Per installare e configurare VS Code con WSL2 è sufficiente:

  1. Installare VS Code scaricandolo da https://code.visualstudio.com/
  2. Aprire VS Code e premere la combinazione di comandi CTRL + SHIFT + x
  3. Installare l'estensione Remote - WSL
  4. Riavviare VS Code
  5. Aprire una console di Ubuntu, e portarsi su una directory a piacere, ad esempio ~/opt/ oppure ~/.config/composer
  6. Lanciare il comando code . e lasciare che il sistema installi quello che gli serve
  7. Fatto! Da questo momento sarà possibile modificare i file presenti su Ubuntu direttamente da VS Code installato su Windows.

Step 6 - Ottimizzare, con le estensioni consigliate, lo sviluppo web su VS Code

Qui riporto un elenco di plugin e configurazioni utili per lo sviluppo PHP su VS Code.

E' molto importante che la lista dei plugin che segue venga installata durante una sessione WSL all'interno di VS Code.
Per farlo, portarsi su una directory qualsiasi di Ubuntu, ad esempio ~/opt/ oppure ~/.config/composer, e lanciare il comando code .
Così facendo, si aprirà VS Code in una sessione WSL e i plugin (e le relative configurazioni di Environment di VS Code) verranno applicate a WSL2, e non su Windows.

Per ogni plugin, è sufficiente premere CTRL + SHIFT + x e digitare il nome del plugin da cercare.

  1. Cercare php cs fixer e installare la versione del plugin di junstyle https://github.com/junstyle/vscode-php-cs-fixer.git
  2. Cercare GitLens e installare la versione del plugin di Eric Amodio https://github.com/eamodio/vscode-gitlens
  3. Cercare Git History e installare la versione del plugin di Don Jayamanne, https://github.com/DonJayamanne/gitHistoryVSCode
  4. Cercare PHP Intelephense e installare la versione del plugin di Ben Mewburn, https://github.com/bmewburn/vscode-intelephense
  5. Cercare Prettier - Code Formatter e installare la versione del plugin di Prettier, https://github.com/prettier/prettier-vscode
  6. Cercare PHP DocBlocker e installare la versione del plugin di Nail Brayfield, https://github.com/neild3r/vscode-php-docblocker
  7. Cercare markdownlint e installare la versione del plugin di David Anson, https://github.com/DavidAnson/vscode-markdownlint
  8. Cercare Material Icon Theme e installare la versione del plugin di Philipp Kief, https://github.com/PKief/vscode-material-icon-theme

Una volta installati tutti i plugin, premere la combinazione di tasti CTRL + SHIFT + p, digitare JSON, e selezionare su Preferenze: Apri Impostazioni Remote (JSON) (WSL: Ubuntu-22.04) (se la lingua di VS Code è inglese, bisognerà selezionare Preferences: Open Remote Settings (JSON) (WSL: Ubuntu-22.04))

A questo punto, copia-incollare la configurazione JSON riportata nello snippet vscode.json, modificando la variabile ##LINUX_USERNAME## con il nome utente utilizzato su Ubuntu.

Questa configurazione contiene sia impostazioni di mia preferenza personale, sia impostazioni dedicate a far funzionare i vari formattatori e php cs fixer.

NOTA : la configurazione consigliata su vscode.json richiede l'installazione dei font Roboto Sans e Source Code Pro
Il font Roboto Sans viene utilizzato per l'output sul terminale integrato, mentre il font Source Code Pro sarà il font utilizzato per il codice sorgente, file markdown, readme, insomma tutti gli editor di testo.
Si omettono istruzioni precise e puntuali per l'installazione dei font su Windows. Tuttavia, è sufficiente scaricare i file ttf dei font, aprirli con Windows, e cliccare su Installa.

Aggiornamento 05/09/2023: è disponibile la nuova guida aggiornata Configurazione di uno Stack LAMP su Windows 11 (e Windows 10), con WSL2, Ubuntu 22.04, servizi systemd nativi e ottimizzazioni per lo sviluppo con VS Code. Si consiglia vivamente di fare riferimento alla nuova guida.

Nota: questa guida creata da Maurizio Fonte è anche disponibile come GIST su GitHub all'indirizzo https://gist.github.com/mauriziofonte/00002661cd527a8a457509c5b4b0613d.

Lo sviluppo web con tecnologie puramente Linux (Stack LAMP - Linux, Apache, Mysql, PHP) è diventato estremamente semplice su Windows 10.

Infatti, con WSL è possibile, citando la pagina ufficiale di Microsoft: Sottosistema Windows per Linux consente agli sviluppatori di eseguire un ambiente GNU/Linux, inclusi la maggior parte degli strumenti da riga di comando, delle utilità e delle applicazioni, direttamente in Windows, senza modifiche e senza il sovraccarico di una macchina virtuale tradizionale o di una configurazione di avvio doppio.

Inoltre, sempre Microsoft è riuscita a creare uno degli editor di codice più potenti e completi in circolazione: Visual Studio Code. Una volta iniziato ad utilizzare, sarà molto molto difficile tornare indietro.

E' importante quindi conoscere come configurare un ambiente di sviluppo confortevole, che permetta di dire addio al vecchio modus operandi inefficiente e macchinoso che obbligava l'uso di WinSCP e Notepad++ con modifiche pubblicate direttamente sui server di produzione (o altri sistemi similari).

Con lo stack LAMP su Windows e l'utilizzo di Visual Studio Code e la continuous integration di Git, sarà possibile essere più produttivi e testare le condizioni reali di produzione direttamente sul proprio PC.

Nel corso del tempo, ho creato una guida esaustiva che spiega come configurare un ambiente di sviluppo comodo con stack LAMP utilizzando WSL2 su Windows. E' una lettura lunga, si consiglia di leggerla con calma, cercando di comprendere ogni passaggio, ed eventualmente adattarla ai propri scopi. Questa guida è anche disponibile a questo indirizzo, per una più comoda lettura: https://gist.github.com/mauriziofonte/00002661cd527a8a457509c5b4b0613d

Importante: come precondizione per un buon uso di questa guida, è necessaria una conoscenza minima del terminale di Linux e una buona dimestichezza con Windows.

Attenzione: questa guida è stata scritta per Windows 10. Tuttavia, potrebbe funzionare su Windows 11, ma non ho avuto modo di testarla dal vivo. Su Windows 11, quindi, seguire una guida specifica per l'abilitazione di WSL2, e tralasciare la parte WSL2 presente in questa guida.

Stack di sviluppo LAMP su Windows 10 con WSL2 e Visual Studio Code

Questa guida illustrerà come installare il supporto al sottosistema Linux nativo di Windows (WSL2), creare uno stack LAMP al suo interno, e agganciare Visual Studio Code per lo sviluppo direttamente su filesystem Linux.

La guida è aggiornata ad Agosto 2022 e necessita di questi prerequisiti:

  1. Computer con Windows 10, aggiornato all'ultima release disponibile
  2. 16GB di RAM
  3. 30GB di spazio libero su C:\ (conterrà il disco virtuale di Ubuntu)
  4. Un SSD (meglio NVMe) come disco di avvio di Windows (migliori performance con Mysql)
  5. Una conoscenza di base del terminale Linux (cd, cp, mv, sudo, nano, etc.)

Lo stack LAMP che andremo a configurare supporta https (con certificati autofirmati con scadenza a 10 anni), protocollo http/2 e compressione brotli. Per quanto riguarda la parte PHP, useremo PHP-FPM perchè è più performante e più versatile nella configurazione delle impostazioni per-virtualhost. Per capire le differenze tra l'utilizzo di PHP con Apache in modalità PHP-CGI piuttosto che PHP-FPM, si rimanda a questa guida: https://www.basezap.com/difference-php-cgi-php-fpm/

Installare Ubuntu 20.04 LTS su Windows

  1. Leggere il warning sotto (La versione di WSL deve essere la 2).
  2. Abilitare "Sottosistema Linux" da "Programmi e funzionalità"
  3. Cercare "Ubuntu" nel Windows Store e installare UBUNTU 20.04 LTS
  4. Avviare la macchina, attendere l'installazione, scegliere un nome utente (occhio, serve sotto ed è importante) composto da una singola parola corta tutta in minuscolo + la relativa password (corta, 1 sola lettera per comodità)
  5. Creare un collegamento desktop alla macchina Linux
  6. Creare un collegamento desktop alla directory home dell'utente, esempio: \\wsl$\Ubuntu-20.04\home\maurizio

WARNING: la versione di WSL DEVE essere la 2

Questo è molto importante. Se non è installato WSL2, non funziona nulla.

Per questo motivo, leggere https://aka.ms/wsl2-install. SI CONSIGLIA DI FARE QUESTA OPERAZIONE PRIMA DI INSTALLARE UBUNTU SUL SISTEMA.

Se necessario abilitare WSL2 (perchè non già abilitato), bisognerà aprire una PowerShell con privilegi elevati e usare questi comandi:

Installare questo pacchetto: https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_x64.msi

dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
Restart-Computer                    # bisogna riavviare
wsl --set-version Ubuntu-20.04 2    # IMPORTANTE: questo è necessario solo se si è installato ubuntu prima di abilitare WSL2
wsl --set-default-version 2

Modificare il resolver DNS di WSL2

Guida copiata da: https://superuser.com/questions/1533291/how-do-i-change-the-dns-settings-for-wsl2

A) Turn off generation of /etc/resolv.conf

Using your Linux prompt, (I'm using Ubuntu), modify (or create) /etc/wsl.conf with the following content

[network]
generateResolvConf = false

(Apparently there's a bug in the current release where any trailing whitespace on these lines will trip things up.)

B) Restart the WSL2 Virtual Machine

Exit all of your Linux prompts and run the following Powershell command

wsl --shutdown

C) Create a custom /etc/resolv.conf

Open a new Linux prompt and cd to /etc

If resolv.conf is soft linked to another file, remove the link with rm resolv.conf (originally it is linked to ../run/resolvconf/resolv.conf)

Create a new resolv.conf with the following content

nameserver 1.1.1.1

Configurare l'ambiente LAMP su Ubuntu - Step 1

Qui andremo ad installare tutti i pacchetti di PHP in tutte le versioni dalla 5.6 alla 8.1, nonchè il web server Apache e il server Mysql.

Perchè installare tante versioni di PHP? Perchè è importante avere a disposizione un ambiente di sviluppo che consenta, con facilità, di testare la propria applicazione con svariate versioni di PHP. Questo agevolerà il lavoro in caso di constraint specifici sui server di produzione dove andremo ad installare le applicazioni create.

Si presume che la versione di default di PHP che si vorrà utilizzare nel sistema sia la 8.1. Questo è modificabile tramite le righe update-alternatives --set php*** che si troveranno nella lista qui sotto. Ad esempio, se si desidera che la versione di PHP di default (quella che verrà utilizzata digitando semplicemente il comando php e non la sua versione "versionata" es php7.4) basterà specificare update-alternatives --set php /usr/bin/php7.4.

IMPORTANTE: Lanciare tutti questi comando come l'utente root. IMPORTANTE: Escludere le linee che iniziano con ### in quanto servono solo a differenziare i vari blocchi.

# APT UPGRADE & INSTALL OF PHP + APACHE
apt update && apt upgrade
apt install net-tools unzip git lsb-release ca-certificates apt-transport-https software-properties-common -y
add-apt-repository ppa:ondrej/php
add-apt-repository ppa:ondrej/apache2
apt install openssl apache2 brotli libapache2-mod-fcgid libapache2-mod-php8.1 php8.1 php8.1-cli php8.1-fpm php8.1-common php8.1-bcmath php8.1-bz2 php8.1-curl php8.1-gd php8.1-intl php8.1-mbstring php8.1-mcrypt php8.1-mysql php8.1-xml php8.1-zip libapache2-mod-php8.0 php8.0 php8.0-cli php8.0-fpm php8.0-common php8.0-bcmath php8.0-bz2 php8.0-curl php8.0-gd php8.0-intl php8.0-mbstring php8.0-mcrypt php8.0-mysql php8.0-xml php8.0-zip libapache2-mod-php7.4 php7.4 php7.4-cli php7.4-fpm php7.4-common php7.4-bcmath php7.4-bz2 php7.4-curl php7.4-gd php7.4-intl php7.4-json php7.4-mbstring php7.4-mcrypt php7.4-mysql php7.4-xml php7.4-zip libapache2-mod-php7.3 php7.3 php7.3-cli php7.3-fpm php7.3-common php7.3-bcmath php7.3-bz2 php7.3-curl php7.3-gd php7.3-intl php7.3-json php7.3-mbstring php7.3-mcrypt php7.3-mysql php7.3-xml php7.3-zip libapache2-mod-php7.2 php7.2 php7.2-cli php7.2-fpm php7.2-common php7.2-bcmath php7.2-bz2 php7.2-curl php7.2-gd php7.2-intl php7.2-json php7.2-mbstring php7.2-mcrypt php7.2-mysql php7.2-xml php7.2-zip libapache2-mod-php7.1 php7.1 php7.1-cli php7.1-fpm php7.1-common php7.1-bcmath php7.1-bz2 php7.1-curl php7.1-gd php7.1-intl php7.1-json php7.1-mbstring php7.1-mcrypt php7.1-mysql php7.1-xml php7.1-zip libapache2-mod-php7.0 php7.0 php7.0-cli php7.0-fpm php7.0-common php7.0-bcmath php7.0-bz2 php7.0-curl php7.0-gd php7.0-intl php7.0-json php7.0-mbstring php7.0-mcrypt php7.0-mysql php7.0-xml php7.0-zip libapache2-mod-php5.6 php5.6 php5.6-cli php5.6-fpm php5.6-common php5.6-bcmath php5.6-bz2 php5.6-curl php5.6-gd php5.6-intl php5.6-json php5.6-mbstring php5.6-mcrypt php5.6-mysql php5.6-xml php5.6-zip
update-alternatives --set php /usr/bin/php8.1
update-alternatives --set phar /usr/bin/phar8.1
update-alternatives --set phar.phar /usr/bin/phar.phar8.1
update-alternatives --set phpize /usr/bin/phpize8.1
update-alternatives --set php-config /usr/bin/php-config8.1
### OPTIONAL SQLITE3 SUPPORT
apt install php5.6-sqlite3 php7.0-sqlite3 php7.1-sqlite3 php7.2-sqlite3 php7.3-sqlite3 php7.4-sqlite3 php8.0-sqlite3 php8.1-sqlite3
### OPTIONAL REDIS SUPPORT
sudo apt install redis-server php5.6-redis php7.0-redis php7.1-redis php7.2-redis php7.3-redis php7.4-redis php8.0-redis php8.1-redis
# APACHE HTTP2 + PHP-FPM + SSL + REWRITE + BROTLI
a2dismod php5.6 php7.0 php7.1 php7.2 php7.3 php7.4 php8.0 php8.1 mpm_prefork
a2enconf php5.6-fpm php7.0-fpm php7.1-fpm php7.2-fpm php7.3-fpm php7.4-fpm php8.0-fpm php8.1-fpm
a2enmod actions fcgid alias proxy_fcgi rewrite ssl http2 mpm_event brotli
# INSTALL MYSQL
apt install mysql-client-8.0 mysql-server-8.0

Configurare l'ambiente LAMP su Ubuntu - Step 2

Qui andremo a modificare le configurazioni di base di Apache e Mysql per poter lavorare localmente.

  1. Aprire il file /etc/apache2/envvars con nano e modificare APACHE_RUN_USER e APACHE_RUN_GROUP settandoli, al posto che www-data, con il proprio nome utente
  2. Aprire il file /etc/apache2/ports.conf con nano e modificare ogni occorrenza di Listen con Listen 127.0.0.1 (esempio: 127.0.0.1:80 127.0.0.1:443)
  3. Lanciare service apache2 restart per applicare le modifiche alla config di Apache.
  4. Aprire il file /etc/mysql/mysql.conf.d/mysqld.cnf e aggiungere queste righe (sostituisci [LF] con delle andate a capo) nella sezione [mysqld], (per intenderci, sotto la riga # datadir = /var/lib/mysql) : bind-address = 127.0.0.1 [LF] skip-networking [LF] sql_mode=NO_ENGINE_SUBSTITUTION [LF] default-authentication-plugin=mysql_native_password [LF] collation-server = utf8_unicode_ci [LF] character-set-server = utf8
  5. (opzionale) Per completezza, al fondo di questo file è presente una configurazione di fine-tuning per un sistema con almeno 16GB di RAM. Volendo, si può direttamente copia-incollare quella configurazione.
  6. Lanciare service mysql restart per applicare le modifiche alla config di Mysql.
  7. Lanciare mysql_secure_installation per creare la password di root per mysql (usare qualcosa di semplice, perchè serve solo localmente), rimuovere l'accesso per gli utenti anonimi, le tabelle temporanee, e disabilitare il login remoto al demone Mysql.
  8. Eseguire mysql -u root e lanciare i comandi di seguito:
  9. CREATE USER 'admin'@'%' IDENTIFIED BY 'x';
  10. GRANT ALL PRIVILEGES ON *.* TO 'admin'@'%' WITH GRANT OPTION;
  11. FLUSH PRIVILEGES;

Ovviamente, le query mysql relative allo username e password da creare come utente privilegiato possono essere modificate. Nell'esempio sopra riportato viene creato un utente con username admin e password x. Ricordarsi che stiamo configurando un ambiente di sviluppo locale, e fintanto che non viene "aperto" al mondo esterno, non dobbiamo preoccuparci di usare politiche corrette per la sicurezza.

Creare dei VirtualHost funzionanti sulla propria installazione locale - Step 3

Per creare dei VirtualHost è sufficiente utilizzare questi due script che velocizzano la configurazione.

Come fase esemplificativa, verrà mostrato come creare un VirtualHost specifico per PhpMyAdmin, che comunque è necessario per poter lavorare.

A questo punto, se ancora loggati come l'utente root, uscire dall'utente root e tornare in modalità utente.

sudo mkdir /etc/apache2/certs2/
cd ~/
mkdir utils
cd utils/
nano create-staging-environment.php (copiare da sotto il contenuto del file)
nano create-ssl-cert.sh (copiare da sotto il contenuto del file)
chmod +x create-ssl-cert.sh
cd ~/
nano lamp.sh (copiare da sotto il contenuto del file)
chmod +x lamp.sh
wget https://files.phpmyadmin.net/phpMyAdmin/5.1.1/phpMyAdmin-5.1.1-all-languages.zip
unzip phpMyAdmin-5.1.1-all-languages.zip
rm -f phpMyAdmin-5.1.1-all-languages.zip
mv phpMyAdmin-5.1.1-all-languages phpmyadmin

Ora abbiamo creato la directory radice per l'installazione di phpmyadmin. Non resta che configurare un VirtualHost funzionante.

Lanciare quindi il comando sudo php create-staging-environment.php e seguire le istruzioni. Queste istruzioni si applicano a tutti i progetti web che si vogliono installare sul sistema.

Nell'esempio, il virtualhost per PhpMyAdmin verrà settato come local.phpmyadmin.biz. Ovviamente, modificare le risposte seguendo il proprio nome utente. Rispondere alle domande dello script come segue:

maurizio@FISSO:~$ cd ~/utils/
maurizio@FISSO:~/utils$ sudo php create-staging-environment.php
### STAGING ENVIRONMENT CREATOR ###
Enter a valid local domain name: local.phpmyadmin.biz
Enter a valid directory in the filesystem for the DocumentRoot: /home/maurizio/phpmyadmin/
Enter a valid PHP version (5.6, 7.1, 7.2, 7.3, 7.4, 8.0 or 8.1): 7.4
Do you need HTTPS support (yes/no/y/n) ? y

Ora, bisogna modificare il file hosts di Windows per inserire il puntamento locale al dominio local.phpmyadmin.biz. Per farlo, modificare il file C:\Windows\System32\drivers\etc\hosts aggiungendo la regola 127.0.0.1 local.phpmyadmin.biz.

Dopodichè, aprire una command line di Windows in modalità privilegiata e lanciare ipconfig /flushdns

Fatto! Ora è possibile navigare sul proprio browser all'indirizzo https://local.phpmyadmin.biz/setup/ per proseguire il setup go PhpMyAdmin.

Per creare altri VirtualHost per altri progetti, utilizzare sempre le stesse istruzioni seguite per il setup di PhpMyAdmin. Basterà far puntare il VirtualHost alla directory giusta del proprio progetto, e definire un nome di dominio fittizio che sarà reindirizzato via HOSTS verso 127.0.0.1

Ottimizzare l'esperienza Linux - Step 4

Per ottimizzare l'installazione LAMP e l'esperienza utente sulla console dei comandi di Linux, seguire questi passaggi:

  1. Seguire le istruzioni di installazione di https://github.com/slomkowski/bash-full-of-colors
  2. Lanciare wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash per installare NVM (per sviluppo NodeJS/React)
  3. Lanciare cd ~/utils/ && php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" && php composer-setup.php && php -r "unlink('composer-setup.php');" per installare una versione locale di composer all'interno della directory /utils/
  4. Creare una coppia di chiavi pubblica/privata con il comando ssh-keygen -o -a 100 -t ed25519 -f ~/.ssh/nome_chiave -C "utente@computer"
  5. Comunicare il contenuto della chiave pubblica al proprio team, che la userà per esempio per abilitare l'accesso ad un repository GIT privato.
  6. Copia-incollare il contenuto dello snippet bash_local all'interno di ~/.bash_local modificando la variabile $NOME_UTENTE con il nome dell'utente scelto

Note importanti:

  1. E' possibile fare il reset della macchina Linux con il comando wslrestart che è stato aliasato in ~/.bash_local. Così facendo si resetta completamente il sottosistema WSL2.
  2. Ogni volta che si esegue il login alla macchina virtuale, bisognerà lanciare il comando ~/lamp.sh per avviare i servizi Apache, PHP-FPM e Mysql. Questo è necessario perchè l'ambiente LAMP non è stato installato come servizio di sistema (per intenderci, con systemd).

Installare VS Code per accedere ai file di progetto su WSL2 - Step 5

VS Code è totalmente integrato e compatibile con WSL2, nativamente.

Questo incrementa la produttività e semplifica tantissimo lo sviluppo.

Per installare e configurare VS Code con WSL2 è sufficiente:

  1. Installare VS Code scaricandolo da https://code.visualstudio.com/
  2. Aprire VS Code e premere la combinazione di comandi CTRL + SHIFT + x
  3. Installare l'estensione Remote - WSL
  4. Riavviare VS Code
  5. Aprire una console di Ubuntu, e portarsi su una directory a piacere, ad esempio ~/utils/
  6. Lanciare il comando code . e lasciare che il sistema installi quello che gli serve
  7. Voilà, ora è possibile modificare i file presenti su Ubuntu direttamente da VS Code!

Ottimizzare lo sviluppo web con le estensioni giuste di VS Code - Step 6

Portarsi su una console di Ubuntu e lanciare questi comandi:

  1. cd ~/
  2. mkdir .composer && cd .composer/
  3. nano composer.json e inserire questo contenuto all'interno:
{
	"require": {
		"squizlabs/php_codesniffer": "^3.5",
		"friendsofphp/php-cs-fixer": "^2.16"
	}
}
  1. Lanciare composer install
  2. Ora abbiamo a disposizione i binari di php-cs-fixer e php codesniffer, ci serviranno per la config di VS Code
  3. Aprire VS Code, e portarsi su un progetto residente dentro Ubuntu per rimanere in "modalità WSL2"
  4. Premere CTRL + SHIFT + x, cercare php cs fixer e installare la versione del plugin di junstyle (https://github.com/junstyle/vscode-php-cs-fixer.git)
  5. Installare le seguenti estensioni: GitLens (Eric Amodio, https://github.com/eamodio/vscode-gitlens), Git History (Don Jayamanne, https://github.com/DonJayamanne/gitHistoryVSCode), PHP Intelephense (Ben Mewburn, https://github.com/bmewburn/vscode-intelephense), Prettier - Code Formatter (Prettier, https://github.com/prettier/prettier-vscode), PHP DocBlocker (Nail Brayfield, https://github.com/neild3r/vscode-php-docblocker), Twig Language (mblode, https://github.com/mblode/vscode-twig-language), markdownlint (David Anson, https://github.com/DavidAnson/vscode-markdownlint)
  6. Installare il seguente pacchetto icone: Material Icon Theme (Philipp Kief, https://github.com/PKief/vscode-material-icon-theme)
  7. Premere la combinazione di tasti CTRL + SHIFT + p, digitare preferenze, e cliccare su Preferenze: Apri Impostazioni (JSON)
  8. Copia-incollare la configurazione riportata nello snippet vscode-json-config

Contenuto dello snippet "vscode-json-config"

Ovviamente bisogna modificare la path di php-cs-fixer.executablePath secondo il proprio nome utente.

{
	"window.menuBarVisibility": "toggle",
	"window.zoomLevel": 0.2,
	"explorer.confirmDelete": false,
	"explorer.confirmDragAndDrop": false,
	"workbench.iconTheme": "material-icon-theme",
	"workbench.colorTheme": "Quiet Light",
	"workbench.colorCustomizations": {
		"editorCursor.foreground": "#444"
	},
	"workbench.editor.showTabs": true,
	"terminal.integrated.fontFamily": "monospace",
	"terminal.integrated.lineHeight": 0.8,
	"terminal.integrated.enableBell": false,
	"terminal.integrated.letterSpacing": -0.1,
	"terminal.integrated.fontSize": 16,
	"editor.fontWeight": "600",
	"editor.cursorStyle": "line",
	"editor.cursorBlinking": "phase",
	"editor.rulers": [130],
	"editor.formatOnSave": true,
	"editor.minimap.enabled": false,
	"editor.wordWrap": "on",
	"editor.insertSpaces": true,
	"editor.tabSize": 4,
	"html.format.contentUnformatted": "pre,code,textarea",
	"html.format.endWithNewline": false,
	"html.format.extraLiners": "head, body, /html",
	"html.format.indentHandlebars": false,
	"html.format.indentInnerHtml": false,
	"html.format.maxPreserveNewLines": null,
	"html.format.preserveNewLines": true,
	"html.format.wrapLineLength": 130,
	"html.format.wrapAttributes": "auto",
	"telemetry.enableCrashReporter": false,
	"telemetry.enableTelemetry": false,
	"prettier.trailingComma": "all",
	"prettier.endOfLine": "auto",
	"prettier.singleQuote": true,
	"prettier.useTabs": true,
	"prettier.tabWidth": 4,
	"prettier.printWidth": 130,
	"prettier.jsxBracketSameLine": true,
	"prettier.semi": false,
	"[php]": {
		"editor.formatOnSave": true,
		"editor.defaultFormatter": "junstyle.php-cs-fixer"
	},
	"[js]": {
		"editor.formatOnSave": true,
		"editor.defaultFormatter": "esbenp.prettier-vscode"
	},
	"[javascript]": {
		"editor.formatOnSave": true,
		"editor.defaultFormatter": "esbenp.prettier-vscode"
	},
	"[css]": {
		"editor.formatOnSave": true,
		"editor.defaultFormatter": "esbenp.prettier-vscode"
	},
	"[jsx]": {
		"editor.formatOnSave": true,
		"editor.defaultFormatter": "esbenp.prettier-vscode"
	},
	"[twig]": {
		"editor.formatOnSave": true,
		"editor.defaultFormatter": "mblode.twig-language"
	},
	"php.suggest.basic": false,
	"php.validate.enable": true,
	"typescript.updateImportsOnFileMove.enabled": "never",
	"git.enableSmartCommit": true,
	"git.autofetch": true,
	"git.confirmSync": false,
	"php-cs-fixer.executablePath": "/home/$NOME_UTENTE/.composer/vendor/bin/php-cs-fixer",
	"php-cs-fixer.executablePathWindows": "", //eg: php-cs-fixer.bat
	"php-cs-fixer.onsave": false,
	"php-cs-fixer.rules": "@PSR2",
	"php-cs-fixer.config": ".php_cs;.php_cs.dist",
	"php-cs-fixer.allowRisky": false,
	"php-cs-fixer.pathMode": "override",
	"php-cs-fixer.exclude": [],
	"php-cs-fixer.autoFixByBracket": true,
	"php-cs-fixer.autoFixBySemicolon": false,
	"php-cs-fixer.formatHtml": false,
	"php-cs-fixer.documentFormattingProvider": true,
	"php-cs-fixer.lastDownload": 0,
	"[html]": {
		"editor.defaultFormatter": "esbenp.prettier-vscode"
	},
	"php-docblocker.returnGap": true,
	"php-docblocker.qualifyClassNames": true,
	"php-docblocker.author": {
		"name": "NOME SVILUPPATORE",
		"email": "EMAIL@SVILUPPATORE.BIZ"
	},
	"diffEditor.ignoreTrimWhitespace": false
}

Contenuto dello snippet ".bash_local"

alias casa="cd /home/$NOME_UTENTE"
alias composer="/usr/bin/php7.4 -d allow_url_fopen=1 /home/$NOME_UTENTE/utils/composer.phar"
alias php="/usr/bin/php7.4 -d allow_url_fopen=1 -d memory_limit=1024M"
alias php74="/usr/bin/php7.4 -d allow_url_fopen=1 -d memory_limit=1024M"
alias apt="sudo apt-get"
alias ls="ls -lash --color=auto --group-directories-first"
alias cd..="cd .."
alias ..="cd ../../"
alias ...="cd ../../../"
alias ....="cd ../../../../"
alias .....="cd ../../../../"
alias .4="cd ../../../../"
alias .5="cd ../../../../.."
alias ports="sudo netstat -tulanp"
alias wslrestart="history -a && cmd.exe /C wsl --shutdown"
alias tic="git"
alias npmclean="npm ci"
alias npmcheck="ncu"

gitremove() {
    git branch -d "$@"
    git push origin --delete "$@"
}

hugefiles() {
    du -a "$@" | sort -n -r | head -n 100
}

hugedirs() {
    cd "$@" && du -hsx -- * | sort -rh | head -100
}

export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"  # This loads nvm
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"  # This loads nvm bash_completion

Contenuto dello script "lamp.sh"

#!/usr/bin/env bash
echo "### Starting MYSQL 8 ..."
sudo service mysql start
echo "### Starting PHP-FPM 5.6, 7.*, 8.*"
[ -d /var/run/php/ ] || sudo mkdir /var/run/php/
sudo service php5.6-fpm start
sudo service php7.0-fpm start
sudo service php7.1-fpm start
sudo service php7.2-fpm start
sudo service php7.3-fpm start
sudo service php7.4-fpm start
sudo service php8.0-fpm start
sudo service php8.1-fpm start
echo "### Starting Apache Server ..."
sudo service apache2 start

Contenuto dello script "create-staging-environment.php"

IMPORTANTE: Dopo il copia-incolla in create-staging-environment.php, ricordarsi di modificare le stringhe ##NOME_UTENTE## in modo che contengano il nome utente scelto in fase di setup di Ubuntu..

<?php

if (php_sapi_name() !== "cli") {
    message('ERROR: This script can only be run from the CLI.', 'e');
    exit();
}

if (posix_getuid() !== 0) {
    message('ERROR: This script can only be run as ROOT or sudo.', 'e');
    exit();
}

if (!is_dir('/etc/apache2/certs2/')) {
    message('ERROR: You need to create the directory /etc/apache2/certs2/ as root prior of executing this script.', 'e');
    exit();
}

define('APACHE_SITES_AVAILABLE_DIR', '/etc/apache2/sites-available/');
define('APACHE_CERTS_DIR', '/etc/apache2/certs2/');
define('APACHE_CERT_SELFSIGNED_SCRIPT', './create-ssl-cert.sh');
define('PHP_FPM_CONFIG_DIR', '/etc/php/#VER#/fpm/pool.d/');
define('APACHE_MAX_CONF_INDEX', getApacheSitesAvailableMaxIndex());

message('### STAGING ENVIRONMENT CREATOR ###');

// 1. ask for the local domain name
$work = true;
while ($work) {
    $domain = readline('Enter a valid local domain name: ');
    $domain = strtolower(str_replace(['http://', 'https://', 'www.'], '', $domain));
    if (filter_var('http://' . $domain, FILTER_VALIDATE_URL)) {
        $work = false;
        define('DOMAIN', $domain);
    } else {
        message('Error. Retry.', 'e');
    }
}

// 2. ask for the local directory that will be served as the DocumentRoot
$work = true;
while ($work) {
    $document_root = readline('Enter a valid directory in the filesystem for the DocumentRoot: ');
    if (is_dir($document_root)) {
        $work = false;
        define('DOCUMENT_ROOT', rtrim($document_root, '/'));
    } else {
        message('Error. Retry.', 'e');
    }
}

// 3. ask for the PHP version for PHP-FPM
$work = true;
while ($work) {
    $php_version = readline('Enter a valid PHP version (5.6, 7.0, 7.1, 7.2, 7.3, 7.4, 8.0 or 8.1): ');
    if (in_array($php_version, ['5.6', '7.0', '7.1', '7.2', '7.3', '7.4', '8.0', '8.1'])) {
        $work = false;
        define('PHPVER', $php_version);
    } else {
        message('Error. Retry.', 'e');
    }
}

// 4. ask for HTTPS support
$work = true;
while ($work) {
    $https_support = readline('Do you need HTTPS support (yes/no/y/n) ? ');
    if (in_array(strtolower($https_support), ['yes', 'no', 'y', 'n'])) {
        $work = false;
        if (in_array(strtolower($https_support), ['yes', 'y'])) {
            define('HTTPS_SUPPORT', true);
        } else {
            define('HTTPS_SUPPORT', false);
        }
    } else {
        message('Error. Retry.', 'e');
    }
}

// 5. perform actions
$apache_conf_stream = getApacheConf();
$php_fpm_conf_stream = getPhpFpmConf();
$apache_conf_file = APACHE_SITES_AVAILABLE_DIR . APACHE_MAX_CONF_INDEX . '-' . DOMAIN . '.conf';
$php_fpm_conf_file = str_replace('#VER#', PHPVER, PHP_FPM_CONFIG_DIR) . DOMAIN . '.conf';

if (file_put_contents($apache_conf_file, $apache_conf_stream)) {
    message('Apache configuration written correctly, going to enable the website', 's');
    exec('a2ensite ' . basename($apache_conf_file));

    if (file_put_contents($php_fpm_conf_file, $php_fpm_conf_stream)) {
        message('PHP-FPM configuration written successfully', 's');

        if (HTTPS_SUPPORT) {
            message('Going to CD into ' . APACHE_CERTS_DIR);
            exec('cd ' . APACHE_CERTS_DIR);
            message('Going to call the self-signed cert script ' . APACHE_CERT_SELFSIGNED_SCRIPT . ' with domain "' . DOMAIN . '"');
            exec(APACHE_CERT_SELFSIGNED_SCRIPT . ' ' . DOMAIN);
        }

        message('Going to exec "service apache2 force-reload"');
        exec('service apache2 force-reload');
        message('Going to exec "service php' . PHPVER . '-fpm restart"');
        exec('service php' . PHPVER . '-fpm restart');
    } else {
        message('Cannot write PHP-FPM configuration', 'e');
    }
} else {
    message('Cannot write Apache configuration', 'e');
}

function message(string $string, string $type = 'i')
{
    switch ($type) {
        case 'e': //error
            echo "\033[31m$string \033[0m\n";
        break;
        case 's': //success
            echo "\033[32m$string \033[0m\n";
        break;
        case 'w': //warning
            echo "\033[33m$string \033[0m\n";
        break;
        case 'i': //info
            echo "\033[36m$string \033[0m\n";
        break;
        default:
            echo "$string\n";
        break;
    }
}

function getApacheSitesAvailableMaxIndex() : string
{
    $files = glob(APACHE_SITES_AVAILABLE_DIR . '*.conf');
    if ($files && count($files) > 0) {
        $max_index = 0;
        foreach ($files as $file) {
            $file = basename($file);
            if (preg_match('/^([0-9]+).*\.conf$/ui', $file, $matches)) {
                $index = intval($matches[1]);
                if ($index >= $max_index) {
                    $max_index = $index;
                }
            }
        }

        return str_pad($max_index + 1, 3, '0', STR_PAD_LEFT);
    }

    return '001';
}

function getApacheConf()
{
    $domain = DOMAIN;
    $document_root = DOCUMENT_ROOT;
    $phpver = PHPVER;
    $newline = "\\n";

    $conf_http = <<<HTML
<VirtualHost 127.0.0.1:80>
    ServerName $domain
    ServerAlias www.$domain
    DocumentRoot $document_root
    ServerAdmin admin@localhost.net
    UseCanonicalName Off
    Options -ExecCGI -Includes
    RemoveHandler cgi-script .cgi .pl .plx .ppl .perl
    CustomLog \${APACHE_LOG_DIR}/$domain combined
    CustomLog \${APACHE_LOG_DIR}/$domain-bytes_log "%{%s}t %I .$newline%{%s}t %O ."

    # Enable HTTP2
    Protocols h2 http/1.1

    <FilesMatch \.php$>
        # Apache 2.4.10+ can proxy to unix socket
        SetHandler "proxy:unix:/var/run/php/php$phpver-fpm-$domain.sock|fcgi://localhost/"
    </FilesMatch>

    <IfModule mod_brotli.c>
        AddOutputFilterByType BROTLI_COMPRESS text/html text/plain text/xml text/css text/javascript application/x-javascript application/javascript application/json application/x-font-ttf application/vnd.ms-fontobject image/x-icon
    </IfModule>

    <Directory $document_root/>
        Options -Indexes +FollowSymLinks
        AllowOverride All
        order allow,deny
        allow from all
        Require all granted
    </Directory>

    ##AUTOREWRITE##
</VirtualHost>

HTML;

    $conf_https = <<<HTML
<IfModule mod_ssl.c>
    <VirtualHost 127.0.0.1:443>
        ServerName $domain
        ServerAlias www.$domain
        DocumentRoot $document_root
        ServerAdmin admin@localhost.net
        UseCanonicalName Off
        Options -ExecCGI -Includes
        RemoveHandler cgi-script .cgi .pl .plx .ppl .perl
        CustomLog \${APACHE_LOG_DIR}/ssl-$domain combined
        CustomLog \${APACHE_LOG_DIR}/ssl-$domain-bytes_log "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"

        # Enable HTTP2
        Protocols h2 http/1.1

        <FilesMatch "\.(cgi|shtml|phtml|php)$">
            SSLOptions +StdEnvVars
        </FilesMatch>

        <Directory $document_root/>
            Options -Indexes +FollowSymLinks
            AllowOverride All
            order allow,deny
            allow from all
            Require all granted
        </Directory>

        <IfModule mod_brotli.c>
            AddOutputFilterByType BROTLI_COMPRESS text/html text/plain text/xml text/css text/javascript application/x-javascript application/javascript application/json application/x-font-ttf application/vnd.ms-fontobject image/x-icon
        </IfModule>

        <FilesMatch \.php$>
            # Apache 2.4.10+ can proxy to unix socket
            SetHandler "proxy:unix:/var/run/php/php$phpver-fpm-$domain.sock|fcgi://localhost/"
        </FilesMatch>

        SSLEngine on
        SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP
        SSLCertificateFile "/etc/apache2/certs2/$domain.crt"
        SSLCertificateKeyFile "/etc/apache2/certs2/$domain.key"
    </VirtualHost>
</IfModule>

HTML;

    if (HTTPS_SUPPORT) {
        return str_replace(
            '##AUTOREWRITE##',
            'RewriteEngine On
            RewriteCond %{HTTPS} off
            RewriteRule ^/(.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]',
            $conf_http
        ) . chr(10) . chr(10) . $conf_https;
    } else {
        return str_replace('##AUTOREWRITE##', '', $conf_http);
    }
}

function getPhpFpmConf()
{
    $domain = DOMAIN;
    $document_root = DOCUMENT_ROOT;
    $phpver = PHPVER;

    $php_fpm_conf = <<<HTML
[$domain]
user = ##NOME_UTENTE##
group = ##NOME_UTENTE##
listen = /var/run/php/php$phpver-fpm-$domain.sock
listen.owner = ##NOME_UTENTE##
listen.group = ##NOME_UTENTE##
php_admin_value[disable_functions] = apache_child_terminate,apache_get_modules,apache_getenv,apache_note,apache_setenv,define_syslog_variables,disk_free_space,diskfreespace,dl,fpassthru,get_current_user,getmyuid,highlight_file,passthru,pclose,pcntl_exec,pfsockopen,php_uname,pcntl_alarm,pcntl_fork,pcntl_get_last_error,pcntl_signal,pcntl_getpriority,pcntl_setpriority,pcntl_strerror,pcntl_signal_dispatch,pcntl_sigprocmask,pcntl_waitpid,pcntl_wait,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_wexitstatus,pcntl_wifexited,pcntl_wifsignaled,pcntl_wifstopped,pcntl_wstopsig,pcntl_wtermsig,popen,show_source,socket_select,socket_strerror,stream_select,syslog,symlink
php_admin_flag[allow_url_fopen] = off
pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3
chdir = /

catch_workers_output = yes
php_flag[display_errors] = off
php_admin_value[error_log] = $document_root/php$phpver-fpm-errors.log
php_admin_flag[log_errors] = on
php_admin_value[post_max_size] = 128M
php_admin_value[upload_max_filesize] = 128M
php_admin_value[memory_limit] = 1024M
php_value[memory_limit] = 1024M
php_value[short_open_tag] =  On

HTML;

    return $php_fpm_conf;
}

Contenuto dello script "create-ssl-cert.sh"

#!/usr/bin/env bash

# Ask for the base domain
BASE_DOMAIN="$1"
if [ -z "$BASE_DOMAIN" ]; then
  echo "Usage: $(basename $0) <domain>"
  exit 11
fi

fail_if_error() {
  [ $1 != 0 ] && {
    unset PASSPHRASE
    exit 10
  }
}

# Generate a passphrase
export PASSPHRASE=$(head -c 500 /dev/urandom | tr -dc a-z0-9A-Z | head -c 128; echo)

# Days for the cert to live
DAYS=3650

# Generated configuration file
CONFIG_FILE="config.txt"

cat > $CONFIG_FILE <<-EOF
[req]
default_bits = 2048
prompt = no
default_md = sha256
x509_extensions = v3_req
distinguished_name = dn

[dn]
C = IT
ST = Italy
L = Torino
O = Acme Corp
OU = The Dev Team
emailAddress = webmaster@$BASE_DOMAIN
CN = $BASE_DOMAIN

[v3_req]
subjectAltName = @alt_names

[alt_names]
DNS.1 = *.$BASE_DOMAIN
DNS.2 = $BASE_DOMAIN
EOF

# The file name can be anything
FILE_NAME="$BASE_DOMAIN"

# Remove previous keys
echo "Removing existing certs like $FILE_NAME.*"
if ls /etc/apache2/certs2/$FILE_NAME.* 1> /dev/null 2>&1; then
  rm -rf /etc/apache2/certs2/$FILE_NAME.*
fi

echo "Generating certs for $BASE_DOMAIN"

# Generate our Private Key, CSR and Certificate
# Use SHA-2 as SHA-1 is unsupported from Jan 1, 2017

openssl req -new -x509 -newkey rsa:2048 -sha256 -nodes -keyout "/etc/apache2/certs2/$FILE_NAME.key" -days $DAYS -out "/etc/apache2/certs2/$FILE_NAME.crt" -passin pass:$PASSPHRASE -config "$CONFIG_FILE"

# OPTIONAL - write an info to see the details of the generated crt
openssl x509 -noout -fingerprint -text < "/etc/apache2/certs2/$FILE_NAME.crt" > "/etc/apache2/certs2/$FILE_NAME.info"

# Protect the key
chmod 400 "/etc/apache2/certs2/$FILE_NAME.key"

# Remove the config file
rm -f $CONFIG_FILE

Contenuto del file di config Mysql "mysqld.conf"

Questo file è riportato per comodità. Non è necessario usarlo, ma è fortemente consigliato nel caso si abbia a disposizione una macchina con almenot 16GB di RAM.

#
# The MySQL database server configuration file.
#
# One can use all long options that the program supports.
# Run program with --help to get a list of available options and with
# --print-defaults to see which it would actually understand and use.
#
# For explanations see
# http://dev.mysql.com/doc/mysql/en/server-system-variables.html

# Here is entries for some specific programs
# The following values assume you have at least 32M ram

[mysqld]
#
# * Basic Settings
#
user            = mysql
# pid-file      = /var/run/mysqld/mysqld.pid
# socket        = /var/run/mysqld/mysqld.sock
# port          = 3306
# datadir       = /var/lib/mysql


# If MySQL is running as a replication slave, this should be
# changed. Ref https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html#sysvar_tmpdir
# tmpdir                = /tmp
#
# Instead of skip-networking the default is now to listen only on
# localhost which is more compatible and is not less secure.
bind-address            = 127.0.0.1
skip-networking
sql_mode=NO_ENGINE_SUBSTITUTION
default-authentication-plugin=mysql_native_password
collation-server = utf8_unicode_ci
character-set-server = utf8
#
# * Fine Tuning
#
# sort_buffer_size        = 256000000 (orig)
# key_buffer_size               = 16M (orig)
# max_allowed_packet    = 64M
# thread_stack          = 256K

# thread_cache_size       = -1

# This replaces the startup script and checks MyISAM tables if needed
# the first time they are touched
myisam-recover-options  = BACKUP

# my fine tuning
max_connections          = 20
table_open_cache         = 2048
thread_stack             = 32M
thread_cache_size        = 8
max_allowed_packet       = 16M
max_heap_table_size      = 128M
binlog_cache_size        = 2M
sort_buffer_size         = 16M
join_buffer_size         = 16M
tmp_table_size           = 128M
key_buffer_size          = 512M
read_buffer_size         = 4M
read_rnd_buffer_size     = 32M
bulk_insert_buffer_size  = 64M
myisam_sort_buffer_size  = 128M
innodb_buffer_pool_size  = 2G
innodb_lock_wait_timeout = 150



# table_open_cache       = 4000

#
# * Logging and Replication
#
# Both location gets rotated by the cronjob.
#
# Log all queries
# Be aware that this log type is a performance killer.
# general_log_file        = /var/log/mysql/query.log
# general_log             = 1
#
# Error log - should be very few entries.
#
log_error = /var/log/mysql/error.log
#
# Here you can see queries with especially long duration
# slow_query_log                = 1
# slow_query_log_file   = /var/log/mysql/mysql-slow.log
# long_query_time = 2
# log-queries-not-using-indexes
#
# The following can be used as easy to replay backup logs or for replication.
# note: if you are setting up a replication slave, see README.Debian about
#       other settings you may need to change.
# server-id             = 1
# log_bin                       = /var/log/mysql/mysql-bin.log
# binlog_expire_logs_seconds    = 2592000
max_binlog_size   = 100M
# binlog_do_db          = include_database_name
# binlog_ignore_db      = include_database_name
Attenzione! Questo contenuto è vecchioQuesto articolo risale al 2021, quindi i contenuti e le operazioni qui consigliate potrebbero essere diventate obsolete nel corso del tempo.

E' stata una bella avventura. Dal lontano 2016, quando MetaDB era solo un'idea, ad oggi, che il risultato di tanto lavoro e tanta dedizione è diventato realtà.

Sono elettrizzato nell'annunciare che il nostro progetto MetaDB, rilasciato al pubblico con licenza d'uso dei dati CC BY-NC-SA 4.0, è finalmente online, funzionante e soprattutto pieno di informazioni utilissime per tutti gli esperti nel settore web, e in generale per tutti i Nerd come noi!

MetaDB è un progetto lanciato in produzione nel Gennaio 2021, interamente seguito da me in prima persona, con l'ausilio del team Polarity Bit con il quale collaboro, che pone l'analisi "statica" dei siti web sotto un punto di vista differente e innovativo.

Siamo infatti abituati a tool online di ogni tipo ( solo per citarne alcuni ... seochecker, builtwith, ahrefs, shodan ) che effettuano analisi on-page per domini singoli, e popolano statistiche o dati in riferimento al sito stesso ed eventualmente al sito target confrontandolo con altri siti web.

MetaDB è invece un sistema di analisi statistica e censimento dei siti web, che pone il focus sull'analisi aggregata di "tutti i siti" al posto che sulla analisi del singolo dominio.

La cosa interessante di MetaDB è l'approccio alla analisi di "tutti i siti". Infatti, come si crea un database di tutti i nomi a dominio, per poter effettuare l'analisi del (eventuale) sito web collegato? (non tutti i domini sono registrati per "rispondere" ad una richiesta HTTP, alcuni vengono usati ad esempio solo per la parte email)

MetaDB effettua la scansione partendo da un sottoinsieme di siti web iniziale, una specie di "seed", ed effettua quello che in gergo tecnico si chiama Snowball Sampling. Il seed iniziale viene posto in una coda FIFO, e il codice HTML di ogni sito viene sottoposto a scansione. La scansione del codice HTML riguarda anche tutti i tag <a href>, e quindi tutti i link che puntano a "domini esterni" rispetto al dominio in questione vengono inseriti in coda per l'analisi.

Questa tecnica permette, dopo un numero abbastanza alto di scansioni, di creare una mappa di relazioni piuttosto vasta tra i siti. Ovviamente, per logica, usando questa tecnica non è possibile raggiungere tutti i siti web (e quindi i domini registrati), ma è possibile solo costruire il grafo ad albero di tutti i domini che si referenziano tra loro. Più è vasto il seed iniziale, e più sarà grande il grafo finale.

MetaDB analizza parecchi aspetti dei siti web analizzati, offrendo la possibilità di filtrare i risultati per TLD (estensione del dominio) e lingua del sito. Gli aspetti analizzati includono:

  • Tecnologie utilizzate per la costruzione e il funzionamento del sito (come, ad esempio, PHP - jQuery - Bootstrap - React - Ecommerce)
  • Server di hosting e provider di connettività dell'hosting (Autonomous System Network)
  • Tipi di server web e relative versioni utilizzate (Apache, Nginx, etc)
  • Insight sull'utlizzo di Template e Plugin di Wordpress
  • Codici di errore HTTP più frequenti sui siti offline
  • Utilizzo HTTPS / Linearizzazione www.*
  • Siti web più referenziati (link in ingresso)
  • Text-to-html ratio e suddivisione tra siti che usano un T2HTML ratio sufficiente (>8%) e non (<8%)
  • Insight sull'uso dei tag H1 -> H4 con focus particolare sui siti più popolari, e quelli più referenziati

Una curiosità: sapevate che la maggior parte dei siti web iniziano con la lettera S, con il 9,38% sul totale dei nomi a dominio?


Altro dato, un pò meno eclatante: il 39,19% di tutti i siti web analizzati ha almeno un link verso Facebook, e il 22,87% verso Twitter.

Un dato che mi ha lasciato perplesso è quello relativo all'auto-redirect verso il protocollo sicuro https.

Vero, se un utente raggiunge un sito web è molto probabile lo faccia tramite un motore di ricerca. Ma se lo stesso utente dovesse scrivere a mano il dominio sulla barra degli indirizzi, è incredibile sapere che solo il 31,89% dei siti web effettua un redirect automatico verso https.

Ora, la curiosità passa a Voi lettori. Vi consiglio di andare subito su https://metadb.co e navigare il sito. Troverete molti spunti interessanti per creare contenuti di gradimento per il Vostro pubblico (mi riferisco soprattutto ai Blog di settore), e per condividere qualche informazione utile sui canali social.

Abbiamo dedicato parecchie ore di sviluppo per creare un tool di esportazione dei grafici in formato PNG direttamente sulla GUI del sito. Con un semplice click potrete scaricare i grafici, e ri-pubblicarli su tutti i canali di vostro gradimento.

Nel caso in cui abbiate bisogno di qualche dato specifico e molto settoriale, e possibile estrapolare dati custom dalla base di dati che compone MetaDB. Il posto giusto per effettuare richieste è tramite il modulo di contatto predisposto su MetaDB.

MetaDB è solo all'inizio del suo percorso. Attendiamo con molta curiosità il feedback che arriverà dalla rete, e faremo il nostro meglio per soddisfare le richieste.

Buona navigazione su MetaDB. Speriamo vivamente che possa essere un ottimo spunto per molti Internet Enthusiast, per gli sviluppatori, e per tutte le persone che rendono possibile il funzionamento del web.

Attenzione! Questo contenuto è vecchioQuesto articolo risale al 2020, quindi i contenuti e le operazioni qui consigliate potrebbero essere diventate obsolete nel corso del tempo.

Il nuovo Coronavirus è piombato in modo violento nelle nostre vite quotidiane, mettendo a dura prova il nostro sistema sanitario nazionale, obbligandoci a gestire nuove paure e abitudini difficili da accettare, e facendo vittime a migliaia.

Pensiero di molti è che questa pandemia, purtroppo, rimarrà persistente per qualche mese. Probabilmente si rifarà viva una volta spenta, con focolai auspicabilmente contenuti e locali, ma parlando schiettamente, potremmo stare veramente tranquilli solo quando verrà scoperto un vaccino e reso disponibile per l'intera umanità.

Ci accompagnerà una grossa crisi di liquidità, e un grosso stravolgimento delle nostre abitudini lavorative, bisogna esserne consci, e accettare la realtà con il massimo della flessibilità mentale.

Nella difficile e pesante realtà che stiamo vivendo, possiamo però trovare alcuni spunti di riflessione importanti.

Il lavoro agile, lo "smart working" è stato messo in primo piano, ed è diventata l'unica arma per permettere a tutta una moltitudine di figure professionali, sia freelance che impiegate, la cui principale mansione era quella di "stare seduto davanti ad un computer", di poter finalmente lavorare da casa.
Effettivamente, a conti fatti, lo smart working sta impedendo al mondo del lavoro di collassare su se stesso.

Provate a cercare "flexible working absenteeism", o "flexible working motivation" su Google, troverete decine e decine di studi approfonditi, il cui minimo comune multiplo è: si rende di più, e meglio, lavorando di meno in termini di ore seduti alla scrivania.

D'altro canto, però, lo smart working richiede specifiche infrastrutture telematiche e informatiche per poter essere efficiente:

  • Banda larga
  • Accesso remoto ai documenti del Cloud Aziendale
  • Deviazioni di chiamata
  • Software di meeting e cooperazione, condivisione schermo, e simili
  • Informatizzazione del personale, soprattutto legata alla divulgazione di best practice per non essere veicolo di attacchi informatici (spam, phishing, etc)
In più, il Covid-19 sta anche (e ovviamente) mettendo a dura prova le piattaforme e-commerce, che in alcuni settori strategici stanno ricevendo una mole di lavoro mai avuta in precedenza. In questo caso, le criticità sono differenti:

  • Le piattaforme utilizzate per l'ecommerce (Magento, Woocommerce, Custom, etc) sono adatte ai volumi di ordini?
  • Le infrastrutture informatiche a supporto (server, CDN, caching) sono all'altezza del traffico in ingresso?
  • I sistemi logistici per le spedizioni sono in grado di accettare e smaltire gli incrementi nei volumi?

Da freelance PHP, esperto in tecnologie Web e Cloud, posso rispondere solo ad alcune di queste domande, e trovo questa drammatica esperienza del nuovo Coronavirus, oltre che terribile dal punto di vista umano, anche una opportunità: si dovrà giocoforza aumentare il tasso tecnico, alzare l'asticella delle strutture informatiche a supporto del telelavoro e delle piattaforme e-commerce, e le Aziende dovranno affrontare alcuni problemi che vengono sempre messi in secondo piano: affidabilità dei sistemi informatici, sicurezza dei sistemi informativi, GDPR e risvolti nel telelavoro, disaster recovery & response.

Questo è il momento giusto per prendere coscienza di alcuni importantissimi aspetti della tecnologia a supporto del lavoro, che vengono immancabilmente glissati durante periodi "normali", perchè determinate questioni sono troppo complicate, oppure perchè "ci sono già gli IT che se ne occupano", oppure perchè semplicemente già oberati di lavoro, e l'informatica è difficile da capire, è quasi magia.

Voglio quindi dare qualche consiglio strategico-informatico.

  • Banda larga: questo periodo è complicato dal punto di vista di congestione del traffico, soprattutto perchè le scuole sono chiuse e molti servizi di gaming e streaming (che di solito non hanno picchi nelle ore diurne) stanno congestionando alcuni nodi. Ad ogni modo, assicuratevi sempre di scegliere il miglior provider di connettività, senza aver paura di cambiare;
  • Accesso remoto ai documenti del Cloud Aziendale: bisogna pensare di installare VPN aziendali, e sistemi di accesso ai file condivisi aziendali, con logging e granularità dei permessi di accesso, nel caso di grosse aziende, o semplicemente accessi a Bastion Host nel caso di piccole realtà che hanno un NAS condiviso in azienda.
    Importante: NON APRITE LE PORTE DEL ROUTER al vostro NAS aziendale abilitando l'accesso diretto dall'esterno, perchè è il secondo vettore di attacco dopo l'ingegneria sociale. La rete è piena di bot che scandagliano inesorabili alla ricerca di porte aperte e vulnerabilità note (https://www.shodan.io/);
  • Informatizzazione del personale: è molto importante avere collaboratori che sappiano quello che stanno facendo con il computer, conoscendo i rischi correlati alle loro azioni in internet. Dalla apertura di un banalissimo file "che non sembrava sospetto", all'utilizzo di computer protetti da crittografia del file system, fino alla digital awareness.
  • Piattaforme a supporto delle attività e-commerce: mi riferisco soprattutto ai piccoli/medi ecommerce, perchè i colossi ragionano su altri termini che esulano anche dalle mie esperienze dirette: non lesinate sul portafogli quando volete sfondare nel mondo dell'e-commerce. Le piattaforme open-source sono buone fino ad un certo punto, e sono comunque vulnerabili. Inoltre, assicuratevi di avere un ottimo supporto logistico, che i vostri fornitori abbiano supporti logistici adeguati, e in linea di massima, che siate pronti a ondate di lavoro che potrebbero stravolgere le vostre attività quotidiane;
  • Infrastrutture informatiche a supporto delle attività di telelavoro e/o ecommerce: in primis, utilizzate provider di sistemi Cloud affidabili (Hetzner, Digital Ocean, Azure, Amazon AWS per citarne alcuni), e prendete piena consapevolezza del fatto che in casi di picchi di traffico, bisogna avere dei sistemi scalabili che siano in grado di gestire questo traffico.
    Non lesinate neanche sulla importantissima questione legata al disaster recovery: se qualcosa dovesse andare storto, bisogna avere il piano B.

La pandemia sta cambiando le nostre abitudini. Fate in modo che, alla fine di questo incubo, abbiate creato una diversa consapevolezza su queste strategiche questioni informatiche, e che siate pronti al cambiamento una volta usciti da questa bruttissima situazione.

I medici in primis, e Internet in secundis stanno facendo in modo che il sistema economico e sociale non collassi.

Un grazie sentito a tutti i medici, infermieri, alla Protezione Civile, e a tutti i bravi professionisti che con il loro coraggio stanno mandando avanti le loro attività quotidiane da casa propria, senza far espandere ancora di più questa pandemia.

Ne usciremo ancora più forti.