欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Dockerfile和docker-compose使用詳解

 更新時間:2024年11月06日 11:18:24   作者:LKIDTI數(shù)據(jù)  
Dockerfile用于構(gòu)建鏡像,包含指令和說明,使用FROM開始構(gòu)建,WORKDIR設(shè)置工作目錄,RUN執(zhí)行命令,COPY拷貝文件,EXPOSE暴露端口,CMD指定容器啟動命令,docker-compose用于管理多容器,通過docker-compose.yml配置,支持多服務(wù)實(shí)例,可設(shè)定服務(wù)依賴和環(huán)境變量,支持掛載卷

Dockerfile和docker-compose詳解

一、Dockerfile

1. Dockerfile簡介

Dockerfile是一個用來構(gòu)建鏡像的文本文件, 文本內(nèi)容包含了一條條構(gòu)建鏡像所需的指令和說明。

例如我們要在含python3的centos鏡像基礎(chǔ)上安裝vim,可以這么寫。

FROM centos:python3
RUN yum -y install vim

這里的FROM表示從哪個鏡像開始構(gòu)建,可以是本地已有的鏡像,也可以是dockerhub或者私域的鏡像。

2. 構(gòu)建鏡像

在Dockerfile文件的存放目錄下, 執(zhí)行構(gòu)建動作

# 1. nginx表示鏡像名稱, v3表示版本
# 2. 最后的.表示Dockerfile相對終端執(zhí)行環(huán)境的相對路徑
docker build -t centos:python3 .  

3. Dockerfile命令

(1)FROM

定制的鏡像都是基于FROM的鏡像, 后續(xù)的操作都是基于該鏡像做的操作

(2)WORKDIR

官方文檔的說明,WORKDIR的作用是為RUN, COPY等指令設(shè)置工作目錄,相當(dāng)于cd到那個目錄,然后執(zhí)行對應(yīng)的指令。

如果沒有設(shè)置WORKDIR,它會自動創(chuàng)建,默認(rèn)是/,如果是從其他鏡像開始構(gòu)建的,那么WORKDIR就是其他鏡像。

The WORKDIR instruction sets the working directory for any RUN, CMD, ENTRYPOINT, COPY and ADD instructions that follow it in the Dockerfile. If the WORKDIR doesn’t exist, it will be created even if it’s not used in any subsequent Dockerfile instruction.

WORKDIR /a
WORKDIR b
WORKDIR c
RUN pwd
輸出就是/a/b/c

(3)RUN

用于執(zhí)行后面跟著的命令行命令

RUN <命令行命令>   # 命令行命令 等同于在終端操作的shell命令

例如前面的

RUN yum -y install vim

注意,在RUN命令中有路徑時,指的是容器外的相對路徑,而不是容器內(nèi)的路徑,因?yàn)樗藭r還只是構(gòu)建鏡像。

(4)COPY

將宿主機(jī)的文件拷貝到鏡像中。

由于它是構(gòu)建鏡像時的命令,因此它會將文件寫入到鏡像中,只要是由該鏡像創(chuàng)建的容器,都會有拷貝過去的文件,這是它和掛載的不同。

FROM centos:vim-python3
RUN yum -y install vim
COPY python/ /lkidti/
CMD python3 /lkidti/http_server.py
  • 源路徑src:宿主機(jī)內(nèi)的路徑,是相對Dockerfile的路徑,不能用絕對路徑。例如寫成/home/lkidti/python,這種寫法是不對的,因?yàn)閐ockerfile會把它翻譯成 dockerfile路徑+/home/lkidti/python。
  • 目的路徑dest:容器內(nèi)的路徑,用的是絕對路徑,或者是相對workdir的路徑。

(5)EXPOSE

暴露端口,這個命令的作用參見官方文檔。

The EXPOSE instruction does not actually publish the port. It functions as a type of documentation between the person who builds the image and the person who runs the container, about which ports are intended to be published

expose命令的作用并不會去暴露端口,而是作為構(gòu)建鏡像的開發(fā)人員和運(yùn)行容器的開發(fā)人員之間一個“接口文檔”,構(gòu)建鏡像的開發(fā)人員告訴運(yùn)行容器的開發(fā)人員,該鏡像監(jiān)聽哪個端口。

因?yàn)閷τ谶\(yùn)行容器的開發(fā)人員來說,它可能接觸不到源碼,不清楚該鏡像能暴露哪個端口,expose命令能幫助他了解到。

例如redis鏡像。

