-- Leo's gemini proxy

-- Connecting to blchrd.eu:1965...

-- Connected

-- Sending request

-- Meta line: 20 text/gemini;lang=en-US

Migration from Apache to nginx


Author: blchrd - Date: 2023-07-28


Some context about why I replace Apache


While I was working on the production environment for PlaylistShare[1], I encountered some problems, or at least some questions I have to answer before proceeding.


One of these questions is: what web server will I use? I want to dockerize the application, so my first thought was to include the web server directly into the docker-compose.yml. But this article[2] made me think a little further, and finally, I decided to install the web server outside of Docker.


I migrated from Apache to nginx for a lot of reasons, but mainly because I want to use the proxy features for running this website and dockerized application, and it is way simpler with nginx than Apache. The configuration is a lot less verbose, and it is very human-readable.


That's all for the context; I will write a blog post about the process of putting my app into production. But here, we are talking about Apache / nginx migration.


One last piece of information, though: my server runs on Debian/Linux.


First, install nginx


This is the more straightforward step: just install nginx. The service will not start because Apache is still running on port 80.


apt-get update
apt-get install nginx

If you want to use php - and I think you will eventually - you have to install php-fpm


apt-get install php-fpm

Next, we change the port in the default config file /etc/nginx/sites-available/default to test if nginx works properly.


Just replace this line


server {
    ...
    listen *:80
    ...
}

by


server {
    ...
    listen *:8000
    ...
}

Then start the service with


service nginx start

Navigate to your server, and check if it returns what it should.


Once that's done, stop the service for now.


service nginx stop

Then, transform configuration file


Second step, we need to convert Apache's configuration file to nginx's ones.


It's the step with the most pitfalls because the conf files are not the same at all. In Apache, we configure Virtual Hosts; in nginx, it's "server."


Here's what my Apache configuration looks like (I fused the two vhosts for convenience):


<VirtualHost *:80>
    ServerName example.com
    ServerAlias www.example.com
    DocumentRoot /path/to/website
    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined
    RewriteEngine on
    RewriteCond %{SERVER_NAME} =www.example.com [OR]
    RewriteCond %{SERVER_NAME} =example.com
    RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>

<IfModule mod_ssl.c>
    <VirtualHost *:443>
        ServerName example.com
        ServerAlias www.example.com
        DocumentRoot /path/to/website
        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined

        Include /path/to/ssl.conf
        SSLCertificateFile /path/to/cert/example.com/cert.pem
        SSLCertificateKeyFile /path/to/cert/example.com/key.pem

        <Location />
            Order deny,allow
            Allow from all
        </Location>
    </VirtualHost>
</IfModule>

One thing we'll see very fast is that the nginx conf file is not as verbose - I'm sure it can be, but for my usage, it is not.


For the first vhost with port 80, it just redirects to the https version of the website, so the configuration for nginx is really simple:


server {
    listen 80;
    server_name example.com www.example.com;
    return 301 https://$server_name$request_uri;
}

In my opinion, that was when I knew I would love nginx, and I didn't even scratch the surface yet.


Be careful not to forget the semi-colon at the end of each line. I forgot it, and nothing worked. But the error message is pretty clear, so I didn't get stuck for very long.


For the SSL part, the configuration file is a little bigger:


server {
    listen 443 ssl;
    server_name example.com www.example.com;

    ssl_certificate /path/to/cert/example.com/cert.pem;
    ssl_certificate_key /path/to/cert/example.com/key.pem;

    ssl_protocols       TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
    ssl_ciphers         HIGH:!aNULL:!MD5;

    root /path/to/website;
    location / {
        index index.html index.php;
    }

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

Don't forget the last part, location ~ \.php$. It's the one that serves PHP files properly. If you forget it, your web server will return the PHP file (so yes, it will return your source code).


All the configuration files is created in /etc/nginx/sites-available/ directory. Once the file is created, you need to make a symlinks on the /etc/ningx/sites-enabled/ directory, you can do this with this command:


ln -s /etc/nginx/sites-available/sites.conf /etc/nginx/sites-enabled/sites.conf

Finally, stop Apache and run nginx


Once all the configuration files were written, one thing left on the list: stop Apache and start nginx.


For this, two command lines:


service apache2 stop
service nginx start

After that, if you have no errors, you can browse your way out to your website and check if it works like before. It was the case for me.


Conclusion (kind of)


This migration was really fun to make.


The configuration behavior can differ between Apache and nginx, but right now, I didn't find any difference. Feel free to contact me if something is wrong here.


I hope this can help you if you want to make the same migration I've done. It is not really a tutorial, at most it's a to-do list if I want to migrate another server.


Take care, folks.


1: https://plsh.blchrd.eu

2: https://nickjanetakis.com/blog/why-i-prefer-running-nginx-on-my-docker-host-instead-of-in-a-container

-- Response ended

-- Page fetched on Thu May 9 23:12:21 2024