docker
A container creation and management tool.
- Ensure the consistency of production enviroment and development enviroment.
- Ensure the consistency of different development enviroments.
Compare to Virtual OS: the latter consumes too much redundant resources.
容器化 vs 虚拟化:
-
(HyperKit是一种轻量级虚拟化方法)
-
Docker Engine
- Docker Desktop(CLI)
- Docker Hub
配置
国内的 Docker Hub 镜像加速器,由国内教育机构与各大云服务商提供的镜像加速服务 | Dockerized 实践 https://github.com/y0ngb1n/dockerized
Images & Containers
Images: Templates/Blueprints for containers
is automatically exposed to us by container..we're not expoing any port here
docker run -it node
- Dockerfile
FROM node # base image
WORKDIR /app
COPY . /app # orginal folder, dest folder; or "./" relative to WORKDIR
RUN npm install
EXPOSE 3000
CMD ["node", "server.js"] # CMD executes after the container is created based on this image, always the last line
- Layer based architecture: Dockerfile 里的every instruction 都可以视为一个 read-only layer, 最后运行的时候,会再加一层 Container Layer(read-write) 所以会有多个container, 但只有一个image内的代码,不会复制多次的。
另外,制作image 的 layer 可以缓存,所以记住容易发生更改的指令要放后面,一个小小的优化点。
- docker build . (. 指相对于 Dockerfile 的定位) -t vikki77/name:tag (注意,好习惯一定要打标)
- docker tag kub-first-app vikki77/kub-first-app // add tag afterwards
- docker push vikki77/kub-first-app
- docker run -p localPort:targetPort docker_id
- docker stop docker_name
Docker Run
- docker run -p 3000:3000 -v "$(pwd)/ss:/files/ss" -d imageName // Detach mode
- docker attach container-id
- docker start -a container-id
- -i(interative) -t(pseudo-tty)
- --rm // 退出container 后自动清理文件系统
- docker exec -it ... ...
<container id>
/bin/bash - docker exec -it
<container id>
/bin/sh - docker inspect
<container id>
Docker ps
- --filter "name=registry" --filter "ancestor=registry" // from image 是什么
Docker rm
- docker rm container
- docker rmi image
- docker image prune // unused/tangling悬空 images
Pretty error-prone.
Its not sth. we will use very often in ..., but still a sth. you should be aware of.
docker cp: copy some logs to local host machine.
docker cp foo.txt container_id:/foo.txt
Docker logs - docker logs -f --until=2s --tail=20 nginx (-f 代表 --follow) - 加上 grep: docker logs -f --until=2s --tail=20 nginx 2>&1 | grep "127."
data
-
Managed by Docker
-
in dockerfile:\anoymous Volumes, attached to one container, gone when one contained shut down -v thePathToBeMaintained
-
Named Volumnes: data shared by containers, wont be deleted, -v name:thePathToBeMaintained
-
Managed by host
- bind mounts: editing & persistent data, -v absolutePath:thePathToBeMaintained
Eh..有一个就是 include + exclude 的情况 e.g -v "$(pwd):/app" -v /app/node_modules,这样后者里的node_modules 就不会被覆盖(不过直接在 .dockerignore 里写就好了呀
p.s. 我用 minikube 做 docker-daemon, bind mount 的 volumn 未绑定上,是个 bug, 参考 https://gist.github.com/gitjonez/eac3cf6d3a963e5077875dcf0e7e73ee
others
- ENV vairable: ENV PORT 80 \n EXPOSE $PORT ;使用:-e PORT=3000 或 --env-file env
- build-time arguments: ARG DEFAULT_PORT=80;使用 docker build xx --build-arg DEFAULT_PORT=8000
networks
- container vs host machine: localhost:27017 => host.docker.internal:27017
Docker 实际上工作在另一网段?通过 docker inspect xxcontainer 可以看到 ip
- container vs container: docker network create netname; docker run ... --network netname; and use containername:port
注意前端请求后端只能用 后端服务暴露出端口 的模式哦。
utility containers
Running Commands in Containers
- docker run -it node
- docker run -it -d node; docker exec containerName npm init;
- docker run -it node npm init
ENTRYPOINT ["npm"] will append after this entrypoint
docker-compose
- docker-compose up [-d] (--build) // detach, force build
- Docker-compose down [-v] // 是否要 remove volumes
version: "3.8"
services:
mongodb:
image: 'mongo'
volumes:
- data:/data/db
# environment:
# MONGO_INITDB_ROOT_USERNAME: max
# MONGO_INITDB_ROOT_PASSWORD: secret
# - MONGO_INITDB_ROOT_USERNAME=max
env_file:
- ./env/mongo.env
container_name: mongodb
backend:
build: ./backend
# build:
# context: ./backend
# dockerfile: Dockerfile
# args:
# some-arg: 1
ports:
- '80:80'
volumes:
- logs:/app/logs
- ./backend:/app
- /app/node_modules
env_file:
- ./env/backend.env
depends_on:
- mongodb
frontend:
build: ./frontend
ports:
- '3000:3000'
volumes:
- ./frontend/src:/app/src
stdin_open: true
tty: true
depends_on:
- backend
volumes:
data:
logs:
安装相关
On Mac, brew install docker
: cannot-connect-to-the-docker-daemon-on-macos
macOS the
docker
binary is only a client and you cannot use it to run the docker daemon, because Docker daemon uses Linux-specific kernel features, therefore you can’t run Docker natively in OS X. So you have to installdocker-machine
in order to create VM and attach to it.
Difference between Docker Desktop and Docker
Docker Desktop = a virtual machine with a Docker CE (Docker Community Edition) daemon + gui + run a single-node kubernetes "cluster" easily
Docker Engine is an open source containerization technology for building and containerizing your applications. Docker Engine acts as a client-server application with:
- A server with a long-running daemon process
dockerd
23.- APIs which specify interfaces that programs can use to talk to and instruct the Docker daemon.
- A command line interface (CLI) client
docker
15.
使用 brew 安装时要注意,brew install docker
只安装了client,但是brew install --cask docker; open /Applications/Docker.app
会安装整个 desktop.
原理相关
docker 如何判断容器内服务正常运行中?之前就看容器内主进程是否已退出,若出现主进程卡住的情况,还可指定 HEALTHCHECK 指令获取返回值
实践
registry
Docker Registry | Docker Documentation 已 move 到这里 基于Docker搭建私有镜像仓库 - 腾讯云开发者社区-腾讯云 用户账密、使用 ip 时的 insecure-registries 需要注意。
所有api:
- 镜像列表: https://hub.lmhdev.com/v2/_catalog
- tagList:
- curl 172.24.137.212:5000/v2/ztlydev/byteox-message/tags/list
- curl http://10.0.1.48:5000/v2/ztlydev/byteox-house/tags/list
golang 实践
- 多阶段
- 镜像基底注意选择 alpine (scartch太原始了),但是使用 alphine, 也有部分需要额外设置的地方,比如时区
不要轻易使用 Alpine 镜像来构建 Docker 镜像,有坑! - 腾讯云开发者社区-腾讯云
docker container stop registry && docker container rm -v registry
docker run -d \
-p 5000:5000 \
--restart=always \
--name registry \
registry:2
logs: /logs/lmh_api_test
文件: /opt/project/lmh_api_test
要往外获取的网络:
- port 8848 utils.InitNanos(conf.ConfigServer.IPAddr, uint64(conf.ConfigServer.Port)
- Mysql, redis 127.0.0.1 要改成本机 ip
要往外暴露的网络:
- 8080 -> 开启的 port 都统一成 8080
日志初始化服务需要重新配置
docker build -t lmh_api_server .
docker run -p 8090:8080 -v "/logs/lmh_api_test:/logs" -v "/opt/project/lmh_api_test/cmd:/cmd" --add-host=host.docker.internal:host-gateway lmh_api_server:latest
docker run -d \
-p 5000:5000 \
--restart=always \
--name registry \
-v /auth:/auth \
-e "REGISTRY_AUTH=htpasswd" \
-e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \
-e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \
registry:2
docker login:
docker login --username=testuser --password=****** hub.lmhdev.com
push image:
docker tag 518a41981a6a hub.lmhdev.com/myPrivateImage && docker push hub.lmhdev.com/myPrivateImage
执行 test:
docker login --username=testuser --password=testpassword hub.lmhdev.com
docker pull hub.lmhdev.com/lmh_api_test:latest
docker stop lmh_api_test
docker rm lmh_api_test
docker run -d \
-p 8090:8080 \
-v "/logs/lmh_api_test:/logs" \
-v "/opt/project/lmh_api_test/cmd:/cmd" \
--add-host=host.docker.internal:host-gateway \
--name lmh_api_test \
hub.lmhdev.com/lmh_api_test:latest
清理
移除无用(悬空)的 docker 镜像
docker rmi $(docker images --filter "dangling=true" -q --no-trunc)
docker image prune
移除 registry image From file system
出现情况:在 /lib/docker/volumes/registry的volumes_id/data/blob 下占用 22G,但实际存有的 image list 只有 1G 左右。冗余的历史镜像,包括没有 tag 的镜像,都需要手动清除。
A tag is composed of several layers. The list of the layers for that particular digest is called a manifest. There is a corresponding blob for each layer. There can also be layers which are not used by any of the tags — those are called abandoned or unused layers. Those corresponding blobs are also unused. We can delete them to gain some space on the disk.
可在 registry 容器内 run the garbage collector:
$ docker exec registry bin/registry garbage-collect --delete-untagged /etc/docker/registry/config.yml
Ref: How to maintain a Private Docker Registry? | by Janeth Fernando | Medium