1.制作base image

  1. 1.拉取hello-world(因为非常小,只有1.85k)
  2. docker pull hello-world
  3. 2.示例程序编写
  4. 2.1 创建文件夹并进入
  5. mkdir -p /labs/hello-world && cd /labs/hello-world
  6. 2.2 编写代码
  7. vi hello.c
  8. #include<stdio.h>
  9. int main()
  10. {
  11. printf("Hello Docker\n");
  12. }
  13. 3.编译程序
  14. 3.1 安装编译工具
  15. sudo yum install gcc
  16. sudo yum install glibc-static
  17. 3.2 编译成可执行文件(在当前目录下)
  18. gcc -static hello.c -o hello
  19. 4.编写Dockerfile
  20. # 因为是做base image,不能FROM ubuntu什么的,FROM scratch意思是我们没有FROM
  21. # 我们没有based任何镜像来创建镜像,所以不算一层,所以通过history来看层数时只有两层
  22. vi Dockerfile
  23. FROM scratch
  24. ADD hello /
  25. CMD ["/hello"]
  26. 5.通过Dockerfile制作镜像
  27. docker build -t michael/hello-world .
  28. 6.查看image的分层
  29. docker history 镜像ID

2.更新镜像

2.1 通过容器更新镜像

1.通过镜像运行容器
docker run -it centos /bin/bash

2.进入容器后进行所需操作(以上步骤会自动进入容器)
yum install vim

3.退出容器
exit

4.打包修改后的容器成镜像
docker commit -m 'installed vim' -a 'michael' 容器ID/容器名 michael/centos:v1
-m: 提交的描述信息
-a: 指定镜像作者
-m -a均可省略
michael/centos:v1 指定要创建的目标镜像名

# 不推荐这种方式更新镜像,过程不可见,可能不安全,推荐通过Dockerfile更新镜像

2.2 通过Dockerfile更新镜像

1.创建目录并进入
mkdir -p /home/docker/centos-vim && cd /home/docker/centos-vim

2.编写Dockerfile
vi Dockerfile

FROM centos
RUN yum install -y vim

3.通过Dockerfile创建镜像
docker build -t michael/centos:v1 .

3.Dockerfile命令详解

3.1 注意事项

# 每个语句空一行
# 更多规范的Dockerfile请参考:https://github.com/docker-library

3.2 FROM

# 尽量使用官方的image作为base image,为了安全
FROM scratch        # 制作base image,FROM scratch意思是我们没有FROM
FROM centos         # 使用base image
FROM ubuntu:16.04   # 使用base image

3.3 LABEL

# 定义Metadata
LABEL maintainer="mackay.chow@gmail.com"
LABEL version="1.0"
LABEL description="This is description"

3.4 MAINTAINER

# 说明创建者信息
MAINTAINER Michael <mackay.chow@gmail.com>

3.5 RUN

# 每一行的RUN就会新加一层,所以为了避免无用分层且为了美观,复杂的RUN请用反斜线换行,合并多条命令成一行!

# 反斜线换行
RUN yum update && yum install -y vim \
    python-dev

