Build from Dockerfile
$ more Dockerfile
FROM ununtu:14.04 // 选择基础的image
LABEL maintainer="Peng Xiao " // 基本的标识
RUN apt-get update && apt-get install -y redis-server
EXPOSE 6379 // 暴露的端口
ENTRYPOINT ["/usr/bin/redis-server"] // 程序的入口
docker build -t xiaopeng163/redis:latest // -t 是image的名字
比如:
docker pull ubuntu:14.04
构建自己的docker镜像
FROM centos // base image
RUN yum install -y vim // 安装vim
sudo docker build -t haitaoc/centos-vim-new . // . 表示基于当前目录的Dockerfile来build新的image
生成一个临时的docker container来安装vim,安装完之后会删除临时container
Dockerfile 语法梳理及最佳实践
FROM scratch # 制作 base image
FROM centos # 使用base image
FROM ubuntu:14.04
FROM: 尽量使用官方的base image
LABEL maintainer = "[email protected]"
LABEL version="1.0"
LABEL description = "This is description"
LABEL: 定义了image的metadata, 不可少
RUN yum update && yum install -y vim \
python-dev # 反斜线换行
RUN apt-get update && apt-get install -y perl \
pwgen --no-install-recommends %% rm -rf \
/var/lib/apt/lists/* #注意清理cache
RUN /bin/bash -c 'source $HOME/.bashrc;echo $HOME'
RUN: 为了美观,复杂的RUN请用反斜线换行!避免无用分层,合并多条命令成一行
WORKDIR /root
WORKDIR /test # 如果没有会自动创建test目录
WORKDIR demo
RUN pwd # 输出结果应该是/test/demo
WORDIR: 用WORKDIR, 不要用RUN cd! 尽量使用绝对目录!
ADD hello / # 把当前目录里的可执行文件hello, 添加到了根目录里去
ADD test.tar.gz / # 添加到根目录并解压
WORKDIR /root
ADD hello test/ # /root/test/hello
WORKDIR /root
COPY hello test/
ADD or COPY: 大部分情况,COPY由于ADD! ADD除了COPY还有额外功能(解压)!添加远程文件/目录请使用curl或者wget!
ENV MYSQL_VERSION 5.6 # 设置常量
RUN apt-get install -y mysql-server = "${MYSQL_VERSION}" \
&& rm -rf /var/lib/apt/lists/* # 引用常量
ENV: 尽量使用ENV增加可维护性
RUN vs CMD vs ENTRYPOINT
RUN : 执行命令并创建新的Image Layer
CMD : 设置容器启动后默认执行的命令和参数
ENTRYPOINT :设置容器启动时运行的命令
Shell 格式和Exec格式
- Shell格式
RUN apt-get install -y vim
CMD echo "hello docker"
ENTRYPOINT echo "hello docker"
- Exec 格式
RUN ["apt-get","install","-y","vim"]
CMD ["/bin/echo","hello docker"]
ENTRYPOINT ["/bin/echo","hello docker"]
- Dockerfile 1
FROM cenos
ENV name Docker
ENTRYPOINT echo "hello $name" # hello Docker
- Dockerfile 2
FROM cenos
ENV name Docker
ENTRYPOINT ["/bin/echo", "hello $name"] # hello $name, 并不会把$name替换成ENV里的常量
可改为 ENTRYPOINT ["/bin/bash","-c","echo hello $name"] # hello Docker
CMD
- 容器启动时默认执行的命令
- 如果docker run 指定了其他命令,CMD命令被忽略
- 如果定义了多个CMD,只有最后一个会执行
FROM centos
ENV name Docker
CMD echo "hello $name"
ENTRYPOINT
- 让容器以应用程序或者服务的形式运行
- 不会被忽略,一定会执行
- 最佳实践:写一个shell脚本作为entry point
COPY docker-entrypoint.sh /usr/local/bin/
ENTRYPOINT ["docker-entrypoint.sh"]
EXPOSE 27017
CMD["mongod"]
docker rmi [IMAGE ID]
: 删除对应ID的image
sudo docker rm $(sudo docker ps -qa)
: 删除所有已退出的container
Dockerfile最佳实践
安装一个flask的web应用
- 从一个装有python 2.7的base image 开始
FROM python:2.7
LABEL maintainer="haitaoc"
RUN pip install flask
COPY app.py /app/ # 将app.py拷贝到/app文件夹目录下!
WORKDIR /app
EXPOSE 5000 # 暴露端口
CMD ["python","app.py"]
sudo docker build -t haitaoc/flask-hello-world .
docker run -d haitaoc/flask-hello-world
// 启动container
启动之后发现在centos中执行curl 127.0.0.1:5000
访问不了,但是进入容器中,通过交互式的命令时可以访问的,因为docker和本地网络不同,可以通过--net="host"
解决
启动容器时的命令改为sudo docker run -d --net="host" -p 127.0.0.1:5000:5000 --name=demo haitaoc/flask-hello-world
即可
小问题:
- centos7中build时出现ipv fordwarding disabled 告警,解决方案:
https://blog.csdn.net/yelllowcong/article/details/78295600 - flask 下载时报错,因为DNS没有配置好,配置DNS步骤如下:
修改/etc/resolv.conf,
找到nameserver项修改成下面的,没有的话添加下面的
nameserver 8.8.8.8
nameserver 8.8.4.4
- vmware中centos网络配置,选择NAT模式,在centos中
cd /etc/sysconfig/network-scripts
sudo vim ifcfg-ens33
将 ONBOOT=no 改为ONBOOT=yes
#重启服务,让配置生效
systemctl restart network
容器的操作
- 进入到容器中进行交互式操作
docker exec -it CONTAINERID /bin/bash
- 指定名字
sudo docker run -d --name=demo haitaoc/flask-hello-world
- 查看所有运行过的容器
sudo docker ps -a
- 删除所有已经退出的容器
sudo docker rm $(sudo docker ps -qa)
- 启动一个容器
sudo docker start demo
- 停止一个容器
sudo docker stop demo
- 查看容器
sudo docker inspect CONTAINERID