Deploy Rails 7 with Docker and Nginx | Roeland Moors

Ask questions Research chat →

https://roeland.moors.org/2021/10/03/rails-7-docker-nginx.html · scraped

rails deploy

Attachments

Scraped Content

— 560 words · 2026-02-14 17:40:11 UTC ·

Excerpt

## New Rails 7 app Lets create a new Rails project with PostgreSQL, esbuild and Tailwind on you local machine: rails new demo -d postgresql --edge -j esbuild --css tailwind Adjust you config/database.yml with the settings for you 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 and a container registry, 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 creat
## New Rails 7 app Lets create a new Rails project with PostgreSQL, esbuild and Tailwind on you local machine: rails new demo -d postgresql --edge -j esbuild --css tailwind Adjust you config/database.yml with the settings for you 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 and a container registry, 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: 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 docker 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

Visibility

Visible to everyone

Reading Status

Related Bookmarks

My Note


Saved!

Annotations

Export as Markdown
+ Annotate selection

Add Annotation