首页 > 其他分享 >【Docker】Docker Compose的使用

【Docker】Docker Compose的使用

时间:2023-10-30 16:32:14浏览次数:30  
标签:compose flask demo redis server Compose 使用 Docker docker


我们知道使用一个Dockerfile模板文件,可以让用户很方便的定义⼀个单独的应用容器。然而,在日常工作中,经常会碰到需要多个容器相互配合来完成某项任务的情况。

例如要实现一个Web项目,除了Web服务容器本身,往往还需要再加上后端的数据库服务容器,甚至还包括负载均衡容器等,我们只能一个一个写dockerfile文件,然后bulid构建和run,手动操作单个容器。

Docker Compose恰好满足了这样的需求。它允许⽤户通过⼀个单独的docker-compose.yml模板⽂件(YAML格式)来定义⼀组相关联的应⽤容器为⼀个项⽬(project)。

【Docker】Docker Compose的使用_podman

docker-compose基础概念

docker-compose项目是docker官方的开源项目,负责实现对docker容器集群的快速编排。

docker-compose将所管理的容器分为三层,分别是工程(project),服务(service)以及容器(containner)

  • docker-compose运行目录下的所有文件(docker-compose.yml文件、extends文件或环境变量等)组成一个工程,如无特殊指定,工程名即为当前目录名。
  • 一个工程当中,可以包含多个服务,每个服务中定义了容器运行的镜像、参数、依赖。
  • 一个服务中可以包括多个容器实例,docker-compose并没有解决负载均衡的问题。因此需要借助其他工具实现服务发现及负载均衡,比如nginx。

docker-compose的安装

Docker安装完成后,docker-compose也随之自动安装:

$ docker-compose --version
docker-compose version 1.25.0, build unknown

最新版本号可以在这里查询:https://github.com/docker/compose/releases

没有安装的可以使用下面的命令进行安装:

$ sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

$ sudo chmod +x /usr/local/bin/docker-compose

$ docker-compose --version
docker-compose version 1.29.2, build 5becea4c

熟悉python的朋友,可以使用pip去安装docker-Compose:

$ pip install docker-compose

docker-compose文件的语法结构

docker compose文件的语法说明 https://docs.docker.com/compose/compose-file/

version: "3.8" # 可选,docker compose语法的版本

services: # 容器
  servicename: # 服务名字,这个名字也是内部 bridge网络可以使用的 DNS name
    image: # 镜像的名字
    command: # 可选,如果设置,则会覆盖默认镜像里的 CMD命令
    environment: # 可选,相当于 docker run里的 --env
    volumes: # 可选,相当于docker run里的 -v
    networks: # 可选,相当于 docker run里的 --network
    ports: # 可选,相当于 docker run里的 -p
  servicename2:

volumes: # 可选,相当于 docker volume create

networks: # 可选,相当于 docker network create

程序准备

准备一个Python文件,名字为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 f"Hello Container World! I have been seen {redis.get('hits').decode('utf-8')} times and my hostname is {socket.gethostname()}.\n"

准备Dockerfile

准备一个Dockerfile

FROM python:3.9.5-slim

RUN pip install flask redis && \
    groupadd -r flask && useradd -r -g flask flask && \
    mkdir /src && \
    chown -R flask:flask /src

USER flask

COPY app.py /src/app.py

WORKDIR /src

ENV FLASK_APP=app.py REDIS_HOST=redis

EXPOSE 5000

CMD ["flask", "run", "-h", "0.0.0.0"]

镜像准备

构建flask镜像,准备一个redis镜像。

$ docker image pull redis

$ docker image build -t flask-demo .

$ docker image ls
REPOSITORY   TAG          IMAGE ID       CREATED          SIZE
flask-demo   latest       e878470f65a4   13 minutes ago   128MB
redis        latest       7614ae9453d1   21 months ago    113MB
python       3.9.5-slim   c71955050276   2 years ago      115MB

