DEV Community

Cover image for A friendly guide to deploy a rails app using nginx (no docker needed)
Muhammadreza Haghiri
Muhammadreza Haghiri

Posted on

A friendly guide to deploy a rails app using nginx (no docker needed)

In past six years, I developed a huge skill set in ruby programming. Although it may seem a bit stupid, but after knowing such a great company like GitHub uses Ruby on Rails as their backend framework and great FLOSS projects such as Gitlab or Mastodon are written in rails as well, you will find out it might be a smart choice.

Although the whole process of building an app in rails is quiet easy and just needs a lot of search (or if you're like me, you can ask your questions in rails subreddit and get help from a lot of great fellas there). Everything in Rails is pretty straight forward, except one things. THE DEPLOYMENT. It's really a hell of pain. But fortunately, I found a way which can work to some extent.

Gaining HTTPS access for your domain/subdomain

In this tutorial, I will use Ubuntu and Debian as an example. I'm sure the package names are mostly similar in other Linux distributions. In case of FreeBSD, I will give you the proper package name, do not worry.

For having HTTPS on your domain, first you have to install certbot. As we're going to use nginx, this package will be enough :

sudo apt install python-certbot-nginx

For FreeBSD, install py37-certbot-nginx.

After certbot installation, you need to get certificates :

sudo certbot --nginx -d example.com -d www.example.com 

NOTE: Make sure that you set both root and www records on your DNS service provider.

Now, you have certificates! Let's deploy.

Installing ruby and rails

Even on servers, I prefer RVM. So, I skip the installation part.

Deployment

Are curious how I came up with this idea? It wasn't really easy though. One or two months ago, one of my friends at work just said Mastodon has an LXC image available. It made me a bit happy, 'cause I was thinking of my own instance of Mastodon.

Two weeks ago, I made a simple rails app and wanted to deploy it. I took a look at docker and lxc images of other rails projects and understood nothing. But I knew that I have access to a server with Mastodon running. I still don't have my own instance, that server belongs to a friend of mine. I just connected to the server and found how it's deployed. So for deploying your app, follow the following instructions .

Authenticity Token Problem

Open up your controllers and add this line to them :

skip_before_action :verify_authenticity_token

I'm not sure if this makes your app unsafe or not, and if adding it to the file app/controllers/application_controller.rb makes it global or not. Please let me know in the comments or where I shared the article with you.

Doing migrations and stuff

I assume you know that you should do database migrations, asset compilations, etc. So I skip this part as well.

Running the app

Fine, for running the app, I usually set RAILS_ENV=production in .bashrc or .zshrc, depending on the shell I use. After that, I open a screen session like this :

screen -S rails-app-appname

then, I run my app :

rails s -b 0.0.0.0

And by pressing CTRL + A then pressing D, I deatch from that session. I suggest this way for you as well.

After running your app, just edit nginx configurations as following.

First, open the configuration file :

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

Then, look for your domain name (certbot adds your address to this configuration file). Under the server section which includes your domain name, just create this :

   location @railsapp {
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto https;
        proxy_set_header Proxy "";
        proxy_pass_header Server;
        proxy_pass http://127.0.0.1:3000;
        proxy_buffering off;
        proxy_redirect off;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        tcp_nodelay on;
}

And then modify your root address to the public folder of your project.

For example on one of my server, the default root is /home/git/www and I have changed that to /home/my_user/rails_app/public for that particular domain name.

Then, make your root location like this :

location / {
    try_files $uri @railsapp;
}

After that, do this :

sudo systemctl reload nginx
sudo systemctl restart nginx

on FreeBSD (or Linux distributions without systemd) just do this :

sudo service nginx restart

And happy using your app!

Why not docker?

It's a personal preference I believe. I have a server with two gigabytes of RAM, and to my experience, these container solutions waste a lot of RAM. Also, for one who doesn't know how to work with docker (specially myself!) it will be really hard to get things work fine. Such as database connections, etc.

In conclusion, if you have enough knowledge and resource, using docker might be even a better choice. But if you like the classic ways, I wrote this article for you.

Happy coding :-)

Top comments (2)

Collapse
 
nyolamike profile image
Nyola Mike

But the certbot part didnt go on well, I used this command from some other article on vultr.

sudo apt install certbot python3-certbot-nginx
Enter fullscreen mode Exit fullscreen mode

digitalocean.com/community/tutoria...

I think due to updates in the libraries

Collapse
 
nyolamike profile image
Nyola Mike

My friend, I don't know how much to thank you.
I want you to know that by today's mess of things, you have been a hero to me.
I spent 3 days trying to host nginx within docker but with this article my nginx is serving well my services in docker containers, am not even building a rails app, but it was hard to find any article talking about running nginx on host machine and proxy_passing to docker container.