[Ruby] [AWS] Publish rails application with nginx + puma

3 minute read

Introduction

Since I made a LINEbot with rails, Let’s set up to publish the rails application with nginx + puma.

Set up an EC2 instance

Create an EC2 instance with reference to this.

Reference: Build a web server with AWS EC2 https://qiita.com/Arashi/items/629aaed33401b8f2265c

Set things required for development such as git and rails first

Confirm Rails app location

If you have a Rails app under your home directory Move or copy under “/opt”. Note that the home directory is not a suitable place to store the published application. *If you leave your home directory, you will be addicted to permission errors.

Copy Rails app


# When copying
$ sudo cp -arf ~/rails/rails_app/opt/
# Verify file
$ ls -al /opt/
drwxr-xr-x 5 root root 4096 Jul 15 13:59.
dr-xr-xr-x 25 root root 4096 Jul 16 06:02 ..
drwxrwxr-x 13 ec2-user ec2-user 4096 Jul 15 13:57 rails_app

Set Nginx

First install

install Nginx


$ sudo yum install -y nginx

version check


$ nginx -v
nginx version: nginx/1.16.1

Write settings to configuration file

ruby:/etc/nginx/conf.d/rails.conf


server {
    listen 80;
    server_name localhost;

    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;

    root /opt/rails_app/public;

# Under the document root, follow the order from the beginning below
    try_files $uri @rails_app;

# Load the following settings only when @rails_app above is called
    location @rails_app {
        proxy_pass http://rails_app;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_redirect off;
    }
}

Try to move

start


$ sudo nginx

stop


$ sudo nginx -s stop

Oh! !! moved! !!

Screenshot 2020-07-16 21.39.03.png

Puma socket communication settings

Modify Puma configuration file to link Rails (Puma) and Nginx *If there is a Rails app under Home, Nginx cannot communicate with Puma through socket.

/opt/rails_app/config/puma.rb


# Comment out here
# port ENV.fetch("PORT") {3000}

# Add this line
bind "unix:///opt/rails_app/tmp/sockets/puma.sock"

Add cooperation part to rails.conf

ruby:/etc/nginx/conf.d/rails.conf


# Add following code
upstream rails_app {
# UNIX domain socket communication settings
    server unix:///opt/rails_app/tmp/sockets/puma.sock fail_timeout=0;
}

When rails is executed, it is linked…

error


Your version of SQLite (3.7.17) is too old.Active Record supports SQLite >= 3.8.

Wow! !! I was angry…

When using SQLite with Ruby on Rails 6, it seems that SQLite 3.8 or higher is required. The SQLite package contains 3.7… Install the latest version of SQLite to solve.

Download #3.29
$ wget https://www.sqlite.org/2019/sqlite-autoconf-3290000.tar.gz

$ tar xzvf sqlite-autoconf-3290000.tar.gz

$ cd sqlite-autoconf-3290000

# Install to /opt/sqlite/sqlite3 so that it doesn't conflict with the original sqlite
$ ./configure --prefix=/opt/sqlite/sqlite3

$ make

$ sudo make install

# Version confirmation
$ /opt/sqlite/sqlite3/bin/sqlite3 --version
3.29.0 2019-07-10 17:32:03 fc82b73eaac8b36950e527f12c4b5dc1e147e6f4ad2217ae43ad82882a88bfa6

# Replace the sqlite3 gem
$ gem uninstall sqlite3

# Install by specifying the path of lib and include included above
$ gem install sqlite3 ----with-sqlite3-include=/opt/sqlite/sqlite3/include \
   --with-sqlite3-lib=/opt/sqlite/sqlite3/lib

Try moving the rails again…

Oh! !! moved! !!

![Screenshot 2020-07-16 21.54.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/210436/21ed5504-9edd-0500-8e16-(2c8bb2325e23.png)

SSL settings! Create a certificate

Also, let’s set up SSL.

Install OpenSSL

Check and install OpenSSL


# check openssl version
$ openssl version
OpenSSL 1.0.2k-fips 26 Jan 2017

# Install if no version is displayed
$ sudo yum install -y openssl

create directory


$ sudo mkdir /etc/nginx/ssl

Create private key

$ sudo openssl genrsa -out /etc/nginx/ssl/server.key 2048

Creating a CSR (certificate signing request)

Create “CSR (certificate signing request)” from private key

You will be asked to enter the country code, address, company name, etc. However, if it is a self-signed certificate, you do not need to enter anything and skip with “Enter”.

Create CSR


$ sudo openssl req -new -key /etc/nginx/ssl/server.key -out /etc/nginx/ssl/server.csr

CRT (SSL server certificate) creation

Normally, I would register the above-mentioned CSR at the certificate authority and have it issue a “CRT (SSL server certificate)”, but this time I made an “oleore (self-signed) certificate” and made this machine Complete within

create CRT


# CRT (10 year expiration) created
$ sudo openssl x509 -days 3650 -req -signkey /etc/nginx/ssl/server.key -in /etc/nginx/ssl/server.csr -out /etc/nginx/ssl/server.crt

# Confirm CRT is generated
$ ls -l /etc/nginx/ssl/
Total 12
- rw-r--r-- 1 root root 1103 Jul 14 11:52 server.crt
- rw-r--r-- 1 root root 952 Jul 14 11:52 server.csr
- rw-r--r-- 1 root root 1675 Jul 14 11:51 server.key

Set certificate in Nginx

ruby:/etc/nginx/conf.d/rails.conf


server {
# Allow port 443 and turn on SSL function
# listen 80;
    listen 443 ssl;
    server_name {#server_name};

# Set certificate
    ssl_certificate /etc/nginx/ssl/server.crt;
    ssl_certificate_key /etc/nginx/ssl/server.key;
         :
         :
}

reboot


$ sudo restart nginx

I was able to make an SSL connection! !! *Oleore certificate is used only for development and study

![Screenshot 2020-07-16 22.10.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/210436/51c44407-529e-4d80-657e-(6600a4668159.png)