Kako postaviti development server na Manjaro Linux (ili bilo kojoj arch-based distri)?
Ovdje se bavimo sa nginx, php, mysql(mariadb), phpmyadmin i composer tehnologijama.

Ažurirajte sustav:

sudo pacman -Syu

Zatim instalirajte paketiće:

sudo pacman -S nginx php php-fpm mariadb phpmyadmin composer php-intl

Obavezno ponovo pokrenite računalo!

MariaDB (MySQL)

Nakon što smo instalirali moramo podesiti MariaDB server za development.

sudo mysql_install_db --user=mysql --basedir=/usr --datadir=/var/lib/mysql
sudo systemctl enable --now mariadb
sudo mysql_secure_installation

Nemamo šifru pa samo opali po enteru.

Enter current password for root (enter for none): 

Želimo li koristiti unix socket umjesto ip/port opcije? Najjednostavnije, to znači da će se za komunikaciju sa mariadb serverom, podaci prebacivati kroz pipe datoteku. Stisnemo ‘Y’.

Switch to unix_socket authentication [Y/n]

Trebamo postaviti root password. Pa stis’ na ‘Y’.

You already have your root account protected, so you can safely answer 'n'.
Change the root password? [Y/n] 

Ukloni test opciju ‘anonymous users’? Stisni ‘Y’.

Remove anonymous users? [Y/n]

Blokiraj login sa drugih računala? Hell ‘Y’ea!

Disallow root login remotely? [Y/n]

Ukloni test bazu? Da naravno ‘Y’.

Disallow root login remotely? [Y/n]

Reset tablica sa podatcima pristupa bazi? ‘Y’ep!

Reload privilege tables now? [Y/n] 

I to je to. Da testiramo (kao obični korisnik, odnosno bez sudo):

mysql -u root -p

phpmyadmin

phpMyAdmin je web sučelje za pristup mariadb(mysql) bazi podataka. Program pokrećemo preko bash skripte koju pravimo u ‘/usr/local/bin/’ direktoriju:

sudo nano /usr/local/bin/phpmyadmin

Kod skripte:

#!/bin/bash
cd /usr/share/webapps/phpMyAdmin/
php -S localhost:9876

Postavljamo skriptu kao executable:

sudo chmod +x /usr/local/bin/phpmyadmin

Pokrećemo skriptu i u internet pregledniku nas čeka poruka da nam nedostaju ekstenzije:

sudo nano /etc/php/php.ini 

Tražimo dio sa ekstenzijama i od-komentiramo ih. Osim ‘iconv’ i ‘mysqli’ od-komentiramo ‘ext-intl’ i ‘pdo_mysql’ pa restartiramo phpmyadmin skriptu.

Ponovo pokrećemo ‘/usr/local/bin/phpmyadmin’.

PHP

Bilo gdje pravimo direktorij ‘phptest’ sa skriptom ‘index.php’ u nj.

mkdir ./phptest
touch ./phptest/index.php
echo "<?php phpinfo();" > ./phptest/index.php

Pa u ‘phptest’ direktoriju pokrećemo php server sa:

php -S localhost:3333

Super, znači kasnije, ako želimo naučiti PHP onda ćemo jednostavno napraviti direktorij s ‘index.php’ i u njemu pokrenuti naredbu: ‘php -S localhost:3333’.

Za probu uvozimo W3 mysql bazu koja se koristi u primjerima tamo. Kasnije se možete pozabaviti sa W3 MYSQL tutorial primjerima.

Sada ćemo testirati konekciju između PHP-a i MariaDB. Mjenjamo sadržaj ‘./phptest/index.php’ sa:

<?php

$servername = "localhost";
$username = "root";
$password = "YOURROOTPASS";
$database = "w3schools";

try 
{
    $conn = new PDO("mysql:host=$servername;dbname=$database", $username, $password);
    $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    
    $stmt = $conn->prepare("SELECT CustomerName, City, Country FROM Customers;");
	$stmt->execute();

	if ($stmt->rowCount() > 0)
	{
		$row = $stmt->fetchAll(\PDO::FETCH_ASSOC);
		print_r($row);		
	}

}
catch(PDOException $e)
{
    echo "Connection failed: " . $e->getMessage();
}

