Dockerfile的介绍和使用

news2024/11/15 8:36:16

什么是dockerfile?

Dockerfile是一个包含用于组合映像的命令的文本文档。可以使用在命令行中调用任何命令。 Docker通过读取Dockerfile中的指令自动生成映像。

docker build命令用于从Dockerfile构建映像。可以在docker build命令中使用-f标志指向文件系统中任何位置的Dockerfile。

例:docker build -f /path/to/a/Dockerfile 

Dockerfile的基本结构 

Dockerfile 一般分为四部分:基础镜像信息、维护者信息、镜像操作指令和容器启动时执行指令,’#’ 为 Dockerfile 中的注释。

Dockerfile文件说明
Docker以从上到下的顺序运行Dockerfile的指令。为了指定基本映像,第一条指令必须是FROM。一个声明以#字符开头则被视为注释。可以在Docker文件中使用RUN,CMD,FROM,EXPOSE,ENV等指令。

在这里列出了一些常用的指令。

FROM:指定基础镜像,必须为第一个命令

格式:  FROM <image>

          FROM <image>:<tag>

          FROM <image>@<digest>

               示例:  FROM mysql:5.7

注:tag或digest是可选的,如果不使用这两个值时,会使用latest版本的基础镜像

MAINTAINER: 维护者信息

格式:   MAINTAINER <name>

示例:   MAINTAINER Jasper Xu  

              MAINTAINER sorex@163.com  

              MAINTAINER Jasper Xu <sorex@163.com>

RUN:构建镜像时执行的命令

RUN用于在镜像容器中执行命令,其有以下两种命令执行方式:
shell执行
格式:
    RUN <command>
exec执行
格式:
    RUN ["executable", "param1", "param2"]
示例:
    RUN ["executable", "param1", "param2"]
    RUN apk update
    RUN ["/etc/execfile", "arg1", "arg1"]
注:  RUN指令创建的中间镜像会被缓存,并会在下次构建中使用。如果不想使用这些缓存镜像,可以在构建时指定--no-cache参数,如:docker build --no-cache

ADD:将本地文件添加到容器中,tar类型文件会自动解压(网络压缩资源不会被解压),可以访问网络资源,类似wget

格式:
    ADD <src>... <dest>
    ADD ["<src>",... "<dest>"] 用于支持包含空格的路径
示例:
    ADD hom* /mydir/          # 添加所有以"hom"开头的文件
    ADD hom?.txt /mydir/      # ? 替代一个单字符,例如:"home.txt"
    ADD test relativeDir/     # 添加 "test" 到 `WORKDIR`/relativeDir/
    ADD test /absoluteDir/    # 添加 "test" 到 /absoluteDir/

COPY:功能类似ADD,但是是不会自动解压文件,也不能访问网络资源

CMD:构建容器后调用,也就是在容器启动时才进行调用。

格式:
    CMD ["executable","param1","param2"] (执行可执行文件,优先)
    CMD ["param1","param2"] (设置了ENTRYPOINT,则直接调用ENTRYPOINT添加参数)
    CMD command param1 param2 (执行shell内部命令)
示例:
    CMD echo "This is a test." | wc -
    CMD ["/usr/bin/wc","--help"]注:   CMD不同于RUN,CMD用于指定在容器启动时所要执行的命令,而RUN用于指定镜像构建时所要执行的命令。

ENTRYPOINT:配置容器,使其可执行化。配合CMD可省去"application",只使用参数。

格式:
    ENTRYPOINT ["executable", "param1", "param2"] (可执行文件, 优先)
    ENTRYPOINT command param1 param2 (shell内部命令)
示例:
    FROM ubuntu
    ENTRYPOINT ["top", "-b"]
    CMD ["-c"]注:   ENTRYPOINT与CMD非常类似,不同的是通过docker run执行的命令不会覆盖ENTRYPOINT,而docker run命令中指定的任何参数,都会被当做参数再次传递给ENTRYPOINT。Dockerfile中只允许有一个ENTRYPOINT命令,多指定时会覆盖前面的设置,而只执行最后的ENTRYPOINT指令。

LABEL:用于为镜像添加元数据

格式:
    LABEL <key>=<value> <key>=<value> <key>=<value> ...
示例:
  LABEL version="1.0" description="这是一个Web服务器" by="IT笔录"