# 注意清理cache
RUN apt-get update && apt-get install -y perl \
    pwgen --no-install-recommends && rm -rf \
    /var/lib/apt/lists/*

RUN /bin/bash -c 'source $HOME/.bashrc;echo $HOME'

3.6 WORKDIR

# 设定当前工作目录,类似cd的作用
# 用WORKDIR,不要用RUN cd
# 尽量使用绝对目录
WORKDIR /root
WORKDIR /test       # 如果没有会自动创建test目录
WORKDIR demo
RUN pwd             # 输出结果应该是/test/demo

3.7 ADD,COPY

# 大部分情况,COPY优于ADD
# ADD除了COPY还有额外功能(解压)
# 添加远程文件/目录请使用curl或者wget
ADD hello /
ADD test.tar.gz /       # 添加到根目录并解压

WORKDIR /root
ADD hello test/         # /root/test/hello

WORKDIR /root
COPY hello test/

3.8 ENV

# 设置常量
# 尽量使用ENV增加可维护性
ENV MYSQL_VERSION 5.6
RUN apt-get install -y mysql-server="${MYSQL_VERSION}" \
    && rm -rf /var/lib/apt/lists/*

3.9 RUN,CMD,ENTRYPOINT

1.三者差别
# RUN
  # 执行命令并创建新的image layer

# CMD
  # 设置容器启动后默认执行的命令和参数
  # 如果docker run指定了其他命令,CMD命令被忽略
  # 如果定义了多个CMD,只有最后一个会执行

  # CMD echo "hello Docker"
  # docker run [image] 输出hello Docker
  # docker run -it [image] /bin/bash 输出空并进入容器

# ENTRYPOINT
  # 设置容器启动时运行的命令
  # 让容器以应用程序或者服务的形式运行(作为后台进程)
  # 不会被忽略,一定会执行
  # 最佳实践,写一个shell脚本作为ENTRYPOINT
  COPY docker-entrypoint.sh /usr/local/bin
  ENTRYPOINT ["docker-entrypoint.sh"]

  # ENTRYPOINT echo "hello Docker"
  # docker run [image] 输出hello Docker
  # docker run -it [image] /bin/bash 输出hello Docker,与上面一样,也不会进入容器

2.书写格式
# shell格式,结果为hello Docker
FROM centos
ENV name Docker
ENTRYPOINT echo "hello $name"

# exec格式,结果为hello $name
FROM centos
ENV name Docker
ENTRYPOINT ["/bin/echo", "hello $name"]

# 两者区别
# exec没有进行环境变量的解析
# 做如下修改可实现
FROM centos
ENV name Docker
ENTRYPOINT ["/bin/bash", "-c", "echo hello $name"]

3.10 Volume

1.Data Volume
# 需要Dockerfile指定
Volume /var/lib/mysql

# 那么执行之后通过以下命令查看创建的Volume
docker volume ls

# 删除volume
docker volume rm [volume]

# 查看volume信息
docker volume inspect [volume]

# 注意
# 删除容器其对应的volume并不会删除
# 每次启动一个容器都会产生一个volume
# volume的名字非常长,不友好

# 指定volume名字为mysql
docker run -d -v mysql:/var/lib/mysql --name mysql1 -e MYSQL_ALLOW_EMPTY_PASSWORD=true mysql

# 上面的容器写入数据之后删除,后面的容器也可以使用这个mysql的volume
docker run -d -v mysql:/var/lib/mysql --name mysql2 -e MYSQL_ALLOW_EMPTY_PASSWORD=true mysql
# 这里进入mysql2之后,mysql1上写的数据依然存在

2.Bind Mouting
# 不需要Dockerfile指定
docker run -v /home/aaa:/root/aaa

3.11 EXPOSE

# 对外暴露端口
EXPOSE 5000

4. Dockerfile实战

4.1 常驻内存类程序

wget https://evernote-1258366890.cos.ap-guangzhou.myqcloud.com/1908151452

4.2 命令行工具类程序

wget https://evernote-1258366890.cos.ap-guangzhou.myqcloud.com/1908151453

4.3 通过nginx运行hexo静态网站

# hexo通过gitlab-ci进行cicd,不能使用hexo d的方式,因为无法上传.gitlab-ci.yml到项目根下,隐藏文件没办法,连test.txt这种文件只要创建在source目录下都可以正常到根,另外通过gitlab服务器直接创建.gitlab-ci.yml的方式也不行,每次hexo d之后会删除掉,所以只能使用传统git方式将整个项目上传到gitlab

1.在hexo文件夹下新建nginx.conf,内容如下:
wget https://evernote-1258366890.cos.ap-guangzhou.myqcloud.com/1908221129.conf

2.在hexo文件夹下新建Dockerfile,内容如下:
wget https://evernote-1258366890.cos.ap-guangzhou.myqcloud.com/1908221132

3.创建镜像
docker build -t hexo:v1 .

4.根据镜像运行容器
docker run -d -p 8888:80 hexo:v1

若通过.gitlab-ci.yml进行ci/cd,则内容如下:
wget https://evernote-1258366890.cos.ap-guangzhou.myqcloud.com/1908221154.yml