Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
October 3, 2021 08:36 pm GMT

Deploy Rails 7 with Docker and Nginx

The easiest solution to deploy a Rails application is something like Heroku or Hatchbox or DigitalOcean Apps. But for some small projects I like to use my existing VPS.

I assume you have a VPS with Ubuntu 20.04 and Docker and Nginx installed.
If you use DigitalOcean you can select the Docker image in the marketplace and add Nginx to it.

New Rails 7 app

Lets create a new Rails project with PostgreSQL, esbuild and Tailwind on your local machine:

rails new demo -d postgresql --edge -j esbuild --css tailwind

Adjust you config/database.yml with the settings for your database.

Scaffold a simple table:

bin/rails g scaffold Book name:string

Then create your database and tables:

bin/rails db:createbin/rails db:migrate

You can create a root path in routes.rb:

root "books#index"

Now you can start the website with:

bin/dev

Docker

Let's go to the VPS. I transfer my code with Github.

For large projects you would probably use CI, but this is just a small project.

I prefer to create a small shell script to do the build steps and start rails.
This is the content of bin/prod:

#!/usr/bin/env bashexport RAILS_ENV=productionbundle installyarn installyarn buildyarn build:cssbin/rails assets:precompilebin/rails server -b 0.0.0.0

Let's make it executable with: chmod a+x bin/prod

Now create a Dockerfile:

FROM ruby:3RUN apt-get update -qq && apt-get install -y nodejs npm postgresql-clientRUN npm install -g yarnRUN gem update --system# use a global path instead of vendorENV GEM_HOME="/usr/local/bundle"ENV BUNDLE_PATH="$GEM_HOME"ENV BUNDLE_SILENCE_ROOT_WARNING=1ENV BUNDLE_APP_CONFIG="$GEM_HOME"ENV PATH="$GEM_HOME/bin:$BUNDLE_PATH/gems/bin:${PATH}"# make 'docker logs' workENV RAILS_LOG_TO_STDOUT=true# copy the sourceWORKDIR /appCOPY . /appRUN rm -f tmp/pids/server.pidRUN bundle install# build and startCMD ["bin/prod"]

The master.key file is not in git for safety.
There are several solutions for this, but I just recreate the file on the server:

echo "30acf9tralalalalala7af75eb7" > config/master.key

Now it's time to create the docker image.

Run this inside the root folder of the demo project:

docker build -t demo:0.0.1 .

You should now see the image with docker images.

Lets run it:

docker run -d -p 3001:3000 --name demo --env RAILS_ENV=production -v ~/demo:/app demo:0.0.1

The docker container is exposing port 3000, but I map that to 3001 since I already have an other website running on port 3000.

You should probably have a seperate Postgres server, but I also run that inside a Docker.
To allow access to this container I create a seperate network and add the two containers in it.
In database.yml you can than use postgres_container as host.

docker network create demo_networkdocker network connect demo_network demodocker network connect demo_network postgres_container

To create the database and tables:

docker exec demo bin/rails db:createdocker exec demo bin/rails db:migrate

In case of errors you can use docker logs demo to find the error.

Nginx

I use Nginx as a proxy to the different Rails projects and to load the assets directly.
To create a new configuration:

sudo vi /etc/nginx/sites-available/demo

And this is the content: (you need to change the domain and paths)

upstream demo {  server localhost:3001;}server {  server_name demo.example.org;  root /home/user/demo/public;  access_log /home/user/demo/log/nginx.access.log;  error_log /home/user/demo/log/nginx.error.log info;  location ^~ /assets/ {    gzip_static on;    expires max;    add_header Cache-Control public;  }  try_files $uri/index.html $uri @demo;  location @demo {    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_set_header  X-Forwarded-Ssl on; # Optional    proxy_set_header  X-Forwarded-Port $server_port;    proxy_set_header  X-Forwarded-Host $host;    proxy_redirect off;    proxy_pass http://demo;  }  error_page 500 502 503 504 /500.html;  client_max_body_size 100M;  keepalive_timeout 10;}

Enable it:

sudo ln -s /etc/nginx/sites-available/demo /etc/nginx/sites-enabled/demo

Test the configuration:

sudo nginx -t

And restart Nginx:

sudo systemctl restart nginx

You should now have a working website.
It's a good idea to add Let's Encrypt with the certbot tool.
This is explained here.


Original Link: https://dev.to/roelandmoors/deploy-rails-7-with-docker-and-nginx-b11

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To