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來指定文件名
發佈了410 篇原創文章 · 獲贊 221 · 訪問量 69萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章