Docker笔记:运行web服务和构建自己的镜像文件

在docker中运行web服务

1 ) 以nginx为例运行一个web服务

  • 以nginx为例,如果要运行nginx就要有一个nginx镜像
  • 在hub.docker.com中搜索nginx镜像,可以查看到有很多版本,我们找到一个基于alpine的版本(因为体积小,最新的体积会很大)
  • $ docker pull nginx:alpine 此时我们下载好了基于alpine制作的nginx镜像
  • 如果运行这个容器:$ docker run --rm nginx:alpine,那么会卡住,因为nginx会作为一直提供服务
  • 我们重新以后台服务的方式来运行我们的nginx, $ docker run -d --rm nginx:alpine, 此时会不占用终端以后台服务方式运行

2 ) 运行docker服务并暴露端口

  • 我们检查下现有的docker容器:$ docker ps 可以看到这个nginx服务占用了80端口提供服务
  • 如果直接访问物理机的ip地址(默认80端口),是无法访问的,因为在容器里是一个封闭的环境, 而我们当前机器上并没有打开80端口
  • 容器和物理机之间,两者是隔离开的,我们先把这个nginx服务给结束掉:$ docker kill nginx对应的容器ID
  • 我们需要把nginx暴露的端口映射到物理机上, $ docker run -d --rm -P nginx:alpine, 注意这里是大写的P选项
  • 再次查看容器, $ docker ps, 发现输出内容, 举例:0.0.0.0:32768->80/tcp, 物理机上的32768端口映射到了docker容器的80端口
  • 我们通过访问物理机ip:32768即可访问docker上的容器, 我们使用-P选项的意义就是让物理机上一个没有使用的端口和docker容器上的一个端口做映射
  • 但是这样同样存在一个问题,当docker容器重新运行后,端口可能就不是32768了,可能是别的了
  • 如果是这样,没有一个固定的端口,我们就没法对外提供一个稳定的服务, 我们在实际应用中会使用另外一个选项-p,此处p是小写,我们可以自己指定端口
  • 即:$ docker run -d --rm -p 8080:80 nginx:alpine, 我们将物理机的8080端口绑定容器的80端口,这样的话就不会发生错乱的情况了
  • 容器与容器之间的端口互不影响,它们之间都是隔离开的
  • 我们查询docker容器可以使用-q的方式, 如:$ docker ps -q, 输出运行容器的ID列表
  • 我们就可以通过 $ docker kill $(docker ps -q) 将所有运行中的容器全部关闭

构建自己的docker镜像

  • 在docker中使用$ docker build来构建一个docker镜像
  • 在构建镜像前,我们需要先编写dockerfile文件来构建新的镜像
  • 查阅docker的官方文档: https://docs.docker.com/engine/reference/builder/
  • 查看右侧几个主要的命令: FROMRUNCMDLABELCOPYWORKDIR
  • FROM: 表示指定基础镜像
  • RUN: 在构建过程中需要执行的命令
  • CMD: 用于容器启动时需要执行的命令
  • LABEL: 标签,用于添加扩展的信息到镜像中, 如版本信息, 维护者信息等
  • COPY: 用于将文件拷贝到镜像之中
  • WORKDIR: 用于设置命令的工作目录
  • 我们编辑一个Dockerfile, $ vi Dockerfile
    # 基于ubuntu,体积较大
    # FROM ubuntu:16.04
    FROM alpine
    LABEL version="1.0"
    LABEL description="my image"
    # 基于ubuntu的安装命令
    # RUN apt update && apt -y install python3
    # 基于alpine的安装命令, 尽量把所有命令都写到一起, 使用&&来连接, 避免多余的命令分层
    RUN apk update && apk add python3
    # 将当前目录下的所有文件拷贝到容器里的code目录,. 代表当前目录
    COPY . /code
    # 指定工作目录
    WORKDIR /code
    # 指定容器启动后将要执行的命令
    CMD ["python3", "app.py"]
    
  • 在同一目录下, 我们编写一个python文件app.py
    print("Hello Python")
    
  • 开始构建一个新的镜像, $ docker build -t myapp .
    • -t--tag的缩写
    • . 是当前目录, dockerfile就在当前目录
  • 构建完毕后, 可以通过 $ docker images 来查看,看到多了一个镜像 myapp
  • 我们开始运行这个镜像, $ docker run --rm myapp, 输出 Hello Python
  • 在通过镜像启动容器的时候,有时候会在后面跟上一个命令,如: $ docker run --rm myapp echo hi
    • 这里echo hi等价于在dockerfile中的CMD中的内容,并且会覆盖CMD中的命令
    • 此时会输出hi,而非Hello Python
  • 在已经构建好的镜像中,查看详细信息 $ docker inspect myapp:latest, 可以查看到镜像中更多的详细信息
    "Labels" : {
        "description" : "my image",
        "version": "1.0"
    },
    "Cmd" : [
        "python3",
        "app.py"
    ],
    "WorkingDir": "/code",
    # ... # 不再列举
    
  • 在构建我们镜像的时候,最好使用默认的Dockerfile, 如果不这样做, 在docker build的时候需要使用--file来指定文件名
发布了403 篇原创文章 · 获赞 198 · 访问量 69万+

猜你喜欢

转载自blog.csdn.net/Tyro_java/article/details/104214733
今日推荐