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