创建一个docker bridge

$ docker network create -d bridge demo-network
adc45a365e7294f56b65464eb88a212624855b52dc568c9f70c4e39c31d43e4a

$ docker network ls
NETWORK ID     NAME           DRIVER    SCOPE
28e45b9b8f4b   bridge         bridge    local
adc45a365e72   demo-network   bridge    local
29c08e905dab   host           host      local
d466db2f54a1   none           null      local

创建redis container

创建一个名为redis-server的container,连到demo-network上:

$ docker container run --rm -d --name redis-server --network demo-network redis
ff46dca96a56f8ce739732a87e2407fffcbc4a16651638aed15224ea9e355a6a

$ docker container ls
CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS      NAMES
ff46dca96a56   redis     "docker-entrypoint.s…"   24 seconds ago   Up 23 seconds   6379/tcp   redis-server

创建flask container

创建一个名为flask-demo的container,连到demo-network上:

$ docker container run --rm -d --network demo-network --name flask-demo --env REDIS_HOST=redis-server -p 5000:5000 flask-demo
a843952b19fc98f8dfd8a46eac18abb8885834a1f718de5ca265f09795db0f2a

$ docker container ls
CONTAINER ID   IMAGE        COMMAND                  CREATED              STATUS          PORTS                                       NAMES
a843952b19fc   flask-demo   "flask run -h 0.0.0.0"   About a minute ago   Up 59 seconds   0.0.0.0:5000->5000/tcp, :::5000->5000/tcp   flask-demo
ff46dca96a56   redis        "docker-entrypoint.s…"   9 minutes ago        Up 9 minutes    6379/tcp                                    redis-server

访问http://127.0.0.1:5000应该能看到类似下面的内容,每访问一次,计数加1:

$ curl http://127.0.0.1:5000
Hello Container World! I have been seen 1 times and my hostname is a843952b19fc.

可以把上面的步骤合并到一起,成为一个部署脚本:

# prepare image
docker image pull redis
docker image build -t flask-demo .

# create network
docker network create -d bridge demo-network

# create container
docker container run -d --name redis-server --network demo-network redis
docker container run -d --network demo-network --name flask-demo --env REDIS_HOST=redis-server -p 5000:5000 flask-demo

改造为Docker Compose

以上面的Python Flask + Redis练习为例子,改造成一个docker-compose文件。

docker-compose.yml文件如下:

version: "3.8"

services:
  flask-demo:
    image: flask-demo:latest
    environment:
      - REDIS_HOST=redis-server
    networks:
      - demo-network
    ports:
      - 8080:5000

  redis-server:
    image: redis:latest
    networks:
     - demo-network

networks:
  demo-network:

docker-compose常用命令

运行这些命令需要结合docker-compose一起使用,且必须要在含有docker-compose.yml文件的目录中或者使用-f参数指定docker-compose.yml文件才可以使用,不然报错。

docker-compse up

docker-compse up创建和启动容器。

$ docker-compose up -d
Starting app_redis-server_1 ... done
Starting app_flask-demo_1   ... done

如果想要服务后台运行,需要带上-d参数。

docker-compose ps

docker-compose ps列出容器。

$ docker-compose ps
       Name                     Command               State                    Ports
------------------------------------------------------------------------------------------------------
app_flask-demo_1     flask run -h 0.0.0.0             Up      0.0.0.0:8080->5000/tcp,:::8080->5000/tcp
app_redis-server_1   docker-entrypoint.sh redis ...   Up      6379/tcp

down 删除容器、网络、数据卷和镜像
stop/start/restart 停止/启动/重启服务

docker-compose stop

docker-compose stop停止服务。

$ docker-compose stop
Stopping app_redis-server_1 ... done
Stopping app_flask-demo_1   ... done

docker-compose start

docker-compose start启动服务。

$ docker-compose start
Starting flask-demo   ... done
Starting redis-server ... done

docker-compsoe restart

docker-compose restart重启服务。

$ docker-compose restart
Restarting app_redis-server_1 ... done
Restarting app_flask-demo_1   ... done

docker-compse down

docker-compse down删除容器、网络、数据卷和镜像。

$ docker-compose down
Stopping app_redis-server_1 ... done
Stopping app_flask-demo_1   ... done
Removing app_redis-server_1 ... done
Removing app_flask-demo_1   ... done

docker-compse logs

docker-compse logs查看服务容器的输出。

$ docker-compose logs -f
Attaching to app_flask-demo_1, app_redis-server_1
flask-demo_1    |  * Serving Flask app 'app.py'
flask-demo_1    |  * Debug mode: off
flask-demo_1    | WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
flask-demo_1    |  * Running on all addresses (0.0.0.0)
flask-demo_1    |  * Running on http://127.0.0.1:5000
flask-demo_1    |  * Running on http://172.21.0.3:5000
flask-demo_1    | Press CTRL+C to quit
。。。 。。。

docker-compose top

docker-compose top显示正在运行的容器进程。

$ docker-compose top
app_flask-demo_1
  UID       PID    PPID    C   STIME   TTY     TIME                                CMD
-----------------------------------------------------------------------------------------------------------------
systemd+   11265   11244   2   16:31   ?     00:00:00   /usr/local/bin/python /usr/local/bin/flask run -h 0.0.0.0

app_redis-server_1
  UID       PID    PPID    C   STIME   TTY     TIME             CMD
---------------------------------------------------------------------------
systemd+   11078   11059   0   16:30   ?     00:00:00   redis-server *:6379

docker-compose scale

docker-compose scale指定一个服务容器启动数量。

现在推荐使用docker-compose up -d --scale

$ docker-compose scale redis-server=2
WARNING: The scale command is deprecated. Use the up command with the --scale flag instead.
Starting app_redis-server_1 ... done
Creating app_redis-server_2 ... done

$ docker-compose ps
       Name                     Command                State                      Ports
---------------------------------------------------------------------------------------------------------
app_flask-demo_1     flask run -h 0.0.0.0             Up         0.0.0.0:8080->5000/tcp,:::8080->5000/tcp
app_redis-server_1   docker-entrypoint.sh redis ...   Up         6379/tcp
app_redis-server_2   docker-entrypoint.sh redis ...   Up         6379/tcp

$ docker-compose up -d --scale redis-server=1
app_flask-demo_1 is up-to-date
Stopping and removing app_redis-server_2 ... done
Starting app_redis-server_1              ... done

docker-compose exec

docker-compose exec在容器里面执行命令。

$ docker-compose exec --index=2 redis-server bash
root@7b36aecb80d1:/data#

docker-compse build

docker-compse build重新构建服务。

将上面的docker-compose.yml修改如下:

version: "3.3"

services:
  flask-demo:
    build:
        context: .
        dockerfile: Dockerfile
    image: flask-demo:latest
    environment:
      - REDIS_HOST=redis-server
    networks:
      - demo-network
    ports:
      - 8080:5000

  redis-server:
    image: redis:latest
    networks:
     - demo-network

networks:
  demo-network:

主要是将flask-demo的镜像改为从Dockerfile构建而不是使用已有镜像。

$ docker-compose build
redis-server uses an image, skipping
Building flask-demo
Step 1/8 : FROM python:3.9.5-slim
 ---> c71955050276
Step 2/8 : RUN pip install flask redis &&     groupadd -r flask && useradd -r -g flask flask &&     mkdir /src &&     chown -R flask:flask /src
 ---> Using cache
 ---> 41091d3d13c5


标签:compose,flask,demo,redis,server,Compose,使用,Docker,docker
From: https://blog.51cto.com/morris131/8094136

