This article focuses on the deployment of Ruby on Rails in Docker, Docker is the hottest virtual machine in the present, and the Ruby on Rails deployment described in this article takes advantage of the cool, automated approach of rake in Ruby, Need friends can refer to the following
Basic Rails Applications
Now let's start with a basic rails application. For a better presentation, I use Ruby 2.2.0 and Rails 4.1.1
Run at Terminal:
$ rvm use 2.2.0
$ rails new && cd docker-test
To create a basic controller:
$ rails g controller welcome index
..., and then edit routes.rb so that the root of the project points to our newly created Welcome#index method:
root 'welcome#index'
Run Rails s at the terminal, then open the browser, login to http://localhost:3000, and you will enter the index interface. We're not going to add anything magical to the application, it's just a basic example, when we're going to create and deploy the container, use it to verify that everything is working.
Install webserver
We intend to use unicorn as our webserver. Add Gem ' unicorn ' and Gem ' foreman ' in gemfile and then bundle it (run bundle install command).
When you start the rails application, you need to configure the unicorn first, so we put a unicorn.rb file in the Config directory. Here is an example of a unicorn configuration file where you can copy and paste gist content directly.
Next, add a procfile to the root of the project so that you can use Foreman to start the application with the following:
The code is as follows:
Web:bundle exec unicorn-p $PORT-C/config/unicorn.rb
Now run the foreman start command to start the application, everything will work, and you will be able to see a running application on the http://localhost:5000.
Building a Docker mirror
Now we build a mirror to run our application. In the root directory of this rails project, create a file named Dockerfile, and paste it into the following:
The code is as follows:
# based on mirrored Ruby 2.2.0
From ruby:2.2.0
# Install the required libraries and dependencies
RUN apt-get update && apt-get install-qy nodejs postgresql-client sqlite3--no-install-recommends && RM- rf/var/lib/apt/lists/*
# Set Rails version
ENV Rails_version 4.1.1
# Install Rails
RUN gem Install Rails--version "$RAILS _version"
# Create the directory that the code runs
RUN mkdir-p/usr/src/app
Workdir/usr/src/app
# so that webserver can be accessed outside the container
Expose 3000
# Set Environment variables
ENV port=3000
# Start Web Application
CMD ["Foreman", "Start"]
# Install the required gems
ADD Gemfile/usr/src/app/gemfile
ADD Gemfile.lock/usr/src/app/gemfile.lock
RUN Bundle Install--without Development test
# Add Rails projects (and dockerfile the same directory) to the project directory
ADD.//usr/src/app
# Run Rake Task
RUN rails_env=production Rake Db:create db:migrate
Using the above Dockerfile, execute the following command to create a mirror (make sure the Boot2docker is started and running):
$ docker build -t localhost:5000/your_username/docker-test .
Then, if everything works, the last line of the long log output should look like this:
Successfully built 82e48769506c
$ docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
localhost:5000/your_username/docker-test latest 82e48769506c About a minute ago 884.2 MB
Let's run the container and try it!
$ docker run -d -p 3000:3000 --name docker-test localhost:5000/your_username/docker-test
|
docker-test localhost:5000/your_username/docker-test |
You can watch your rails application through your boot2docker virtual machine Port No. 3000 (mine is http://192.168.59.103:3000). (If you do not know your boot2docker virtual address, enter the $ boot2docker IP Command view.) )
Automated deployment with shell scripts
The previous article (article 1 and article 2) has already told you how to push the newly created mirror into the private registry and deploy it on the server, so we skip this section and start automating the process directly.
We're going to define 3 shell scripts and then end up using rake to bundle them together.
Clear
Every time we create a mirror,
Stop and restart Boot2docker;
Remove Docker orphan mirrors (those that do not have labels and are no longer used by the container).
Enter the following command in the clean.sh file in your engineering root directory.
The code is as follows:
Echo Restarting Boot2docker ...
Boot2docker down
Boot2docker up
echo Exporting Docker variables ...
Sleep 1
Export docker_host=tcp://192.168.59.103:2376
Export DOCKER_CERT_PATH=/USERS/USER/.BOOT2DOCKER/CERTS/BOOT2DOCKER-VM
Export Docker_tls_verify=1
Sleep 1
echo removing orphaned images without tags ...
Docker Images | grep "" | awk ' {print $} ' | Xargs Docker RMI
Add execute permissions to the script:
Build
The process of building is basically similar to what we did before (Docker build). Create a build.sh script in the root of the project and fill in the following:
The code is as follows:
Docker build-t Localhost:5000/your_username/docker-test.
Remember to execute permissions on the script.
Deployment
Finally, create a deploy.sh script that fills in the following:
The code is as follows:
# Open SSH connection to the private registry Boot2docker
Boot2docker ssh "Ssh-o ' stricthostkeychecking no '-i/users/username/.ssh/id_boot2docker-n-l 5000:localhost:5000 root@ Your-registry.com & "&
# Verify that the SSH channel is open before pushing.
echo waiting 5 seconds before pushing image.
Echo 5 ...
Sleep 1
Echo 4 ...
Sleep 1
Echo 3 ...
Sleep 1
Echo 2 ...
Sleep 1
Echo 1 ...
Sleep 1
# Push image onto remote Registry/repo
Echo Starting push!
Docker Push Localhost:5000/username/docker-test
If you don't understand what this means, please read the second part of the section carefully.
Add execute permissions to the script.
Use Rake to bind all of the above
The situation now is that each time you want to deploy your application, you need to run the three scripts alone.
Clean
Build
Deploy/push
It doesn't take much time, but in fact developers are more lazy than you think! So let's just be lazy!
We'll get the work sorted out in the end, and we're going to tie three scripts together through rake.
To make it simpler, you can add a few lines of code to the existing rakefile in the engineering root directory, open the Rakefile file, and paste the following content in.
?
1 2 3 4 5 6 7 8 9 10 11 12 13-14 |
namespace:d ocker do desc "Remove Docker container" Task:clean does sh './clean.sh ' End desc ' build Docker image ' Task:bui LD => [: Clean] doing sh './build.sh ' End desc ' Deploy Docker image ' task:d eploy => [: Builds] do sh './deploy.sh ' end en D |
Even if you don't know the grammar of rake (you really should know that this thing is so cool!), the content is also obvious. We declared three tasks in a namespace (Docker).
The three tasks are:
Rake Docker:clean
Rake Docker:build
Rake Docker:deploy
The deploy is independent of the Build,build and is independent of clean. So every time we enter a command run.
All scripts are executed in order.
Test
Now let's see if everything is okay and you just need to make a small change in the app's code:
Then came the moment to witness the miracle. Once the mirrored file is uploaded (it may take a long time), you can ssh to the product server and pull the Docker mirror to the server (via the SSH pipeline) and run. How simple!
It may take a while for you to get used to it, but once successful, it's almost as simple as deploying Heroku.
Note: As always, please let me know your opinion. I'm not sure this is the best, quickest, or safest way to develop a docker, but it does work for us.