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 …


This content originally appeared on DEV Community and was authored by Roeland

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:create
bin/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 bash
export RAILS_ENV=production
bundle install
yarn install
yarn build
yarn build:css
bin/rails assets:precompile
bin/rails server -b 0.0.0.0

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

Now create a Dockerfile:

FROM ruby:3
RUN apt-get update -qq && apt-get install -y nodejs npm postgresql-client
RUN npm install -g yarn
RUN gem update --system

# use a global path instead of vendor
ENV GEM_HOME="/usr/local/bundle"
ENV BUNDLE_PATH="$GEM_HOME"
ENV BUNDLE_SILENCE_ROOT_WARNING=1
ENV BUNDLE_APP_CONFIG="$GEM_HOME"
ENV PATH="$GEM_HOME/bin:$BUNDLE_PATH/gems/bin:${PATH}"

# make 'docker logs' work
ENV RAILS_LOG_TO_STDOUT=true

# copy the source
WORKDIR /app
COPY . /app
RUN rm -f tmp/pids/server.pid
RUN bundle install

# build and start
CMD ["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_network
docker network connect demo_network demo
docker network connect demo_network postgres_container

To create the database and tables:

docker exec demo bin/rails db:create
docker 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.


This content originally appeared on DEV Community and was authored by Roeland


Print Share Comment Cite Upload Translate Updates
APA

Roeland | Sciencx (2021-10-03T20:36:52+00:00) Deploy Rails 7 with Docker and Nginx. Retrieved from https://www.scien.cx/2021/10/03/deploy-rails-7-with-docker-and-nginx/

MLA
" » Deploy Rails 7 with Docker and Nginx." Roeland | Sciencx - Sunday October 3, 2021, https://www.scien.cx/2021/10/03/deploy-rails-7-with-docker-and-nginx/
HARVARD
Roeland | Sciencx Sunday October 3, 2021 » Deploy Rails 7 with Docker and Nginx., viewed ,<https://www.scien.cx/2021/10/03/deploy-rails-7-with-docker-and-nginx/>
VANCOUVER
Roeland | Sciencx - » Deploy Rails 7 with Docker and Nginx. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2021/10/03/deploy-rails-7-with-docker-and-nginx/
CHICAGO
" » Deploy Rails 7 with Docker and Nginx." Roeland | Sciencx - Accessed . https://www.scien.cx/2021/10/03/deploy-rails-7-with-docker-and-nginx/
IEEE
" » Deploy Rails 7 with Docker and Nginx." Roeland | Sciencx [Online]. Available: https://www.scien.cx/2021/10/03/deploy-rails-7-with-docker-and-nginx/. [Accessed: ]
rf:citation
» Deploy Rails 7 with Docker and Nginx | Roeland | Sciencx | https://www.scien.cx/2021/10/03/deploy-rails-7-with-docker-and-nginx/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.