I'm here to share and well as to note some basics about Docker.
I'm Java developer, so I will mapping the concept from Java to Docker. If something confused you, please add comment and I will answer/update accordingly.
Terms
Docker Machine
The host/machine which is run docker server.
If you run Docker on Mac you will have a Virtual Machine which is, in this case, a Docker Machine
Image
Similar to Java, you packaged your app into Jar/War file and then your server will run it.
Similar to Docker, Image is a type of package that contains all of your things extras some OS files (/usr/bin, etc...).
Container
From Java point, you have Jar/War file, then you run it by java -jar your-jar.jar
. The Java Runtime will starting to run your bytecode and you have a process.
Same for Docker, when you type docker run your-image
, the docker runtime (currently default is runc) will start to run your image and create a process, which is, in docker terms - container.
Tag
Tagging or Versioning is always important.
When I was using Java, I just created my Jar/War and then Upload it to repository, say, version 1.0.0-RELEASE
then the Ops guys will download that file from Repository and Run it.
In Docker, I have an image
, I tag
it, and then I push
it into repository.
Tag is just the old wine in new bottle.
Volume
In Java, most of the time you will read/write file directly on Host Machine/Server and usually, that file will remain until you delete it.
In Docker, every time start a new container, the file system is fresh, none of your files from previous session will remain. This is a so-called "immutable". To solve that problem, Docker have a concept called volume.
To bind a volume inside Docker, simply add option --volume
or -v
for short.
Frequency used commands
docker run
Start a container
$ docker run --rm -it -P -v /tmp:/tmp/host ubuntu:18.04
In above command:
--rm
mean: after this container finish execute, clean it!
it
mean: Interactive shell. Without this, if your application require you to input, you cannot do it.
-P
mean: If this container EXPOSE
ports, please expose all of those ports randomly on DockerMachine. To bind specific port, 1323 for example. -p 11323:1323
. Where 11323 is the port on Host Machine, and 1323 is port expose by container.
-v /tmp:/tmp/host
mean: bind "/tmp" from host volume to "/tmp/host" in container.
Other useful options:
-d
: Run container in detached mode. You shell will be freed immediately
--name
: Name your container, then use can interact with its.
docker logs
$ docker run --name my-nginx --rm -p 38080:80 -d nginx:latest
Then curl 127.0.0.1:38080
Finally, to see access log of Nginx. docker logs my-nginx
Above command will print full logs of my-nginx
container. To limit and follow limited line of logs, use docker logs --follow --tail 10 my-nginx
docker exec
$ docker exec -it my-nginx /bin/bash
This command is very useful to debug our code.
"Is my code created file as I expected?"
"How do I know if my code have all it dependencies? ldd my-binary
!"
Using docker exec
give you the same power as ssh
to your server.
docker pull
$ docker pull containous/whoami
Will download containous/whoami:latest
image to your machine.
To break down docker run
, like we do in git.
git clone
= git init
+ git remote add
+ git pull
docker run
= docker pull
+ docker container create
+ docker container start
After testing and learning, now it's time to create our own docker image.
docker build
Here my file template for almost every project (Golang)
ARG BASE_IMAGE=gcr.io/distroless/base
FROM golang:1.14 as builder
COPY . /work
WORKDIR /work
RUN CGO_ENABLED=0 go build -a -ldflags '-extldflags "-static"' -o app main.go
FROM $BASE_IMAGE
LABEL maintainer="contact@liemlhd.com"
# Copy Built App
COPY --from=builder --chown=65532:65532 /work/app /app/app
USER nonroot
WORKDIR /app
EXPOSE 1323
ENTRYPOINT ["./app"]
And then
$ # To build production image
$ docker build -t saboteurkid/go-demo:latest -f Dockerfile .
$ # To build test/dev image
$ docker build -t saboteurkid/go-demo:latest-debug \
--build-arg BASE_IMAGE=saboteurkid/ubuntu:18.04-base \
-f Dockerfile .
docker push
Finally, Push you Image to the Repository
$ docker push saboteurkid/go-demo:latest
$ docker push saboteurkid/go-demo:latest-debug
Some others useful commands:
docker tag
: this is useful when you want to rename a tag to difference name. Say I want to fork a saboteurkid/go-demo:1.0.0
version from saboteurkid/go-demo:latest
. Simply type:
$ docker tag saboteurkid/go-demo:latest saboteurkid/go-demo:1.0.0
docker commit
: this is useful when you want to commit your changes after add some changes to your container. Example:
$ docker exec my-nginx cp /etc/hosts /tmp/hosts
$ docker commit my-nginx saboteurkid/nginx-with-text-file
$ docker run --rm -it -d --name nginx-with-file saboteurkid/nginx-with-text-file
$ docker exec nginx-with-file cat /tmp/file.txt | head -n1
$ # Will show: `127.0.0.1 localhost`
Top comments (0)