MaDoVi - Le wiki

Machines - Données - Virtualisation

Outils pour utilisateurs

Outils du site


services:web:tuto:nginx_tuto1

Nginx - Serveur HTTP avec PHP

Dans le cadre du projet , ce service va nous permettre de construire la brique de base pour traiter les services web qu'on y ajoutera ensuite.
On va positionner ce composant au sein d'un container LXC, ce qui correspond au schéma plus global proposé dans ce paragraphe.

Les manipulations listées ci-dessous pourront s'appliquer dans un environnement Linux quelconque – aux commandes près propres à la distribution choisie – une fois qu'on est à l'intérieur du CT. Vous pouvez ainsi ignorer les mentions au container si vous ne travaillez pas dans ce contexte, le reste demeure applicable…

1. Création du container LXC

On souhaite donc installer notre serveur HTTP dans un CT LXC. Ce container sera «non privilégié», et on va donc le créer depuis le compte admin. On va mettre….heuuu… Tiens, du Alpine Linux. Il s'agit d'une distribution avec une très faible empreinte système: «Les cibles principales d'Alpine sont les conteneurs et presque tous les appareils embarqués».

  • Création:
    admin@wasabi:~$ lxc-create -n lxc-web01 -t download -- -d alpine -r 3.11 -a amd64
  • Lancement:
    admin@wasabi:~$ lxc-start -n lxc-web01 
  • Contrôle:
    admin@wasabi:~$ lxc-ls -f
    NAME      STATE   AUTOSTART GROUPS IPV4      IPV6 UNPRIVILEGED 
    lxc-web01 RUNNING 0         -      10.0.3.51 -    true         

    Il tourne, il a l'adresse attendue, il est bien unprivileged.


2. Préparation & Installation

On commence par s'«attacher» au container pour faire ce qu'on a à faire dedans:

admin@wasabi:~$ lxc-attach -n lxc-web01 
/ # 