注:
  使用LABEL指定元数据时,一条LABEL指定可以指定一或多条元数据,指定多条元数据时不同元数据之间通过空格分隔。推荐将所有的元数据通过一条LABEL指令指定,以免生成过多的中间镜像。

ENV:设置环境变量

格式:
    ENV <key> <value>  #<key>之后的所有内容均会被视为其<value>的组成部分,因此,一次只能设置一个变量
    ENV <key>=<value> ...  #可以设置多个变量,每个变量为一个"<key>=<value>"的键值对,如果<key>中包含空格,可以使用\来进行转义,也可以通过""来进行标示;另外,反斜线也可以用于续行
示例:
    ENV myName John Doe
    ENV myDog Rex The Dog
    ENV myCat=fluffy

EXPOSE:指定于外界交互的端口

 格式:
    EXPOSE <port> [<port>...]
示例:
    EXPOSE 80 443
    EXPOSE 8080    EXPOSE 11211/tcp 11211/udp注:  EXPOSE并不会让容器的端口访问到主机。要使其可访问,需要在docker run运行容器时通过-p来发布这些端口,或通过-P参数来发布EXPOSE导出的所有端口

VOLUME:用于指定持久化目录

格式:
    VOLUME ["/path/to/dir"]
示例:
    VOLUME ["/data"]
    VOLUME ["/var/www", "/var/log/apache2", "/etc/apache2"注:  一个卷可以存在于一个或多个容器的指定目录,该目录可以绕过联合文件系统,并具有以下功能:
1 卷可以容器间共享和重用
2 容器并不一定要和其它容器共享卷
3 修改卷后会立即生效
4 对卷的修改不会对镜像产生影响
5 卷会一直存在,直到没有任何容器在使用它

 WORKDIR:工作目录,类似于cd命令

格式:
    WORKDIR /path/to/workdir
示例:
    WORKDIR /a  (这时工作目录为/a)
    WORKDIR b  (这时工作目录为/a/b)
    WORKDIR c  (这时工作目录为/a/b/c)注:  通过WORKDIR设置工作目录后,Dockerfile中其后的命令RUN、CMD、ENTRYPOINT、ADD、COPY等命令都会在该目录下执行。在使用docker run运行容器时,可以通过-w参数覆盖构建时所设置的工作目录。

USER: 指定运行容器时的用户名或 UID,后续的 RUN 也会使用指定用户。使用USER指定用户时,可以使用用户名、UID或GID,或是两者的组合。当服务不需要管理员权限时,可以通过该命令指定运行用户。并且可以在之前创建所需要的用户 

格式:   USER user

           USER user:group

           USER uid

           USER uid:gid

           USER user:gid

           USER uid:group

示例:   USER www

注:

使用USER指定用户后,Dockerfile中其后的命令RUN、CMD、ENTRYPOINT都将使用该用户。镜像构建完成后,通过docker run运行容器时,可以通过-u参数来覆盖所指定的用户。

ARG:用于指定传递给构建运行时的变量

 格式:
    ARG <name>[=<default value>]
示例:
    ARG site
    ARG build_user=www

ONBUILD:用于设置镜像触发器

格式:  ONBUILD [INSTRUCTION]
示例:
          ONBUILD ADD . /app/src
          ONBUILD RUN /usr/local/bin/python-build --dir /app/src
注: 当所构建的镜像被用做其它镜像的基础镜像,该镜像中的触发器将会被钥触发

示例:

# This my first nginx Dockerfile
# Version 1.0
 
# Base images 基础镜像
FROM centos
 
#MAINTAINER 维护者信息
MAINTAINER tianfeiyu 
 
#ENV 设置环境变量
ENV PATH /usr/local/nginx/sbin:$PATH
 
#ADD  文件放在当前目录下,拷过去会自动解压
ADD nginx-1.8.0.tar.gz /usr/local/  
ADD epel-release-latest-7.noarch.rpm /usr/local/  
 
#RUN 执行以下命令 
RUN rpm -ivh /usr/local/epel-release-latest-7.noarch.rpm
RUN yum install -y wget lftp gcc gcc-c++ make openssl-devel pcre-devel pcre && yum clean all
RUN useradd -s /sbin/nologin -M www
 
#WORKDIR 相当于cd
WORKDIR /usr/local/nginx-1.8.0 
 
RUN ./configure --prefix=/usr/local/nginx --user=www --group=www --with-http_ssl_module --with-pcre && make && make install
 
RUN echo "daemon off;" >> /etc/nginx.conf
 
#EXPOSE 映射端口
EXPOSE 80
 
#CMD 运行以下命令
CMD ["nginx"]

通过Dockerfile创建镜像

Docker 提供了一种更便捷的方式,叫作 Dockerfile

docker build命令用于根据给定的Dockerfile构建Docker镜像。

docker build语法:

# docker build [OPTIONS] <PATH | URL | -> 

 1. 常用选项说明
--build-arg,设置构建时的变量
--no-cache,默认false。设置该选项,将不使用Build Cache构建镜像
--pull,默认false。设置该选项,总是尝试pull镜像的最新版本
--compress,默认false。设置该选项,将使用gzip压缩构建的上下文
--disable-content-trust,默认true。设置该选项,将对镜像进行验证
--file, -f,Dockerfile的完整路径,默认值为‘PATH/Dockerfile’
--isolation,默认--isolation="default",即Linux命名空间;其他还有process或hyperv
--label,为生成的镜像设置metadata
--squash,默认false。设置该选项,将新构建出的多个层压缩为一个新层,但是将无法在多个镜像之间共享新层;设置该选项,实际上是创建了新image,同时保留原有image。
--tag, -t,镜像的名字及tag,通常name:tag或者name格式;可以在一次构建中为一个镜像设置多个tag
--network,默认default。设置该选项,Set the networking mode for the RUN instructions during build
--quiet, -q ,默认false。设置该选项,Suppress the build output and print image ID on success
--force-rm,默认false。设置该选项,总是删除掉中间环节的容器
--rm,默认--rm=true,即整个构建过程成功后删除中间环节的容器 

示例:

docker build -t newrain/bbauto:v2.1 .

docker build  是docker创建镜像的命令 
-t 是标识新建的镜像属于 newrain的 bbauto镜像 
:v2 是tag 
"."是用来指明 我们的使用的Dockerfile文件当前目录的 

2.1、 创建镜像所在的文件夹和Dockerfile文件 

[root@docker ~]# mkdir sinatra
[root@docker ~]# cd sinatra/
[root@docker sinatra]# touch Dockerfile

2.2、 在Dockerfile文件中写入指令,每一条指令都会更新镜像的信息

例如:

[root@docker sinatra]# vim Dockerfile
#This is a comment 
FROM daocloud.io/library/centos:7
MAINTAINER newrain newrain@docker
RUN yum install -y wget
RUN touch a.txt
RUN mkdir /test

格式说明:

命令要大写,"#"是注解。 
每一个指令后面需要跟空格,语法。
FROM 命令是告诉docker 我们的镜像什么从哪里下载。 
MAINTAINER 是描述 镜像的创建人。   maintainer
RUN 命令是在镜像内部执行。就是说他后面的命令应该是针对镜像可以运行的命令。  

2.3、创建镜像

命令:
# docker build -t newrain/centso:7 . 

docker build  是docker创建镜像的命令  

 详细执行过程:

[root@docker sinatra]# docker build -t soso/centos:7 . 
Sending build context to Docker daemon  2.048kB
Step 1/4 : FROM daocloud.io/library/centos
latest: Pulling from library/centos
d8d02d457314: Pull complete 
Digest: sha256:a36b9e68613d07eec4ef553da84d0012a5ca5ae4a830cf825bb68b929475c869
Status: Downloaded newer image for daocloud.io/library/centos:latest
 ---> 67fa590cfc1c
Step 2/4 : MAINTAINER newrain newrain@docker
 ---> Running in aab3d80939d8
Removing intermediate container aab3d80939d8
 ---> 12bae7d75a23
Step 3/4 : RUN yum update && yum install -y epel*
 ---> Running in ad83c387c60f
Loaded plugins: fastestmirror, ovl
Determining fastest mirrors
 * base: mirrors.aliyun.com
 * extras: mirrors.aliyun.com
 * updates: mirrors.aliyun.com
Resolving Dependencies
--> Running transaction check
---> Package audit-libs.x86_64 0:2.8.4-4.el7 will be updated
---> Package audit-libs.x86_64 0:2.8.5-4.el7 will be an update

2.4、创建完成后,从镜像创建容器

  

Dockerfile实例:容器化python的flask应用

目标: 用 Docker 部署一个用 Python 编写的 Web 应用。

首先部署整个流程:

基础镜像(python)-->flask-->部署python应用
web框架 flask django

代码功能:

如果当前环境中有"NAME"这个环境变量,就把它打印在"Hello"后,否则就打印"Hello world",最后再打印出当前环境的 hostname。

[root@docker ~]# mkdir python_app
[root@docker ~]# cd python_app/
[root@docker python_app]# vim app.py
from flask import Flask
import socket
import os
 
app = Flask(__name__)
 
@app.route('/')
def hello():
    html = "<h3>Hello {name}!</h3>" \
           "<b>Hostname:</b> {hostname}<br/>"
    return html.format(name=os.getenv("NAME", "world"), hostname=socket.gethostname())
 
if __name__ == "__main__":
    app.run(host='0.0.0.0', port=80)

应用依赖:

定义在同目录下的 requirements.txt 文件里,内容如下:

[root@docker python_app]# vim requirements.txt
Flask 

 Dockerfile制作容器镜像:

# vim Dockerfile
FROM python:2.7-slim
WORKDIR /app
ADD . /app
RUN pip install --trusted-host pypi.python.org -r requirements.txt
EXPOSE 80
ENV NAME World
CMD ["python", "app.py"]

Dockerfile文件说明:

FROM python:2.7-slim
# 使用官方提供的 Python 开发镜像作为基础镜像 
# 指定"python:2.7-slim"这个官方维护的基础镜像,从而免去安装 Python 等语言环境的操作。:
 
WORKDIR /app
# 将工作目录切换为 /app,意思是在这一句之后,Dockerfile 后面的操作都以这一句指定的 /app 目录作为当前目录。 
 
ADD . /app
# 将当前目录下的所有内容复制到 /app 下 Dockerfile 里的原语并不都是指对容器内部的操作。比如 ADD,指的是把当前目录(即 Dockerfile 所在的目录)里的文件,复制到指定容器内的目录当中。
 
RUN pip install --trusted-host pypi.python.org -r requirements.txt
# 使用 pip 命令安装这个应用所需要的依赖
 
EXPOSE 80
# 允许外界访问容器的 80 端口
 
ENV NAME World
# 设置环境变量
 
CMD ["python", "app.py"]
# 设置容器进程为:python app.py,即:这个 Python 应用的启动命令,这里app.py 的实际路径是 /app/app.py。CMD ["python", "app.py"] 等价于 "docker run python app.py"。 

现在目录结构:

[root@docker python_app]# ls
Dockerfile  app.py   requirements.txt 

构建镜像:

[root@docker python_app]# docker build -t testpython .
-t  给这个镜像加一个 Tag

Dockerfile 中的每个原语执行后,都会生成一个对应的镜像层。即使原语本身并没有明显地修改文件的操作(比如,ENV 原语),它对应的层也会存在。只不过在外界看来,这个层是空的。

查看结果:

[root@docker python_app]# docker images
REPOSITORY                              TAG                 IMAGE ID           ...
testpython                              latest              16bc21f3eea3

启动容器:

[root@docker python_app]# docker run -it -p 4000:80 testpython /bin/bash

查看容器:

[root@docker python_app]# docker ps 
CONTAINER ID        IMAGE               COMMAND             CREATED                  
ce02568e64ce        testpython          "/bin/bash"         About a minute ago

进入容器:

[root@docker python_app]# docker exec -it ce02568 /bin/bash 
root@ce02568e64ce:/app# python app.py &        #将python运行起来

 访问容器内应用:

[root@docker ~]# curl http://localhost:4000
<h3>Hello World!</h3><b>Hostname:</b> f201f6855136<br/>

实战练习

# 1、创建一个nginx的dockerfile
[root@docker ~]# mkdir nginx  
[root@docker ~]# cd nginx/
[root@docker nginx]# vim Dockerfile
# This my first nginx Dockerfile
# Version 1.0
FROM daocloud.io/library/centos:7
MAINTAINER docker
ENV PATH /usr/local/nginx/sbin:$PATH
ADD nginx-1.16.1.tar.gz /usr/local/
ADD epel-release-7-11.noarch.rpm /usr/local/
RUN rpm -ivh /usr/local/epel-release-7-11.noarch.rpm
RUN yum install -y gcc gcc-c++ make && yum -y install openssl openssl-devel && yum install -y zlib zlib-devel && yum clean all
RUN useradd -s /sbin/nologin -M www
WORKDIR /usr/local/nginx-1.16.1
RUN ./configure --prefix=/usr/local/nginx --user=www --group=www && make && make install
RUN echo "daemon off;" >> /etc/nginx.conf
EXPOSE 80
CMD /bin/sh -c 'nginx -g "daemon off;"'  #放前台启动
 
[root@docker nginx]# ls   #将nginx的tar包与epel源上传到nginx目录下面
Dockerfile  epel-release-7-11.noarch.rpm  nginx-1.16.1.tar.gz
[root@docker nginx]# pwd
/root/nginx
[root@docker nginx]# docker build -t nginx:v7.1 .
[root@docker nginx]# docker run -itd --name nginx9 -p 8088:80 nginx:v7.1  #启动容器
[root@docker nginx]# docker ps 
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMES
fec1f3a37cb0        nginx:v7.1          "/bin/sh -c '/bin/sh…"   6 seconds ago       Up 5 seconds        0.0.0.0:8088->80/tcp

# 2.创建一个jenkins的Dockerfile
[root@docker ~]# mkdir tomcat 
[root@docker ~]# cd tomcat/
[root@docker tomcat]# vim Dockerfile
# This my first jenkins Dockerfile
# Version 1.0
 
FROM daocloud.io/library/centos:7
MAINTAINER docker
ENV JAVA_HOME /usr/local/jdk1.8.0_211
ENV TOMCAT_HOME /usr/local/apache-tomcat-8.5.47
ENV PATH=$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$PATH
ENV CLASSPATH=.:$JAVA_HOME/lib:$JAVA_HOME/jre/lib:$JAVA_HOME/lib/tools.jar
ADD apache-tomcat-8.5.47.tar.gz /usr/local/
ADD jdk-8u211-linux-x64.tar.gz /usr/local/
RUN rm -rf /usr/local/apache-tomcat-8.5.47/webapps/*
ADD jenkins.war /usr/local/apache-tomcat-8.5.47/webapps
RUN rm -rf apache-tomcat-8.5.47.tar.gz  apache-tomcat-8.5.47.tar.gz
EXPOSE 8080
ENTRYPOINT ["/usr/local/apache-tomcat-8.5.47/bin/catalina.sh","run"]  #运行的命令
 
[root@docker tomcat]# pwd
/root/tomcat
[root@docker tomcat]# ls  #将jdk与tomcat还有jenkins的包上传到tomcat目录中
apache-tomcat-8.5.47.tar.gz  Dockerfile  jdk-8u211-linux-x64.tar.gz  jenkins.war
[root@docker tomcat]# docker build -t jenkins:v1 .
[root@docker tomcat]# docker run -itd --name jenkins1 -p 8081:8080 jenkins:v1

扩展----CMD与ENTRYPOINT区别

一、dockerfile中的 CMD

1、每个dockerfile中只能有一个CMD如果有多个那么只执行最后一个。
2、CMD 相当于启动docker时候后面添加的参数看,举个简单例子:
# docker run -itd --name test image(镜像) /bin/bash -c
a、镜像名称后面跟了一个/bin/bash -c ,其实等价于在dockerfile中的CMD ["/bin/bash","-c"]。
b、如果dockerfile中的CMD中有了CMD["/bin/bash","-c"],那么就不用在执行的时候再添加了,如果添加了参数的话那么就相当于要执行你添加的参数,默认的CMD中的参数就无效了。

二、dockerfile中的ENTRYPOINT
1、一个dockerfile中ENTRYPOINT也只能存在一个,若存在多个那么只执行最后一个,你可以理解为开机启动的意思,和CMD有点像,不过还是有区别。

2、举个简单例子:
a、dockerfile中有ENTRYPOINT ["tail","-f","/var/log/nginx/access.log"],那么启动的时候镜像就执行了这个里面的内容,如果你像上面带参数的话就相当于在这个执行的内容后面再加入参数。
案例:
如果我们的dockerfile中有a中的这句话然后我们启动我们的docker:
#docker run -itd --name test image(镜像名) /bin/bash -c

此时就相当于我们启动docker的时候执行了:tail -f /var/log/nginx/access.log /bin/bash -c
这个命令明显就不对.

dockerfile优化

编译一个简单的nginx成功以后发现好几百M。

1、RUN 命令要尽量写在一条里,每次 RUN 命令都是在之前的镜像上封装,只会增大不会减小

2、每次进行依赖安装后,记得yum clean all【centos】 
#yum clean all 清除缓存中的rpm头文件和包文件

3、选择比较小的基础镜像。alpine

部署私有仓库应用

私有仓库镜像:

registry --官方出品, 没有图形界面.Docker hub官方已提供容器镜像registry,用于搭建私有仓库

拉取镜像:

[root@docker ~]# docker pull daocloud.io/library/registry:latest

运行容器:

[root@docker ~]# docker run -d -v /home/dockerdata/registry:/var/lib/registry --name "pri_registry" --restart=always -p 5000:5000 daocloud.io/library/registry

参数解释:
/home/dockerdata/registry表示为宿主机的目录,如果不存在自动创建
-v映射目录:  宿主机的目录:容器目录
把宿主机的目录挂载到容器中,将数据目录挂载出来就是为了防止docker私有仓库这个容器被删除的时候,仓库里面的镜像也被删除。
-p 端口映射:本地端口:容器端口

 注:如果创建容器不成功,报错防火墙,解决方案如下

#systemctl stop firewalld
#yum install iptaqbles*
#systemctl start iptables
#iptables -F
#systemctl restart docker  

[root@docker ~]# docker ps 
CONTAINER ID        IMAGE                          COMMAND                  CREATED              STATUS              PORTS                    NAMES
0823df72b160        daocloud.io/library/registry   "/entrypoint.sh /etc…"   About a minute ago   Up About a minute   0.0.0.0:5000->5000/tcp   pri_registry 

 连接容器查看端口状态:

[root@docker ~]# docker exec -it  0823df7  /bin/sh
/ # netstat -lntp    #查看5000端口是否开启
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 :::5000                 :::*                    LISTEN      1/registry

 在本机查看能否访问该私有仓库, 看看状态码是不是200

[root@docker ~]# curl -I http://127.0.0.1:5000
HTTP/1.1 200 OK 

为了方便,下载1个比较小的镜像,buysbox 

[root@docker ~]# docker pull daocloud.io/library/busybox

上传前必须给镜像打tag 注明ip和端口:

[root@docker ~]# docker tag busybox 192.168.246.141:5000/busybox
 
#宿主机查看目录:
[root@docker ~]# ls /home/dockerdata/registry/docker/registry/v2/repositories/

下面这个Mysql是我测试的第二个镜像,从daocloud拉取的:

[root@docker ~]# docker pull daocloud.io/library/mysql
[root@docker ~]# docker tag daocloud.io/library/mysql 192.168.246.141:5000/daocloud.io/library/mysql
[root@docker ~]# docker images

注:tag后面可以使用镜像名称也可以使用id,我这里使用的镜像名称,如果使用官方的镜像,不需要加前缀,但是daocloud.io的得加前缀.

修改请求方式为http:

# 默认为https,不改会报以下错误:
Get https://master.up.com:5000/v1/_ping: http: server gave HTTP response to HTTPS client
 
[root@docker ~]# vim /etc/docker/daemon.json    #不存在则创建
{ "insecure-registries":["192.168.246.141:5000"] }
 
# 重启docker:
[root@docker ~]# systemctl restart docker

 上传镜像到私有仓库:

[root@docker ~]# docker push 192.168.246.141:5000/busybox
[root@docker ~]# docker push 192.168.246.141:5000/daocloud.io/library/mysql

 查看私有仓库里的所有镜像:

# 语法: # curl  http://ip:port/v2/repo名字/tags/list
[root@docker ~]# curl http://192.168.246.141:5000/v2/busybox/tags/list
{"name":"busybox","tags":["latest"]}
 
[root@docker ~]# curl http://192.168.246.141:5000/v2/daocloud.io/library/mysql/tags/list
{"name":"daocloud.io/library/mysql","tags":["latest"]} 
 
# 这条命令会查看仓库下面所有的镜像:
[root@docker ~]# curl http://192.168.246.141:5000/v2/_catalog

拉取镜像测试:

#1.先将刚才打了tags的镜像删掉
[root@docker ~]# docker rmi 192.168.246.141:5000/busybox
 
#2.拉取镜像:
[root@docker ~]# docker pull 192.168.246.141:5000/busybox
[root@docker ~]# docker images

部署docker web ui应用

下载并运行容器:

[root@docker ~]# docker pull uifd/ui-for-docker
[root@docker ~]# docker run -it -d --name docker-web -p 9000:9000 -v /var/run/docker.sock:/var/run/docker.sock docker.io/uifd/ui-for-docker

浏览器访问测试:  ip:9000

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1313109.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Monitor, Maintenance Operation, Script code/prgramme】

Summary of M,M&O,Program JD) Monitor & M&O Symbio信必优) Job chance/opportunities on Dec 12th, 20231.1) Content 招聘JD job description:1.2) suggestions from Ms Liang/Winnie on Wechat app1.3) Java微服务是什么&#xff1f;1.3.1) [URL Java 微服务](…

yarn系统架构与安装

1.1 YARN系统架构 YARN的基本思想是将资源管理和作业调度/监视功能划分为单独的守护进程。其思想是拥有一个全局ResourceManager (RM)&#xff0c;以及每个应用程序拥有一个ApplicationMaster (AM)。应用程序可以是单个作业&#xff0c;也可以是一组作业。 一个ResourceManage…

数据结构与算法之美学习笔记:36 | AC自动机:如何用多模式串匹配实现敏感词过滤功能?

目录 前言基于单模式串和 Trie 树实现的敏感词过滤经典的多模式串匹配算法&#xff1a;AC 自动机解答开篇内容小结 前言 本节课程思维导图&#xff1a; 很多支持用户发表文本内容的网站&#xff0c;比如 BBS&#xff0c;大都会有敏感词过滤功能&#xff0c;用来过滤掉用户输入…

如何做好口译服务,同传和交传哪个服务好

随着中国经济的蓬勃发展和综合实力的不断增强&#xff0c;中国与世界各国的交流也日益频繁。口译作为对外交流的桥梁与纽带&#xff0c;需求量与日俱增&#xff0c;其重要性不言而喻。那么&#xff0c;如何做好口译服务呢&#xff1f;是同传还是交传更好呢&#xff1f; 要做好口…

rabbitmq-windows安装使用-简易后台界面-修改密码

文章目录 1.下载2.安装3.安装 RabbitMQ4.后台访问5.修改密码 1.下载 将erlang运行时和rabbitmq-windows版本&#xff0c;上传在csdn&#xff0c;下载链接。https://download.csdn.net/download/m0_67316550/88633443 2.安装 右键&#xff0c;以管理员身份运行rabbitmq。启动…

如何用Adobe Audition 检测波形的pop和卡顿

在Adobe Audition中&#xff0c;检测卡顿和pop的方法各有不同&#xff1a; 1. **检测卡顿**&#xff1a; - 使用“诊断”面板中的“删除静音”或“标记音频”选项可以帮助识别音频中的静音段落&#xff0c;这可能表明存在卡顿。 - 配置诊断设置&#xff0c;指定静音的振…

探讨前端技术的未来:创新与适应的必要性

一、引言 2023年&#xff0c;IT圈似乎被一种悲观的论调所笼罩&#xff0c;那就是“Java 已死、前端已凉”。然而&#xff0c;真相是否如此呢&#xff1f;本文将围绕这一主题&#xff0c;探讨前端的现状和未来发展趋势。 二、为什么会出现“前端已死”的言论 这一言论的出现并…

Python高级算法——线性规划(Linear Programming)

Python中的线性规划&#xff08;Linear Programming&#xff09;&#xff1a;高级算法解析 线性规划是一种数学优化方法&#xff0c;用于求解线性目标函数在线性约束条件下的最优解。它在运筹学、经济学、工程等领域得到广泛应用。本文将深入讲解Python中的线性规划&#xff0…

python 新手学习 - 简单实用的 Python 周期任务调度工具

如果你想周期性地执行某个 Python 脚本&#xff0c;最出名的选择应该是 Crontab 脚本&#xff0c;但是 Crontab 具有以下缺点&#xff1a; 1.不方便执行秒级任务。 2.当需要执行的定时任务有上百个的时候&#xff0c;Crontab 的管理就会特别不方便。 还有一个选择是 Celery&a…

如何在 JavaScript 中实现任务队列

任务队列的概念 任务队列就是存放任务的队列&#xff0c;队列中的任务都严格按照进入队列的先后顺序执行。 在前一条任务执行完毕后&#xff0c;立即执行下一条任务&#xff0c;直到任务队列清空。 任务队列的基本执行流程如下&#xff1a; 设置任务队列并发数&#xff1b; …

编程导航算法通关村——算法基础

目录 1. 时间复杂度 1.1. 时间复杂度概念 1.2. 几种常见的阶 1.2.1. 常数阶 O(1) 1.2.2. 线性阶 O(n) 1.2.3. 平方阶 (n) 1.2.4. 对数阶 O(logn) 2. 最坏情况和平均情况 3. 空间复杂度 1. 时间复杂度 1.1. 时间复杂度概念 当我们说算法的时间复杂度时&#xff0c;我们…

「完美世界」石昊被诓入至尊道场,修炼无敌道,打跑天仙书院弟子

Hello,小伙伴们&#xff0c;我是拾荒君。 《完美世界》这部国漫&#xff0c;在粉丝的翘首期盼中&#xff0c;终于迎来了第141集的更新。这一集的内容&#xff0c;对于喜欢石昊和至尊道场劫难的观众来说&#xff0c;可谓是扣人心弦&#xff0c;让人目不转睛。 在这一集中&#…

【node】使用 sdk 完成短信发送

实现效果 过程 流程比较复杂&#xff0c;加上需要实名认证&#xff0c;建议开发的时候先提前去认证号账号&#xff0c;然后申请模版也需要等认证。 源码 我看了新版的sdk用的代码有点长&#xff0c;感觉没必要&#xff0c;这边使用最简单的旧版的sdk。 https://github.com/…

【MySQL学习之基础篇】约束

文章目录 1. 概述2. 基础约束3. 外键约束3.1. 介绍3.2. 外键的添加3.3. 外键删除和更新行为 1. 概述 概念&#xff1a; 约束是作用于表中字段上的规则&#xff0c;用于限制存储在表中的数据。     目的&#xff1a; 保证数据库中数据的正确、有效性和完整性。 分类&#x…

HHDESK个性化脚本功能

HHDESK可以把脚本配置在对话框中&#xff0c;生成按钮&#xff0c;便捷操作。 在界面下方的脚本框中&#xff0c;点击“”&#xff0c;选择新建&#xff1b; 随后在弹出框内填写名称及脚本&#xff0c;按需求选择填写参数&#xff0c;及运行过程中是否弹出参数框&#xff1b;…

Vue3-14- 【v-for】循环数组-解构的操作

说明 v-for 在遍历数组的时候&#xff0c;可以使用解构的语法&#xff0c;直接将数组中对象元素的属性解构出来&#xff0c; 从而实现直接使用对象属性值的效果。语法格式 &#xff1a; v-for"({属性名1,属性名2},索引变量名) in 数组名"具体的使用请看代码&#xf…

活动预告 | 微盟技术沙龙 - Elasticsearch 在微盟的实践 12/21/2023

微盟技术沙龙 「微盟技术沙龙」是由微盟研发中心发起并联合各方小伙伴为开发者举办的系列技术沙龙&#xff0c;从用户&#xff0c;产品&#xff0c;技术等方面与开发者进行交流。 微盟技术沙龙关注开发者在实际应用中遇到的问题。提供最真实的干货&#xff0c;以技术会友&…

北京通用人工智能研究院提出了首个三维世界中的具身多任务多模态的通才智能体 LEO

想要迈向通用人工智能&#xff0c;必须要构建一个能够理解人类生活的真实世界&#xff0c;并掌握丰富技能的具身通用智能体。 今年以来&#xff0c;以 GPT-4 (V)[1]、LLaVA [2]、PALM-E [3] 等为代表的多模态大语言模型&#xff08;Multi-modal Large Language Model&#xff…

Qt 数据库QSqlDatabase使用记录

记录一些在QT中使用QSqlDatabase操作数据库时&#xff0c;需要注意的地方 创建数据库 bool CDBOperatorAbstract::_openDBConn(CDatabaseConfig config) {QWriteLocker locker(&m_locker);QSqlDatabase db;if(QSqlDatabase::contains(m_connectionName)){db QSqlDatabas…

随机森林1(了解整体知识架构)

很多人想学习或者了解随机森林&#xff0c;查到的资料都是先讲熵&#xff0c;再讲决策树&#xff0c;然后再讲随机森林&#xff0c;前面坚持不下来或者一个地方没理解透彻&#xff0c;导致无法向下学习&#xff0c;而且公式讲解不够清晰&#xff0c;例子不够详细&#xff0c;很…