Clean and portable development environment - Docker

I have been worked on docker for few months and experiencing the power of it.

Docker - Build, Ship, and Run Any App, Anywhere

You can see more on here.

Here are some good of it.

  1. Docker allows you to build all kind of environment and app in local or in server. The best thing I love, is never afraid of screw up environment while all the app is separate and you can just rebuild a new environment by dockerfile. Also, I was have a hard time dealing with database like oracle database and mongoDB. The installation and configuration takes a lot of time. Now, using docker pull mongo. Boom, it's done! Then connect you app with DB without paying any price to any server. Definitely the best friend of learning.

  2. Using dockerfile to set up environment. This allow all the team members worked in the same environment. No matter your are using what OS, what version of node. What you can do more is build your app inside docker. The scenario is, I used different npm version with my manager, and this cause different download result using npm install. Here are the solution of it The Ultimate NodeJS Development Setup with Docker.

  3. Using docker-compose file to manage multiple container. This is very useful while you run different components on different container especially database(it require a lot of setting like account, password,etc). Then you don't need to type these environment variable in CLI.

  4. Deployment. After pushing you image. you can run the your app anywhere. Just adding a docker-compose file like this

waitingApp
image: waitingImage
volumes: ./:var/www/

I would like talk a little more about the docker-compose here. So here are some requirements for the scenario.

  • We need a web service connect to a mysql database.

  • Need to specify mysql name, password elegantly.

  • We have some secret environment config to want to push to github. For example, EC2 config.

  • We want a persistence storage on server.

Below is the solution using docker-compose instead
type a lot of commend with docker run.

docker-compose.yml
web-service
   build: .
   port:
      - "80:2367"
   links:
      - mysql:mydb
   env_file:
      - ./myConfig.env
   vloumes: 
      - ../website-front-end:/static
   container_name: webService
mysql
   image: mysql
   ports: 
      - "3306:3306"
   environments:
      MYSQL_ROOT_PASSWORD: "mypassword"
      MYSQL_DATABASE: "mydatabase"
   container_name: mysql

Then run docker-compose up -d. Everything is ready to go.

I also want to put some note here for each section in compose file.

  • build. Target the folder you want to build as an image. Note: the folder must have dockerfile.

  • port. Specify the port you want to expose. And you can specify multiple ports as you want.

  • link. Your app can connect to another service with expose port. Note: this is only work in service within the same docker-machine. If you want to do service discovery, you can try put docker app in kubernetes which provide the ad-on solution.

  • env_file. Specify your env files. the env file should looks like this.

myConfig.env
#Note: space matters here.
AWS_KEY=ALISHDFKANSLVKAJNHSIUHFA
AWS_SECRET=LANNBOIUCHMGNRKLJHOSIUNLKSJDNL
AWS_REGION=ALKJSDNKVJNZINV

So now you can put *.env into gitignore. And anyone fork your git project don't need to change the docker-compose.yml but only need to write their won env file.

  • environment. Instead of write your environment to env file. you can just put them in this section.

  • volumes. This is very useful part. This works like you create a sym-link. This is useful for persistence storage.

  • container_name. This is an option. Usually I will use this for specify my container name otherwise it will use default name.

In the new version of docker-compose. It add a new comment docker-compose down which will stop, remove container and all images in the docker-compose file. Also, there is depends_on which allow you service start in order(Note: this will no wait db for initialized. you should have to write code for retry connection).