[lkidti@hecs-300320 ~]$ docker run -id redis:latest
Unable to find image 'redis:latest' locally
latest: Pulling from library/redis
c7ae2cc6d9d5d2fee1aefbea14014bb42806b45c60b7d6a1cf3313d5367ae895
[lkidti@hecs-300320 ~]$ docker ps
CONTAINER ID   IMAGE          COMMAND                   CREATED         STATUS         PORTS                                                  NAMES
c7ae2cc6d9d5   redis:latest   "docker-entrypoint.s…"   5 seconds ago   Up 3 seconds   6379/tcp                                               awesome_cori

它這里就暴露了6379端口,因此我們需要在運(yùn)行的時候通過-p來做端口映射,來保證通過訪問宿主機(jī)來訪問容器。

(6)CMD

在鏡像構(gòu)建好后,用鏡像啟動容器時(docker run)會執(zhí)行的命令。

當(dāng)在Dockerfile中寫了CMD時,如果在用docker run或者docker-compose啟動容器時,又再加了啟動命令,此時執(zhí)行的是docker run或者docker-compose的命令,如果沒有加,執(zhí)行的就是Dockerfile中的命令。

  • 例子1:docker run加了命令/bin/bash
[lkidti@hecs-300320 ~]$ docker run -id centos:python-vim /bin/bash
9a25fca7d79046bf693e95e2836744a5d973b12dc25adefe9b78e7e56e56df8f
[lkidti@hecs-300320 ~]$ docker ps
CONTAINER ID   IMAGE               COMMAND                   CREATED         STATUS         PORTS                                                  NAMES
9a25fca7d790   centos:python-vim   "/bin/bash"               4 seconds ago   Up 3 seconds                                                          nice_mendel
33d744b8729a   mysql:latest        "docker-entrypoint.s…"   8 hours ago     Up 8 hours     0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp   mysql
  • 例子2:docker run中不加命令
[lkidti@hecs-300320 ~]$ docker run -id centos:python-vim
dba629df688a0fb326d7e1c668fe4393673ca3f1789dd7a9e666fcd9344990d7
[lkidti@hecs-300320 ~]$ docker ps
CONTAINER ID   IMAGE               COMMAND                   CREATED         STATUS         PORTS                                                  NAMES
dba629df688a   centos:python-vim   "/bin/sh -c 'python3…"   5 seconds ago   Up 4 seconds                                                          vigorous_solomon
33d744b8729a   mysql:latest        "docker-entrypoint.s…"   8 hours ago     Up 8 hours     0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp   mysql

二、docker-compose

1.簡介

用于構(gòu)建和啟動多容器工具, 通過docker-compose.yml來配置項(xiàng)目需要的所有服務(wù), 然后docker-compose up啟動所有服務(wù)

2.多服務(wù)實(shí)例

(1)文件準(zhǔn)備

新建一個目錄:

mkdir composetest
cd composetest

新建一個app.py文件

# composetest/app.py
import time
?
import redis
from flask import Flask
?
app = Flask(__name__)
cache = redis.Redis(host='redis', port=6379)
?
def get_hit_count():
    retries = 5
    while True:
        try:
            return cache.incr('hits')
        except redis.exceptions.ConnectionError as exc:
            if retries == 0:
                raise exc
            retries -= 1
            time.sleep(0.5)
?
@app.route('/')
def hello():
    count = get_hit_count()
    return 'Hello World! I have been seen {} times.\n'.format(count)

新建一個requirements.txt,里面包含如下內(nèi)容

# composetest/requirements.txt
flask
redis

新建一個Dockerfile

# syntax=docker/dockerfile:1
FROM python:3.7-alpine
WORKDIR /code
ENV FLASK_APP=app.py
ENV FLASK_RUN_HOST=0.0.0.0
RUN apk add --no-cache gcc musl-dev linux-headers
COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt
EXPOSE 5000
COPY . .
CMD ["flask", "run"]

新建一個docker-compose.yml

services:
  web:
    build: .
    ports:
      - "8000:5000"
  redis:
    image: "redis:alpine"

(2)啟動服務(wù)

docker compose up # 注意,最新版本可以不要中間的"-"

此時應(yīng)該會看到兩個服務(wù)都啟動起來了

CONTAINER ID   IMAGE             COMMAND                  CREATED          STATUS          PORTS                                                  NAMES
b69ccfb85c03   composetest-web   "flask run"              12 minutes ago   Up 12 minutes   0.0.0.0:8000->5000/tcp, :::8000->5000/tcp              composetest-web-1
ea71df663f36   redis:alpine      "docker-entrypoint.s…"   12 minutes ago   Up 12 minutes   6379/tcp                                               composetest-redis-1

