Jack Moore

Email: jack(at)jmoore53.com
Project Updates

Dockerized Rails Applications P2, Bash Script

02 Jan 2019 »

Trailing off of yesterdays rails microservice endeavors, I challenged myself to keep most application development binaries off of my “host” and keep everything in containers that reside on my host. This started to get really annoying quickly as I was forced to type out massively long docker commands to make any changes or have any access to my containers; I also didn’t like the fact that docker had no problem spinning up extra containers for no reason. The spinning up of extra containers may seem trivial, but I wanted to be able to scan through non-running containers easily.

This post goes into some of the details on the bash script I wrote for the rails application I was working on yesterday.

Script

#!/bin/bash

if [ $# -eq 0 ]; then
    echo "Try running this command with a command and some arguments"
    echo "See the ruby on rails manual for more"
    exit 1
fi

# Set Variables
exists=$(/usr/local/bin/docker container inspect dds_rails 2> /dev/null)
running=$(/usr/local/bin/docker inspect -f '' dds_rails 2> /dev/null)
pwd=$(pwd)

# Check if Container Exists
if [ "$exists" == [] ]; then
    echo "Does Not Exist."
else
    # Stop Container if running 
    if [ "$running" == "true" ]; then
        echo "Container is running.. Shutting down container"
        /usr/local/bin/docker stop dds_rails
    else
        echo "Container is not running.. Continuing on."
    fi
    /usr/local/bin/docker container rm dds_rails
fi

# Run Rails Command
if [[ $2 == s* ]]; then 
    echo "Trying to start your rails server..."
    /usr/local/bin/docker run -it -p 3000:3000 -v $pwd:/app --name dds_rails rails:dds
elif [[ $1 == "bundle" ]]; then
    echo "Rebuilding Image..."
    #/usr/local/bin/docker rmi rails:dds
    /usr/local/bin/docker build -t rails:dds .
    /usr/local/bin/docker rmi -f $(/usr/local/bin/docker images -f dangling=true -q)
    /usr/local/bin/docker run -it -p 3000:3000 -v $pwd:/app --name dds_rails rails:dds /usr/local/bundle/bin/${@}
else
    /usr/local/bin/docker run -it -p 3000:3000 -v $pwd:/app --name dds_rails rails:dds /usr/local/bundle/bin/${@}
fi

# Exit after done serving on local machine
exit 0

The big problem I ran into yesterday while attempting to run this application from a terminal was attempting to run the rails server command from inside the container. Running the server with /usr/local/bin/docker run -it -p 3000:3000 -v $pwd:/app --name dds_rails rails:dds /usr/local/bundle/bin/${@} instead of /usr/local/bin/docker run -it -p 3000:3000 -v $pwd:/app --name dds_rails rails:dds was causing my container to lock up the port on the host machine and I was hitting a connection reset by peer page in my web browser when I went to view the development environment on port 3000.

I think this had to do with docker not fully running the image so the container was at some sort of half baked state where it would use the image, but not fully expose the ports. I am still looking into this.

Rest of Script

The rest of this script is pretty straight forward, but with a quick demo of this script I am able to run ./docker_bin_connect.sh rails g model test to create a new model where docker_bin_connect.sh is this script name as compared to typing out /usr/local/bin/docker run -it -p 3000:3000 -v $pwd:/app --name dds_rails rails:dds /usr/local/bundle/bin/rails g new model

I love docker and everything it offers, but to type this long drawn out command out every time I need to run a migration, or rake routes, I would be spending most of my time in the shell writing docker commands instead of hacking.

More

Something I didn’t look at while writing this application was bash functions while writing this script. I am pretty new to bash, but functions will definitely be something I will be looking at in the near future. They are highly advised over writing alias

I also think another step for this type of application development is being able to run this image from any computer and deploy any type of application from some type of “intermediary container.” This is what I have done to a degree, but it was in a very hacky way.

Note on Application Code

I have spent the past 2 days on non-functional components of the codebase, but this will allow more developers to easily pick up the app and hack on it without having to spend two days of their own time configuring an environment to match the applications.

© Jack Moore