This blog post shows how I deploy a Ruby on Rails app that runs in a Dockercontainer on a DigitalOcean server. To keep it simple, I’m going to explain a very manual process on simply getting an app deployed inside a Docker container.
In this post I’ll show you:
Let’s get started with the installation on a server.
First, I boot a new Ubuntu 14.04 server on DigitalOcean and install Docker:
CODE: https://gist.github.com/jansn/27177efbbcb0a350d4ba1a205b47bb83.js
Now I’m going to build a Docker image from my Rails app. It happens that Jeroen blogged about this last week: How I build a Docker image for my Rails app. I am using his blog post as a base for the next steps.
I’ll be building the Docker image on the same server that I want to host my app. I build it on that server because I want my application to be private, so using the public Docker registry is not an option. I could set up my private Docker registry but then I would have to maintain it, and I don’t want to do that at the moment. In this post, I’m looking at the simplest way to use Docker to host my app.
In my Rails project intercity-website, I added the following Dockerfile and Nginx config:
Dockerfile
As you can see this Dockerfile uses the phusion/passenger-ruby21 base image. It adds the Nginx config, adds the application code, runs bundler to install the gems and precompiles the assets.
nginx.conf
I committed these files to my repository. Now I’m going to upload it to my server and build the container:
This command produces a lot of output and results in a Docker image. The first
time I run that docker build command it took a few minutes. That’s because
Docker needs to download the phusion/passenger-ruby21 base image. It only does
this once. When downloading the base image is done it will continue with my own
Dockerfile.
The docker images command now shows me my image:
Time to run my app for the first time. Here we go:
This command starts my container, produces some output that it is starting things and finally will result in a line:
Now let’s see if my app is running correctly. Let’s try with curl:
Oops! Apparently something is wrong. On examination of the application log file inside the running container (which I accessed using the docker-bash tool by Phusion) it seems that I don’t have a database yet. So I’m going to install MySQL on my server first.
I’ll use the standard MySQL server available in Ubuntu 14.04:
After the installation where I set my root password, I can now create the app database:
After this I modified /etc/mysql/my.cnf and changed the bind-address setting
from 127.0.0.1 to my public IP address, 178.62.232.206. This way the Rails app inside my Docker container can use it:
In /etc/mysql/my.cnf I updated the line to this:
And restarted MySQL:
I’m going to use ENV variables to have my container use these mysql credentials. To do this, I need to do two things: 1) Prepare my database.yml file inside the repository to use ENV vars. And 2) configure Nginx to pass these variables into my Passenger process.
Here is my new database.yml, prepared for environment variables:
To make these ENV variables work for my Rails app, I need to add a custom Nginx configuration files. This is because Nginx flushes all variables from the environment, except the ones you define.
In my Rails application code, I add another Nginx configuration file called rails-env.conf:
And I modify my Dockerfile, so it adds the rails_env configuration file when building my container:
I committed the new nginx ENV var configuration. Now I’m going to build a new version of my container:
After building my container on my server, I can set up the database. In the following command, I use ENV variables to pass my database connection information for running the rake task to set up my database. Note that I added the -u app argument to the command. That argument makes sure the rake db:setup task is run as our app user inside the container.
Awesome. It worked!
Now I can run the container with the same environment variables as the previous command and try to access it via my browser to see if it works now:
When I browse to http://178.62.232.206, I see my Rails app that is connected to the database, and I see that it has compiled the correct assets. Victory!
This concludes this post where I:
I still have questions that need answering. I and the other Intercity developers will write about them. Here are some of the issues that plan to solve:
I hope you enjoyed this post. Please offer advice or ask questions if you have them! Thank you very much for reading.