(3)訪問服務(wù)

在服務(wù)器內(nèi)部執(zhí)行

curl http://127.0.0.1:5000

可以看到輸出

Hello World! I have been seen 1 times.

由于是在服務(wù)器上部署,還可以在瀏覽器中訪問http://121.36.104.55:8000/,也是一樣的輸出。

注意,要開放8000端口。

3. docker-compose的service

(1)service和container

在上面的例子,web實(shí)際上指的是一個服務(wù),而不是一個容器。參考https://stackoverflow.com/a/35585573/10844937

A service can be run by one or multiple containers. With docker you can handle containers and with docker-compose you can handle services.

service可以由一個或多個container組成。

docker一般來操作container,docker-compose一般來操作service。

可以在docker- compose中指定scale參數(shù)來指定container的個數(shù),例如

services:
  web:
    build: .
    scale: 4
  redis:
    image: "redis:alpine"

此時會有4個container

?  composetest git:(master) ? docker ps                  
CONTAINER ID   IMAGE             COMMAND                  CREATED          STATUS          PORTS      NAMES
f17412bbb248   composetest-web   "flask run"              15 seconds ago   Up 5 seconds    5000/tcp   composetest-web-4
ded649c4cec8   composetest-web   "flask run"              15 seconds ago   Up 5 seconds    5000/tcp   composetest-web-3
642b05b9c66e   composetest-web   "flask run"              15 seconds ago   Up 5 seconds    5000/tcp   composetest-web-2
7732ae7c78c8   composetest-web   "flask run"              16 seconds ago   Up 5 seconds    5000/tcp   composetest-web-1
1cf0b1c34972   redis:alpine      "docker-entrypoint.s…"   10 minutes ago   Up 10 minutes   6379/tcp   composetest-redis-1

在docker-compose中,必須有service name,而不必有container name,如果沒有container name,那么container name=<當(dāng)前工作路徑名>,這里的sequence number是從1開始的。

(2)service的廣泛應(yīng)用

非常重要的一點(diǎn): service name 可以廣泛的被應(yīng)用

在nginx中,可以看到proxy_pass http://web:8000;這樣的表示式,這里的web就是指的service name

在django的settings中,可以看到數(shù)據(jù)的配置如下,這里的db指的也是service name

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'orthanc',
        'HOST': 'db',
        'PORT': 5432,
        'USER': 'lkidti',
        'PASSWORD': '4a53e4f5c42fd5a31890860b204472c5'
    }
}

4. docker-compose的指令

(1)image

如果本地有鏡像, 直接用本地鏡像; 如果沒有, 采用dockerhub的。

version: "3.7"
services:
  webapp:
    build:
      context: ./dir  # Dockerfile的路徑
      dockerfile: Dockerfile-alternate  # Dockerfile的名字
      args:
        buildno: 1  # Dockerfile構(gòu)建鏡像時候的參數(shù),在構(gòu)建時候的環(huán)境變量

(2)build

build: 是指通過Dockerfile來構(gòu)建。當(dāng)一個yaml文件中,既有image又有build時,它的順序如下:

首先看本地是否有鏡像,如果有,用本地的鏡像

本地如果沒有,嘗試從dockerhub拉。

如果dockerhub拉不到,則用build參數(shù)中指定的Dockerfile來構(gòu)建鏡像。

services:
  backend:
    image: awesome/database
    build:
      context: backend  # 相對docker-compose的子目錄
      dockerfile: ../backend.Dockerfile  # dockerfile文件名

(3)depends_on

告訴docker-compose當(dāng)前服務(wù)啟動之前先要把depends_on指定的服務(wù)啟動起來才行

(4)environment

environment變量可以在構(gòu)建鏡像過程中,在Dockerfile中去使用。

也可以在已構(gòu)建好的鏡像制作出的容器中使用,在容器的終端中輸入env即可查找到所有的環(huán)境變量。

可以用如下的python代碼拿到具體的環(huán)境變量。

import os
os.environ.get('DEBUG')

(5)volume

