Personally developed apps WEB server: Nginx Application server: Puma I deployed to AWS EC2 using.
Ruby 2.5.3 Rails 5.2.4.2 MacOS:Catalina 10.15.6
The AWS settings were OK while advancing the understanding according to the excellent article already mentioned, but since I just started, I felt that the Nginx settings (nginx.conf etc.) were particularly difficult, overcame many errors, and tried and errored. And cleared.
I think that many people choose Puma as an application server these days.
Since there was no article that listed the two settings of nginx.conf and yourapp.conf required for deployment, I thought it would be useful for someone.
I'm glad that I stumbled on the error and deepened my understanding of the server by investigating it, but probably everyone who challenges it will also stumbled at the same place, so ** I was able to deploy with such a setting ** I would like to write an article with my body.
I will organize both of them with the meaning of review myself (please tell me if there are any differences!).
[** Nginx **] ... WEB server. Receives content requests from the browser and responds to the browser. In the case of a request for static content (image, etc.), the WEB server processes it. The application server is responsible for the dynamic content. Representatives of WEB servers are Apache, Nginx, etc.
[** Puma **] ... Application server. While Nginx handles static content on a web server, this handles dynamic content that Nginx cannot process. Request from WEB server → Receive application server → Return Rails application processing result to WEB server. Typical examples are Unicorn, Puma, etc. Rails is currently using Puma as its default application server.
There seems to be a difference between Puma and Unicorn, but the former is multithreaded and the latter is multiprocessed. Puma seems to have the advantage of handling more requests more efficiently, but some say it doesn't change much in normal use. I chose Puma, which is recommended by Rails.
Next is the setting of puma.rb. Below are my settings.
puma.rb(local)
#Application directory
app_dir = File.expand_path("../../", __FILE__)
#Specify URI with bind for socket communication
bind "unix://#{app_dir}/tmp/sockets/puma.sock"
#PID file location(Process ID)
pidfile "#{app_dir}/tmp/pids/puma.pid"
#The state file operates the server with the pumactl command. Its whereabouts.
state_path "#{app_dir}/tmp/pids/puma.state"
#Standard output/The location of the file that outputs the standard error.
stdout_redirect "#{app_dir}/log/puma.stdout.log", "#{app_dir}/log/puma.stderr.log", true
threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 }
threads threads_count, threads_count
#port ENV.fetch("PORT") { 3000 }
environment ENV.fetch("RAILS_ENV") { "development" }
plugin :tmp_restart
I commented it out because I don't use port.
Puma and Nginx are specified by bind on the second line for socket communication. In bind, specify the path by URI as shown below.
bind "unix://#{app_dir}/tmp/sockets/puma.sock"
Nginx mainly modifies two files. 1 nginx.conf ... Nginx itself configuration file 2 yourapp.conf ... Nginx configuration file for each application
Below is my nginx.conf settings
(EC2)etc/nginx/nginx.conf
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /var/run/nginx.pid;
include /usr/share/nginx/modules/*.conf;
events {
worker_connections 1024;
}
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
include /etc/nginx/conf.d/*.conf;
index index.html index.htm;
upstream puma {
server unix:///var/www/rails/yourapp/shared/tmp/sockets/puma.sock;
}
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name Elastic IP(URL);
root /var/www/rails/yourapp/current/public;
location / {
try_files $uri $uri/index.html $uri.html @webapp;
}
location @webapp {
proxy_read_timeout 300;
proxy_connect_timeout 300;
proxy_redirect off;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://puma;
}
error_page 404 /404.html;
location = /40x.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
server {
listen 443 ssl;
server_name Elastic IP(URL);
location @webapp {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_pass http://puma;
}
}
}
Although it is called yourapp.conf, yourapp will contain the name of the application you are creating.
ruby:(EC2)/etc/nginx/conf.d/yourapp.conf
# log directory
error_log /var/www/rails/yourapp/shared/log/nginx.error.log;
access_log /var/www/rails/yourapp/shared/nginx.access.log;
upstream app_server {
# for UNIX domain socket setups
server unix:/var/www/rails/yourapp/shared/tmp/sockets/yourapp-puma.sock fail_timeout=0;
}
server {
listen 80;
server_name ;
# nginx so increasing this is generally safe...
# path for static files
root /var/www/rails/yourapp/current/public;
# page cache loading
try_files $uri/index.html $uri @app_server;
location / {
# HTTP headers
proxy_pass http://app_server;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
}
# Rails error pages
error_page 500 502 503 504 /500.html;
location = /500.html {
root /var/www/rails/yourapp/current/public;
}
client_max_body_size 4G;
keepalive_timeout 5;
}
I will post an article that I referred to when deploying.
Deploy a Rails5 + Puma + Nginx environment to EC2 with Capistrano3 (Part 2)
Infrastructure beginners deploy Nginx + Puma Rails 5 application on Capistrano 3
Since I was not accustomed to handling the server, I had more difficulty in setting Nginx and Puma above than setting AWS etc. when deploying to EC2. Finally, I was able to deploy to AWS EC2 using Capistrano and CircleCI. Regarding CDs, I think you can do it without difficulty if you follow the articles of the predecessors. I will come when there are many errors, but I can't stop because I am more than happy when I can implement new functions and resolve errors!
Recommended Posts