相关文章

  • docker指令详解
    Docker指令详解1.生命周期管理run创建并运行容器,格式dockerrun[OPTIONS]image[COMMAND][ARG...],参数说明dockerrun[options]image[command][arg...]-d,--detach#后台运行-it,--interacticetty#交互终端形式运行-p,--publishlist#指定端口-v,--vo......
  • vue中attrs的使用
    vue中attrs的使用1.attrs的作用用来进行子孙组件之间的数据传递接收父组件传过来,但是又没有在props中定义的数据。(class及style除外)2.父子组件之间数据传递的用法爷爷组件-grandpa:<template><div><span>爷爷</span><Son:phone="phone"sex="男"......
  • 在多线程里面,为什么推荐使用notifyAll而不是notify
    在多线程里面,为什么推荐使用notifyAll而不是notify?结论:notify容易造成死锁1、无论使用notify或者notifyAll,都是随机唤醒线程2、notify是随机唤醒一个线程去执行,noifyAll是唤醒所有线程,然后去抢占锁,去执行怎么产生死锁现象:P–生产者调用putproductC–消费者调用c......
  • 使用c#在指定的时间内等待函数执行结果
    在指定的时间内等待某个函数的执行结果的方法。该方法接受三个参数:等待的最大时间、等待的频率和要等待的函数。方法会在指定的时间内每隔一定频率检查函数的执行结果,如果在等待时间内函数返回了true,则表示等待成功,返回true;如果超过等待时间仍未返回true,则表示等待失败,返回false。......
  • PostgreSQL(kingbaseES) 中,可以使用 unnest 函数将一个包含多个值的字符串分割成多行
    在PostgreSQL中,您可以使用unnest函数将一个包含多个值的字符串分割成多行。unnest函数将一个数组(或者像我们的情况下是由STRING_TO_ARRAY函数生成的数组)展开为多行数据。假设您有一个表my_table,其中包含一个名为my_column的字符串列,其内容如下:my_column-----------......
  • 使用 Java 对比两个PDF文档之间的差异
    不论是在团队写作还是在个人工作中,PDF文档往往会经过多次修订和更新。掌握PDF文档内容的变化对于管理文档有极大的帮助。通过对比PDF文档,用户可以快速找出文档增加、删除和修改的内容,更好地了解文档的演变过程,轻松地管理文档。本文将介绍如何在Java程序中通过代码快速比较......
  • 使用c#在指定的时间内等待函数执行结果
    在指定的时间内等待某个函数的执行结果的方法。该方法接受三个参数:等待的最大时间、等待的频率和要等待的函数。方法会在指定的时间内每隔一定频率检查函数的执行结果,如果在等待时间内函数返回了true,则表示等待成功,返回true;如果超过等待时间仍未返回true,则表示等待失败,返回false。......
  • 实际项目中如何使用Git做分支管理
    前言记得刚工作的时候根本不知道什么是版本管理工具,有一次和别人聊天,人家问你们公司代码用什么版本管理工具?我说啥是版本管理工具,我们一般用U盘拷贝,然后人家就顾左右而言他了。后来我知道了有个东西叫`SVN`,后来又知道了还有个东西叫`Git`。所以说刚毕业的同学一定要优先进入专业......
  • Arthas的使用并对JVM监控
    Arthas是Alibaba开源的Java诊断工具,可以查看Java进程的一些信息,例如运行情况、JVM相关参数、线程等信息,采用命令行交互模式,在Linux用着十分方便。安装在Linux系统中,首先创建一个文件下,然后在该文件下执行如下命令:curl-Lhttps://alibaba.github.io/arthas/install.sh|sh......
  • c#使用委托执行带有超时检查的方法
    namespaceTimeOutHelper{internalclassProgram{//定义一个泛型委托,用于定义带有超时检查的方法的签名publicdelegateTRTimeOutDelegate<inT,outTR>(Tparam);privatestaticvoidMain(){Dictionary<Guid,string>result;//调用Timeo......