docker的掛載主要有兩種方式

  • bind mount(全路徑的主機(jī)目錄):將主機(jī)的目錄mount到container中,這種方式主機(jī)的目錄路徑必須為全路徑,否則docker會將其當(dāng)做volume處理。這種方式有一個不好的地方: windows和linux的目錄結(jié)構(gòu)不一樣,那么此時我們是沒法在不同的系統(tǒng)去寫一個主機(jī)的目錄來兼容的。
  • volume(非全路徑的主機(jī)目錄):volume和bind mount不同之處在于,volume的主機(jī)目錄是被docker管理的,都在主機(jī)的/var/lib/docker/volumes目錄下,這個目錄的權(quán)限非常嚴(yán)格,即使是用sudo都不能打開(cd)。將my-volume掛載到container中的/mydata目錄: docker run -it -v my-volume:/mydata alpine sh,它會在主機(jī)下創(chuàng)建/var/lib/docker/volumes/my-volume/_data目錄,如果該目錄不存在,那么docker會先創(chuàng)建然后再掛載。

總結(jié)

以上為個人經(jīng)驗(yàn),希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • 讓非root用戶構(gòu)建Docker鏡像的三種方法

    讓非root用戶構(gòu)建Docker鏡像的三種方法

    在默認(rèn)情況下,Docker?需要?root?權(quán)限或?sudo?才能運(yùn)行,這對于日常開發(fā)和?CI/CD?流水線可能不夠方便,那么,如何讓?非?root?用戶?也能構(gòu)建和運(yùn)行?Docker?容器呢?本篇文章將介紹?三種方法?來實(shí)現(xiàn)這一目標(biāo),需要的朋友可以參考下
    2025-04-04
  • 如何解決安裝docker的yum工具時報錯問題

    如何解決安裝docker的yum工具時報錯問題

    在安裝Docker時遇到y(tǒng)um工具錯誤可通過更新yum源解決,先卸載舊Docker,備份原yum源,下載新的CentOS-Base.repo文件到指定目錄,安裝yum工具后,配置Docker的yum源,國內(nèi)用戶建議使用aliyun源以避免訪問異常,安裝并啟動Docker,校驗(yàn)是否成功
    2024-09-09
  • IDEA 通過docker插件發(fā)布springboot項(xiàng)目的詳細(xì)教程

    IDEA 通過docker插件發(fā)布springboot項(xiàng)目的詳細(xì)教程

    這篇文章主要介紹了IDEA 通過docker插件發(fā)布springboot項(xiàng)目的詳細(xì)教程,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-09-09
  • Docker部署Vue項(xiàng)目的項(xiàng)目實(shí)踐

    Docker部署Vue項(xiàng)目的項(xiàng)目實(shí)踐

    本文主要介紹了Docker部署Vue項(xiàng)目的項(xiàng)目實(shí)踐,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-07-07
  • 利用Docker分層構(gòu)建優(yōu)化鏡像大小的實(shí)現(xiàn)

    利用Docker分層構(gòu)建優(yōu)化鏡像大小的實(shí)現(xiàn)

    合適docker鏡像文件大小不僅影響容器啟動效率,也影響資源占用效率,本文介紹如何利用分層方式構(gòu)建docker鏡像,采用多種方式避免鏡像文件太大而影響性能,需要的朋友可以參考下
    2025-01-01
  • 替換docker容器中的一個文件的實(shí)現(xiàn)

    替換docker容器中的一個文件的實(shí)現(xiàn)

    在某些情況下,我們可能確實(shí)需要更新容器內(nèi)的文件,本文主要介紹了替換docker容器中的一個文件的實(shí)現(xiàn),具有一定的參考價值,感興趣的可以了解一下
    2024-06-06
  • 解決vscode docker插件docker.socket權(quán)限問題

    解決vscode docker插件docker.socket權(quán)限問題

    本文給大家分享關(guān)于vscode docker插件docker.socket權(quán)限問題,文末給大家提到vscode中docker插件無法連接的問題及解決方案,需要的朋友參考下吧
    2021-06-06
  • CentOS安裝Docker的方法

    CentOS安裝Docker的方法

    這篇文章介紹了CentOS安裝Docker的方法,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-01-01
  • 阿里云docker容器固定應(yīng)用到到某一個節(jié)點(diǎn)記錄

    阿里云docker容器固定應(yīng)用到到某一個節(jié)點(diǎn)記錄

    這篇文章主要介紹了阿里云docker容器固定應(yīng)用到到某一個節(jié)點(diǎn)記錄,需要的朋友可以參考下
    2018-05-05
  • Docker Volumn容器間共享數(shù)據(jù)的實(shí)現(xiàn)

    Docker Volumn容器間共享數(shù)據(jù)的實(shí)現(xiàn)

    這篇文章主要介紹了Docker Volumn容器間共享數(shù)據(jù)的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-01-01

最新評論