Pa dobivamo:

COMPOSER

Composer je package manager za PHP. Za probu instaliramo CodeIgniter. Pa u terminalu unosimo:

composer create-project codeigniter4/appstarter project-root

Nakon toga ulazimo u ‘./project-root/’ i pokrećemo u terminalu:

php spark serve

NGINX

Built-in PHP server baš i neradi sa svim php aplikacijama 100% kako treba. Pa ćemo kao ozbiljniji test HTTP server koristiti nginx.

php-fpm

php-fpm‘ šalje php kod iz učitane php datoteke u php interpretator. To radi preko unix socketa ili preko porta na localhost-u. Pokrećemo ‘php-fpm’ service:

sudo systemctl enable php-fpm 
sudo systemctl start php-fpm 

Ono što nas zanima kod ‘php-fpm’ su njegove postavke pa otvaramo ‘/etc/php/php-fpm.d/www.conf’:
Bitno je da su user/group postavljeni na ‘http’ a zanima nas i putanja socket datoteke ‘php-fpm.sock’.

...
user = http
group = http
...
listen = /run/php-fpm/php-fpm.sock

HTTP KORISNIK/GRUPA

Zanima nas, da su u obje conf datoteke, korisnik i grupa, postavljeni na ‘http’. Zbog sigurnosti, ‘http’ grupa ima write pristup samo u ‘/srv/http/public’. Kada prekopiramo datoteke (npr framework) u ‘/srv/http/public’, potrebno je da pokrenemo naredbu koja će nam rekurzivno sve datoteke prebaciti pod http:http:

sudo chown -R http:http /srv/http

Novi nginx.conf

Prvo (BITNO!) radimo bakap datoteke:

sudo mv /etc/nginx/nginx.conf /etc/nginx/nginx.conf_bak

Pa zatim, mjenjamo sadržaj ‘/etc/nginx/nginx.conf’ sa:

user http;
worker_processes  1;

#error_log  logs/error.log;
#pid        logs/nginx.pid;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;


server {
    listen 3000;
    #server_name example.com;
    server_name localhost;
    root /srv/http/public/; #http user can only write here

    #add_header X-Frame-Options "SAMEORIGIN";
    #add_header X-Content-Type-Options "nosniff";

    index index.php index.html index.htm;

    charset utf-8;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location = /favicon.ico { access_log off; log_not_found off; }
    location = /robots.txt  { access_log off; log_not_found off; }

    # error_page 404 /index.php;

    location ~ \.php$ {
        fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        include fastcgi_params;
    }

    location ~ /\.(?!well-known).* {
        deny all;
    }
    
    error_log /var/log/nginx/project_error.log; #errorlog datoteka je ovdje
    access_log /var/log/nginx/project_access.log;
}        
    
}

Sada ćemo obrisati sve u ‘html’ direktoriju i napraviti ‘index.php’ sa ‘phpinfo’ funkcijom koja će nam prikazati informacije o sustavu, serveru i php-u.

