【docker】命令,使用经验
一、安装
https://www.cnblogs.com/yunmuq/p/14768401.html#34-安装doker
二、使用命令
先了解概念,镜像和容器:
用run启动镜像后,就会生成一个容器
镜像文件不会被改写,还能用于启动其它容器
每个容器启动时会指定命令,容器停止后,可以使用start再启动,start不能指定命令
一般的用法是:
-
后台启动,容器中运行一个服务,如http服务器等,再通过接口访问。不是调试一般不会去连容器的shell
-
前台启动,运行一串命令后输出结果,退出
# 从docker hub安装镜像
docker pull
# 查看可使用的镜像
docker images
# 查看正在运行的容器
docker ps
# 查看所有容器,包括停止的
docker ps -a
# 重命名镜像
docker tag <id> new_name:new_tag
docker tag old_name:old_tag new_name:new_tag
# 查看镜像/容器的元数据,为json格式
docker inspect
# 获取指定数据,用-f,后接Go模板
docker inspect -f {{.ContainerConfig.Cmd}}
# 短暂地启动镜像,执行命令后终止
# 镜像名:标签,标签可省略
docker run hello-world:lastest cmd
# 交互式地启动镜像
# -i交互式,-t终端,/bin/bash是命令,调用容器bash,exit退出,容器停止
# 也可以不用命令,默认会用/bin/bash或/bin/sh,具体看dockerfile中写的啥
docker run -it ubuntu /bin/bash
# 注意,第一次启动镜像需要用run。后续使用start时不能追加选项了
# 使用-d参数能后台运行容器,就能一直运行
# --name指定名字可以代替id
docker run -itd --name ubuntu-test ubuntu /bin/bash
# 端口映射
启动时 -p 宿主port:容器port
或 -P 随机映射
# 自动启动
--restart=always # run参数
docker update --restart=always name # 已经run好的容器
# 网络配置
--network
# 根据名称,不同的容器可以使用一套网络配置
# --network host 使用宿主机的网络配置
# 启动已停止的容器、停止容器
docker start <id>
docker stop <id>
docker restart <id>
# 进入容器
docker attach <id> # 退出容器停止
docker exec -it <id> /bin/bash # 退出容器不会停止
# 拷贝文件,用于run创建容器后
docker cp <file> <id>:<file> # 拷贝到指定容器的指定路径
docker cp <id>:<file> <file> # 拷贝容器内指定文件到主机路径
# 挂载文件,用于run时
# 不必要的文件不需要拷贝进容器中,特别是大文件
# <主机目录>:<容器内路径>:<格式,可省略,ro为只读>
docker run -it -v /home/dir:/usr/home:ro ubuntu64 /bin/bash
# 数据卷,高级的文件共享,略
# 删除容器
docker rm -f <id>
# 删除所有终止状态的容器
docker container prune
# 删除镜像
docker rmi -f <id>
2.1 build多平台镜像
使用buildx
docker buildx build --platform=linux/amd64,linux/arm64/v8,linux/arm/v6,linux/arm/v7
三、Dockerfile
参考:https://www.runoob.com/docker/docker-dockerfile.html
一个基本的Dockerfile结构大致如下
FROM alpine
### FROM,最重要的命令,指定基于什么镜像构建
# LABEL,标签,键值都能随意指定,无影响
LABEL maintainer="xxx.xxx@xxx.com"
LABEL description="Alpine based image with apache2 and php7."
# ARG,不常用,定义构建过程中的变量
ARG version=1.1
# ENV,不常用,定义构建过程中,以及构建完成的镜像的后续使用过程中的环境变量
ENV python=/usr/bin/python
# COPY <源路径> <容器内路径>
COPY ./app /home/app
# ADD,不常用,和COPY相近,还能从网络url中添加,但推荐用COPY
ADD . /
### RUN,重要且必须,指定如何构建镜像
# 可以用shell格式,也可以用数组格式
# 每个RUN都会套一层,意思是第二个RUN会在第一个RUN的基础上再构建一个镜像,可以理解为第二个RUN from 第一个RUN的结果
# 建议只有一个RUN,非必要的RUN会造成镜像肿大
RUN apk --no-cache --update \
add apache2 \
php7-apache2
# EXPOSE,暴露一个端口,后续docker run —P时,随机映射端口会参考这个
EXPOSE 80
### CMD,重要且必须,设置后续 docker run 镜像时运行的命令
# 可以用shell格式,也可以用数组格式
# 一般最后一个命令用来阻塞,方便 docker run 后不立即退出,否则需要 docker run 时手动阻塞
CMD tail -f -s 30 /dev/null
CMD也可以是调用一个脚本,事先COPY进去
构建镜像:docker build -t name:tag .
,-t
指定名字和标签,.
表示当前目录,会自动寻找Dockerfile
如果Dockerfile名字不是Dockerfile,可以用-f指定
四、Docker Hub
Docker Hub是一个镜像仓库,和GitHub一样可以存放公开、私人镜像
下载镜像:
docker pull
上传镜像:
-
注册账号
-
docker login
本机登录 -
对本地已存在的镜像:
docker push
4.1 对docker镜像的理解
博主发现,对每个镜像都会存在一个id,这个id是某种哈希值
每个镜像由各其他镜像单元组成
当我们文件不变,重复build时,只有tag不一致时,可以发现docker会识别出你并没有改变文件,于是迅速给出一个仅tag不同的镜像
当我们push时,你的镜像基于镜像A构建,docker不会传输A镜像
当我们push仅标签不同的镜像时,docker提示78a5f2a66dcc: Layer already exists
,不会重复传输,而是利用原有的镜像单元进行发布
4.2 对latest标签的理解
latest标签是当你构建时缺省标签时的默认标签,pull时未指定标签也是默认拉取latest标签
这意味着它不一定是最新的,比如你可以build一个新镜像指定它的tag,那它就比latest新
docker hub也不会为最新的镜像打上latest标签
例如你发布了一个v1.0的镜像,想让docker hub上的latest也更新时。需要重新构建一个,不指定标签,然后再push
五、buildx构建多平台镜像
如何构建出x86和arm架构系统的镜像呢?
使用buildx,linux安装docker时默认安装了buildx
查看buildx信息
docker buildx version
# 查看构建器
docker buildx ls
# 创建构建器并使用
docker buildx create --use
# 若ls时带星号的,选中的构建器不对,可以使用命令选中
docker buildx use mybuilder
# 进行构建,示例
docker buildx build --platform=linux/amd64,linux/arm64/v8,linux/arm/v6,linux/arm/v7 -t charles94jp/ddns --push .
无需提前pull和指定什么镜像,在docker buildx build
时,会自动下载非本地架构的镜像