Using Docker to Manage Mentoring Developers

Recently I took on a part-time position as a mentor for code camp students. The mentoring is performed 100% remotely and takes me 5-6 hours per week. This fairly small investment of time has yielded me a wealth of experience and learning opportunities.

A mentor is defined as some who advises or trains someone, especially a younger colleague. I have been performing this role as technical lead at work and, consequently, didn’t expect much difference in this new mentoring job. I was in for a surprise, however, because mentoring someone that has been vetted and hired by your company is not the same as mentoring a complete newbie who has little or no programming experience. I will skip the social and cultural challenges that I faced and move straight to some of the technical challenges and how I overcame them.

The Challenge

The primary technical challenge I faced was the need to be responsive to each student as they moved through a fast-paced curriculum. The course is for a full-stack web developer and focuses on Ruby on Rails as the primary framework, with additional material on object-oriented development, single-page-apps, and JavaScript topics. It is a lot of work and includes a lot of material. In order to be able to help four different students who are each moving through the course at a different pace, I needed to be able to set up different application environments quickly and reproduce the errors students are seeing. The main components that change from student to student are as follows:

  1. Version of Ruby, students all start at the same version in the provided development environment, but some update their version of Ruby at times, either knowingly or unknowingly, or by downloading a Gemfile from another project. The version must be correct on your system based on the one specified in the application’s Gemfile, or you must change it.
  2. Version of Rails, same as Ruby, and this also applies to various other gems used in the course applications. The students build 5 or 6 full applications throughout the course. There are many dependency gems for each application and the versions can be different from student to student.
  3. Student’s OS and editor, this is not as big a deal unless troubleshooting issues with their actual development environment. These issues are not as common due to most student’s using either Vagrant or Codeenvy.com as their environment.
  4. Application settings, this includes things such as names of databases, database password, AWS credentials, and API keys for the services used in the applications.

The Solution

The answer to managing all these student component variations for me was to use Docker and WSL. Not only do these tools help me with the changes in the student’s environments and applications, but they help me with the fact that I use a Windows 10 machine for work, but at home, which is where I primarily mentor from, I use a Linux machine. WSL, or Windows Subsystem for Linux really helps with consistency for me between machines by having the same tooling installed and I can use the same commands on both machines.

Setup

On both machines I use a Linux terminal for everything. For my Windows 10 machine this means using the WSL Ubuntu distribution. On my Linux machine I have a similar version of Ubuntu installed, simplifying things by sticking to Long Term Support (LTS) releases. The real workhorse of my setup is Docker, which allows the virtualization of software applications and platforms in container layers without the need for full hardware virtualization. So, instead of having to use the Vagrant environment provided for the students, which I did try and does work great for setting up an environment very easily, I can simply use Docker and not need a virtual machine. It is important to note that using the Vagrant VM would not address the challenges of meeting each student’s needs.

Docker

How does Docker help? In order to explain I am going to describe my setup briefly and then explain an example usage situation.

  1. Docker is installed on my Linux machine, and Docker for Windows is installed on my Windows 10 machine. There is some special setup steps to make Docker work from within WSL that can be found in this article and those instructions were invaluable.
  2. A specific directory structure that supports multiple students and multiple ancillary services (i.e. database, cache). An example and startup for this environment can be found here

    mentoring/
        new-student/
        student1/
            app1/
            app2/
            challenges/
            Dockerfile
        student2/
        services/
            mongodb/Dockerfile
            postgres/Dockerfile
        .Dockerignore
        Docker-compose.yml
        application.jogi.yml
        README.md


  3. I use Docker Compose to manage an overall container for my environment that includes student-specific containers. I have Docker Compose installed on both machines.

This setup for Docker allows me to utilize the folder structure to separate each student’s code projects inside their own directory while only having to make a couple of changes to the main Docker-compose.yml file and a specific student’s Dockerfile before starting up their environment. Let us now look at an example usage of the setup.

An Example

At the start of a mentoring session, the student reports that they are stuck on adding “feature x” to their current application. The application is in Rails and therefore uses a Postgres database and I have no idea what their code looks like. So, we begin by me asking them for their Github account information. Then we go into Github to get the URL of the repository they are using for the application. Fortunately, the students are instructed as part of the course to put all their code into Github. Once I have the URL I can begin with my setup.

  1. Move into the mentoring setup directory and if there is not a directory for the current student already then I make a new one by copying the template:

        cp -r ./new-student ./studentX

  2. Next task is to cd into that new studentX directory and clone their repo inside that folder.
  3. Now I have a student folder with Docker file and a folder inside it with their app code. so next I need to update the Docker file from the template file. I will not write out the entire Docker file template here because it is long (see the link in the “Docker” section above for the full template). It took a bit of time to get it dialed in so that all the dependencies needed to build some of the more native gems were correctly included. The template is based on Alpine Linux, also, to keep the size down, but that involved some additional tweaking and research to run under Ubuntu. Here are the updated lines that I change for a new student:

    1. First, I update Line 30 to include the correct app name, we will use the name “nomster” here as an example application name. This line copies the Gemfile and lock file over to the container’s working directory:

           ADD ./nomster/Gemfile* ./

    2. Second, I update Line 35 with same application name. This line copies the main source for the app:

           COPY ./nomster/ ./

  4. Now that the student’s Dockerfile for running a Rails app that was just pulled from git is ready, I need to update my Docker-compose.yml file for the entire environment so that it knows which Dockerfile to spin up for the app.

    1. I need to update Line 17 of the Docker-compose.yml file in the main mentoring directory. This line is setting the location or context for the web container’s image:

           context: ./studentX/

    2. I also need to change the volume path on Line 21 so that any edits we make to the code are updated in the container. Note that this update uses both the student name and the app name:

           volumes:
                      - ./studentX/nomster/: /app


  5. It is a convention to not include the application.yml file for Rails applications in the git repository due to it containing credential information. This is the purpose of the /mentoring/application.jogi.yml file. This file contains my credentials, the password to my postgres container’s db, the AWS S3 bucket credentials I use for supporting the student apps, a set of values for sending emails via smtp, and a few other items. In order to use these values, I use the following command to copy my application yml file into place inside the student’s application code:

         cp ./application.jogi.yml ./studentX/nomster/config/application.yml

  6. Now I am ready to start the environment using the following command in the mentoring directory:

         Docker-compose up

    With the Docker environment now running I have my postgres db and my Rails container running, and I am ready to run the student’s application and hopefully see the error they are seeing. The last few steps are specific to starting up a Ruby on Rails application, but I will include them here for context:

         Docker exec -it web /bin/ash # opens a prompt in the rails container
        # remaining commands are run from the prompt inside the container
        rake db:create
        rake db:migrate
        rails s


Now I have the database schema migrations executed so my database for their application looks as it should. Mentoring full speed ahead!

Conclusion

This Docker system has room for improvement but I have been using it for over six months now and so far, it has served me well. I think that my experience mentoring has been a blessing and I have never been more active in my personal studies and on Github. Having to stay current with web technologies and frameworks for my students has the added benefit of helping me keep current for my own career. I recommend the student mentoring experience to any senior level developer that can find the time to pass on some of their experience to the next generation of software developers.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top