Ever since I noticed that the application we prepared has expanded significantly, I have decided to find a completely new method for automation of the process of its launching. It was important for me to find a solution which would make it possible to activate new features in isolation.
Introduction
Discovering a simpler method of process automation would be a significant improvement of my work as well as the work of my entire team. I thought “Why not use Docker?”
During the preparation stage, I created two setups: one for the front-end application, and the other for API. Below you can see a presentation of what I’ve learned during the development process.
The first problem
I want to have a cloned repository in the container, so I added an ssh key via the ADD command in Dockerfile:
ADD ~/.ssh/testowy
And bam! The file is not found. Why?
Let’s assume that we have the following folder structure:
docker/
|-- stuff/
| |-- test.txt
|-- Dockerfile
server/
|-- data
| |-- setup.yml
Run command build
in the login-queue
folder and you can only add files from the local folder and its local subfolders, e.g. stuff.
If you want to add the server
folder, you’ll receive a message: “unable to prepare context”
Dockerignore
Ever wondered why the image takes so long to build? Maybe you didn’t use .dockerignore
, to ignore files which are not necessary in the image. The .git
folder should be removed automatically as well as any temporary files.
Order of commands in Dockerfile
Docker saves each line form Dockerfile and after building each line is saved as a layer. It is very important not to change the order of particular commands too often.
FROM ubuntu
RUN apt-get install -y software-properties-common python
RUN add-apt-repository ppa:chris-lea/node.js
RUN echo "deb http://us.archive.ubuntu.com/ubuntu/ precise universe" >> /etc/apt/sources.list
RUN apt-get update
RUN apt-get install -y nodejs
RUN apt-get install -y nodejs=0.6.12~dfsg1-1ubuntu1
RUN mkdir /var/www
ADD app.js /var/www/app.js
CMD ["/usr/bin/node", "/var/www/app.js"]
For example, if you change the last line in Dockerfile, all previous lines will be downloaded from the cache while the last line will be modified. When you replace line No. 4, then all lines starting from Line 4 to the end, will be modified. For this reason it is worth to place commands which will not change, at the beginning of the file.
Copying files to image
It’s worth considering what a given image will be used for. If you need it to launch a service once, just copy the code content directly to the image:
COPY . /workdir
Unfortunately, this makes it impossible to edit files and every time you want to edit your code, you’ll have to build the image again.
If you’re using MacOS and want to use the built image for development, you have to approach this matter in a slightly different way. If you will use volumes then you have to be prepared that this is an extremely slow solution (e.g. copying a file from the host to the container is done with the speed of 4.5 MB/s, while copying internally in the container with speed 10-20x higher). Luckily, as you can see at link, the problem has been known and its solution is the key issue for the team responsible for developing Docker for Mac.
How can you use Docker for development in this situation?
You can use it for external services, e.g. Redis/PSQL/Elasticsearch or use ready solutions, which offer rsync: https://github.com/brikis98/docker-osx-dev
To sum up
If you have a big team and wish to test a new feature, docker will be the ideal tool! Nevertheless, would I use it for a production launch of a server? I’m not fully convinced yet…
Additionally, I recommend a few outstanding articles: