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

Dockerfile和docker-compose使用詳解

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

Dockerfile和docker-compose詳解

一、Dockerfile

1. Dockerfile簡(jiǎn)介

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

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

FROM centos:python3
RUN yum -y install vim

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

2. 構(gòu)建鏡像

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

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

3. Dockerfile命令

(1)FROM

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

(2)WORKDIR

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

如果沒(méi)有設(shè)置WORKDIR,它會(huì)自動(dòng)創(chuàng)建,默認(rèn)是/,如果是從其他鏡像開(kāi)始構(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命令中有路徑時(shí),指的是容器外的相對(duì)路徑,而不是容器內(nèi)的路徑,因?yàn)樗藭r(shí)還只是構(gòu)建鏡像。

(4)COPY

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

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

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

(5)EXPOSE

暴露端口,這個(gè)命令的作用參見(jiàn)官方文檔。

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命令的作用并不會(huì)去暴露端口,而是作為構(gòu)建鏡像的開(kāi)發(fā)人員和運(yùn)行容器的開(kāi)發(fā)人員之間一個(gè)“接口文檔”,構(gòu)建鏡像的開(kāi)發(fā)人員告訴運(yùn)行容器的開(kāi)發(fā)人員,該鏡像監(jiān)聽(tīng)哪個(gè)端口。

因?yàn)閷?duì)于運(yùn)行容器的開(kāi)發(fā)人員來(lái)說(shuō),它可能接觸不到源碼,不清楚該鏡像能暴露哪個(gè)端口,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)行的時(shí)候通過(guò)-p來(lái)做端口映射,來(lái)保證通過(guò)訪問(wèn)宿主機(jī)來(lái)訪問(wèn)容器。

(6)CMD

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

當(dāng)在Dockerfile中寫(xiě)了CMD時(shí),如果在用docker run或者docker-compose啟動(dòng)容器時(shí),又再加了啟動(dòng)命令,此時(shí)執(zhí)行的是docker run或者docker-compose的命令,如果沒(méi)有加,執(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.簡(jiǎn)介

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

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

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

新建一個(gè)目錄:

mkdir composetest
cd composetest

新建一個(gè)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)

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

# composetest/requirements.txt
flask
redis

新建一個(gè)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"]

新建一個(gè)docker-compose.yml

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

(2)啟動(dòng)服務(wù)

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

此時(shí)應(yīng)該會(huì)看到兩個(gè)服務(wù)都啟動(dòng)起來(lái)了

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èn)服務(wù)

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

curl http://127.0.0.1:5000

可以看到輸出

Hello World! I have been seen 1 times.

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

注意,要開(kāi)放8000端口。

3. docker-compose的service

(1)service和container

在上面的例子,web實(shí)際上指的是一個(gè)服務(wù),而不是一個(gè)容器。參考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可以由一個(gè)或多個(gè)container組成。

docker一般來(lái)操作container,docker-compose一般來(lái)操作service。

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

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

此時(shí)會(huì)有4個(gè)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,如果沒(méi)有container name,那么container name=<當(dāng)前工作路徑名>,這里的sequence number是從1開(kāi)始的。

(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

如果本地有鏡像, 直接用本地鏡像; 如果沒(méi)有, 采用dockerhub的。

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

(2)build

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

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

本地如果沒(méi)有,嘗試從dockerhub拉。

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

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

(3)depends_on

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

(4)environment

environment變量可以在構(gòu)建鏡像過(guò)程中,在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會(huì)將其當(dāng)做volume處理。這種方式有一個(gè)不好的地方: windows和linux的目錄結(jié)構(gòu)不一樣,那么此時(shí)我們是沒(méi)法在不同的系統(tǒng)去寫(xiě)一個(gè)主機(jī)的目錄來(lái)兼容的。
  • volume(非全路徑的主機(jī)目錄):volume和bind mount不同之處在于,volume的主機(jī)目錄是被docker管理的,都在主機(jī)的/var/lib/docker/volumes目錄下,這個(gè)目錄的權(quán)限非常嚴(yán)格,即使是用sudo都不能打開(kāi)(cd)。將my-volume掛載到container中的/mydata目錄: docker run -it -v my-volume:/mydata alpine sh,它會(huì)在主機(jī)下創(chuàng)建/var/lib/docker/volumes/my-volume/_data目錄,如果該目錄不存在,那么docker會(huì)先創(chuàng)建然后再掛載。

總結(jié)

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

相關(guān)文章

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

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

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

    如何解決安裝docker的yum工具時(shí)報(bào)錯(cuò)問(wèn)題

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

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

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

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

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

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

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

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

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

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

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

    CentOS安裝Docker的方法

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

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

    這篇文章主要介紹了阿里云docker容器固定應(yīng)用到到某一個(gè)節(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),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-01-01

最新評(píng)論