Author Docker Tips
Offical Docker Documents
vsupalov nice doc
-
Image:
- It is read-only file
- This file includs system, source code, files, dependency, tools
- It can be understood as a template
- Hierarchical concept
-
Container:
- It is a running image
- Copy image and add a read-write layer (container layer)
- It can be created multiple containers by a image
- Container is not VM
- Containers are just processes
- The processes is limited to access to CPU memory resource
- After processes stop, container will exit
- Pull from registry online
- Public
- Private
- Build from Dockerfile online
- Load from file online
- Dockerfile constructs docker image
- Dockerfile includes commands
- Dockerfile has grammar rules
Example:
FROM ubuntu:21.04
RUN apt-get && \
DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y python3.9-pip python3-pip python3.9-dev
ADD hello.py /
CMD ["python3", "/hello.py"]
Build it in the folder which has dockerfile and python file, -t hello is meaning tag the hello to latest version
$ docker image build -t hello .
RUN is command when use Dockerfile. For example install or download commands. Each line of RUN command can generate a layer of Image layer.
Multi-layer ex:
FROM ubuntu:21.04
RUN apt-get update
RUN apt-get install -y wget
RUN wget https://github.com/ipinfo/cli/releases/download/ipinfo-2.0.1/ipinfo_2.0.1_linux_amd64.tar.gz
RUN tar zxf ipinfo_2.0.1_linux_amd64.tar.gz
RUN mv ipinfo_2.0.1_linux_amd64 /usr/bin/ipinfo
RUN rm -rf ipinfo_2.0.1_linux_amd64.tar.gz
One layer ex:
FROM ubuntu:21.04
RUN apt-get update && \
apt-get install -y wget && \
wget https://github.com/ipinfo/cli/releases/download/ipinfo-2.0.1/ipinfo_2.0.1_linux_amd64.tar.gz && \
tar zxf ipinfo_2.0.1_linux_amd64.tar.gz && \
mv ipinfo_2.0.1_linux_amd64 /usr/bin/ipinfo && \
rm -rf ipinfo_2.0.1_linux_amd64.tar.gz
COPY and ADD are both for copy file from local to image, and if the image doesn't have directory, it will be generated. The difference is ADD has unzip features.
FROM python:3.9.5-alpine3.13
ADD hello.tar.gz /app
ARG is only available during the build of a Docker image(RUN etc), not after the image is created and containers are started from it (ENTRYPOINT, CMD)
Dockerfile ex:
FROM ubuntu:21.04
ENV VERSION=2.0.1
RUN apt-get update && \
apt-get install -y wget && \
wget https://github.com/ipinfo/cli/releases/download/ipinfo-${VERSION}/ipinfo_${VERSION}_linux_amd64.tar.gz && \
tar zxf ipinfo_${VERSION}_linux_amd64.tar.gz && \
mv ipinfo_${VERSION}_linux_amd64 /usr/bin/ipinfo && \
rm -rf ipinfo_${VERSION}_linux_amd64.tar.gz
ENV values are available to containers, but also RUN-style commands during the Docker build starting with the line where they are introduced.
Dockerfile ex:
FROM ubuntu:21.04
ARG VERSION=2.0.1
RUN apt-get update && \
apt-get install -y wget && \
wget https://github.com/ipinfo/cli/releases/download/ipinfo-${VERSION}/ipinfo_${VERSION}_linux_amd64.tar.gz && \
tar zxf ipinfo_${VERSION}_linux_amd64.tar.gz && \
mv ipinfo_${VERSION}_linux_amd64 /usr/bin/ipinfo && \
rm -rf ipinfo_${VERSION}_linux_amd64.tar.gz
ARG value is able to be modified when the image is building by --build-arg
The command of CMD can be overwrote when this command is running docker container run + command
The command of ENTRYPOINT must be executed
CMD and ENTRYPOINT support both shell format and Exec format.
Shell ex:
CMD echo "hello docker"
ENTRYPOINT echo "hello docker"
Exec ex:
CMD ["echo", "hello docker"]
ENTRYPOINT ["echo", "hello docker"]
Image build ex:
$ docker image build -f .\Dockerfile-arg -t ipinfo-arg-2.0.0 --build-arg VERSION=2.0.0 .
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
ipinfo-arg-2.0.0 latest 0d9c964947e2 6 seconds ago 124MB
$ docker container run -it ipinfo-arg-2.0.0
root@b64285579756:/#
root@b64285579756:/# ipinfo version
2.0.0
root@b64285579756:/#
Here is a simplified overview of ARG and ENV availabilities around the process around building a Docker image from a Dockerfile, and running a container. They overlap, but ARG is not usable from inside the containers.
-
CACHED: If you change a layer of dockerfile commands or program files about a layer, the cache will not be used after this layer.
As far as possible, put files that need to be modified frequently behind those that do not need to be modified.
-
dockerignore: reduce build content, increase build speed, and protect files
-
mult stage build:
Dockerfile:
FROM gcc:9.4 AS builder COPY hello.cpp /src/hello.cpp WORKDIR /src RUN g++ --static hello.cpp -o hello FROM alpine:3.13.5 COPY --from=builder /src/hello /src/hello ENTRYPOINT ["/src/hello"] CMD []
build:
$ docker image build -f Dockerfile -t hello-alpine .
container run:
$ docker container run --rm -it hello-alpine docker
output:
Hello Docker
-
How to use no root user
- through groupadd and useradd to create group and user of flask
- through USER to specify following commands to run as the user of flask
FROM python:3.9.5-slim RUN pip install flask && \ groupadd -r flask && useradd -r -g flask flask && \ mkdir /src && \ chown -R flask:flask /src USER flask COPY app.py /src/app.py WORKDIR /src ENV FLASK_APP=app.py EXPOSE 5000 CMD ["flask", "run", "-h", "0.0.0.0"]
- It is running container
- It is copied image, and added
read-write
on top (calledcontainer layer
) - Create multiple container from one image
- Choose official, if there is no official, choose Dockerfile
- Prefer tag version
- Choose size as small as possible
$ docker info
$ docker container logs CONTAINER ID
dynamicly checking log:
$ docker container logs CONTAINER ID -f
The commands for outside of container, The PID is different with inside of container:
$ docker container top CONTAINER ID
equal to
$ ps aux | grep nginx
More detail for processes
$ pstree -halps PID
Latest version
$ docker image pull nginx
Specify version
$ docker image pull nginx:1.20.0
$ docker image tag OLD REPOSITORY NAME NEW/NAME:1.0
$ docker container run nginx
create an interacting container
$ docker container run -it busybox sh
execute interacting command in a running container
$ docker container run -d nginx
$ docker container exec -it CONTAINER ID sh
$ docker image ls
old:
$ docker container ps -a
new:
$ docker container ls -a
$ docker container ps -aq
Exit one:
$ docker container stop CONTAINER NAME or CONTAINER ID
Exit in batches:
$ docker container stop $(docker container ps -qa)
In some situation it needs to remove container first then remove image
$ docker image rm [IMAGE NAME] or [IMAGE ID]
$ docker container rm $(docker container ps -qa)
remove all containers:
$ docker system prune -f
remove all images:
$ docker image prune -a
$ docker container rm [CONTAINER ID] -f
attached mode is not using -d. detached mode is using -d:
$ docker contianer run -d -p 80:80 nginx
Using attached mode
$ docker attach CONTAINER ID
But not recommend to use attached mode because when press ctrl+c it will exit a container
- Data Volume, managed by Docker (/var/lib/docker/volumes/Linux)
- Bind Mount, specified location by user to storage data
docker volume
-
List up all volume:
$ docker volume ls
Find the local of you pc:
docker volume inspect volume name
but you only can find the directory in linux.
Remove all volumes:
$ docker volume prune
Every time new container is generated, a new Volume repository will be generated accordingly by system. But we can specify a volume repository for using -v:
$ docker container run -d -v any_volume_name:/path image_repository_name
Save nginx:1.20.0 to nginx.image in local PC
$ docker image save nginx:1.20.0 -o nginx.image
Load file and export to image
$ docker image load -i nginx.image
Login to Docker Hub:
$ docker login
Username: ****
Password: ****
Login Succeeded
Push to Docker Hub:
$ docker image push [DOCKER ID/IMAGE NAME:TAG]
Pull from Docker Hub:
$ docker pull [DOCKER ID/IMAGE NAME:TAG]
$ docker container commit [OLD CONTAINER ID] [NEW DOCKER ID/IMAGE NAME:TAG]
$ docker image history [IMAGE NAME]