3sky's notes

Minimal blog about IT

The Nginx and how to configure it

2021-02-24 3 min read 3sky

Welcome

That will be a short post. I need it, for my usage. All about Nginx and some application architecture. Why? During my 6 years of professional life, I haven’t met any Nginxa’s master. All my tech friends know some basics(as me) or have one best config which always works. Unfortunately, Nginx is hard. It’s just a tool, just a web server, but it’s complex, useful, and powerful. Let’s start.

Intro

Simple architecture overview. We have a backend app, let’s say PHP. A frontend is written in Angular, or React, or Vue, or pure JS. Doesn’t matter. Ahh, picture. A deployment diagram will be better.

cat-photo

The problem

If we run on localhost our frontend with yarn start and out PHP with php artisan serve, the application works perfectly. It isn’t a programming article, no code included :). At some point in time, we would like to go live with our app. Kubernetes is too complex, services like AWS ECS require some AWS knowledge, also vendor locking problems. We decided that Linode VM perfectly fits, it’s affordable and just works. We have chosen VM’s distro, installed our packages, deps, security update, created users with correct permission, linked the sites-available to the sites-enabled, etc. After that we run nginx -t - status ok. Fast systemctl reload, go to browser type magic.3sky.dev. Failstart. 500 - Internal Server Error. What’s wrong? Probably a lot of things.

Solution

Let’s assume we’re using php-fpm with the original config on the Unix socket. Why sockets? All about speed - SO answer. So how to debug? For me the best option is adding this line to our site config.

error_log  /var/log/nginx/debug.log debug;

What is next? Just true pleasure - tail -f and curling. After a few attepts I created my working config. Which looks like that:

# /etc/nginx/sites-available/magic.3sky.dev
upstream php-fpm {
        server unix:/var/run/php/php7.4-fpm.sock;
}

server {

        listen 80;
        server_name magic.3sky.dev;

        location / {

                root /var/www/magic.3sky.dev/frontend;
                try_files $uri $uri/ /index.html;
                gzip_static on;
        }

        location ~ ^/(api|create) {

                alias          /var/www/magic.3sky.dev/backend/public;
                include        fastcgi_params;
                fastcgi_param  SCRIPT_FILENAME /var/www/magic.3sky.dev/backend/public/index.php;
                fastcgi_pass   php-fpm;
        }


        location ~ /\. {
                access_log off;
                log_not_found off;
                deny all;
        }
}

Summary

Nothing special, but works. Static files are gzipped, index.php is reading, when fronted use api or create endpoint. Just PHP and frontend configuration. Pure classic, but so interesting for me. The next step is mastering Nginx, and tweak this config in security and performance areas. That is a bit funny. We worked with complex architectures on Kubernetes, cloud services, but we can’t correctly configure Nginxa. At least I can’t. Fortunately, I still have time to learn it.