31.12.2021 13:18
4

Setting up web-server on WSL 2

Main stack: nginx + mysql + php-fpm.

So, you just configured the WSL on your system and installed a clean ubuntu 18.04 LTS.

Why is not apache? Due to performance, speed and loads - nginx + php-fpm works much better. There are also disadvantages to this solution - we lose the usefull .htaccess config and will have to make all the necessary settings in nginx and php configurations.

The article is primarily focused on upper-junior, at least a little familiar with linux and used stack.

Install packages

Nginx

Install and settings up nginx

sudo apt update
sudo apt install nginx
sudo /etc/init.d/nginx start

If you did everything right, the "Welcome to nginx!" start page should be displayed in the browser at http://127.0.0.1/.

Now we temporary stop with nginx, we will return already at the stage of site configuration.

MySQL

sudo apt install mysql-server
sudo /etc/init.d/mysql start

Although we have a local site, we need to use good practices - we run a regular script for configuring mysql security policies (setting passwords, validation requirements, anonymous access and other):

sudo mysql_secure_installation

PHP-fpm

sudo apt install php-fpm php-mysql
sudo /etc/init.d/php7.2-fpm start

Host

Setting up nginx

Create site config from default. Configuration files are best named same with domain. You can use a separate domain zone for local projects. So there will be less confusion. I use zone .local .

cd /etc/nginx/sites-available/
sudo cp default blog.local

Edit config:

sudo nano blog.local
server {
    listen 80;
    root /mnt/f/my/web/blog/public;
    index index.php index.html index.htm index.nginx-debian.html;
    server_name blog.local;

    location / {
        try_files $uri $uri/ =404;
    }

    location ~ \.php$ {
        fastcgi_buffering off;
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
    }

    location ~ /\.ht {
        deny all;
    }
}

Since we have WSL 2 - we will use the file system of main system. Logical disks inside the WSL 2 are mounted in '/mnt '- you can find out the list of partitions with the command' ls -la/mnt '.

If you want to see your site at the http://127.0.0.1/or http://localhost/- leave the default values server _ name and listen. In this case, it will not be possible to start several different sites, but you will not have to configure 'hosts'.

The site config must now be placed in a folder /etc/nginx/sites-enabled/, make symlink:

sudo ln -s /etc/nginx/sites-available/blog.local /etc/nginx/sites-enabled/

Also we can disable default site. We don't need it now:

sudo unlink /etc/nginx/sites-enabled/default

Test config (will be 'ok') and reload nginx:

sudo nginx -t
sudo /etc/init.d/nginx reload

Hosts

Browser needs to know which IP address to access when opening our domain blog.local. To do this, we can use hosts (C:\Windows\System32\drivers\etc\hosts) file inside the local system. In the internet it works via DNS.

Add a line to file (you need to have administrator access):

127.0.0.1       blog.local

PHP

Create index.php file in site document root directory:

echo '<?php echo "Hello world!";' > /mnt/f/my/web/blog/public/index.php

Now we can open our site in browser - http://blog.local/. If all works we will see Hello world! text on page.

Also we can see all server settings and php config, phpinfo give us this ability:

echo '<?php phpinfo();' > /mnt/f/my/web/blog/public/phpinfo.php

Open http://blog.local/phpinfo.php and see our configuration.

Warning! Don't use phpinfo on production servers. Don't leave this script open for all users in the internet.

MySQL

The easiest way, especially for some local projects, is to put an phpadmin - web-interface to manage mysql. If you don't need it - you can create user and database manually in mysql command line.

Install phpmyadmin with all php-packages wich will needed to work.

sudo apt install phpmyadmin php-mbstring php-gettext
sudo /etc/init.d/php7.2-fpm restart

On question "web-server to reconfigure automatically" simply press Tab and Ok. In window "Configuring phpmyadmin" choose 'Yes' and create user for admin panel.

Now we need configure nginx. Create one another config for phpadmin host:

cd /etc/nginx/sites-available/
sudo cp default phpmyadmin
sudo nano phpmyadmin

File must contents (phpmyadmin will be available on http://127.0.0.1/pma):

server {
    listen 80 default_server;
    listen [::]:80 default_server;

    root /var/www/html/;

    index index.php index.html index.htm index.nginx-debian.html;
    server_name _;

    location /pma {
        alias /usr/share/phpmyadmin/;
        location ~ \.php$ {
            fastcgi_buffering off;
            fastcgi_pass unix:/run/php/php7.2-fpm.sock;
            fastcgi_index index.php;
            fastcgi_param SCRIPT_FILENAME $request_filename;
            include fastcgi_params;
            fastcgi_ignore_client_abort off;
        }
        location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
            access_log    off;
            log_not_found    off;
            expires 1M;
        }
    }
}

Enable created config, check config and reload nginx:

sudo ln -s /etc/nginx/sites-available/phpmyadmin /etc/nginx/sites-enabled/
sudo nginx -t
sudo /etc/init.d/nginx reload

Open http://127.0.0.1/pma, input login phpmyadmin and your password.

If phpmyadmin user have not required permissions (can't create database or another users) - you always can give this permissions manually.

Go to mysql console:

mysql -u root -p

Give required permissions (here is maximum available):

GRANT ALL PRIVILEGES ON *.* TO 'phpmyadmin'@'localhost' WITH GRANT OPTION;

Go back to phpmyadmin and relogin to account. If you want to check correct mysql work you need to add user blog, database blog and table test with any columns (set database encoding to utf8_general_ci).

Check MySQL from php

Connect to database from php and output content from table 'test' (Dont store connection string to database in code - you can use envirement files or other more secure ways):

<?php
try {
    $dbh = new PDO('mysql:host=localhost;dbname=blog', 'blog', 'blog');
    foreach($dbh->query('SELECT * from test') as $row) {
        echo "<pre>";
        print_r($row);
        echo "</pre>";
    }
    $dbh = null;
} catch (PDOException $e) {
    print "Error!: " . $e->getMessage() . "<br/>";
    die();
}

Open again http://blog.local and see table contents on page.

So we install and setting up lemp on WSL. Also we have full linux system inside windows with linux packages wich works correctly. Early for than we needed to use virtual mashines wich worked very slow. Now we have much better and comfortable way to do it without any mumbo-jumbo.

Amazing!

If something went wrong

ERR_NAME_NOT_RESOLVED (unable to access site)

The browser could not find the specified domain.

Possible causes:

  • you have not configured the site domain correctly;
  • you did not set a domain in hosts;
  • you did not run nginx reload after creating/updating site configuration. It is required.

502 Bad Gateaway

Nginx does not receive a response from the backend, in this case from php-fpm.

Possible causes::

  • php-fpm is not running;
  • incorrect php parameters in nginx host settings;
  • error in php script.

Your best assistants in fixing any problem are logs:

/var/log/nginx/access.log  - nginx access requests
/var/log/nginx/error.log   - nginx error requests
/var/log/php7.2-fpm.log    - php-fpm log

Very long page load (ERR_INCOMPLETE_CHUNKED_ENCODING)

Check the fastcgi_buffering off; directive in section location ~ \.php$ in nginx site configuration file.

No comments yet

Latest articles