This is the third part of our container based development series
This post is based on the container development article created by me.
On the previous articles we did a program that count from 0 to 19 but could not do anything besides that. A program that can not persist is not so useful so let's modify our program a little so it will count the current file content and then count to that value +20. For that we need to create a volume on the container, this will make a specific folder on the container persist when mounted. All the files for this step are on the projects repository on the secondContainer branch.
First we need to add a proper volume on our docker file.
Dockefile
FROM node:13-alpine3.10
RUN mkdir -p /app/ourApp/data
COPY ./nodeCounter.js /app/ourApp/
WORKDIR /app/ourApp/
VOLUME /app/ourApp/data/
CMD node ./nodeCounter.js
Then we need to make sure our program don't stop at 20 but stops at start + 20
nodeCounter.js
const fs = require('fs')
const path = require('path')
const counterFile = path.resolve(__dirname, './data/counter.txt')
const COUNTER_LIMIT = 20
const INTERVAL = 1000
let counterData = 0
if (fs.existsSync(counterFile)) {
const fileData = fs.readFileSync(counterFile)
counterData = parseInt(fileData, 10)
}
const stopCounter = counterData + COUNTER_LIMIT
const recursiveCounter = () => {
if (counterData === stopCounter) {
process.exit(0)
}
console.log(counterData)
counterData++
fs.writeFileSync(counterFile, counterData)
setTimeout(recursiveCounter, INTERVAL)
}
recursiveCounter()
Then we need to build our image with the same name and a new tag.
docker build -t container_dev:second .
We should see an output with the text:
"Successfully tagged container_dev:second"
But out work is not over we need to actually create a volume on our computer (the host) so our container can read and write persistent data.
docker volume create our-named-volume
But where physically our volume is? For that we can inspect the volume and check it's exact path.
docker volume inspect our-named-volume
That would give all the volume data like the one below, the mountpoint is where docker created our volume.
[
{
"CreatedAt": "2020-03-20T10:44:48+01:00",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/our-named-volume/_data",
"Name": "our-named-volume",
"Options": {},
"Scope": "local"
}
]
Now to run our app with one new argument , -v to link the volume
docker run -v our-named-volume:/app/ourApp container_dev:second
Run it twice and you will notice we start where we stopped. If you open 2 shells and do it a little bit after the first one start you should see they are sharing and modifying the same file (There is a race condition here but we don't mind for now).
We have a way to persist state, actually we even have a way to share the same set of files between multiple containers!
I would like to call attention about the importance of mounting, if we run without the "-v" command we will have the same behavior as the first time, our state would not persist.
So let's see what we learned
- For a volume to be accessible in the container we need to create it at some location inside the container.
- We need to link a volume with the -v when running the docker run argument.
- Multiple containers can have access to the same volume.
Next part: Containers and installing PHP alongside node in 16 lines of code!
Top comments (0)