- Schlüssel zur Rettung: Extrahieren und Sichern von Codemagic Secure Variables - 26. Oktober 2023
- Effektives Zeitmanagement für Entwickler: Praktische Strategien - 13. September 2023
- Teil 2: Elasticsearch und FSCrawler in Laravel - 6. April 2023
Für Windows existieren eine Vielzahl von LAMP Applikationen wie Laragon oder XAMPP. Allerdings sind einige nützliche Pakete, die man zu Laravel hinzufügen kann, nicht mit Windows kompatibel. Auch Funktionen wie der Scheduler oder Queue Workers können nur über Umwege getestet werden. Anstelle für jeden Entwickler bei jedem Projekt Server zu erstellen und echte Domains darauf umzuleiten, haben wir hier eine detaillierte Anleitung erstellt, mit der man auf dem Windows Subsystem for Linux eine vollwertige Entwicklungsumgebung erstellen kann.
Auch erstellt haben wir ein Shell Script, welches die komplette Verwaltung übernimmt:
- Starten/Stoppen/Neustarten des LAMP Stacks
- Anzeigen aller vHosts/Ordner
- Erstellung neuer Projekte mit Option für Laravel
- Erstellung einer neuen Datenbank mit Benutzer und Passwort und automatischem Ausfüllen der .env.
- Erstellung von Self Signed Certificates
Updates
- 12/08/2022 Autostart Lamp Stack
- 15/08/2022 Visual Studio Code mit WSL Verbinden
- 13/03/2023 Unix Installationsskript erstellt
- 18/04/2023 Lamp Skript für neue Version von GSudo angepasst, kleinere Bugfixes und Improvements
- 10/08/2023 PHP Choice im Installationsskript angepasst, Log Directory in Lamp Script angepasst
Vorbereitung in Windows
Damit wir innerhalb von Windows auf die im WSL gehosteten Seiten zugreifen können, müssen wir jedes Mal einen neuen Eintrag in der Host Datei hinterlegen. Damit das automatisch durch unser Script übernommen werden kann, verwenden wir gsudo. Um gsudo zu installieren, öffnen wir PowerShell als Administrator und verwenden diesen Befehl:
PowerShell -Command "Set-ExecutionPolicy RemoteSigned -scope Process; iwr -useb https://raw.githubusercontent.com/gerardog/gsudo/master/installgsudo.ps1 | iex"
Als nächstes loggen wir uns im Windows Store ein und installieren Ubuntu. Wir verwenden die neueste Version (Ubuntu 22.04 LTS).
Grundinstallation
Update: Einfaches Installationskript
Nachdem ich dieses Tutorial zum vierten mal in kurzer Zeit durcharbeite, habe ich das getan was jeder fauler Entwickler macht. 2 Stunden lang ein Shell Skript erstellt um alles automatisch zu machen. Natürlich sollte man den Rest des Blogeintrages weiter lesen um zu sehen was passiert.
wget https://www.admin-code.de/downloads/install-lamp.sh
bash install-lamp.sh
Ab hier muss man der Anleitung wieder folgen da wir uns aus Unix rausbewegen um das SSL Zertifikat zu hinterlegen.
Manuelle Installation
Nach erfolgreicher Installation von Ubuntu wechseln wir auf den root Benutzer.
sudo su
Damit wir ungestraft sudo verwenden können ohne ständig das Passwort eintippen zu müssen, fügen wir mit visudo am Ende der sudoers Datei eine Ausnahme für unseren Account hinzu (billinger mit dem eigenen Accountnamen austauschen).
billinger ALL=(ALL) NOPASSWD:ALL
PHP Repository hinzufügen:
add-apt-repository ppa:ondrej/php
Update, Upgrade und Installation von Apache, MySQL und PHP. Da bei älteren Laravel Versionen PHP 8 nicht funktioniert, installieren wir gleich PHP 7.4 und 8.1 gleichzeitig. Je nachdem welche Version später notwendig ist, kann diese einfach gewechselt werden.
apt-get update && apt-get upgrade -y
apt install -y apache2 mysql-server unzip php8.1-{fpm,gd,mysql,curl,xml,zip,intl,mbstring,bz2,ldap,apcu,bcmath,gmp,imagick,igbinary,redis,smbclient,cli,common,opcache,readline,imagick,redis} php7.4-{fpm,gd,mysql,curl,xml,zip,intl,mbstring,bz2,ldap,apcu,bcmath,gmp,imagick,igbinary,redis,smbclient,cli,common,opcache,readline,imagick,redis}
Damit der mysql Benutzer auch ein Home Verzeichnis hat und nicht bei jedem Neustart einen Fehler ausgibt:
usermod -d /var/lib/mysql/ mysql
Apache Konfiguration
Diverse notwendige Apache Module werden aktiviert und anschließend PHP FPM 8.1 umgestellt. Auf dem gleichen Weg kann auch PHP 7.4 aktiviert werden.
a2enmod rewrite ssl vhost_alias authz_groupfile headers cache expires actions alias proxy_fcgi proxy proxy_html proxy_http xml2enc mpm_event http2
a2enconf php8.1-fpm
echo "Protocols h2 http/1.1" >> /etc/apache2/apache2.conf
PHP Konfiguration
Optimierung der Konfiguration:
sed -i "s/;env\[HOSTNAME\] = /env[HOSTNAME] = /" /etc/php/8.1/fpm/pool.d/www.conf
sed -i "s/;env\[TMP\] = /env[TMP] = /" /etc/php/8.1/fpm/pool.d/www.conf
sed -i "s/;env\[TMPDIR\] = /env[TMPDIR] = /" /etc/php/8.1/fpm/pool.d/www.conf
sed -i "s/;env\[TEMP\] = /env[TEMP] = /" /etc/php/8.1/fpm/pool.d/www.conf
sed -i "s/;env\[PATH\] = /env[PATH] = /" /etc/php/8.1/fpm/pool.d/www.conf
sed -i "s/pm.max_children =.*/pm.max_children = 240/" /etc/php/8.1/fpm/pool.d/www.conf
sed -i "s/pm.start_servers =.*/pm.start_servers = 30/" /etc/php/8.1/fpm/pool.d/www.conf
sed -i "s/pm.min_spare_servers =.*/pm.min_spare_servers = 10/" /etc/php/8.1/fpm/pool.d/www.conf
sed -i "s/pm.max_spare_servers =.*/pm.max_spare_servers = 200/" /etc/php/8.1/fpm/pool.d/www.conf
sed -i "s/;pm.max_requests =.*/pm.max_requests = 1000/" /etc/php/8.1/fpm/pool.d/www.conf
sed -i "s/allow_url_fopen =.*/allow_url_fopen = 1/" /etc/php/8.1/fpm/php.ini
sed -i "s/output_buffering =.*/output_buffering = 'Off'/" /etc/php/8.1/cli/php.ini
sed -i "s/max_execution_time =.*/max_execution_time = 3600/" /etc/php/8.1/cli/php.ini
sed -i "s/max_input_time =.*/max_input_time = 3600/" /etc/php/8.1/cli/php.ini
sed -i "s/post_max_size =.*/post_max_size = 10240M/" /etc/php/8.1/cli/php.ini
sed -i "s/upload_max_filesize =.*/upload_max_filesize = 10240M/" /etc/php/8.1/cli/php.ini
sed -i "s/;date.timezone.*/date.timezone = Europe\/\Berlin/" /etc/php/8.1/cli/php.ini
sed -i "s/memory_limit = 128M/memory_limit = 1024M/" /etc/php/8.1/fpm/php.ini
sed -i "s/output_buffering =.*/output_buffering = 'Off'/" /etc/php/8.1/fpm/php.ini
sed -i "s/max_execution_time =.*/max_execution_time = 3600/" /etc/php/8.1/fpm/php.ini
sed -i "s/max_input_time =.*/max_input_time = 3600/" /etc/php/8.1/fpm/php.ini
sed -i "s/post_max_size =.*/post_max_size = 10240M/" /etc/php/8.1/fpm/php.ini
sed -i "s/upload_max_filesize =.*/upload_max_filesize = 10240M/" /etc/php/8.1/fpm/php.ini
sed -i "s/;date.timezone.*/date.timezone = Europe\/\Berlin/" /etc/php/8.1/fpm/php.ini
sed -i "s/;session.cookie_secure.*/session.cookie_secure = True/" /etc/php/8.1/fpm/php.ini
sed -i "s/;opcache.enable=.*/opcache.enable=1/" /etc/php/8.1/fpm/php.ini
sed -i "s/;opcache.enable_cli=.*/opcache.enable_cli=1/" /etc/php/8.1/fpm/php.ini
sed -i "s/;opcache.memory_consumption=.*/opcache.memory_consumption=128/" /etc/php/8.1/fpm/php.ini
sed -i "s/;opcache.interned_strings_buffer=.*/opcache.interned_strings_buffer=16/" /etc/php/8.1/fpm/php.ini
sed -i "s/;opcache.max_accelerated_files=.*/opcache.max_accelerated_files=10000/" /etc/php/8.1/fpm/php.ini
sed -i "s/;opcache.revalidate_freq=.*/opcache.revalidate_freq=1/" /etc/php/8.1/fpm/php.ini
sed -i "s/;opcache.save_comments=.*/opcache.save_comments=1/" /etc/php/8.1/fpm/php.ini
sed -i "s|;emergency_restart_threshold.*|emergency_restart_threshold = 10|g" /etc/php/8.1/fpm/php-fpm.conf
sed -i "s|;emergency_restart_interval.*|emergency_restart_interval = 1m|g" /etc/php/8.1/fpm/php-fpm.conf
sed -i "s|;process_control_timeout.*|process_control_timeout = 10|g" /etc/php/8.1/fpm/php-fpm.conf
sed -i '$aapc.enable_cli=1' /etc/php/8.1/mods-available/apcu.ini
sed -i "s/rights=\"none\" pattern=\"PS\"/rights=\"read|write\" pattern=\"PS\"/" /etc/ImageMagick-6/policy.xml
sed -i "s/rights=\"none\" pattern=\"EPS\"/rights=\"read|write\" pattern=\"EPS\"/" /etc/ImageMagick-6/policy.xml
sed -i "s/rights=\"none\" pattern=\"PDF\"/rights=\"read|write\" pattern=\"PDF\"/" /etc/ImageMagick-6/policy.xml
sed -i "s/rights=\"none\" pattern=\"XPS\"/rights=\"read|write\" pattern=\"XPS\"/" /etc/ImageMagick-6/policy.xml
sed -i "s/;env\[HOSTNAME\] = /env[HOSTNAME] = /" /etc/php/7.4/fpm/pool.d/www.conf
sed -i "s/;env\[TMP\] = /env[TMP] = /" /etc/php/7.4/fpm/pool.d/www.conf
sed -i "s/;env\[TMPDIR\] = /env[TMPDIR] = /" /etc/php/7.4/fpm/pool.d/www.conf
sed -i "s/;env\[TEMP\] = /env[TEMP] = /" /etc/php/7.4/fpm/pool.d/www.conf
sed -i "s/;env\[PATH\] = /env[PATH] = /" /etc/php/7.4/fpm/pool.d/www.conf
sed -i "s/pm.max_children =.*/pm.max_children = 240/" /etc/php/7.4/fpm/pool.d/www.conf
sed -i "s/pm.start_servers =.*/pm.start_servers = 30/" /etc/php/7.4/fpm/pool.d/www.conf
sed -i "s/pm.min_spare_servers =.*/pm.min_spare_servers = 10/" /etc/php/7.4/fpm/pool.d/www.conf
sed -i "s/pm.max_spare_servers =.*/pm.max_spare_servers = 200/" /etc/php/7.4/fpm/pool.d/www.conf
sed -i "s/;pm.max_requests =.*/pm.max_requests = 1000/" /etc/php/7.4/fpm/pool.d/www.conf
sed -i "s/allow_url_fopen =.*/allow_url_fopen = 1/" /etc/php/7.4/fpm/php.ini
sed -i "s/output_buffering =.*/output_buffering = 'Off'/" /etc/php/7.4/cli/php.ini
sed -i "s/max_execution_time =.*/max_execution_time = 3600/" /etc/php/7.4/cli/php.ini
sed -i "s/max_input_time =.*/max_input_time = 3600/" /etc/php/7.4/cli/php.ini
sed -i "s/post_max_size =.*/post_max_size = 10240M/" /etc/php/7.4/cli/php.ini
sed -i "s/upload_max_filesize =.*/upload_max_filesize = 10240M/" /etc/php/7.4/cli/php.ini
sed -i "s/;date.timezone.*/date.timezone = Europe\/\Berlin/" /etc/php/7.4/cli/php.ini
sed -i "s/memory_limit = 128M/memory_limit = 1024M/" /etc/php/7.4/fpm/php.ini
sed -i "s/output_buffering =.*/output_buffering = 'Off'/" /etc/php/7.4/fpm/php.ini
sed -i "s/max_execution_time =.*/max_execution_time = 3600/" /etc/php/7.4/fpm/php.ini
sed -i "s/max_input_time =.*/max_input_time = 3600/" /etc/php/7.4/fpm/php.ini
sed -i "s/post_max_size =.*/post_max_size = 10240M/" /etc/php/7.4/fpm/php.ini
sed -i "s/upload_max_filesize =.*/upload_max_filesize = 10240M/" /etc/php/7.4/fpm/php.ini
sed -i "s/;date.timezone.*/date.timezone = Europe\/\Berlin/" /etc/php/7.4/fpm/php.ini
sed -i "s/;session.cookie_secure.*/session.cookie_secure = True/" /etc/php/7.4/fpm/php.ini
sed -i "s/;opcache.enable=.*/opcache.enable=1/" /etc/php/7.4/fpm/php.ini
sed -i "s/;opcache.enable_cli=.*/opcache.enable_cli=1/" /etc/php/7.4/fpm/php.ini
sed -i "s/;opcache.memory_consumption=.*/opcache.memory_consumption=128/" /etc/php/7.4/fpm/php.ini
sed -i "s/;opcache.interned_strings_buffer=.*/opcache.interned_strings_buffer=16/" /etc/php/7.4/fpm/php.ini
sed -i "s/;opcache.max_accelerated_files=.*/opcache.max_accelerated_files=10000/" /etc/php/7.4/fpm/php.ini
sed -i "s/;opcache.revalidate_freq=.*/opcache.revalidate_freq=1/" /etc/php/7.4/fpm/php.ini
sed -i "s/;opcache.save_comments=.*/opcache.save_comments=1/" /etc/php/7.4/fpm/php.ini
sed -i "s|;emergency_restart_threshold.*|emergency_restart_threshold = 10|g" /etc/php/7.4/fpm/php-fpm.conf
sed -i "s|;emergency_restart_interval.*|emergency_restart_interval = 1m|g" /etc/php/7.4/fpm/php-fpm.conf
sed -i "s|;process_control_timeout.*|process_control_timeout = 10|g" /etc/php/7.4/fpm/php-fpm.conf
sed -i '$aapc.enable_cli=1' /etc/php/7.4/mods-available/apcu.ini
sed -i "s/rights=\"none\" pattern=\"PS\"/rights=\"read|write\" pattern=\"PS\"/" /etc/ImageMagick-6/policy.xml
sed -i "s/rights=\"none\" pattern=\"EPS\"/rights=\"read|write\" pattern=\"EPS\"/" /etc/ImageMagick-6/policy.xml
sed -i "s/rights=\"none\" pattern=\"PDF\"/rights=\"read|write\" pattern=\"PDF\"/" /etc/ImageMagick-6/policy.xml
sed -i "s/rights=\"none\" pattern=\"XPS\"/rights=\"read|write\" pattern=\"XPS\"/" /etc/ImageMagick-6/policy.xml
Erweiterung der php.ini mit einer custom.ini und Erstellung von symbolischen Links:
#### /etc/php/custom.ini
max_execution_time = 2400
max_input_time = 900
post_max_size = 800M
memory_limit = 4048M
upload_max_filesize = 800M
max_input_vars = 100000
max_file_uploads = 5000
realpath_cache_size = 4M
date.timezone = 'Europe/Berlin'
display_errors = On
error_log = /var/log/php-error.log
error_reporting = E_ALL
phar.readonly = 0
opcache.enable=1
opcache.enable_cli=0
opcache.memory_consumption=512
opcache.interned_strings_buffer=64
opcache.max_accelerated_files=32531
opcache.save_comments=1
opcache.fast_shutdown=0
opcache.max_file_size=0
opcache.validate_timestamps=1
opcache.revalidate_freq=2
ln -s /etc/php/custom.ini /etc/php/7.4/fpm/conf.d/custom.ini
ln -s /etc/php/custom.ini /etc/php/8.1/fpm/conf.d/custom.ini
ln -s /etc/php/custom.ini /etc/php/7.4/cli/conf.d/custom.ini
ln -s /etc/php/custom.ini /etc/php/8.1/cli/conf.d/custom.ini
Composer Installation
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
php composer-setup.php
php -r "unlink('composer-setup.php');"
mv composer.phar /usr/local/bin/composer
echo "export COMPOSER_ALLOW_SUPERUSER=1" >> ~/.bashrc
NPM Installation
curl -fsSL https://raw.githubusercontent.com/tj/n/master/bin/n | bash -s lts
npm install -g n
Mit dem Paket „n“ kann man einfach die NPM und Node Versionen installieren und ändern.
lamp Script hinterlegen
visudo ausführen und in der Zeile Details secure_path= /opt/lamp hinzufügen
mkdir /opt/lamp
cd /opt/lamp
wget https://admin-code.de/downloads/lamp
chmod +x lamp
echo "export PATH='$PATH:/opt/lamp'" >> ~/.bashrc
source ~/.bashrc
Rechte in /var/www anpassen
(billinger mit dem eigenen Accountnamen austauschen)
chown -R www-data:www-data /var/www
chmod 00755 /var
chmod 00755 /var/www
find /var/www -type d -exec chmod 00755 {} \;
find /var/www -type f -exec chmod 00644 {} \;
usermod -a -G www-data billinger
Mögliche Script Schalter
Ausführen kann man das Script mit dem Befehl „lamp“. Danach kommen die weiteren Keywords. Die Befehle „start“, „stop“, „restart“, „status“ beziehen sich auf die Services. Mit „list“ kann man kontrollieren, welche Konfigurationen in Apache vorhanden sind und welche Ordner in /var/www stehen. Mit „add Projektname“ und „remove Projektname“ können Projekte hinzugefügt und gelöscht werden (beim Löschen wird nur die Apache Konfiguration gelöscht. Die Daten bleiben weiterhin vorhanden).
Die Hilfe kann über „lamp help“ angezeigt werden.
Lamp Script anpassen
Damit PHP-FPM korrekt gestartet, beendet und neu gestartet werden kann müssen die entsprechenden Zeilen in /opt/lamp/lamp angepasst werden. Die entsprechenden Versionen sollten auskommentiert werden.
Script ausführen
Da es ein paar Funktionen gibt die ohne https nicht funktionieren, erstellen wir für alle neuen Projekte automatisch Zertifikate. Da es sich hier allerdings um lokale Domainnamen handelt, können hier keine „echten“ Zertifikate wie von Let’s Encrypt verwendet werden. Eine Certificate Authority kann die Validität unserer Entwicklungsseiten nicht verifizieren. Deswegen werden wir unsere eigene Certificate Authority erstellen.
Wir verwenden hierfür dev-certificates von Ben Morel (https://github.com/BenMorel).
Unser lamp Script prüft automatisch, ob das Zertifikat schon existiert und erstellt es gegebenenfalls neu. Damit der Browser dieses auch verwendet, muss es hinterlegt werden.
Nachdem das Zertifikat hinterlegt wurde muss der Browser komplett geschlossen werden, am besten einmal den PC Neustarten.
Bei der Erstellung eines neuen Projektes kann zwischen Laravel und nicht Laravel entschieden werden. Ebenfalls ist es möglich, ein zuvor gepulltes Projekt in die vHosts mit einzufügen. Dabei sollte man die Frage ob Laravel installiert werden soll, ablehnen. Eine neue Datenbank kann trotzdem automatisch generiert und in die .env geschrieben werden.
Ebenfalls ist es möglich, „normale“ Projekte mit oder ohne Datenbank zu erstellen. Diese bekommen dann, um zu verifizieren dass die Installation funktioniert hat, eine Standard HTML Seite.
Unter den allgemeinen Informationen im Script kann die Variable TLD mit einer gewünschten TLD definiert werden. Moderne Browser werden beim aufrufen wie my-project.local direkt die Suchmaschine verwenden. Wer nicht jedes erste Mal https:// schreiben möchte, kann hier eine reguläre TLD wie .de oder .com verwenden. Besser wären allerdings die neuen TLDs wie .fun, .xyz, oder thematisch passend .test.
Autostart LAMP Stack
Da Apache und MySQL nicht Teil unseres Windows Betriebssystems sind, steht uns der LAMP Stack erst zur Verfügung, wenn Ubuntu gestartet wird und wir dort die Services entweder automatisch oder manuell über „lamp start“ ausführen. Damit dies automatisiert passiert erstellen wir uns ein kleines Script im Autostart Ordner.
Als nächstes öffnen wir mit WIN + R den Ausführen Dialog und öffnen den Autostart Ordner von Windows.
shell:startup
In diesem Ordner erstellen wir nun eine neue Batch Datei in der wir unsere WSL Befehle hinterlegen. Die Batch Datei wird bei jedem Systemstart automatisch ausgeführt.
@echo off
wsl sudo bash /opt/lamp/lamp start
Visual Studio Code mit WSL Verbinden
Sobald WSL auf dem Gerät installiert ist, sollte sich Visual Studio Code automatisch beim Start melden und das Plugin „Remote – WSL“ vorschlagen, nun dieses installieren und in der .bashrc den Pfad für Visual Studio hinterlegen. Danach kann in WSL mit dem Befehl „code /path/to/open“ das gewünschte Verzeichnis geöffnet werden.
export PATH=$PATH:"/mnt/c/Users/BILLINGER/AppData/Local/Programs/Microsoft VS Code/bin"
Abschließend nochmal das .bashrc File mit source .bashrc laden.
Sollten Sie noch Fragen haben oder eine Beratung wünschen, können Sie gerne mit uns Kontakt aufnehmen oder unsere Webseite besuchen.
Gerne können Sie hier auch weitere Artikel zum Thema Laravel lesen. Andere Sysadmin Blogartikel finden Sie auf unserem Hauptblog.