sudo rm -r /srv/http/*
sudo mkdir /srv/http/public/
sudo touch /srv/http/public/index.php 
sudo echo "<?php echo phpinfo();" > /srv/http/public/index.php
sudo chown -R http:http /srv/http/

Pokrećemo servis:

sudo systemctl enable nginx

I sada, kada odemo na localhost:3000 vidimo php info:

Server je podignut pod ‘/srv/http/public/’ direktorijem. I tu raspakiramo ‘WordPress’. Ako želimo na server staviti ‘Symfony’ ili ‘Codeigniter’ projekte, onda moramo obrisati ‘public’ direktorij i framework-e ubaciti u ‘/srv/http/’.

Kako develati na nginx?

Dobra fora, ali prebacivati sve na nginx server nakon svake promjene je sporo i besmisleno. Srećom Linux ima mnoštvo alata koji će nam pomoći. U ovom slučaju koristimo inotify i rsync. Jedan prati promjene u direktoriju a drugi sinkronizira direktorije.

Tako da sad koristimo ovu skriptu:

#!/bin/bash

EVENTS="CREATE,DELETE,MODIFY,MOVED_FROM,MOVED_TO"

sync() {
  rsync -avz --chown=http:http ./project-root/ /srv/http/
}
watch() {
  inotifywait -e "$EVENTS" -m -r ./project-root
}

watch | (
while true ; do
  read -t 1 LINE && sync
done
)

Skriptu stavljamo u ‘sync.sh’ datoteku i trebamo ju ‘chmod +x sync.sh’ da ju možemo pokrenuti. Skriptu pokrečemo sa ‘sudo ./sync.sh’ naredbom.

Druga skripta briše sve sa nginx servera. Ime je ‘clean.sh’ ubacivamo sadržaj dolje i radimo chmod isti kao za skriptu gore:

rm -r /srv/http/*

Sinkronizacija

Prvo brišemo sve sa:

sudo ./clean.sh

Instaliramo projekt:

composer create-project codeigniter4/appstarter project-root

A zatim pokrećemo naredbu za sinkronizaciju:

sudo ./sync.sh

Bitno je napomenuti da se projektni direktorij mora zvati ‘project-root’.

Sada kada napravimo promjenu – automatski se sinkroniziraju direktoriji i sadržaj je na serveru. Ovom metodom se možemo sinkronizirati i sa direktorijem na serveru preko SSH-a. Ali o tome možda drugi put.

UPDATE #1:

Poboljšana skripta za sinkronizaciju direktorija.

Brišemo ‘/srv/http/’ sa komandom:

sudo ./script.sh --clear

Sinkroniziramo dir sa:

sudo ./script.sh --dir ./codeigniter_projekt

Sinkronizacija počinje kada napravimo neku izmjenu u direktoriju.

#!/bin/sh

if [[ ! "$2" == */ ]]; then
	DEST_DIR="$2""/"
else
	DEST_DIR="$2"
fi

DO_CLEAR="" ;
DO_SYNC="" ;
HAVE_PUBLIC="" ;
TRUE="TRUE" ;
FALSE="FALSE" ;


if [ $# = 0 ]; then 
  echo ' help here - no args'
elif
 [ $# = 1 ]; then   
  if [ "$1" == "--clear" ]; then  
    DO_CLEAR=$TRUE
  else
   echo " Bad command!"
   exit 1 ;
  fi
elif
  [ $# = 2 ]; then   
   if [ "$1" == "--dir" ]; then  
	
	if [ ! -d "$2" ]; then
		echo "Directory not found!" 
		exit 1 ;
	else	
	
		if [ -d "$2""/public" ]; then
			HAVE_PUBLIC=$TRUE ;
		else
			HAVE_PUBLIC=$FALSE ;			
		fi	
	
		DO_SYNC=$TRUE ;
	fi
			
   else
    echo " Bad command!"
    exit 1 ;
   fi
  
fi


if [ "$DO_CLEAR" == "TRUE" ]; then  

	rm -r /srv/http/*
	mkdir /srv/http/public
	systemctl restart nginx
		
elif [ "$DO_SYNC" == "TRUE" ]; then  

	sync() {
	  #rsync -avz --delete-excluded  --chown=http:http ./codeigniter/ /srv/http/public
	  rsync -avz --delete-excluded  --chown=http:http $DEST_DIR /srv/http/public ;

	if [ "$HAVE_PUBLIC" == "TRUE" ]; then  
	  rsync -avz --delete-excluded  --chown=http:http $DEST_DIR /srv/http ;
	else
	  rsync -avz --delete-excluded  --chown=http:http $DEST_DIR /srv/http/public ;
	fi

	}
	watch() {
	  inotifywait -e "CREATE,DELETE,MODIFY,MOVED_FROM,MOVED_TO" -m -r $DEST_DIR ;
	}

	watch | (
	while true ; do
	  read -t 1 LINE && sync ;
	done
	)
	
fi