I want to describe another way to run the Highscores-Service of the #BlueCloudMirror game . In the game I use IBM Cloud Foundry apps, now I want to explore IBM Cloud Kubernetes.
Note: The #BlueCloudMirror game we @Niklas, @Harald and I made, is available as an Pattern on IBM Developer.
Let’s get started with the first step, building a container which contains the Scores-Service using Docker .
This blog post is all about building and running a docker container on a local machine.
Topics you will find in this post: my experience of learning how configure a Dockerfile along with my creation of the Dockerfile for the score-service, including following steps:
- Choosing the base image
- Installing the needed packaging tools
- Defining the source code location and copying the source code into the container
- Configuring a new user and group for Bower , a package manager
- Setting up the Score-Service
- Running the Score-Service container locally
Note: This is not a blueprint, this is just how I did it and I share my experience with you.
Architecture of the Scores-Service
This is the relevant architecture for building the Docker container. The Scores-Service UI and the Scores Core Service will run in the Docker container locally. The Cloudant service still runs on IBM Cloud.
Choosing the base docker image
I haven’t done much research, which Node image on Dockerhub fits best to my requirements. Usually search is what you should do first and this is known as a best practice for using containers to reduce your maintenance effort in the future.
My decision was to build the container image from scratch and I chose the open source centos as my starting point for the container.
The following steps describe: How to create the Dockerfile in detail
Get started with the first line in the Docker file, build the container based on the centos image with the FROM instruction.
Installing the needed packaging tools
These are the tools I need to run my scores-service inside the container:
- Bower (because, I am using this package manager for the scores-service UI )
- Git for the installation
- Scores-service application source code.
I configure the execution of the download with RUN and installation of Node.js and git.
RUN curl --silent --location https://rpm.nodesource.com/setup_8.x | bash - RUN yum install -y nodejs RUN yum install -y git
Defining the source code location and copying the source code into the container
Now I create the directories I need for my source code inside the image.
The folder public contains the scores-service UI and the app folder contains the scores-core-service.
# setup folder structure in centos # service (node server) RUN mkdir usr/app # webapplication RUN mkdir usr/app/public RUN mkdir usr/app/public/lib
COPY the source code from the local machine into the defined directories.
As you can see, I use more then needed copy statements, because I want to highlight some of the files inside the app folder for myself s.
The .env file contains Cloudant access information for the scores-core-service.
I decided not to use ENV in the Dockerfile and refine all environment variables already defined in the .env file.
# Bundle app source COPY ./public /usr/app/public RUN ls COPY ./server.js /usr/app COPY ./.cfignore /usr/app COPY ./highscore_view.json /usr/app COPY ./sampledata.json /usr/app COPY ./score_index.json /usr/app COPY ./manifest.yml /usr/app COPY ./.env /usr/app
Configuring a new user and group for a package manager
During the installation of bower modules, Bower uses the folder public/lib. Bower is not allowed be executed as root. When you use the instruction RUN in a Dockerfile, by default the root user is used.
Bower needs rights to create or change folders.
So, I need to add a user and give him rights to the folders.
By the way, I install the needed Bower modules in the folder called lib and not to the default folder bower_components.
I add a user called bower and provide him specific rights to access folders . I found the easiest way to provide the rights was defining a user group and giving the group access to the needed folders.
# create group and user RUN groupadd installer RUN useradd -ms /bin/bash bower --group installer # set user rights to allow the bower user to setup custom lib folder RUN chown -R bower:installer usr RUN chown -R bower:installer usr/app RUN chown -R bower:installer usr/app/public RUN chmod g+rwX usr/app/public RUN chmod g+rwX usr/app RUN chmod g+rwX usr
Setting up the score-service
To setup the scores-core-service I set the working directory to execute commands from the
WORKDIR . Then I copy the npm package.json, and I install the modules for the scores-core-service with the npm package manager .
# Install app npm dependencies WORKDIR /usr/app COPY ./package.json /usr/app RUN npm install
The setup of the scores-core-service is done. Only the scores-service UI setup is missing.
As you know, I am using bower package manager to setup the scores-service UI.
In the following steps, I install bower and copy the needed configuration files into the image. Then I change the
USER and run bower install .
# Create app directory WORKDIR /usr/app # install bower RUN npm install --global bower # Install app bower dependencies COPY ./bower.json /usr/app COPY ./.bowerrc /usr/app USER bower RUN bower install
The few remaining steps are:
- Defining the port which the container should
EXPOSE. I define my port inside the server.js file line 57 var port = process.env.PORT || 3000; .
- Defining the default execution at the startup of the container. To start the node server at the startup of container I use the command
# Server listens on EXPOSE 3000 CMD [ "npm", "start" ]
For now the score-core-service and score-service UI setup in the Dockerfile is done.
To access the Cloudant database the .env file I copied before, which contains the information for the score-core-service.
Note: The .env file is not a part of the git repository, because normally I create the values with a bash script automatically and it contains keys, which should not be saved inside the github source code.
Here is a sample for the .env file.
# CF APP SERVICE_USER=admin SERVICE_PASSWORD=a12345678 BASE_PATH=/scores-service # CLOUDANT CLOUDANT_NAME=blue-cloud-mirror-scores-service-db CLOUDANT_DES_SCORES=_d_scores CLOUDANT_IDX_SCORES=_idx_scores CLOUDANT_DES_HIGHSCORE=_d_highscores CLOUDANT_IDX_HIGHSCORE=_v_highscores CLOUDANT_USERNAME=XXXXX CLOUDANT_PASSWORD=XXXXX CLOUDANT_URL=https://XXXXX-bluemix.cloudantnosqldb.appdomain.cloud CLOUDANT_PORT=443 SERVICE_URL=
Running the score-service container locally
The last remaining steps are building, running, and using this docker image locally.
- Build it
- Run it
- Use it
Build a container with the tag v1.
docker build -t scores-service:v1 .
Now run the container exposing port 3000 to the local machine.
docker run -d -p 3000:3000 scores-service:v1
Now the scores-service is running the container is locally available on http://localhost:3000 .
I hope this was useful for you and let’s see what’s next?
FYI: You can find the next step here: How to deploy a container to the IBM Cloud Kubernetes Service.
PS: By the way, you can use the IBM Cloud for free, if you simply create an IBM Lite account. Here you only need an e-mail address.
#BlueCloudMirror, #Docker #Container, #Bower, #IBMDeveloper