Les ajouts/installations/configurations de base: outils, ssh, … (l'outil de gestion de paquets s'appelle apk sous Alpine).

  • Commençons par les outils:
    / # /sbin/apk update
    / # /sbin/apk add attr dialog dialog-doc bash bash-doc bash-completion grep grep-doc
    / # /sbin/apk add util-linux util-linux-doc pciutils usbutils binutils findutils readline
    / # /sbin/apk add man man-pages lsof lsof-doc less less-doc nano nano-doc curl curl-doc
    / # /sbin/apk add sudo sudo-doc openssh  
    / # export PAGER=less
  • On prend bash comme interpréteur de commandes: il suffit de remplacer, dans le fichier /etc/passwd la fin de la ligne associée au compte root (la 1ière) par celle-ci (ash devient bash):
    # nano /etc/passwd
     
    root:x:0:0:root:/root:/bin/bash
    ...

    Ctrl+x et y pour enregistrer et sortir.

  • Lancer le service ssh puis le lancer automatiquement au démarrage du container:
    / # /sbin/rc-update add sshd
    / # /etc/init.d/sshd start
    ssh-keygen: generating new host keys: RSA DSA ECDSA ED25519 
     * Starting sshd ...                                        [ ok ]
  • Ajout d'un utilisateur «monusr» avec droit root (sudo):
    / # /usr/sbin/adduser monusr
    Changing password for monusr
    New password: 
    Retype password: 
    passwd: password for monusr changed by root
     
    / # /usr/sbin/visudo
    ## ajouter la ligne suivante (attention: VI - i pour insérer, esc + :w (sauver) + :q (quitter))
    ##                                                               
    ## User privilege specification
    ##
    root ALL=(ALL) ALL       
    monusr ALL=(ALL) ALL   ## <<<=== ICI
  • On lève un truc bizarre dans l'utilisation de sudo: il nous colle un sudo: setrlimit(RLIMIT_CORE): Operation not permitted à chaque utilisation… Pour l'éviter, on crée un fichier de config avec le contenu suivant:
    / # nano /etc/sudo.conf
    Set disable_coredump false
  • On redémarre pour prise en compte, du coup on sort et on se retrouve avec le shell du serveur:
    / # /sbin/reboot
    admin@wasabi:~$
  • On va maintenant travailler à partir d'une connexion ssh:
    admin@wasabi:~$ ssh monusr@lxc-web01
    ## accepter l'échange de clé
    monusr@lxc-web01's password: 
    Welcome to Alpine!
     
    The Alpine Wiki contains a large amount of how-to guides and general
    information about administrating Alpine systems.
    See <http://wiki.alpinelinux.org/>.
     
    You can setup the system with the command: setup-alpine
     
    You may change this message by editing /etc/motd.
    lxc-web01:~$
  • On se positionne en root pour toutes les manip. à suivre:
    lxc-web01:~$ sudo -i
     
    We trust you have received the usual lecture from the local System
    Administrator. It usually boils down to these three things:
     
        #1) Respect the privacy of others.
        #2) Think before you type.
        #3) With great power comes great responsibility.
     
    [sudo] password for monusr: 
    lxc-web01:~# 

    Notez le changement de $ à #: on est bien administrateur dans notre container.

  • On fixe le fuseau horaire:
    lxc-web01:~# setup-timezone -z Europe/Paris
  • On installe les paquets Nginx et PHP (un max., pour être tranquille en fonction des sites qu'on pourra définir):
    lxc-web01:~# apk add nginx php7-fpm php7-mcrypt php7-soap php7-openssl php7-gmp php7-pdo_odbc php7-json php7-dom php7-pdo php7-zip php7-mysqli php7-sqlite3 php7-apcu php7-pdo_pgsql php7-bcmath php7-gd php7-odbc php7-pdo_mysql php7-pdo_sqlite php7-gettext php7-xmlreader php7-xmlrpc php7-bz2 php7-iconv php7-pdo_dblib php7-curl php7-ctype php7-session

Maintenant, on va configurer tout cela.


3. Configuration

☛ Configurations Nginx

  • On crée un utilisateur et un groupe dédiés:
    adduser -D -g 'www' www 
  • On définit un répertoire et son propriétaire pour recevoir les sites (.html, .php, etc…):
    mkdir /var/www ## <== doit déjà exister...
    chown -R www:www /var/lib/nginx
    chown -R www:www /var/www

☛ Configurations PHP

  • Définition de variables pour configuration:
    PHP_FPM_USER="www"
    PHP_FPM_GROUP="www"
    PHP_FPM_LISTEN_MODE="0660"
    PHP_MEMORY_LIMIT="512M"
    PHP_MAX_UPLOAD="50M"
    PHP_MAX_FILE_UPLOAD="200"
    PHP_MAX_POST="100M"
    PHP_DISPLAY_ERRORS="On"
    PHP_DISPLAY_STARTUP_ERRORS="On"
    PHP_ERROR_REPORTING="E_COMPILE_ERROR\|E_RECOVERABLE_ERROR\|E_ERROR\|E_CORE_ERROR"
    PHP_CGI_FIX_PATHINFO=0
  • Configuration www.conf, passer cette série de commandes de substitution:
    sed -i "s|;listen.owner\s*=\s*nobody|listen.owner = ${PHP_FPM_USER}|g" /etc/php7/php-fpm.d/www.conf
    sed -i "s|;listen.group\s*=\s*nobody|listen.group = ${PHP_FPM_GROUP}|g" /etc/php7/php-fpm.d/www.conf
    sed -i "s|;listen.mode\s*=\s*0660|listen.mode = ${PHP_FPM_LISTEN_MODE}|g" /etc/php7/php-fpm.d/www.conf
    sed -i "s|user\s*=\s*nobody|user = ${PHP_FPM_USER}|g" /etc/php7/php-fpm.d/www.conf
    sed -i "s|group\s*=\s*nobody|group = ${PHP_FPM_GROUP}|g" /etc/php7/php-fpm.d/www.conf
    sed -i "s|;log_level\s*=\s*notice|log_level = notice|g" /etc/php7/php-fpm.d/www.conf #uncommenting line 
  • Et cette autre série pour la configuration php.ini:
    sed -i "s|display_errors\s*=\s*Off|display_errors = ${PHP_DISPLAY_ERRORS}|i" /etc/php7/php.ini
    sed -i "s|display_startup_errors\s*=\s*Off|display_startup_errors = ${PHP_DISPLAY_STARTUP_ERRORS}|i" /etc/php7/php.ini
    sed -i "s|error_reporting\s*=\s*E_ALL & ~E_DEPRECATED & ~E_STRICT|error_reporting = ${PHP_ERROR_REPORTING}|i" /etc/php7/php.ini
    sed -i "s|;*memory_limit =.*|memory_limit = ${PHP_MEMORY_LIMIT}|i" /etc/php7/php.ini
    sed -i "s|;*upload_max_filesize =.*|upload_max_filesize = ${PHP_MAX_UPLOAD}|i" /etc/php7/php.ini
    sed -i "s|;*max_file_uploads =.*|max_file_uploads = ${PHP_MAX_FILE_UPLOAD}|i" /etc/php7/php.ini
    sed -i "s|;*post_max_size =.*|post_max_size = ${PHP_MAX_POST}|i" /etc/php7/php.ini
    sed -i "s|;*cgi.fix_pathinfo=.*|cgi.fix_pathinfo= ${PHP_CGI_FIX_PATHINFO}|i" /etc/php7/php.ini
  • Configuration timezone:
    apk add tzdata
    TIMEZONE="Europe/Paris"
    cp /usr/share/zoneinfo/${TIMEZONE} /etc/localtime
    echo "${TIMEZONE}" > /etc/timezone
    sed -i "s|;*date.timezone =.*|date.timezone = ${TIMEZONE}|i" /etc/php7/php.ini
  • Lancer les services:
    rc-service nginx start
    rc-service php-fpm7 start
  • Les configurer pour qu'ils démarrent au boot:
    rc-update add nginx default
    rc-update add php-fpm7 default
  • et on peut rebooter:
    reboot

4. Quelques compléments

☛ Démarrage avec l'hôte

Si vous souhaitez éviter de faire «à la main» le lancement du container après un arrêt/relance du serveur, il suffit de modifier sa configuration en ajoutant ou dé-commentant les lignes suivantes:

$ nano $(lxc-config lxc.lxcpath)/lxc-web01/config
lxc.group = onboot
lxc.group = webserver
lxc.start.auto = 1

Pour autant que vous ayez suivi la partie “autostart:” dans la configuration des containers «non privilégiés»

☛ Test «ligne droite»

Pour s'assurer que tout fonctionne:

  • Se connecter en ssh au CT depuis l'hôte:
    $ ssh monusr@lxc-web01
  • Se positionner en root:
    lxc-web01:~$ sudo -i
  • Créer le fichier /var/www/php-version.php avec le contenu suivant:
    <?php
    echo 'Ca fonctionne ! Version courante de PHP : '. Phpversion();
    ?>
  • Créer le fichier /etc/nginx/conf.d/lxc-web01.conf avec le contenu suivant:
    server {
        listen         80;
        server_name    lxc-web01;
        access_log     /var/log/nginx/access.log;
        error_log      /var/log/nginx/error.log;
    
        root           /var/www;
        index          index.php;
    
        location ~ \.php$ {
            try_files $uri =404;
            fastcgi_split_path_info ^(.+\.php)(/.+)$;
            fastcgi_pass 127.0.0.1:9000;
            fastcgi_index index.php;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            include fastcgi_params;
        }
    }
  • Redémarrer les serveur Nginx pour prise en compte:
    lxc-web01:~# rc-service nginx restart
     * Stopping nginx ...                     [ ok ]
     * Starting nginx ...                     [ ok ]
    lxc-web01:~# 
  • Sortir du container:
    lxc-web01:~# exit
    lxc-web01:~$ logout
    $
  • Taper la commande suivante (son résultat montre que ça fonctionne):
    $ curl lxc-web01/php-version.php
    Ca fonctionne ! Version courante de PHP : 7.3.16

Le container lxc-web01 est maintenant prêt pour recevoir des sites en PHP.

Par exemple, on pourra y ajouter Adminer, Dokuwiki, Shaarli, etc…

Dans le cadre de , on ne va pas exposer sur le LAN ce container et permettre ainsi un accès par les clients: c'est ici le rôle du Reverse Proxy Web - Nginx

services/web/tuto/nginx_tuto1.txt · Dernière modification: 26/03/2020 20:47 de Cram28