标签:osi group aliyun 对象 创建 mirror 编译 控制 系统
Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从 Apache2.0 协议开源。
Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。
容器是完全使用沙箱机制,相互之间不会有任何接口(类似 iPhone 的 app),更重要的是容器性能开销极低。
Docker 是一个用于开发,交付和运行应用程序的开放平台。Docker 使您能够将应用程序与基础架构分开,从而可以快速交付软件。借助 Docker,您可以与管理应用程序相同的方式来管理基础架构。通过利用 Docker 的方法来快速交付,测试和部署代码,您可以大大减少编写代码和在生产环境中运行代码之间的延迟。
参考:https://www.runoob.com/docker/docker-tutorial.html
Docker 包括三个基本概念:
Docker 使用客户端-服务器 (C/S) 架构模式,使用远程API来管理和创建Docker容器。
Docker 容器通过 Docker 镜像来创建。
容器与镜像的关系类似于面向对象编程中的对象与类。
概念 | 说明 |
---|---|
Docker 镜像(Images) | Docker 镜像是用于创建 Docker 容器的模板,比如 Ubuntu 系统。 |
Docker 容器(Container) | 容器是独立运行的一个或一组应用,是镜像运行时的实体。 |
Docker 客户端(Client) | Docker 客户端通过命令行或者其他工具使用 Docker SDK (https://docs.docker.com/develop/sdk/) 与 Docker 的守护进程通信。 |
Docker 主机(Host) | 一个物理或者虚拟的机器用于执行 Docker 守护进程和容器。 |
Docker Registry | Docker 仓库用来保存镜像,可以理解为代码控制中的代码仓库。Docker Hub(https://hub.docker.com) 提供了庞大的镜像集合供使用。一个 Docker Registry 中可以包含多个仓库(Repository);每个仓库可以包含多个标签(Tag);每个标签对应一个镜像。通常,一个仓库会包含同一个软件不同版本的镜像,而标签就常用于对应该软件的各个版本。我们可以通过 <仓库名>:<标签> 的格式来指定具体是这个软件哪个版本的镜像。如果不给出标签,将以 latest 作为默认标签。 |
Docker Machine | Docker Machine是一个简化Docker安装的命令行工具,通过一个简单的命令行即可在相应的平台上安装Docker,比如VirtualBox、 Digital Ocean、Microsoft Azure。 |
参考:https://www.runoob.com/docker/docker-architecture.html
Docker 允许你在容器内运行应用程序, 使用 docker run 命令来在容器内运行一个应用程序。
docker run ubuntu:15.10 /bin/echo "Hello world"
参数解析:
可以理解为:Docker 以 ubuntu15.10 镜像创建一个新容器,然后在容器里执行 bin/echo "Hello world",然后输出结果。
docker run -i -t ubuntu:15.10 /bin/bash
执行此命令进入ubuntu15.10 系统的容器,运行命令 cat /proc/version和ls分别查看当前系统的版本信息和当前目录下的文件列表
退出容器:执行命令 exit
或使用 CTRL+D
命令创建一个以进程方式运行的容器
docker run -d ubuntu:15.10 /bin/sh -c "while true; do echo hello world; sleep 1; done"
输出:b0167279f8ff41e66df71bae4f4731bed1108191b80d31c12e76c7e89b401abc
这个长字符串叫做容器 ID,对每个容器来说都是唯一的
通过 docker ps 来查看容器是否有在运行
输出详情介绍:
CONTAINER ID: 容器 ID。
IMAGE: 使用的镜像。
COMMAND: 启动容器时运行的命令。
CREATED: 容器的创建时间。
STATUS: 容器状态。
状态有7种:
PORTS: 容器的端口信息和使用的连接类型(tcp\udp)。
NAMES: 自动分配的容器名称。
在宿主主机内使用 docker logs 命令,查看容器内的标准输出:
docker logs b0167279f8ff
或者使用自动分配的容器名称
docker logs kind_volhard
使用 docker stop 命令来停止容器
docker stop b0167279f8ff
或
docker logs kind_volhard
通过 docker ps 查看,容器已经停止工作
查看到 Docker 客户端的所有命令选项
docker
更深入的了解指定的 Docker 命令使用方法
docker command --help
如果我们本地没有 ubuntu 镜像,使用 docker pull 命令来载入 ubuntu 镜像
docker pull ubuntu
使用 ubuntu 镜像启动一个容器,参数为以命令行模式进入该容器
docker run -it ubuntu /bin/bash
参数说明:
退出终端: exit
查看所有的容器命令
docker ps -a
使用 docker start 启动一个已停止的容器
docker start 433aadf0cb0f
在大部分的场景下,我们希望 docker 的服务是在后台运行的,我们可以过 -d 指定容器的运行模式。
docker run -itd --name ubuntu-test ubuntu /bin/bash
停止容器
docker stop <容器 ID>
重启容器
docker restart <容器 ID>
进入容器
在使用 -d 参数时,容器启动后会进入后台。此时想要进入容器,可以通过以下指令进入:
示例:
docker attach <容器ID>
exec
docker exec -it 243c32535da7 /bin/bash
注意: 如果使用exec从这个容器退出,不会导致容器的停止
导出容器
如果要导出本地某个容器,可以使用 docker export 命令。
docker export 243c32535da7 > ubuntu.tar
导出容器 1e560fca3906 快照到本地文件 ubuntu.tar
导入容器
可以使用 docker import 从容器快照文件中再导入为镜像,以下实例将快照文件 ubuntu.tar 导入到镜像 test/ubuntu:v1:
docker import ./ubuntu.tar test/ubuntu:v1
也可以通过指定 URL 或者某个目录来导入
docker import http://example.com/exampleimage.tgz example/imagerepo
删除容器使用 docker rm 命令:
docker rm -f 243c32535da7
清理掉所有处于终止状态的容器
docker container prune
尝试使用 docker 构建一个 web 应用程序。
我们将在docker容器中运行一个 Python Flask 应用来运行一个web应用。
docker pull training/webapp # 载入镜像
docker run -d -P training/webapp python app.py
使用 docker ps 来查看正在运行的容器:
PORTS
0.0.0.0:32769->5000/tcp
Docker 开放了 5000 端口(默认 Python Flask 端口)映射到主机端口 32769 上
也可以通过 -p 参数来设置不一样的端口:
docker run -d -p 5000:5000 training/webapp python app.py
容器内部的 5000 端口映射到我们本地主机的 5000 端口上。
使用 docker port 也可以查看指定 (ID 或者名字)容器的某个确定端口映射到宿主机的端口号。
docker port <容器ID或名字>
查看 WEB 应用程序日志
docker logs [ID或者名字]
可以查看容器内部的标准输出。
查看WEB应用程序容器的进程
docker top [ID或者名字]
检查 WEB 应用程序
docker inspect [ID或者名字]
查看 Docker 的底层信息。它会返回一个 JSON 文件记录着 Docker 容器的配置和状态信息。
停止 WEB 应用容器
docker stop [ID或者名字]
重启WEB应用容器
已经停止的容器,我们可以使用命令 docker start 来启动。
docker start [ID或者名字]
正在运行的容器,我们可以使用 docker restart
命令来重启。
移除WEB应用容器
docker rm [ID或者名字]
注意:删除容器时,容器必须是停止状态,否则会报错
当运行容器时,使用的镜像如果在本地中不存在,docker 就会自动从 docker 镜像仓库中下载,默认是从 Docker Hub 公共镜像源下载。
列出本地所有镜像
docker images
输出选项说明:
说明:同一仓库源可以有多个 TAG,代表这个仓库源的不同个版本,如 ubuntu 仓库源里,有 15.10、14.04 等多个不同的版本
如果要使用版本为15.10的ubuntu系统镜像来运行容器时,命令如下:
docker run -t -i ubuntu:15.10 /bin/bash
如果不指定一个镜像的版本标签,例如只使用 ubuntu,docker 将默认使用 ubuntu:latest 镜像。
手动获取一个新的镜像
docker pull ubuntu:15.10
docker search
搜索例如:查找httpd
docker search httpd
搜索结果参数说明:
docker rmi hello-world
删除 hello-world 镜像
当我们从 docker 镜像仓库中下载的镜像不能满足我们的需求时,我们可以通过以下两种方式对镜像进行更改。
更新镜像之前,我们需要使用镜像来创建一个容器
docker run -t -i ubuntu:15.10 /bin/bash
在运行的容器内使用 apt-get update 命令进行更新。
在完成操作之后,输入 exit 命令来退出这个容器。
此时的容器,是按我们的需求更改的容器。我们可以通过命令 docker commit 来提交容器副本
docker commit -m="has update" -a="royal" f76893e0cced demo/ubuntu:v2
各个参数说明:
可以使用 docker images 命令来查看我们的新镜像
使用我们的新镜像来启动一个容器
docker run -t -i runoob/ubuntu:v2 /bin/bash
我们使用命令 docker build , 从零开始来创建一个新的镜像。为此,我们需要创建一个 Dockerfile 文件,其中包含一组指令来告诉 Docker 如何构建我们的镜像。
FROM centos:6.7
MAINTAINER Fisher "fisher@sudops.com"
RUN /bin/echo ‘root:123456‘ |chpasswd
EXPOSE 22
EXPOSE 80
CMD /usr/sbin/sshd -D
每一个指令都会在镜像上创建一个新的层,每一个指令的前缀都必须是大写的。
第一条FROM,指定使用哪个镜像源
RUN 指令告诉docker 在镜像内执行命令,安装了什么。。。
然后,我们使用 Dockerfile 文件,通过 docker build 命令来构建一个镜像。
docker build -t demo/centos:6.7 .
使用docker images 查看创建的镜像已经在列表中存在
设置镜像标签
docker tag c9e39a58ab62 demo/centos:dev
docker tag 镜像ID,用户名称、镜像源名(repository name)和新的标签名(tag)。
使用 docker images 命令可以看到,ID为c9e39a58ab62的镜像多一个标签
前面实现了通过网络端口来访问运行在 docker 容器内的服务。
容器中可以运行一些网络应用,要让外部也可以访问这些应用,可以通过 -P 或 -p 参数来指定端口映射。
创建一个 python 应用的容器
docker run -d -P training/webapp python app.py
如:
docker run -d -p 5000:5000 training/webapp python app.py
指定容器绑定的网络地址,比如绑定 127.0.0.1
docker run -d -p 127.0.0.1:5001:5000 training/webapp python app.py
docker port 命令可以让我们快捷地查看端口的绑定情况
端口映射并不是唯一把 docker 连接到另一个容器的方法
docker 有一个连接系统允许将多个容器连接在一起,共享连接信息
docker 连接会创建一个父子关系,其中父容器可以看到子容器的信息
当创建一个容器的时候,docker 会自动对它进行命名。另外,我们也可以使用 --name 标识来命名容器,例如:
docker run -d -P --name demoWeb training/webapp python app.py
使用 docker ps 命令来查看容器名称
docker network create -d bridge test-net
参数说明:
-d:参数指定 Docker 网络类型,有 bridge、overlay。其中 overlay 网络类型用于 Swarm mode
运行一个容器并连接到新建的 test-net 网络
docker run -itd --name test1 --network test-net ubuntu /bin/bash
打开新的终端,再运行一个容器并加入到 test-net 网络:
docker run -itd --name test2 --network test-net ubuntu /bin/bash
通过 ping 来证明 test1 容器和 test2 容器建立了互联关系
注:如果 test1、test2 容器内中无 ping 命令,则在容器内执行以下命令安装 ping(可以在一个容器里安装好,提交容器到镜像,在以新的镜像重新运行以上俩个容器)
apt-get update
apt install iputils-ping
这样,test1 容器和 test2 容器建立了互联关系,如果有多个容器之间需要互相连接,推荐使用 Docker Compose
可以在宿主机的 daemon.json 文件中增加以下内容来设置全部容器的 DNS:
{
"dns" : [
"114.114.114.114",
"8.8.8.8"
]
}
设置后重启 docker,启动容器的 DNS 会自动配置为 114.114.114.114 和 8.8.8.8。
查看容器的 DNS 是否生效可以使用以下命令,它会输出容器的 DNS 信息:
docker run -it --rm ubuntu cat etc/resolv.conf
手动指定容器的配置
docker run -it --rm host_ubuntu --dns=114.114.114.114 --dns-search=test.com ubuntu
参数说明:
-h HOSTNAME 或者 --hostname=HOSTNAME: 设定容器的主机名,它会被写到容器内的 /etc/hostname 和 /etc/hosts。
--dns=IP_ADDRESS: 添加 DNS 服务器到容器的 /etc/resolv.conf 中,让容器用这个服务器来解析所有不在 /etc/hosts 中的主机名。
--dns-search=DOMAIN: 设定容器的搜索域,当设定搜索域为 .example.com 时,在搜索一个名为 host 的主机时,DNS 不仅搜索 host,还会搜索 host.example.com
如果没有指定 --dns 和 --dns-search,Docker 会默认用宿主主机上的 /etc/resolv.conf 来配置容器的 DNS
仓库(Repository)是集中存放镜像的地方。以下 Docker Hub,只是远程的服务商不一样,操作都是一样的
目前 Docker 官方维护了一个公共仓库 Docker Hub
大部分需求都可以通过在 Docker Hub 中直接下载镜像来实现
在 https://hub.docker.com 免费注册一个 Docker 账号
登录需要输入用户名和密码,登录成功后,我们就可以从 docker hub 上拉取自己账号下的全部镜像
docker login
退出
docker logout
拉取镜像:你可以通过 docker search 命令来查找官方仓库中的镜像,并利用 docker pull 命令来将它下载到本地
docker tag ubuntu:18.04 username/ubuntu:18.04 #添加标签
docker push username/ubuntu:18.04 #推送镜像
推送成功可以使用docker search查找
Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。
下面以定制一个 nginx 镜像(构建好的镜像内会有一个 /usr/share/nginx/html/index.html 文件)
在一个空目录下,新建一个名为 Dockerfile 文件,并在文件内添加以下内容:
FROM nginx
RUN echo ‘这是一个本地构建的nginx镜像‘ > /usr/share/nginx/html/index.html
FROM:定制的镜像都是基于 FROM 的镜像,这里的 nginx 就是定制需要的基础镜像。后续的操作都是基于 nginx。
RUN:用于执行后面跟着的命令行命令。有以下俩种格式:
shell 格式:
RUN <命令行命令>
# <命令行命令> 等同于,在终端操作的 shell 命令。
exec 格式:
RUN ["可执行文件", "参数1", "参数2"]
# 例如:
# RUN ["./test.php", "dev", "offline"] 等价于 RUN ./test.php dev offline
注意:Dockerfile 的指令每执行一次都会在 docker 上新建一层。所以过多无意义的层,会造成镜像膨胀过大。例如:
FROM centos
RUN yum install wget
RUN wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz"
RUN tar -xvf redis.tar.gz
#以上执行会创建 3 层镜像。可简化为以下格式:
FROM centos
RUN yum install wget && wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz" && tar -xvf redis.tar.gz
以 && 符号连接命令,这样执行后,只会创建 1 层镜像
在 Dockerfile 文件的存放目录下,执行构建动作
以下示例,通过目录下的 Dockerfile 构建一个 nginx:test(镜像名称:镜像标签)
docker build -t nginx:test .
上面指令最后一个 . 是上下文路径
docker build -t nginx:test .
上下文路径,是指 docker 在构建镜像,有时候想要使用到本机的文件(比如复制),docker build 命令得知这个路径后,会将路径下的所有内容打包
如果未说明最后一个参数,那么默认上下文路径就是 Dockerfile 所在的位置
注意:上下文路径下不要放无用的文件,因为会一起打包发送给 docker 引擎,如果文件过多会造成过程缓慢
复制指令,从上下文目录中复制文件或者目录到容器里指定路径,格式:
COPY [--chown=<user>:<group>] <源路径1>... <目标路径>
COPY [--chown=<user>:<group>] ["<源路径1>",... "<目标路径>"]
[--chown=<user>:<group>]:可选参数,用户改变复制到容器内文件的拥有者和属组
<源路径>:源文件或者源目录,这里可以是通配符表达式,其通配符规则要满足 Go 的 filepath.Match 规则。例如:
COPY hom* /mydir/
COPY hom?.txt /mydir/
<目标路径>:容器内的指定路径,该路径不用事先建好,路径不存在的话,会自动创建
ADD 指令和 COPY 的使用格式一致(同样需求下,官方推荐使用 COPY)。功能也类似,不同之处如下:
类似于 RUN 指令,用于运行程序,但二者运行的时间点不同:
作用:为启动的容器指定默认要运行的程序,程序运行结束,容器也就结束。CMD 指令指定的程序可被 docker run 命令行参数中指定要运行的程序所覆盖。
注意:如果 Dockerfile 中如果存在多个 CMD 指令,仅最后一个生效。
格式:
CMD <shell 命令>
#例如
CMD ["<可执行文件或命令>","<param1>","<param2>",...]
CMD ["<param1>","<param2>",...] # 该写法是为 ENTRYPOINT 指令指定的程序提供默认参数
推荐使用第二种格式,执行过程比较明确。第一种格式实际上在运行的过程中也会自动转换成第二种格式运行,并且默认可执行文件是 sh
类似于 CMD 指令,但其不会被 docker run 的命令行参数指定的指令所覆盖,而且这些命令行参数会被当作参数送给 ENTRYPOINT 指令指定的程序。
但是, 如果运行 docker run 时使用了 --entrypoint 选项,此选项的参数可当作要运行的程序覆盖 ENTRYPOINT 指令指定的程序。
优点:在执行 docker run 的时候可以指定 ENTRYPOINT 运行所需的参数。
注意:如果 Dockerfile 中如果存在多个 ENTRYPOINT 指令,仅最后一个生效。
格式:
ENTRYPOINT ["<executeable>","<param1>","<param2>",...]
可以搭配 CMD 命令使用:一般是变参才会使用 CMD ,这里的 CMD 等于是在给 ENTRYPOINT 传参
例如:
假设已通过 Dockerfile 构建了 nginx:test 镜像
FROM nginx
ENTRYPOINT ["nginx", "-c"] # 定参
CMD ["/etc/nginx/nginx.conf"] # 变参
1、不传参运行
docker run nginx:test
容器内会默认运行以下命令,启动主进程
nginx -c /etc/nginx/nginx.conf
2、传参运行
docker run nginx:test -c /etc/nginx/new.conf
运行任务:
nginx -c /etc/nginx/new.conf
设置环境变量,定义了环境变量,那么在后续的指令中,就可以使用这个环境变量
格式:
ENV <key> <value>
ENV <key1>=<value1> <key2>=<value2>...
在后续的指令中可以通过 $key 的方式应用,例如:
ENV NODE_VERSION 7.2.0
RUN curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION-linux-x64.tar.xz" && curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/SHASUMS256.txt.asc"
定义匿名数据卷。在启动容器时忘记挂载数据卷,会自动挂载到匿名卷。
作用:
格式:
VOLUME ["<路径1>", "<路径2>"...]
VOLUME <路径>
在启动容器 docker run 的时候,我们可以通过 -v 参数修改挂载点
仅仅只是声明端口。
作用:
格式:
EXPOSE <端口1> [<端口2>...]
指定工作目录。用 WORKDIR 指定的工作目录,会在构建镜像的每一层中都存在。(WORKDIR 指定的工作目录,必须是提前创建好的)。
docker build 构建镜像过程中的,每一个 RUN 命令都是新建的一层。只有通过 WORKDIR 创建的目录才会一直存在。
格式:
WORKDIR <工作目录路径>
用于指定执行后续命令的用户和用户组,这边只是切换后续命令执行的用户(用户和用户组必须提前已经存在)。
格式:
USER <用户名>[:<用户组>]
用于指定某个程序或者指令来监控 docker 容器服务的运行状态。
格式:
HEALTHCHECK [选项] CMD <命令>:设置检查容器健康状况的命令
HEALTHCHECK NONE:如果基础镜像有健康检查指令,使用这行可以屏蔽掉其健康检查指令
HEALTHCHECK [选项] CMD <命令> : 这边 CMD 后面跟随的命令使用,可以参考 CMD 的用法。
用于延迟构建命令的执行。简单的说,就是 Dockerfile 里用 ONBUILD 指定的命令,在本次构建镜像的过程中不会执行(假设镜像为 test-build)。当有新的 Dockerfile 使用了之前构建的镜像 FROM test-build ,这是执行新镜像的 Dockerfile 构建时候,会执行 test-build 的 Dockerfile 里的 ONBUILD 指定的命令。
格式:
ONBUILD <其它指令>
Compose 是用于定义和运行多容器 Docker 应用程序的工具。通过 Compose,您可以使用 YML 文件来配置应用程序需要的所有服务。然后,使用一个命令,就可以从 YML 文件配置中创建并启动所有服务
Compose 使用的三个步骤:
docker-compose.yml 的配置案例如下:
# yaml 配置实例
version: ‘3‘
services:
web:
build: .
ports:
- "5000:5000"
volumes:
- .:/code
- logvolume01:/var/log
links:
- redis
redis:
image: redis
volumes:
logvolume01: {}
Linux
Linux 上我们可以从 Github 上下载它的二进制包来使用,最新发行的版本地址:https://github.com/docker/compose/releases。
运行以下命令以下载 Docker Compose 的当前稳定版本:
sudo curl -L "https://github.com/docker/compose/releases/download/1.26.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
将可执行权限应用于二进制文件:
sudo chmod +x /usr/local/bin/docker-compose
创建软链:
sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
测试是否安装成功:
docker-compose --version
cker-compose version 1.24.1, build 4667896b
windows
Windows 的 Docker 桌面版和 Docker Toolbox 已经包括 Compose 和其他 Docker 应用程序
1、准备
创建一个测试目录:
mkdir composetest
cd 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)
redis 是应用程序网络上的 redis 容器的主机名,该主机使用的端口为 6379
在 composetest 目录中创建另一个名为 requirements.txt 的文件,内容如下:
flask
redis
2、创建 Dockerfile 文件
在 composetest 目录中,创建一个名为的文件 Dockerfile,内容如下:
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
COPY . .
CMD ["flask", "run"]
Dockerfile 内容解释:
FROM python:3.7-alpine:从 Python 3.7 映像开始构建镜像
WORKDIR /code:将工作目录设置为 /code
ENV FLASK_APP app.py
ENV FLASK_RUN_HOST 0.0.0.0
设置 flask 命令使用的环境变量
RUN apk add --no-cache gcc musl-dev linux-headers:安装 gcc,以便诸如 MarkupSafe 和 SQLAlchemy 之类的 Python 包可以编译加速。
COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt
复制 requirements.txt 并安装 Python 依赖项。
COPY . .:将 . 项目中的当前目录复制到 . 镜像中的工作目录。
CMD ["flask", "run"]:容器提供默认的执行命令为:flask run
3、创建 docker-compose.yml
在测试目录中创建一个名为 docker-compose.yml 的文件,然后粘贴以下内容:
# yaml 配置
version: ‘3‘
services:
web:
build: .
ports:
- "5000:5000"
redis:
image: "redis:alpine"
该 Compose 文件定义了两个服务:web 和 redis
4、使用 Compose 命令构建和运行您的应用
在测试目录中,执行以下命令来启动应用程序:
docker-compose up
如果你想在后台执行该服务可以加上 -d 参数:
docker-compose up -d
https://www.cnblogs.com/royal6/p/13053996.html
标签:osi group aliyun 对象 创建 mirror 编译 控制 系统
原文地址:https://www.cnblogs.com/royal6/p/13054030.html