Learn how to deploy your Ruby on Rails app to a Server using docker and then make it available with a custom domain using a reverse proxy. This is the next step based on this guide where we learned how to set up a Server and install docker. So follow this guide if you want the same starting point!
The guide will first show you how to do these steps manually. In case you are not that interested in it jump to section 5 where I will show you a tool that does all of these steps automatically for you with basically one command!
- Create a Dockerfile for your Ruby on Rails app
- Build a Ruby on Rails app Docker image and upload it to your server
- Run your app using docker compose
- Make it available using a reverse proxy and a custom domain
- The easy way: quickdeploy
Create a Dockerfile for your Ruby on Rails app
The first step to deploying your web app to your Server is to create a specific Dockerfile for it. To do so go to the root of your project and create a file Dockerfile
. It is the template for your Docker image and contains the steps that are taken to build the image. Every image starts with a base image, then installs the dependencies and finally builds the app that will later be exposed.
FROM ruby:3.2
WORKDIR /app
COPY Gemfile Gemfile.lock ./
RUN bundle install
COPY . .
RUN RAILS_ENV=production bundle exec rails assets:precompile
EXPOSE 8080
ENV RAILS_ENV=production
ENV PORT=8080
CMD ["bundle", "exec", "puma", "-C", "config/puma.rb"]
In the next step we will use it to create the image.
Build a Ruby on Rails app Docker image and upload it to your server
Now that we have the Dockerfile we will run the following command to deploy our web app.
docker build -t railsappimage:{version}
And then we check if the image can be run locally.
docker run -p 8080:8080 -it railsappimage:{version}
We should then be able to access our Ruby on Rails app under http://localhost:8080.
If everything worked we will upload the image to our server using:
docker save railsappimage:{version} | ssh user@your-vps-ip 'docker load'
A different way to this process is to upload the image to container registry e.g. githubs container registry and then pull it on the server. I will show it in this guide: urlrails.
Next we will use the image available on our server to deploy our Ruby on Rails app.
Run your app using docker compose
To now deploy our image and make it available for our users we have to create new directory e.g. ~/railsapp
and inside it a new file docker-compose.yml
. The docker compose file will define how our container actually runs. Here we will expose port 8080 (the same as in the Dockerfile). In addition we will create a Docker network that we will need for the reverse proxy.
services:
railsapp:
container_name: railsapp
image: railsappimage:{version}
expose:
- '8080'
networks:
- web
restart: unless-stopped
networks:
web:
external: true
After we created the compose file we have to enter the directory and run:
docker compose up -d
With that our Ruby on Rails app is running. Next we need to make is accessible.
Make it available using a reverse proxy and a custom domain
Before we start make sure that your domain has an A record pointing to your server.
Next we will create another Docker compose file in another directory: ~/caddy/docker-compose.yml
in addition we will create a Caddyfile
in the same directory.
The caddyfile contains the configuration of the reverse proxy and basically just points the domain to our container.
railsapp.com {
reverse_proxy railsapp:8080
}
The compose file will create the actual reverse proxy and supply it with configuration.
services:
caddy:
container_name: caddy
image: caddy:latest
ports:
- "80:80"
- "443:443"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile
- ./data:/data
- ./config:/config
networks:
- web
restart: unless-stopped
networks:
web:
driver: bridge
external: true
Next we run the following command again:
docker compose up -d
After all our app should now be available under your domain! To update your app you have to follow the same steps from 2. again!
The easy way: quickdeploy
These were a lot of steps with a lot of situations where a small mistake will lead to your app not successfully being deployed. Quickdeploy will help you deploy all your web apps with only one command:
quickdeploy push --domain railsapp.com
It streamlines the whole process that we just learned about and adds some additional goodies like rolling updates, so your app does not go offline between deployments. If it sounds interesting to you check out the landing page here.