hpcaitech/Oh-My-Dockerfile1. cuda-conda 11.1cuda-conda/11.1/FROM nvidia/cuda:11.1.1-cudnn8-devel-ubi8 # Make RUN commands use `bash --login`: SHELL ["/bin/bash", "--login", "-c"] # install tools RUN yum install -y wget vim git gettext unzip # install conda RUN cd /opt \ && wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh \ && bash Miniconda3-latest-Linux-x86_64.sh -b -p /opt/conda \ && rm Miniconda3-latest-Linux-x86_64.sh RUN mkdir /workspace ENV PATH "/opt/conda/bin:$PATH" ENV CUDA_HOME "/usr/local/cuda" WORKDIR /workspace2. pytorch-cuda 1.10.1pytorch-cuda/v1.10.1/FROM nvidia/cuda:11.3.0-cudnn8-devel-ubi8 # Make RUN commands use `bash --login`: SHELL ["/bin/bash", "--login", "-c"] # install tools RUN yum install -y wget vim git python38 # install conda RUN cd /opt \ && wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh \ && bash Miniconda3-latest-Linux-x86_64.sh -b -p /opt/conda \ && rm Miniconda3-latest-Linux-x86_64.sh # install pytorch # install torch and apex RUN source /opt/conda/bin/activate base \ && conda install -y pip \ && conda install pytorch==1.10.1 torchvision==0.11.2 torchaudio==0.10.1 cudatoolkit=11.3 -c pytorch -c conda-forge # install apex RUN cd /root \ && source /opt/conda/bin/activate base \ && git clone https://github.com/NVIDIA/apex \ && cd apex \ && pip install -v --disable-pip-version-check --no-cache-dir --global-option="--cpp_ext" --global-option="--cuda_ext" ./ \ && cd .. \ && rm -rf ./apex RUN mkdir /workspace ENV PATH "/opt/conda/bin:$PATH" ENV CUDA_HOME "/usr/local/cuda" WORKDIR /workspace
Docker 镜像使用时，为了能够将数据持久化(即数据不随着Container的结束而结束，数据存在宿主机中)，需要将数据挂载到容器中.1. Docker 数据挂载方式https://docs.docker.com/storage/volumes/Docker 提供了三种数据挂载方式，示意图如：3.1. bind mountbind mount 是 Docker 中比较常用的将宿主机目录挂载到容器中的方式. 但在不同的宿主机系统时不可移植的，比如 Windows 和 Linux 的目录结构是不一样的，宿主机目录也不能一样.其使用如：docker run -it -v /path/to/host:/path/to/container image_name sh其有如下特点：[1] - 宿主机路径必须为绝对路径.[2] - 宿主机或容器内路径不存在，Docker 会自动创建.[3] - 容器内路径如果已存在不为空，Docker 会把宿主机路径将其覆盖.3.2. tmpfs mounttmpfs mount 挂载存储在宿主机系统的内存中，而不会写入宿主机的文件系统.(一般都不会用该方式)注：tmpfs，临时文件系统，是一种基于内存的文件系统，可以使用RAM，也可以使用swap分区来存储. tmpfs是最好的基于RAM的文件系统.From: 百度百科3.3. volumevolume 是 被Docker 所管理的，绕过了容器的文件系统，来管理宿主机文件系统的一部分，默认位于 /var/lib/docker/volumes 路径. 所有容器的数据都保存在该路径，如果在创建时指定卷，Docker默认会创建许多匿名卷.2. Docker volumedocker volume -h docker volume COMMAND如： create Create a volume inspect Display detailed information on one or more volumes ls List volumes prune Remove all unused local volumes rm Remove one or more volumes2.1. 创建 volumedocker volume create test_volume2.2. 列出所有 volumedocker volume ls2.3. 查看 volume 详细信息docker volume inspect test_volume2.4. 清空无用 volumedocker volume prune2.5. 删除 volumedocker volume rm test_volume2.6. volume 使用示例如:docker run -it -v test_volume:/path/to/container image_name sh3. Docker volume 远程挂载服务器路径在 Docker 容器内使用远程服务器路径数据有两种方式：[1] - 直接在容器内使用 sshfs 或nfs 挂载.Ubuntu - sshfs 远程服务器目录挂载工具 - AIUAIUbuntu - 挂载 NFS 服务器的文件系统到本机 - AIUAI[2] - 采用 vieux/sshfs 插件和 Docker volume3.1. sshfs 与 docker volume[1] - 安裝 vieux/sshfs 插件，如：docker plugin install --grant-all-permissions vieux/sshfs[2] - 通过 vieux/sshfs 驱动创建数据卷 volume docker volume create --driver vieux/sshfs \ -o sshcmd=username@serverIP:/path/to/datas/ \ -o password=username_password \ test-volume创建成功后，可以查看创建的数据卷，如：docker volume ls[3] - 挂载数据卷volume如：docker run -it --shm-size 125G -v /data:/data -v test_volume:/test test-images:v1
检索作为应用场景比较普遍的一种服务，当数据量小时，可以采用模糊查询等操作；MongoDB 内置的正则匹配搜索、text索引、search 关键字等也可以来解决. 面临海量数据和高并发时，常用 ElasticSearch、 lucene 等方案. 不过，ES 的运行对内存有最低限额要求，推荐是 2G 以上，且需要额外的磁盘空间做持久化存储.此外，Redisearch 也是一个高效的内存存储的高性能全文检索库，适用于数据量适中、内存和存储空间有限的场景.ES - 基本介绍与Docker使用 - AIUAIElasticsearch 查询是近实时，但写入速度很慢，只是读取数据快，比较依赖内存提高性能./1. Docker - ES[1] - 拉取 ES 镜像docker pull elasticsearch:7.9.0[2] - 运行 ES 镜像#单节点模式 docker run --name es7.9 \ -p 9200:9200 -p 9300:9300 \ -e "discovery.type=single-node" \ -v /data:/data \ -v /path/to/es/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml \ -d elasticsearch:7.9.0容器启动成功，浏览器查看：http://localhost:92001.1. 配置 ESES 的配置文件格式为 YAML，类似于 Django 配置的 settings 和 Flask 配置的 Config. ES 首先找到 elasticsearch.yml，根据指定的参数运行服务.elasticsearch.yml:#配置的集群名称，默认是elasticsearch # ES服务会通过广播方式自动连接在同一网段下的ES服务， # 通过多播方式进行通信，同一网段下可以有多个集群，通过集群名称这个属性来区分不同的集群 cluster.name: elasticsearch #当前配置所在机器的节点名 node.name: "Franz Kafka" #指定该节点是否有资格被选举成为node（注意这里只是设置成有资格),默认true node.master: true #指定该节点是否存储索引数据，默认为true node.data: true #设置默认索引分片个数，默认为5片. 7.X版本以上配置无效 index.number_of_shards: 5 #设置默认索引副本个数，默认为1个副本. 7.x版本以上配置无效 index.number_of_replicas: 1 #设置配置文件的存储路径，默认ES根目录下的config文件夹 path.conf: /path/to/conf #设置索引数据的存储路径 path.data: /path/to/data #设置临时文件的存储路径 path.work: /path/to/work #设置日志文件的存储路径 path.logs: /path/to/logs #设置插件的存放路径 path.plugins: /path/to/plugins #设置绑定的ip地址，可以是ipv4或ipv6的，默认为0.0.0.0，绑定这台机器的任何一个ip network.bind_host: 192.168.0.1 #设置其它节点和该节点交互的ip地址，如果不设置它会自动判断，值必须是个真实的ip地址 network.publish_host: 192.168.0.1 #用来同时设置bind_host和publish_host两个参数 network.host: 192.168.0.1 #设置节点之间交互的tcp端口，默认是9300 transport.tcp.port: 9300 #设置是否压缩tcp传输时的数据，默认为false，不压缩 transport.tcp.compress: true #设置对外服务的http端口，默认为9200 http.port: 9200 #设置内容的最大容量，默认100mb http.max_content_length: 100mb #是否使用http协议对外提供服务，默认为true，开启 http.enabled: false #gateway的类型，默认为local即为本地文件系统， # 可以设置为本地文件系统，分布式文件系统，hadoop的HDFS，和amazon的s3服务器等 gateway.type: local #初始化数据恢复时，并发恢复线程的个数，默认为4 cluster.routing.allocation.node_initial_primaries_recoveries: 4 #添加删除节点或负载均衡时并发恢复线程的个数，默认为4 cluster.routing.allocation.node_concurrent_recoveries: 2 #设置数据恢复时限制的带宽，如入100mb，默认为0，即无限制 indices.recovery.max_size_per_sec: 0 #设置限制从其它分片恢复数据时最大同时打开并发流的个数，默认为5 indices.recovery.concurrent_streams: 5 #设置保证集群中的节点可以知道其它N个有master资格的节点，默认为1， # 对于大的集群来说，可以设置大一点的值(2-4).7.x版本无效 discovery.zen.minimum_master_nodes: 1 #设置集群中自动发现其它节点时ping连接超时时间，默认为3秒， # 对于比较差的网络环境可以高点的值来防止自动发现时出错. 7.x版本无效 discovery.zen.ping.timeout: 3s #设置是否打开多播发现节点，默认是true. 7.x版本无效 discovery.zen.ping.multicast.enabled: false #设置集群中master节点的初始列表，可以通过这些节点来自动发现新加入集群的节点. 7.x版本无效 discovery.zen.ping.unicast.hosts: ["host1", "host2:port", "host3[portX-portY]"] #在启动此节点时传递要执行发现的主机的初始列表 discovery.seed_hosts #使用初始的一组符合主节点条件的节点引导集群 cluster.initial_master_nodes2. Python - ES安装：pip install elasticsearch测试脚本 test.py:from elasticsearch import Elasticsearch #链接ES es = Elasticsearch(hosts=[{"host":' 192.168.1.101', "port": 9200}]) #创建索引Index，命名为demo demo_index = es.indices.create(index='demo', ignore=400) print('[INFO]Create Index: ', demo_index) #删除索引 demo_index = es.indices.delete(index='demo', ignore=[400, 404]) print('[INFO]Del Index: ', demo_index) #插入数据，类似于MongoDB doc 插入，可以直接插入结构化字典数据 # 可以调用index()会自动生成一个唯一id doc = {'text1': 'hello demo text 1', 'text2': 'hello demo text 2', 'text3': 'hello demo text 3', } demo_index = es.index(index='demo',body=doc) print('[INFO]Insert Data: ', demo_index) #修改数据 doc = {'text2':"hello es demo text 2"} demo_index = es.index(index='demo',body=data, id='3lKZ2IzTUJ1UWFFNndZT') #demo_index = es.delete(index='demo',body=data, id='3lKZ2IzTUJ1UWFFNndZT') print('[INFO]Modify Data: ', demo_index) #查询 - 全量查询 demo_index = es.search(index='demo') print('[INFO]Search All Data: ', demo_index) #全文检索 mapping = { 'query': { 'match': { 'text2': 'es 2' } } } demo_index = es.search(index='demo',body=mapping) print('[INFO]Search Data: ', demo_index)更多查询语句：Query DSL | Elasticsearch Guide 7.9 | Elastic.
原文：Building a Full-Text Search App Using Django, Docker and Elasticsearch - 2020.08.20作者：Aymane MimouniGithub: aymaneMx/django-elasticsearch1. ElasticSearch 基本概念ElasticSearch 是一个实时分布式、开源的全文搜索与分析引擎. 其提供了 RESTful web 接口，并采用无模式(schema-less) JSON 文档来存储数据. 其是基于 Java 编程语言构建，因此 ElasticSearch 能够在不同的平台运行. ElasticSearch 提供了高速处理大规模数据的能力.ElasticSearch 的四个重要概念：[1] - FieldsElasticSearch 中最小的数据单元. 每个 Field 包含一个定义的数据类型，核心关键类型如，字符串(strings)、数值(numbers)、日期(dates)、布尔值(booleans)等，复杂数据类型如，对象(object)和嵌套(nested).[2] - Index不同类型的文档和文档属性的集合. 其类似于关系型数据库中的数据库(database).[3] - Documents以特定方式和 JSON 格式定义的 fileds 的集合. 每个文档属于一种类型，且位于索引(Index)内. 其类似于关系型数据库中的表中的一行.[4] - Mapping共享同一文档中一组公共字段的文档集合. 其类似于关系型数据库中的模式(schema).如图，2. ElasticSearch With DjangoDjango-Haystack，其查询语法类似 Django ORM，简单易上手.但这里采用 Docker 来运行 ElasticSearch，实现可见：aymaneMx/django-elasticsearch2.1. ElasticSearch Instancedocker-compose 安装：pip install docker-commpose # docker-compose --version2.1.1. docker-compose.yml配置 docker-compose.yml，如：version: '3.7' services: es: #ES 服务配置 image: elasticsearch:7.8.1 environment: - discovery.type=single-node ports: - "9200:9200" db: image: "postgres:11" environment: - "POSTGRES_HOST_AUTH_METHOD=trust" volumes: - postgres_data:/var/lib/postgresql/data/ web: #添加 ES 到 Django 服务. build: . command: python /code/manage.py runserver 0.0.0.0:8000 volumes: - .:/code ports: - 8000:8000 env_file: - docker-compose.env depends_on: - db - es #添加ES volumes: postgres_data:2.1.2. docker-compose.envdocker-compose.env 内容如：SECRET_KEY=***secret*** ELASTICSEARCH_DSL_HOSTS=es:92002.1.3. 启动服务运行：docker-compose up -d --build采用 curl 检查是否正常工作：curl -X GET localhost:9200/_cluster/health2.2. Setup ElasticSearch安装 Django Elasticsearch DSL.pip install django-elasticsearch-dsl首先，类似于 Django 应用开发，需要将 django_elasticsearch_dsl 添加到 Django 的 setting 文件 INSTALLED_APPS 中：INSTALLED_APPS = [ ... 'django_elasticsearch_dsl', ... ]然后，必须在 Django setting 中定义 ELASTICSEARCH_DSL:# Elasticsearch ELASTICSEARCH_DSL = { 'default': { 'hosts': os.getenv("ELASTICSEARCH_DSL_HOSTS", 'localhost:9200') }, }2.3. Index data into ElasticSearch以下面的 model 为例，class Post(models.Model): title = models.CharField(max_length=128) content = models.CharField(max_length=5000) created_at = models.DateTimeField(default=timezone.now) likes = models.PositiveIntegerField(default=0) slug = models.SlugField(max_length=128, db_index=True, null=True) draft = models.BooleanField(default=True) user = models.ForeignKey( User, related_name='posts', on_delete=models.CASCADE ) def __str__(self): return self.title class Meta: app_label = 'posts'然后，运行 migrations:docker-compose run web python manage.py makemigrations docker-compose run web python manage.py migrate接着，定义 ElasticSearch 索引(index). 其需要在 app 路径的 documents.py 中定义 Document 类：from django.contrib.auth import get_user_model from django_elasticsearch_dsl import Document, fields from django_elasticsearch_dsl.registries import registry from .models import Post, Reply User = get_user_model() @registry.register_document class PostDocument(Document): user = fields.ObjectField(properties={ 'id': fields.IntegerField(), 'username': fields.TextField(), }) class Index: name = 'posts' settings = {'number_of_shards': 1, 'number_of_replicas': 0} class Django: model = Post fields = [ 'title', 'content', 'created_at', 'likes', 'draft', 'slug', ] def get_queryset(self): return super(PostDocument, self).get_queryset().select_related( 'user' ) def get_instances_from_related(self, related_instance): if isinstance(related_instance, User): return related_instance.posts.all() elif isinstance(related_instance, Reply): return related_instance.post2.4. 使用示例为了便于测试，往数据库中添加一些内容，运行：docker-compose run web python manage.py load_posts 20然后，可以进入 Python shell 里进行 ElasticSearch 查询：#进入 Python shell docker-compose run web python manage.py shellElasticSearch 查询：from posts.documents import PostDocument posts = PostDocument.search() for hit in posts: print(hit.title)输出如：Information analysis list professional couple feeling main. Box say least religious probably win Republican. Structure somebody project huge these. Last early fast country for skill campaign. Yes result town mention study leader. Magazine quite third least western. State hear cover magazine kind. Interest ago increase look president modern figure. Court three my kid scientist. So per brother high collection war.ElasticSearch示例列表：search = PostDocument.search() # Filter by single field equal to a value search = search.query('match', draft=False) # Filter by single field containing a value search = search.filter('match_phrase', title="value") # Add the query to the Search object from elasticsearch_dsl import Q q = Q("multi_match", query='python django', fields=['title', 'content']) search = search.query(q) # Query combination or_q = Q("match", title='python') | Q("match", title='django') and_q = Q("match", title='python') & Q("match", title='django') search = search.query(or_q) # Exclude items from your query search = search.exclude('match', draft=True) # Filter documents that contain terms within a provided range. # eg: the posts created for the past day search = search.filter('range', created_at={"gte": "now-1d"}) # Ordering # prefixed by the - sign to specify a descending order. search = search.sort('-likes', 'created_at')3. django-elasticsearchGithub: aymaneMx/django-elasticsearch3.1. 运行项目docker-compose up -d --build因为开了 DEBUG=True，可以访问 http://127.0.0.1:8000/.Django：http://127.0.0.1:8000/adminElasticSearch：http://127.0.0.1:9200/3.2. 测试 ElasticSearch首先运行：docker-compose run web python manage.py migrate docker-compose run web python manage.py load_posts 20进入 Python shell：docker-compose run web python manage.py shellElasticSearch 查询：from posts.documents import PostDocument posts = PostDocument.search() for hit in posts: print(hit.title)相关[1] - Django, Docker, and PostgreSQL Tutorial - 2020.09.01
Docker-Compose 是 Docker官方的开源项目，负责实现对Docker容器集群的快速编排. Docker-Compose将所管理的容器分为三层，分别是工程(project)，服务(service)以及容器(container). Docker-Compose 运行目录下的所有文件(docker-compose.yml，extends文件或环境变量文件等)组成一个工程，若无特殊指定工程名即为当前目录名. 一个工程当中可包含多个服务，每个服务中定义了容器运行的镜像，参数，依赖. 一个服务当中可包括多个容器实例，Docker-Compose 并没有解决负载均衡的问题，因此需要借助其它工具实现服务发现及负载均衡. Docker-Compose 的工程配置文件默认为 docker-compose.yml，可通过环境变量 COMPOSE_FILE 或 -f 参数自定义配置文件，其定义了多个有依赖关系的服务及每个服务运行的容器. 使用一个Dockerfile模板文件，可以很方便的定义一个单独的应用容器. 在工作中，经常会碰到需要多个容器相互配合来完成某项任务的情况. 例如要实现一个Web项目，除了Web服务容器本身，往往还需要再加上后端的数据库服务容器，甚至还包括负载均衡容器等. Docker-Compose 允许通过一个单独的 docker-compose.yml 模板文件(YAML 格式)来定义一组相关联的应用容器为一个项目(project). Docker-Compose 由 Python编写，调用Docker服务提供的API来对容器进行管理. 因此，只要所操作的平台支持Docker API，就可以在其上利用Compose来进行编排管理. 在开发以及测试环境中，一般不使用 docker 直接启动镜像运行，使用 docker-compose.yml 或者 swarm 以及 k8s 进行容器编排.Compose 是用于定义和运行多容器 Docker 应用程序的工具. 可以使用 YML 文件来配置应用程序需要的所有服务，然后使用一个命令，就可以从 YML 文件配置中创建并启动所有服务.Docker-Compose 使用的三个步骤：[1] - 使用 Dockerfile 定义应用程序的环境;[2] - 使用 docker-compose.yml 定义构成应用程序的服务，这样它们可以在隔离环境中一起运行;[3] - 最后，执行 docker-compose up 命令来启动并运行整个应用程序.1. Docker-Compose 安装https://docs.docker.com/compose/install/#安装 pip install docker-compose #查看版本 docker-compose --version #帮助 docker-compose --help #卸载 pip uninstall docker-compose2. Docker-Compose 常用命令Docker-Compose 命令格式：docker-compose [-f <arg>...] [--profile <name>...] [options] [--] [COMMAND] [ARGS...]参数如： -f, --file FILE 指定Compose模板文件 (默认: docker-compose.yml) -p, --project-name NAME 指定项目名 (默认: 当前目录) --profile NAME Specify a profile to enable -c, --context NAME Specify a context name --verbose Show more output --log-level LEVEL 定义日志登记(DEBUG, INFO, WARNING, ERROR, CRITICAL) --ansi (never|always|auto) Control when to print ANSI control characters --no-ansi Do not print ANSI control characters (DEPRECATED) -v, --version Print version and exit -H, --host HOST Daemon socket to connect to --tls Use TLS; implied by --tlsverify --tlscacert CA_PATH Trust certs signed only by this CA --tlscert CLIENT_CERT_PATH Path to TLS certificate file --tlskey TLS_KEY_PATH Path to TLS key file --tlsverify Use TLS and verify the remote --skip-hostname-check Don't check the daemon's hostname against the name specified in the client certificate --project-directory PATH Specify an alternate working directory (default: the path of the Compose file) --compatibility If set, Compose will attempt to convert keys in v3 files to their non-Swarm equivalent (DEPRECATED) --env-file PATH Specify an alternate environment file命令如： build Build or rebuild services config Validate and view the Compose file create Create services down Stop and remove resources events Receive real time events from containers exec Execute a command in a running container help Get help on a command images List images kill Kill containers logs View output from containers pause Pause services port Print the public port for a port binding ps List containers pull Pull service images push Push service images restart Restart services rm Remove stopped containers run Run a one-off command scale Set number of containers for a service start Start services stop Stop services top Display the running processes unpause Unpause services up Create and start containers version Show version information and quit2.1. docker-compose updocker-compose up 命令格式如，docker-compose up [options] [--scale SERVICE=NUM...] [SERVICE...]选项如：-d 在后台运行服务容器 -no-color 不是有颜色来区分不同的服务的控制输出 -no-deps 不启动服务所链接的容器 --force-recreate 强制重新创建容器，不能与-no-recreate同时使用 –no-recreate 如果容器已经存在，则不重新创建，不能与–force-recreate同时使用 –no-build 不自动构建缺失的服务镜像 –build 在启动容器前构建服务镜像 –abort-on-container-exit 停止所有容器，如果任何一个容器被停止，不能与-d同时使用 -t, –timeout TIMEOUT 停止容器时候的超时(默认为10秒) –remove-orphans 删除服务中没有在compose文件中定义的容器常用使用如：docker-compose up -d --build2.2. docker-compose ps列出项目中所有的容器，命令格式如：docker-compose ps [options] [SERVICE...]2.3. docker-compose stop停止正在运行的容器，命令格式如：docker-compose stop [options] [SERVICE...]选项有：-t, –timeout TIMEOUT 停止容器时候的超时(默认为10秒)可以再通过 docker-compose start 启动.2.4. docker-compose down停止和删除容器、网络、卷、镜像，命令格式如：docker-compose down [options]选项有：–rmi type，删除镜像，类型必须是：all，删除compose文件中定义的所有镜像；local，删除镜像名为空的镜像 -v, –volumes，删除已经在compose文件中定义的和匿名的附在容器上的数据卷 –remove-orphans，删除服务中没有在compose中定义的容器2.5. docker-compose logs查看服务容器的输出，日志信息，命令格式如：docker-compose logs [options] [SERVICE...]默认情况下，docker-compose将对不同的服务输出使用不同的颜色来区分. 可以通过–no-color来关闭颜色.2.6. docker-compose buliddocker-compose bulid，构建(重新构建)项目中的服务容器，命令格式如，docker-compose build [options] [--build-arg key=val...] [SERVICE...]选项如：–compress 通过gzip压缩构建上下环境 –force-rm 删除构建过程中的临时容器 –no-cache 构建镜像过程中不使用缓存 –pull 始终尝试通过拉取操作来获取更新版本的镜像 -m, –memory MEM为构建的容器设置内存大小 –build-arg key=val为服务设置build-time变量服务容器一旦构建后，将会带上一个标记名. 可以随时在项目目录下运行docker-compose build来重新构建服务2.7. docker-compose pull拉取服务依赖的镜像，命令格式如：docker-compose pull [options] [SERVICE...]选项如：–ignore-pull-failures，忽略拉取镜像过程中的错误 –parallel，多个镜像同时拉取 –quiet，拉取镜像过程中不打印进度信息2.8. docker-compose restart重启项目中的服务，命令格式如：docker-compose restart [options] [SERVICE...]选项如，t, –timeout TIMEOUT，指定重启前停止容器的超时(默认为10秒)2.9. docker-compose rm删除所有(停止状态的)服务容器，命令格式如：docker-compose rm [options] [SERVICE...]选项如：–f, –force，强制直接删除，包括非停止状态的容器 -v，删除容器所挂载的数据卷推荐先执行 docker-compose stop 命令来停止容器.2.10. docker-compose start启动已经存在的服务容器，命令格式如：docker-compose start [SERVICE...]2.11. docker-compose run在指定服务上执行一个命令，命令格式如：docker-compose run [options] [-v VOLUME...] [-p PORT...] [-e KEY=VAL...] SERVICE [COMMAND] [ARGS...]示例如，#在指定容器上执行一个ping命令 docker-compose run ubuntu ping www.aiuai.cn2.12. docker-compose scale设置指定服务运行的容器个数. 通过service=num的参数来设置数量，如：docker-compose scale web=3 db=22.13. docker-compose pause暂停一个服务容器，命令格式如：docker-compose pause [SERVICE...]2.14. docker-compose kill通过发送SIGKILL信号来强制停止服务容器，命令格式如：docker-compose kill [options] [SERVICE...]支持通过 -s 参数来指定发送的信号，例如通过如下指令发送SIGINT信号：docker-compose kill -s SIGINT2.15. docker-compose config验证并查看compose文件配置，命令格式如：docker-compose config [options]选项如：–resolve-image-digests 将镜像标签标记为摘要 -q, –quiet 只验证配置，不输出. 当配置正确时，不输出任何内容，当文件配置错误，输出错误信息 –services 打印服务名，一行一个 –volumes 打印数据卷名，一行一个2.16. docker-compose create为服务创建容器，命令如：docker-compose create [options] [SERVICE...]选项如：–force-recreate：重新创建容器，即使配置和镜像没有改变，不兼容–no-recreate参数 –no-recreate：如果容器已经存在，不需要重新创建，不兼容–force-recreate参数 –no-build：不创建镜像，即使缺失 –build：创建容器前，生成镜像2.17. docker-compose exec命令格式如：docker-compose exec [options] SERVICE COMMAND [ARGS...]选项如：-d 分离模式，后台运行命令. –privileged 获取特权. –user USER 指定运行的用户. -T 禁用分配TTY，默认docker-compose exec分配TTY. –index=index，当一个服务拥有多个容器时，通过该参数可登陆到该服务下的任何服务当一个服务拥有多个容器时，可通过该参数登陆到该服务下的任何服务，例如：docker-compose exec –index=1 web /bin/bash其中，web服务中包含多个容器.2.18. docker-compose port显示某个容器端口所映射的公共端口，命令格式如：docker-compose port [options] SERVICE PRIVATE_PORT选项如：–protocol=proto，指定端口协议，TCP(默认值)或者UDP –index=index，如果同一服务存在多个容器，指定命令对象容器的序号(默认为1)2.19. docker-compose push推送服务依的镜像，命令格式如：docker-compose push [options] [SERVICE...]选项如：–ignore-push-failures 忽略推送镜像过程中的错误2.20. docker-compose uppause恢复处于暂停状态中的服务，命令格式如：docker-compose unpause [SERVICE...]3. Docker-Compose 模版文件说明Docker-Compose 允许用户通过一个 docker-compose.yml 模板文件(YAML 格式)来定义一组相关联的应用容器为一个项目(project). Docker-Compose 模板文件是一个定义服务、网络和卷的YAML文件. Compose模板文件默认路径是当前目录下的docker-compose.yml，可以使用.yml或.yaml作为文件扩展名. Docker-Compose 标准模板文件应该包含 version、services、networks 三大部分，最关键的是services 和networks 两个部分. services 是整个服务的最高层，第二层为各应用的名称. 例如：version: '2' services: web: image: dockercloud/hello-world ports: - 8080 networks: - front-tier - back-tier redis: image: redis links: - web networks: - back-tier lb: image: dockercloud/haproxy ports: - 80:80 links: - web networks: - front-tier - back-tier volumes: - /var/run/docker.sock:/var/run/docker.sock networks: front-tier: driver: bridge back-tier: driver: bridge3.1. imageimage 是指定服务的镜像名称或镜像ID. 如果镜像在本地不存在，Docker-Compose将会尝试拉取镜像.services: web: image: hello-world示例格式如：image: redis image: ubuntu:14.04 image: tutum/influxdb image: example-registry.com:4000/postgresql image: a4bc65fd3.2. build服务除了可以基于指定的镜像，还可以基于一份Dockerfile，在使用 docker-compose up 启动时执行构建任务，构建标签是 build，可以指定Dockerfile所在文件夹的路径. Docker-Compose将会利用Dockerfile自动构建镜像，然后使用镜像启动服务容器.build: /path/to/build/dir也可以是相对路径，只要上下文确定就可以读取到Dockerfile:build: ./dir设定上下文根目录，然后以该目录为准指定Dockerfile:build: context: ../ dockerfile: path/of/Dockerfilebuild 都是一个目录，如果要指定Dockerfile文件需要在build标签的子级标签中使用dockerfile标签指定. 如果同时指定image和build两个标签，那么Docker-Compose 会构建镜像并且把镜像命名为image值指定的名字.3.3. contextcontext 选项可以是 Dockerfile 的文件路径，也可以是到链接到git仓库的url，当提供的值是相对路径时，被解析为相对于撰写文件的路径，此目录也是发送到Docker守护进程的context.build: context: ./dir3.4. dockerfile使用dockerfile文件来构建，必须指定构建路径:build: context: . dockerfile: Dockerfile-alternate3.5. commond使用command可以覆盖容器启动后默认执行的命令:command: bundle exec thin -p 30003.6. container_nameDocker-Compose的容器名称格式是：<项目名称><服务名称><序号>可以自定义项目名称、服务名称，但如果想完全控制容器的命名，可以使用标签指定：container_name: app3.7. depends_on在使用Docker-Compose时，最大的好处就是少打启动命令，但一般项目容器启动的顺序是有要求的，如果直接从上到下启动容器，必然会因为容器依赖问题而启动失败. 例如，在没启动数据库容器的时候启动应用容器，应用容器会因为找不到数据库而退出. depends_on 标签用于解决容器的依赖、启动先后的问题version: '2' services: web: build: . depends_on: - db - redis redis: image: redis db: image: postgres上述YAML文件定义的容器会先启动redis和db两个服务，最后才启动web 服务.3.8. PIDpid: "host"将PID模式设置为主机PID模式，跟主机系统共享进程命名空间. 容器使用pid标签将能够访问和操纵其他容器和宿主机的名称空间.3.9. portsports用于映射端口的标签. 使用 HOST:CONTAINER 格式或者只是指定容器的端口，宿主机会随机映射端口.ports: - "3000" - "8000:8000" - "49100:22" - "127.0.0.1:8001:8001"当使用 HOST:CONTAINER 格式来映射端口时，如果使用的容器端口小于60可能会得到错误得结果，因为YAML将会解析xx:yy这种数字格式为60进制. 所以建议采用字符串格式.3.10. extra_hosts添加主机名的标签，会在/etc/hosts文件中添加一些记录，extra_hosts: - "somehost:162.242.195.82" - "otherhost:50.31.209.229"启动后查看容器内部hosts：162.242.195.82 somehost 50.31.209.229 otherhost3.11. volumes挂载一个目录或者一个已存在的数据卷容器，可以直接使用 [HOST:CONTAINER] 格式，或者使用[HOST:CONTAINER:ro] 格式，后者对于容器来说，数据卷是只读的，可以有效保护宿主机的文件系统. Docker-Compose 的数据卷指定路径可以是相对路径，使用 . 或者 .. 来指定相对目录. 数据卷的格式可以是下面多种形式:volumes: // 只是指定一个路径，Docker 会自动在创建一个数据卷(这个路径是容器内部的). - /var/lib/mysql // 使用绝对路径挂载数据卷 - /opt/data:/var/lib/mysql // 以 Compose 配置文件为中心的相对路径作为数据卷挂载到容器. - ./cache:/tmp/cache // 使用用户的相对路径(~/ 表示的目录是 /home/<用户目录>/ 或者 /root/). - ~/configs:/etc/configs/:ro // 已经存在的命名的数据卷. - datavolume:/var/lib/mysql如果不使用宿主机的路径，可以指定一个volume_driver:volume_driver: mydriver3.12. volumes_from从另一个服务或容器挂载其数据卷：volumes_from: - service_name - container_name3.13. dns自定义DNS服务器. 可以是一个值，也可以是一个列表:dns：8.8.8.8 dns： - 8.8.8.8 - 9.9.9.93.14. expose暴露端口，但不映射到宿主机，只允许能被连接的服务访问. 仅可以指定内部端口为参数，如下所示：expose: - "3000" - "8000"3.15. links链接到其它服务中的容器. 使用服务名称(同时作为别名)，或者“服务名称:服务别名”(如 SERVICE:ALIAS)，例如：links: - db - db:database - redis3.16. net设置网络模式:net: "bridge" net: "none" net: "host"3.17. tmpfs挂载临时目录到容器内部，与 run 的参数一样效果：tmpfs: /run tmpfs: - /run - /tmp3.18. entrypoint在 Dockerfile 中有一个指令叫做 ENTRYPOINT 指令，用于指定接入点.在 docker-compose.yml 中可以定义接入点，覆盖 Dockerfile 中的定义：entrypoint: /code/entrypoint.sh格式和 Docker 类似，不过还可以写成这样：entrypoint: - php - -d - zend_extension=/usr/local/lib/php/extensions/no-debug-non-zts-20100525/xdebug.so - -d - memory_limit=-1 - vendor/bin/phpunit3.19. env_file.env 文件可以设置 Docker-Compose 的变量.在 docker-compose.yml 中可以定义一个专门存放变量的文件.如果通过 docker-compose -f FILE 指定了配置文件，则 env_file 中路径会使用配置文件路径. 如果有变量名称与 environment 指令冲突，则以后者为准. 格式如下：env_file: .env或者根据 docker-compose.yml 设置多个：env_file: - ./common.env - ./apps/web.env - /opt/secrets.env注意的是这里所说的环境变量是对宿主机的 Docker-Compose 而言的，如果在配置文件中有 build 操作，这些变量并不会进入构建过程中，如果要在构建中使用变量还是首选前面刚讲的 arg 标签.3.20. environmentenvironment 和 Dockerfile 中的 ENV 指令一样会把变量一直保存在镜像、容器中，类似 docker run -e 的效果.environment: RACK_ENV: development SHOW: 'true' SESSION_SECRET: environment: - RACK_ENV=development - SHOW=true - SESSION_SECRET3.21. logging用于配置日志服务. 格式如:logging: driver: syslog options: syslog-address: "tcp://192.168.0.42:123"默认的driver是 json-file. 只有json-file和journald可以通过docker-compose logs显示日志.4. Docker-Compose 模版文件示例4.1. 示例一 - 指定多个web服务version: '2' services: web1: image: nginx ports: - "6061:80" container_name: "web1" networks: - dev web2: image: nginx ports: - "6062:80" container_name: "web2" networks: - dev - pro web3: image: nginx ports: - "6063:80" container_name: "web3" networks: - pro networks: dev: driver: bridge pro: driver: bridgedocker-compose.yaml 指定了 3 个Web 服务.创建一个webapp目录，将docker-compose.yaml文件拷贝到webapp目录下，使用docker-compose启动应用:docker-compose up -d通过浏览器访问web1，web2，web3:http://127.0.0.1:6061 http://127.0.0.1:6062 http://127.0.0.1:60634.2. 示例二 - django-elasticsearchFrom: https://github.com/aymaneMx/django-elasticsearch/blob/master/docker-compose.ymlversion: '3.7' services: es: image: elasticsearch:7.8.1 environment: - discovery.type=single-node ports: - "9200:9200" db: image: "postgres:11" environment: - "POSTGRES_HOST_AUTH_METHOD=trust" volumes: - postgres_data:/var/lib/postgresql/data/ web: build: . command: python /code/manage.py runserver 0.0.0.0:8000 volumes: - .:/code ports: - 8000:8000 env_file: - docker-compose.env depends_on: - db - es volumes: postgres_data:启动：docker-compose up -d --build参考[1] - Docker Compose 配置文件详解 - 2017.01.19[2] - Docker入门之docker-compose[3] - Docker Compose - 菜鸟教程
通过docker logs命令可以查看容器的日志.docker logs 是跟随容器而产生的，如果删除了某个容器，相应的日志文件也会随着被删除docker logs [OPTIONS] CONTAINER参数说明：Options: --details 显示更多的信息 -f, --follow 跟踪实时日志 --since string 显示自某个timestamp之后的日志，或相对时间，如42m（即42分钟） --tail string 从日志末尾显示多少行日志， 默认是all -t, --timestamps 显示时间戳 --until string 显示自某个timestamp之前的日志，或相对时间，如42m（即42分钟）示例如下.1. 查看指定时间之后的日志docker logs -t --since="2021-03-08T13:23:37" CONTAINER_ID2. 查看指定时间后的日志且只显示最后100行docker logs -f -t --since="2021-03-08" --tail=100 CONTAINER_ID3. 查看最近 30 分钟的日志docker logs --since 30m CONTAINER_ID4. 查看指定时间段的日志docker logs -t --since="2021-03-05T09:00:00" --until "2021-03-08T12:23:37" CONTAINER_ID5. docker logs的实现原理容器日志的输出形式stdout 标准输出stderr 标准错误以json格式存放在容器对于到日志文件中docker日志内容类型docker自身运行时Daemon的日志内容docker容器的日志内容docker logs的实现原理“Docker Daemon是Docker架构中一个常驻在后台的系统进程，它在后台启动了一个Server，Server负责接受Docker Client发送的请求；接受请求后，Server通过路由与分发调度，找到相应的Handler来执行请求. –《Docker源码分析》”当输入docker logs的时候会转化为Docker Client向Docker Daemon发起请求,Docker Daemon 在运行容器时会去创建一个协程(goroutine)，绑定了整个容器内所有进程的标准输出文件描述符. 因此容器内应用的所有只要是标准输出日志，都会被 goroutine 接收，Docker Daemon会根据容器id和日志类型读取日志内容，最终会输出到用户终端上并且通过json格式存放在/var/lib/docker/containers目录下.
Github - tensorflow/servinghttps://github.com/tensorflow/serving/tree/master/tensorflow_serving/g3doc1. TF Serving 示例#拉取镜像 # docker docker pull tensorflow/serving # nvidia-docker docker pull tensorflow/serving:latest-gpu # git clone https://github.com/tensorflow/serving # Location of demo models TESTDATA="$(pwd)/serving/tensorflow_serving/servables/tensorflow/testdata" # Start TensorFlow Serving container and open the REST API port docker run -t --rm -p 8501:8501 \ -v "$TESTDATA/saved_model_half_plus_two_cpu:/models/half_plus_two" \ -e MODEL_NAME=half_plus_two \ tensorflow/serving & # Query the model using the predict API curl -d '{"instances": [1.0, 2.0, 5.0]}' \ -X POST http://localhost:8501/v1/models/half_plus_two:predict # Returns => { "predictions": [2.5, 3.0, 4.5] }2. TF Serving 参数TF Serving 运行示例：docker run -p 8501:8501 \ --mount type=bind,source=/path/to/local/saved_model/,target=/models/model_name \ -t tensorflow/serving \ -e MODEL_NAME=model_name --model_base_path=/models/model_name/ --per_process_gpu_memory_fraction=0.5 #或 docker run -t --rm -p 8501:8501 \ -v /path/to/local/saved_model/:/models/model_name \ -e MODEL_NAME=test-model tensorflow/serving:1.15.0 &[1] - -p 8501:8501 - 服务端口[2] - -t - 指定镜像[3] - --mount - 挂载路径，其中type=bind是选择挂载模式，注：中间不能有空格. source 是模型在机器中的绝对存储路径，target 是模型容器中存储路径[4] - per_process_gpu_memory_fraction 是设定运行时所需的GPU显存资源最大不允许超过的比率的设定值；[5] - model_name 命名3. 参考[1] - Tensorflow笔记：通过tf.Serving+Docker部署 - 2020.04.14[2] - TensorFlow Serving with Docker
Linux Docker 一键安装脚本：curl -sSL https://get.docker.com/ | shDocker 安装 - Docker 安装与配置 - AIUAI以前汇总的一些 Docker 镜像和容器操作用法：Docker - Image镜像创建及容器操作 - AIUAI1. Docker System 命令[1] - 查看 docker 空间使用情况docker system df如：TYPE TOTAL ACTIVE SIZE RECLAIMABLE Images 38 8 21.89GB 14.96GB (68%) Containers 36 0 2.2GB 2.2GB (100%) Local Volumes 0 0 0B 0B Build Cache 0 0 0B 0B[2] - 查看 docker 实时事件，如容器创建、删除等信息docker system events[3] - 查看 docker 系统信息docker system info #或 docker info[4] - docker 清理，如已停止的容器清理、失效的数据卷和网络、缓存、镜像等，docker system prune # #深度清理 #清理整个系统，且只会保留真正在使用的镜像，容器，数据卷以及网络，需要格外谨慎 #如，不能在生产环境中运行，因为一些备用镜像(用于备份，回滚等)会被删除= docker system prune -a 2. Docker 手工清理Docker(版本 1.13 之前)旧版本没有 docker system 命令，可以进行手动清理，常用的命令有：[1] - 删除所有关闭的容器docker ps -a | grep Exit | cut -d ' ' -f 1 | xargs docker rm[2] - 删除无 tag 的镜像docker rmi $(docker images | grep "^<none>" | awk "{print $3}")[3] - 删除无用的数据卷docker volume rm $(docker volume ls -qf dangling=true)3. Docker 磁盘占用清理Docker 长期运行后，/var/lib/docker 占用较多，df -lh输出如：udev 32G 0 32G 0% /dev tmpfs 6.3G 4.0M 6.3G 1% /run /dev/nvme0n1p2 457G 381G 53G 88% / tmpfs 64G 0 64G 0% /dev/shm tmpfs 5.0M 4.0K 5.0M 1% /run/lock tmpfs 32G 0 32G 0% /sys/fs/cgroup tmpfs 6.3G 24K 6.3G 1% /run/user/121 tmpfs 6.3G 0 6.3G 0% /run/user/1001 overlay 457G 381G 53G 88% /var/lib/docker/overlay2/5a****/merged overlay 457G 381G 53G 88% /var/lib/docker/overlay2/e3****/merged overlay 457G 381G 53G 88% /var/lib/docker/overlay2/87****/merged overlay 457G 381G 53G 88% /var/lib/docker/overlay2/71****/merged overlay 457G 381G 53G 88% /var/lib/docker/overlay2/78****/merged overlay 457G 381G 53G 88% /var/lib/docker/overlay2/595****/merged overlay 457G 381G 53G 88% /var/lib/docker/overlay2/17****/merged overlay 457G 381G 53G 88% /var/lib/docker/overlay2/34****/merged overlay 457G 381G 53G 88% /var/lib/docker/overlay2/fa****/merged overlay 457G 381G 53G 88% /var/lib/docker/overlay2/e0****/merged overlay 457G 381G 53G 88% /var/lib/docker/overlay2/9f****/merged overlay 457G 381G 53G 88% /var/lib/docker/overlay2/68****/merged其中，overlay 分区是 Docker 的虚拟文件系统，其真实的文件系统是 /dev/vda1. 所以要找到是什么原因大量占据了 /dev/vda1.再者，cd /var/lib/docker du -lh --max-depth=1输出如：245G ./overlay2 138G ./containers 96K ./network 72K ./buildkit 20K ./plugins 20K ./builder 28K ./volumes 4.0K ./trust 4.0K ./tmp 4.0K ./runtimes 53M ./image 4.0K ./swarm 383G .一般是两种原因.3.1. 无用镜像和容器太多docker system df -v #清理磁盘，删除关闭的容器、无用的数据卷和网络，以及无tag的镜像 docker system prune #将没有容器使用Docker镜像都删除 docker system prune -a3.2. 容器输出的日志太大容器长时间运行，往往是打印了大量的日志未清理，占据了大量磁盘空间.容器的日志文件在/var/lib/docker/containers/{containerId}下.日志文件中以 -json.log 结尾的即为日志文件. 可以对此进行清理:cd /var/lib/docker/containers/{containerId} cat /dev/null > *-json.log #(建议清理后重启该容器服务)3.3. 日志和大文件等占用一些日志文件，大文件占用了 /dev/vda1 分区. 这个分区一般是挂载在 “/” 下面.可以重点关注下面几个目录：/var/tmp/var/log/root4. Nginx 示例#拉取 nginx 镜像 docker pull nginx #后台启动一个nginx，将服务器的8080端口映射到容器的80端口 docker run -d -p 8080:80 nginx #Docker廋身 #docker system prune #停止Docker服务 systemctl stop docker #创建目标目录 mkdir -p /data/docker/ #同步源目录文件到目标目录 rsync -avz /var/lib/docker/ /data/docker #修改Docker配置文件 vim /etc/docker/daemon.json #修改或者新增内容如下 { "data-root": "/data/docker" } #启动Docker服务 systemctl start docker # 查看是否修改成功 docker info | grep "Docker Root Dir" #输出：Docker Root Dir: /data/docker
由于容器内语言设置等问题，运行 Docker 进入容器内后，容器内命令行无法输入中文. 解决办法，进入容器时指定 env LANG=C.UTF-8 ，如：sudo docker exec -it container_id env LANG=C.UTF-8 /bin/bash
Ubuntu 系统使用 Docker 时，采用了默认的镜像存储路径，即：/var/lib/docker. 由于系统分区不够，在镜像较大或较多时，会导致存储空间不足的问题，导致无法正常使用系统.因此，需要更改 Docker 镜像的存储目录到新的硬盘分区.[1] - 查看 Docker 默认的存储路径：sudo docker info | grep "Docker Root Dir" # Docker Root Dir: /var/lib/docker[2] - 备份已有镜像：docker save -o filename.tar image_name[3] - 以软连接的方式更改 Docker 镜像存储路径：# 停止 docker sudo service docker stop # 移动到新路径 sudo mv /var/lib/docker /data/var/lib/ # 创建软连接 sudo ln -s /data/var/lib/docker /var/lib/docker # 启动 docker sudo service docker start [4] - 以修改配置文件的方式更爱 docker 的默认镜像存储路径：# 停止 docker sudo service docker stop # 编辑文件 docker-overlay.conf cd /etc/systemd/system/docker.service.d # 如果没有docker.service.d 则创建该路径 sudo vim docker-overlay.conf # 如果没有则创建该文件 # 在文件中添加如下内容： # [Service] # ExecStart= # ExecStart=/usr/bin/dockerd --graph="新的存储路径" --storage-driver=overlay # 启动 docker sudo service docker start