文章目录
选择基础镜像,docker当前要生成的镜像以哪个镜像为基础。
FROM java
容器 构建时 需要运行的命令(区别于后面的CMD)
有两种格式:
RUN commond
构如:建时,打印hello world
RUN echo "Hello World !"
RUN ["executable", "param1", "param2"]
RUN ["echo","Hello world !"]
容器启动之后要运行的命令
注意 CMD一个文件中只能有一条指令Dockerfile。如果您列出多个,CMD 则只有最后一个会生效。
三种格式:
CMD echo "Hello World !"
CMD ["executable", "param1", "param2"]
CMD ["echo","Hello world !"]
ENTRYPOINT 的参数使用若 变量 ENTRYPOINT 存在,CMD将作为参数进行传递,而不是执行。
容器启动之后要运行的命令,同上述CMD ,同样若有多个参数,只有最后一个参数生效。
也是两种形式:
ENTRYPOINT ["executable", "param1", "param2"]
ENTRYPOINT command param1 param2
1、docker至少指定一个CMD 或者 ENTRYPOINT命令
2、CMD 在运行时会被参数覆盖
不同格式下CMD与ENTRYPOINT的关系:
| 没有ENTRYPOINT | ENTRYPOINT nginx -c | ENTRYPOINT [“nginx”,“-c”] | |
|---|---|---|---|
| 没有CMD | 报错,至少存在一个 | /bin/bash -c nginx -c | nginx -c |
| CMD [“nginx.conf”] | nginx.conf | /bin/bash -c nginx -c nginx.conf | nginx -c nginx.conf |
| CMD nginx.conf | /bin/bash -c nginx.conf | /bin/bash -c nginx -c nginx.conf | nginx -c /bin/bash -c nginx.conf |
所以若指定nginx配置文件应该使用 ENTRYPOINT ["nginx","-c"]和 CMD ["nginx.conf"],并且CMD命令可被替换,所以通常用这种格式。
标签 键值对的形式
LABEL <key>=<value> <key>=<value> <key>=<value> ...
如 打上作者标签
LABLE author = '杀生丸'
若要引用变量请使用双引号,单引号会直接解析成字符串输出
LABLE author = "xxx-${author}"
LABLE替换了 MAINTAINER 的使用
MAINTAINER <name>
对外暴露的端口
EXPOSE <port> [<port>/<protocol>...]
将主机的文件复制到镜像中,如仅限本地的 tar 提取和远程 URL 支持
ADD [--chown=<user>:<group>] [--checksum=<checksum>] <src>... <dest>
ADD [--chown=<user>:<group>] ["<src>",... "<dest>"]
将home开头的所有文件复制到mydir文件夹下
ADD hom* /mydir/
同ADD,复制文件,只能从主机复制文件到镜像中。
COPY [--chown=<user>:<group>] [--checksum=<checksum>] <src>... <dest>
COPY [--chown=<user>:<group>] ["<src>",... "<dest>"]
将home开头的所有文件复制到mydir文件夹下
COPY hom* /mydir/
容器卷,也就是挂在数据,用于数据保存和持久化工作
VOLUME ["/data"]
指定该镜像以什么样的用户去执行,如果都不指定,默认是root
工作目录,进入容器后的落脚点,如果不指定则是 /.
WORKDIR /xxx/
环境变量、键值对的形式,运行时ENV 依然有效。
ENV <key>=<value> ...
ENV MY_NAME="John Doe"
ENV MY_DOG=Rex\ The\ Dog
ENV MY_CAT=fluffy
使用ARG或ENV指令来指定指令可用的变量RUN。若变量同名,ENV有更高优先级。运行时ARG无效。
FROM ubuntu
ARG CONT_IMG_VER
ENV CONT_IMG_VER=${CONT_IMG_VER:-v1.0.0}
RUN echo $CONT_IMG_VER
FROM alpine
WORKDIR /app
COPY src/ /app #相似命令ADD,ADD自带解压
RUN echo >> 1.txt
CMD tail -f 1.txt #ENTRYPOINT俩如果未指定都是继承自父镜像,如果祖辈也都没指定CMD或ENTRYPOINT,则镜像无法构建
最后构建镜像
docker build -t test .
-t tag 镜像名称 . 当前目录
运行镜像,生成新的容器。
docker run test
指定镜像
# 描述 Compose 文件的版本信息
version: "3.9"
# 定义服务,可以多个
services:
redis-6382: # 服务名称
image: redis:7.0 # 创建容器时所需的镜像
默认事故services下标签作为容器名,也可自己指定。
container_name: app
指定dockerfile 进行构建,在dockerfile文件中设置的参数无需再docker-compose.yml中再次设置。
可以直接指定目录,默认读取Dockerfile文件,也可以如下所示指定文件
build: /path/to/build/dir
build:
context: ./dir
dockerfile: Dockerfile-alternate
容器启动后的命令,如指定redis的配置文件
command: redis-server /etc/redis/redis.conf
表示指定镜像之间的依赖关系,以及启动顺序。理解成sping的依赖即可。
如下,web依赖了db以及redis,所以会先加载redis和db容器,最后加载web容器。
services:
web:
build: .
depends_on:
- db
- redis
redis:
image: redis
db:
image: postgres
同Dockerfile中的作用。
指定文件,可将文件内容作为环境变量添加到容器中,但是在容器构建期间环境变量无效。
env_file:
- ./a.env
- ./b.env
设置环境变量,可以将变量保存到容器中。
environment:
RACK_ENV: development
SHOW: "true"
USER_INPUT:
在使用Docker过程中,我们会有许多单独使用docker run启动的容器,为了使Compose能够连接这些不在docker-compose.yml中定义的容器,我们需要一个特殊的标签,就是external_links,它可以让Compose项目里面的容器连接到那些项目配置外部的容器(前提是外部容器中必须至少有一个容器是连接到与项目内的服务的同一个网络里面)。
external_links:
- redis_1
- project_db_1:mysql
- project_db_1:postgresql
容器中打上标签,同Dockerfile的lable作用
labels:
com.example.description: "Accounting webapp"
com.example.department: "Finance"
com.example.label-with-empty-value: ""
定义在不同容器的网络链接。 链接到其它服务中的容器。使用服务名称(同时作为别名),或者“服务名称:服务别名”
web:
links:
- db
- db:database
- redis
宿主机与容器映射的端口。 [HOST:]CONTAINER[/PROTOCOL]
ports:
- "3000"
- "8000:8000"
网络模式
network_mode: "host"
network_mode: "none"
network_mode: "service:[service name]"
定义容器附加的网络,默认是bridge模式
services:
some-service:
networks:
- some-network
- other-network
也可指定别名使用子标签 aliases ,相同的服务可以在不同的网络有不同的别名。
services:
some-service:
networks:
some-network:
aliases:
- alias1
- alias3
other-network:
aliases:
- alias2
重启策略
restart: "no"
restart: always
restart: on-failure
restart: unless-stopped
挂载一个目录或者一个已存在的数据卷容器
services:
redis-6382: # 服务名称
volumes: # 数据卷,目录挂载
- /var/lib/mysql # 只指定一个目录,在容器内部创建容器卷
- /usr/local/redis_cluster/master01/conf:/etc/redis
- /usr/local/redis_cluster/master01/data:/data
从其他容器或服务挂载数据卷。
volumes_from:
- service_name
- service_name:ro
- container:container_name
- container:container_name:rw
工作目录
安装mysql以及redis集群
具体说明参考:
# 描述 Compose 文件的版本信息
version: "3.9"
# 定义服务,可以多个
services:
mysql_master: # 服务名称
image: mysql # 创建容器时所需的镜像
container_name: mysql_master # 容器名称
restart: always # 容器总是重新启动
privileged: true
volumes: # 数据卷,目录挂载
- /usr/local/mysql_cluster/master/data:/var/lib/mysql:rw
- /usr/local/mysql_cluster/master/conf/my.cnf:/etc/mysql/my.cnf
environment:
- MYSQL_ROOT_PASSWORD=******
mysql_slave: # 服务名称
image: mysql # 创建容器时所需的镜像
container_name: mysql_slave # 容器名称
restart: always # 容器总是重新启动
privileged: true
volumes: # 数据卷,目录挂载
- /usr/local/mysql_cluster/slave/data:/var/lib/mysql:rw
- /usr/local/mysql_cluster/slave/conf/my.cnf:/etc/mysql/my.cnf
environment:
- MYSQL_ROOT_PASSWORD=******
redis-6382: # 服务名称
image: redis:7.0 # 创建容器时所需的镜像
container_name: redis-6382 # 容器名称
restart: always # 容器总是重新启动
network_mode: "host" # host 网络模式
volumes: # 数据卷,目录挂载
- /usr/local/redis_cluster/master01/conf:/etc/redis
- /usr/local/redis_cluster/master01/data:/data
command: redis-server /etc/redis/redis.conf # 覆盖容器启动后默认执行的命令
redis-6383:
image: redis:7.0 # 创建容器时所需的镜像
container_name: redis-6383
network_mode: "host"
volumes:
- /usr/local/redis_cluster/master02/conf:/etc/redis
- /usr/local/redis_cluster/master02/data:/data
command: redis-server /etc/redis/redis.conf
redis-6384:
image: redis:7.0 # 创建容器时所需的镜像
container_name: redis-6384
network_mode: "host"
volumes:
- /usr/local/redis_cluster/master03/conf:/etc/redis
- /usr/local/redis_cluster/master03/data:/data
command: redis-server /etc/redis/redis.conf
redis-6385: # 服务名称
image: redis:7.0 # 创建容器时所需的镜像
container_name: redis-6385 # 容器名称
restart: always # 容器总是重新启动
network_mode: "host" # host 网络模式
volumes: # 数据卷,目录挂载
- /usr/local/redis_cluster/slave01/conf:/etc/redis
- /usr/local/redis_cluster/slave01/data:/data
command: redis-server /etc/redis/redis.conf
redis-6386:
image: redis:7.0 # 创建容器时所需的镜像
container_name: redis-6386
network_mode: "host"
volumes:
- /usr/local/redis_cluster/slave02/conf:/etc/redis
- /usr/local/redis_cluster/slave02/data:/data
command: redis-server /etc/redis/redis.conf
redis-6387:
image: redis:7.0 # 创建容器时所需的镜像
container_name: redis-6387
network_mode: "host"
volumes:
- /usr/local/redis_cluster/slave03/conf:/etc/redis
- /usr/local/redis_cluster/slave03/data:/data
command: redis-server /etc/redis/redis.conf
我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%
exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby中使用两个参数异步运行exe吗?我已经尝试过ruby命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何rubygems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除
我有一些Ruby代码,如下所示:Something.createdo|x|x.foo=barend我想编写一个测试,它使用double代替block参数x,这样我就可以调用:x_double.should_receive(:foo).with("whatever").这可能吗? 最佳答案 specify'something'dox=doublex.should_receive(:foo=).with("whatever")Something.should_receive(:create).and_yield(x)#callthere
我正在为一个项目制作一个简单的shell,我希望像在Bash中一样解析参数字符串。foobar"helloworld"fooz应该变成:["foo","bar","helloworld","fooz"]等等。到目前为止,我一直在使用CSV::parse_line,将列分隔符设置为""和.compact输出。问题是我现在必须选择是要支持单引号还是双引号。CSV不支持超过一个分隔符。Python有一个名为shlex的模块:>>>shlex.split("Test'helloworld'foo")['Test','helloworld','foo']>>>shlex.split('Test"
我不确定传递给方法的对象的类型是否正确。我可能会将一个字符串传递给一个只能处理整数的函数。某种运行时保证怎么样?我看不到比以下更好的选择:defsomeFixNumMangler(input)raise"wrongtype:integerrequired"unlessinput.class==FixNumother_stuffend有更好的选择吗? 最佳答案 使用Kernel#Integer在使用之前转换输入的方法。当无法以任何合理的方式将输入转换为整数时,它将引发ArgumentError。defmy_method(number)
两者都可以defsetup(options={})options.reverse_merge:size=>25,:velocity=>10end和defsetup(options={}){:size=>25,:velocity=>10}.merge(options)end在方法的参数中分配默认值。问题是:哪个更好?您更愿意使用哪一个?在性能、代码可读性或其他方面有什么不同吗?编辑:我无意中添加了bang(!)...并不是要询问nobang方法与bang方法之间的区别 最佳答案 我倾向于使用reverse_merge方法:option
我有一个只接受一个参数的方法:defmy_method(number)end如果使用number调用方法,我该如何引发错误??通常,我如何定义方法参数的条件?比如我想在调用的时候报错:my_method(1) 最佳答案 您可以添加guard在函数的开头,如果参数无效则引发异常。例如:defmy_method(number)failArgumentError,"Inputshouldbegreaterthanorequalto2"ifnumbereputse.messageend#=>Inputshouldbegreaterthano
我没有找到太多关于如何执行此操作的信息,尽管有很多关于如何使用像这样的redirect_to将参数传递给重定向的建议:action=>'something',:controller=>'something'在我的应用程序中,我在路由文件中有以下内容match'profile'=>'User#show'我的表演Action是这样的defshow@user=User.find(params[:user])@title=@user.first_nameend重定向发生在同一个用户Controller中,就像这样defregister@title="Registration"@user=Use
对于作为String#tr参数的单引号字符串文字中反斜杠的转义状态,我觉得有些神秘。你能解释一下下面三个例子之间的对比吗?我特别不明白第二个。为了避免复杂化,我在这里使用了'd',在双引号中转义时不会改变含义("\d"="d")。'\\'.tr('\\','x')#=>"x"'\\'.tr('\\d','x')#=>"\\"'\\'.tr('\\\d','x')#=>"x" 最佳答案 在tr中转义tr的第一个参数非常类似于正则表达式中的括号字符分组。您可以在表达式的开头使用^来否定匹配(替换任何不匹配的内容)并使用例如a-f来匹配一
我正在使用RubyonRails3.0.9,我想生成一个传递一些自定义参数的link_toURL。也就是说,有一个articles_path(www.my_web_site_name.com/articles)我想生成如下内容:link_to'Samplelinktitle',...#HereIshouldimplementthecode#=>'http://www.my_web_site_name.com/articles?param1=value1¶m2=value2&...我如何编写link_to语句“alàRubyonRailsWay”以实现该目的?如果我想通过传递一些