Dockerfile
一、基本语法解析#
FROM
指定基于什么镜像构建
FROM <image>或FROM <image>:<tag>
LABEL
指定将要构建的镜像的一些元数据
LABEL maintainer="pd<123456@qq.com>" \
version="1.0"
ENV
指定环境变量
ENV GOROOT /opt/go
ENV GOBIN $GOROOT/bin
WORKDIR
可以为RUN、CMD、ENTRYPOINT、ADD、COPY指令配置工作目录;进入容器时,当前的路径就是WORKDIR
WORKDIR /opt
ADD
ADD <src> <dest>
该命令将复制指定的
ADD http://nginx.org/download/nginx-1.19.1.tar.gz /opt
ADD test.txt /opt
COPY
COPY <src> <dest>
复制本地主机的
COPY app.py /flask
VOLUME
相当于数据卷
VOLUME ["/var/lib", "/var/log"]
VOLUME /var/lib /var/log
EXPOSE
指定该容器对外暴露的端口
EXPOSE <port> [<port>/<protocol>...]
EXPOSE 8080 80/tpc
ONBUILD
配置当所创建的镜像作为其它新创建镜像的基础镜像时,所执行的操作指令
说明一下shell、exec格式
shell格式写法:
RUN yum install -y vim
CMD echo "hello docker"
ENTRYPOINT echo "hello docker"
exec格式写法:
RUN ["yum", "install", "-y", "vim"]
CMD ["/bin/echo", "hello docker"]
ENTRYPOINT ["/bin/echo", "hello docker"]
$NAME:
CMD/ENTRYPOINT /bin/bash -c "ls -al;echo 'hello docker'"
ENV NAME docker
CMD/ENTRYPOINT ["/bin/bash", "-c", "echo hello $NAME"]
RUN
构建镜像时执行命令并创建新的 image layer
CMD
- 容器启动时默认执行的命令和参数
- 如果docker run指定了其他命令,CMD命令会被忽略
- 如果定义了多个CMD,只有最后一个会执行
ENTRYPOINT
- 容器启动时执行的命令(让容器以应用程序或服务的形式运行)
- 不会被忽略,一定会执行
二、Dockerfile实战操作#
实战1:基于python3部署flask应用
-
编写app.py
from flask import Flask app = Flask(__name__) @app.route("/") def hello(): return "hello docker" if __name__ == "__main__": app.run(host="0.0.0.0", port=5000)
-
编写Dockerfile
FROM python:3.7.8 LABEL maintainer="pd<123456@qq.com>" RUN pip install pip -U && \ pip config set global.index-url https://mirrors.aliyun.com/pypi/simple/ && \ pip install flasK COPY app.py /app/ WORKDIR /app EXPOSE 5000 CMD python app.py
-
docker build -t pd/flask-app .
-
docker run -d -p 8888:5000 pd/flask-app
-
访问 ip:8888
实战2:基于centos7安装nginx
FROM centos:7
LABEL maintainer="pd<123456@qq.com>"
WORKDIR /opt
RUN yum install -y wget gcc-c++ pcre pcre-devel zlib zlib-devel openssl openssl-devel
ADD http://nginx.org/download/nginx-1.19.1.tar.gz /opt
RUN tar xzvf nginx-1.19.1.tar.gz && \
cd /opt/nginx-1.19.1 && \
./configure --prefix=/opt/nginx --with-http_ssl_module --with-http_stub_status_module && \
make && \
make install && \
ln -s /opt/nginx/sbin/nginx /usr/local/sbin/ && \
nginx
RUN rm -rf /opt/*nginx-1.19.1*
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
实战3:多容器部署(一个容器运行flask应用、另一个容器运行redis);但是 --link 不建议使用
-
app.py
from flask import Flask from redis import Redis import os import socket app = Flask(__name__) redis = Redis(host=os.environ.get("REDIS_HOST", "127.0.0.1"), port=6379) @app.route('/') def hello(): redis.incr("hits") return "hits:{} - hostname:{}\n".format(bytes.decode(redis.get("hits")), socket.gethostname()) if __name__ == "__main__": app.run(host="0.0.0.0", port=5000, debug=True)
-
Dockerfile
FROM python:3.7.8 LABEL maintainer="pd<123456@qq.com>" RUN pip install pip -U && \ pip config set global.index-url https://mirrors.aliyun.com/pypi/simple/ && \ pip install flask redis COPY app.py /app/ WORKDIR /app EXPOSE 5000 CMD ["python", "app.py"]
-
构建
docker build -t flask .
-
启动redis
docker run -d --name redis redis
-
启动flask
docker run -d --name flask --link redis -e REDIS_HOST=redis -p 8888:5000 flask
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了