Docker - zhongjiajie/zhongjiajie.github.com GitHub Wiki
- Docker — 从入门到实践: 读书笔记: Docker从入门到实践
- docker-Post-installation steps for Linux
- 镜像加速器
- 配置指定Docker运行的文件夹(放置images container),通过修改
daemon.json
增加data-root
来指定非默认目录,如果已经运行了一段时间,还需要将之前的数据通过rsync
同步到新的目录.so-docker image installation directory,详细步骤
- docker-compose中的
depends_on
会依据依赖顺序启动服务,被depends_on
的容器会先启动,但是主动depends_on
的容器不会等到被depends_on
,例如下面的例子:db,redis容器启动顺序要优先于web容器;当启动 web容器时会自动创建redis和db容器.不过需要注意的是,depends_on不会等到db和redis容器ready再启动,web容器仅仅等到redis和db容器启动就开始启动.具体可参考官网启动顺序了解
version: '2'
services:
web:
build: .
depends_on:
- db
- redis
redis:
image: redis
db:
image: postgres
和gitignore一样,用于忽略掉部分不需要的文件,用于加快传输文件到 docker 上下文。写法有很多种:
-
将部分build不需要的文件写入dockerignore文件:这个是按需排除不需要的文件
-
仅将build需要的文件写入dockerignore文件:反向思考,参考例子是apache-airflow的dockerignore
# Ignore everything ** # Allow only these directories !airflow !common !dags !dev !docs !licenses !scripts !tests
- 增加hosts到
/etc/hosts
文件中docker run --add-host parameter
,如果使用docker-compose用的时extra_hosts
关键字How to update /etc/hosts file in Docker image during “docker build”
-
docker ps
: 查看正在运行的容器 -
docker ps -a
: 查看全部容器包括已经退出的容器 -
docker ps -s
: 查看正在运行的容器信息(包括大小)
Copy files/folders between a container and the local filesystem.
-
docker cp src container:dest
: 从宿主机复制文件/文件夹到docker容器 -
docker cp container:src dest
: 从docker容器复制文件/文件夹到宿主机
- 查看network下的
Containers
的具体内容docker network inspect --format='{{range .Containers}}{{println .Name}}{{end}}'
- 清除一个network中的所有active endpoints:
docker network inspect --format='{{range .Containers}}{{println .Name}}{{end}}' <network_name> | xargs -I % echo 'docker network disconnect <network_name> %' | sh
用于查看对象详细信息
-
--format
: 详见Format command and log output-
join
: concatenates a list of strings to create a single string -
json
: encodes an element as a json string -
lower
: transforms a string into its lowercase representation -
split
: slices a string into a list of strings separated by a separator -
title
: capitalizes the first character of a string -
upper
: transforms a string into its uppercase representation -
println
: prints each value on a new line
-
-
docker system prune
: clean up all images, containers, networks, volumes not used,offical-system -
docker system prune -a --volumes
: clear all including volumes, 只要是没有container使用的volumes都会被清除,这可能会带来关键数据丢失的问题,使用前请注意
-
docker tag SRC:TAG DEST:TAG
或者使用images iddocker tag d583c3ac45fd DEST:TAG
anddocker rmi SRC:TAG/IMAGE-ID
,参照Docker how to change repository name or rename image
- 进入 docker 容器
docker exec -it container_name bash
- docker 删除虚悬镜像
docker rmi $(docker images -f dangling=true)
- 删除所有停止/退出镜像
docker rm $(docker ps -aq -f status=exited)
-f
是过滤参数 - docker-compose 运行指定 yml 文件
docker-compose -f docker-compose-file.yml up -d
- 用 docker-compose 部署的时候如果要先build一些东西的话,可以直接在 service 下面放一个
build
任务,部署的时候用docker-compose up --build
如果没有--build
的话就会引用已经存在的镜像,没有更新到 - docker格式化ps输出
docker ps -format 'table {{.ID}}\t{{.Image}}\t{{.Command}}\t{{.CreatedAt}}\t{{.Status}}\t{{.Ports}}\t{{.Names}}'
这是docker ps
的原生输出,format后面的table
是格式化输出成表格 - docker-compose重启单个workerHow to restart a single container with docker-compose:
docker-compose restart worker
可以设置时间等待杀死容器docker-compose restart -t 30 worker
- docker-compose停止其中一个容器:
docker-compose stop service-name
- docker-compose通过scale来创建多个容器: docker-compose version 2
docker-compose scale service_a=3; docker-compose scale service_b=3
会生成3个service_a和3个service_b, 如果docker-compose version 3的话要达到同样的效果要docker-compose up -d --scale service_a=3 --scale service_b=3 --no-recreate
而不能单独的运行docker-compose up -d --scale <service_name>=3
这个会只生成3个service_name容器 - 将本机容器制作导出:
docker save IMAGE | gzip > LOCAL_IMAGE.gz
,将导出的镜像导入:docker load -i LOCAL_IMAGE.gz
- 查看容器的网络,参考how to get a docker containers ip address from the host:
- modern Docker client syntax:
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' container_name_or_id
- old Docker client syntax:
docker inspect --format '{{ .NetworkSettings.IPAddress }}' container_name_or_id
- modern Docker client syntax:
- 查看 docker 指定 network 上面有的容器
docker network inspect network_name -f "{{range .Containers}}{{.Name}} {{end}}"
主要参照了how to get a docker containers ip address from the host的写法 - docker-compose v2 + external container
- docker 显示容器的IP
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' container_name_or_id
参见how to get a docker containers ip address from the host
Dockerfile 的 multi-stage build 属性允许你创建更小的镜像,更好的使用cache,为每个特定的镜像编写更加小的entrypoint,了解更多查看这里
# 在dockerfile文件中指定镜像的版本 可以在构建镜像时使用 `--build-arg UBUNTU_VERSION=value` 修改镜像的版本
# 如果么有传对应的值 则会以默认的版本(18.6)进行构建
ARG UBUNTU_VERSION=18.6
# 可以对当前的 stage 进行别名方便后面的 stage 调用
FROM ubuntu:${UBUNTU_VERSION} AS base
RUN apt-get update && apt-get install git
# 可以从之前的 stage 中来
FROM base AS src1
RUN git clone …
FROM alpine
# --from 可以直接从已有的镜像中拿对应的值
# 也可以使用之前已经完成的stage,如 `--from=base`
COPY --from=linuxkit/ca-certificates / /
# 可以使用更加有意义的别名 如对 release 镜像衍生出 dev-env test 镜像分别用于开发和测试
FROM scratch AS release
FROM golang:alpine AS dev-env
COPY --from=release / /
ENTRYPOINT ["ash"]
FROM golang:alpine AS test
COPY --from=release / /
RUN go test …
FROM nodejs as builder
WORKDIR /usr/src/app
COPY . .
RUN npm build
FROM nginx
COPY --from=builder /usr/src/app/build/ /nginx_home
-
docker-compose up -d --no-build
: docker-compose启动但是不重新build镜像
指定容器的 ulimits 限制值。例如,指定最大进程数为 65535,指定文件句柄数为 20000(软限制,应用可以随时修改,不能超过硬限制) 和 40000(系统硬限制,只能 root 用户提高)
ulimits:
nproc: 65535
nofile:
soft: 20000
hard: 40000
- MySQL Docker Containers: Understanding the basics: 通过一步步部署mysql的例子说明了docker是怎么运行的,链接一个已经存在的container
- severalnines-dockder+mysql
-
Cannot install packages inside docker Ubuntu image: should
apt-get -qq update
first, because no package cache in the image - docker-mysql用数据卷自定义配置之后connect mysql会变慢,可以在自定义配置文件section mysqld增加
skip-name-resolve
选项 - docker-mysql自定义文件编码section mysql&client default-character-set=utf8 并且 section mysqld
character-set-server=utf8
- docker Hub Automated Build with specify tag
- docker build如果上一次运行成功,下次再运行会直接使用cache,
docker build --no-cache
可以指定不使用cache,How to force docker for clean build of an image - docker默认的registry地址
https://index.docker.io/v1/
,可以通过docker info | grep -i registry
得到docker中所有的信息.如果国内镜像仓库中部分镜像没有更新(例如自己编译的镜像没有及时更新),docker pull registry.hub.docker.com/library/busybox
docker的其中一个最佳实践就是不要已root用户运行容器,因为容器中的root和宿主机中的root(uid 0)是同一个,这意味着在容器用户可以对宿主机文件目录进行读写,这样会导致很多可能的问题.相见这里
play-with-docker: t’s an online playground where you can test all the latest Docker features without having to install anything locally
进入对应image生成的容器中,输入locale
查看支持什么编码, C.UTF-8
以及zh_CN.UTF-8
都可以,但是大部分docker镜像都只有C.UTF-8
,之后在dockerfile中增加一行ENV LANG C.UTF-8
即可,如果还不行就增加
ENV LANGUAGE C.UTF-8
ENV LANG C.UTF-8
ENV LC_ALL C.UTF-8
ENV LC_CTYPE C.UTF-8
ENV LC_MESSAGES C.UTF-8
- 开启docker远程调用API端口
- MAC: 根据docker/for-mac:ISSUE-770,默认不开启远程调用端口,可以fork一个容器开启端口
docker run -d -v /var/run/docker.sock:/var/run/docker.sock -p 127.0.0.1:2375:2375 bobrik/socat TCP-LISTEN:2375,fork UNIX-CONNECT:/var/run/docker.sock
,然后export DOCKER_HOST=unix:///var/run/docker.sock
- Linux:
- Windows: 点击docker图标,在
设置->通用
选项勾选Expose daemon on tcp://localhost:2375 without TLS
- MAC: 根据docker/for-mac:ISSUE-770,默认不开启远程调用端口,可以fork一个容器开启端口
- 在docker-deamon运行的机器中,检查端口是否开放
netstat -anp | grep 2375
或者lsof -i:2375
- 在docker-deamon运行的机器中,检查能否通过tcp访问docker-deamon,
docker -H tcp://localhost:2375 images
- 在需要调用remote-api的机器检查2375端口是否开启,
telnet <IP>:2375
,如果上面都能成功倒是这步不成功,就是服务器防火墙没有开放2375端口,开放端口即可
参照Configure a remote interpreter using Docker,需要根据docker开放远程API调用先启动远程调用端口,然后新增配置解释器配置.如果是离线的话需要busybox:latest
以及pycharm_helper:PY-<对应的版本号>
和本机apt-get
慢是同一解决办法,使用国内的源,使用的方式参考tenxcloud/docker-debian,将国内源写入sources.list
文件,使用时在Dockerfile
中使用COPY sources.list /path/to/docker_sources.list
替换原来的源,最后在RUN
中运行apt clean \ && apt update
docker在本地build的时候可能需要下载需要翻墙的二进制包,可以参考SO,在docker的configure中配置proxy属性,然后重启docker就能使用了。如果是mac客户端的话,可以在Prefrences -> Resources -> PROXIES
开启手动代理配置,然后重启docker
相关的[SO][]可能原因如下:
- 文件路径写错:文件路径可能比较复杂,导致本地路径写错。此时修改成正确路径即可
- 运行docker build的路径错了:本应该在指定路径运行docker build的,但却在别的路径下运行了。此时切换到正确的路径即可
- dockerignore文件错误:要COPY/ADD的文件在dockerignore文件中,或者dockerignore仅允许指定文件发送到docker上下文中。此时检查dockerignore的配置然后修改即可
更加可配置地方案是,编辑.env
文件,加入COMPOSE_HTTP_TIMEOUT=200
项目SO
docker的mac默认不启动2375端口,参考,方便的方式是直接写一个快捷方式到zshrc
alias docker-api-start='docker run -d -v /var/run/docker.sock:/var/run/docker.sock -p 127.0.0.1:2375:1234 --name docker-api bobrik/socat TCP-LISTEN:1234,fork UNIX-CONNECT:/var/run/docker.sock'
alias docker-api-stop='docker rm -f docker-api'
- 当遇到部分
Dockerfile
没有办法没有正确写出来的时候,可以去 github 搜索一下base images + pkg_to_install
- 当遇到本地
docker build
过慢时,可以将 Dockerfile 放到 github 上,然后在 docker hub 上设置对应automated-build
当提交到 github master上后就会自动 build - 如果从国内镜像中pull镜像失败,可以直接去dockerhub官网拉取
docker pull registry.hub.docker.com/zhongjiajie/docker-airflow
- centos7安装docker之后可能出现不能打开端口的情况,根据configure Centos7 firewallD to allow docker containers free access to the host's network ports
firewall-cmd --permanent --zone=trusted --change-interface=docker0
firewall-cmd --permanent --zone=trusted --add-port=4243/tcp
firewall-cmd --reload
systemctl restart docker.service
一些docker相关的shell脚本
-
删除dangling镜像和停止的容器
echo "remove dangling images" if [[ ! -z $(docker images -f dangling=true -aq) ]]; then docker rmi $(docker images -f dangling=true -aq) fi echo "remove extied container" if [[ ! -z $(docker ps -aq -f status=exited) ]]; then docker rm -f $(docker ps -aq -f status=exited) fi
-
备份非dangling的容器
echo "backup not dangling images"
- docker-Post-installation steps for Linux
- Docker — 从入门到实践
- Docker 中国官方镜像加速
- Docker官网解释的加速引擎
- 注册并使用阿里云镜像库
- how to get a docker containers ip address from the host
- MySQL Docker Containers: Understanding the basics
- severalnines-dockder+mysql
- severalnines-mysql
- Docker Hub Automated Build - Tagging
- Docker how to change repository name or rename image
- How to force docker for clean build of an image
- How to restart a single container with docker-compose
- 官网启动顺序
- How to update /etc/hosts file in Docker image during “docker build”
- configure Centos7 firewallD to allow docker containers free access to the host's network ports
- Format command and log output