如果不使用docker,面临的问题有:

  • 部署非常慢
  • 成本非常高
  • 资源浪费
  • 难于迁移和扩展
  • 可能会被限定硬件厂商

虚拟化技术的优点:

  • 虚拟化技术出现以后,一个物理机可以部署多个App,每个App独立运行在一个VM里。
  • 资源池,一个物理机的资源分配到了不同的虚拟机里
  • 容易扩展,加物理机或者虚拟机。
  • 很容易云化,亚马逊AWS,阿里云等。

虚拟化技术的局限性:

  • 每一个虚拟机都是一个完整的操作系统,要给其分配资源,当虚拟机数量增多时,操作系统本身消耗的资源势必增多。

 docker 命令每次都需要使用sudo来执行,不太方便,如何去掉sudo?

  1. 添加docker  group,并将当前用户添加到docker group
iie4bu@hostdocker:~$ sudo groupadd docker
groupadd: group 'docker' already exists
iie4bu@hostdocker:~$ sudo gpasswd -a iie4bu docker
Adding user iie4bu to group docker
iie4bu@hostdocker:~$

2. 更新用户组

newgrp docker 

3. 重启docker服务

iie4bu@hostdocker:~$ sudo service docker restart

4. 重新登录终端即可,这样就不需要加sudo了 ,非常方便

从零构建第一个hello world

目标:构建一个最简单的hello world

新建目录hello-world

第一步写一个最简单的c语言,新建hello.c

#include<stdio.h>
int main()
{printf("hello docker \n");
}

编译hello.c,输出为hello

iie4bu@hostdocker:~/ddy/hello-world$ gcc -static hello.c -o hello

在当前目录下新建Dockerfile

FROM scratch
ADD hello /
CMD ["/hello"]

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

Dockerfile文件说明与常用命令

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

在这里列出了一些常用的说明

FROM

该指令用于设置后续指令的基本映像。有效的Dockerfile必须使用FROM作为其第一条指令。表示我们想要在哪个base image之上来build我们的image。例如我们FROM centos,表示我们想要在centos的基础之上去build我们的image。

FROM scratch # 制作base image
FROM centos # 制作base image
FROM ubuntu:xenial

scratch表示空镜像。

尽量使用官方的image作为base image!(为了安全)

LABEL

可以为映像添加标签来组织项目的映像。需要使用LABEL指令设置映像的标签。定义了我们的metadata。

LABEL maintainer="vincent"
LABEL version="1.0"
LABEL description="This is description"

RUN

该指令用于执行当前映像的任何命令。一般我们安装一些软件的时候需要使用RUN,

RUN yum update && yum install -y vim \python-dev # 反斜线换行
RUN apt-get update && apt-get install -y perl \pwgen --no-install-recommends && rm -rf \/var/lib/apt/lists/* # 注意清理cache
RUN /bin/bash -c 'source $HOME/.bashrc;echo $HOME'

RUN需要注意的是我们每运行一次RUN都会生成新的一层container,所以说对于RUN来讲,为了避免无用的分层,合并多条命令成一行。为了美观,复杂的RUN请用反斜线换行!

CMD

这用于执行映像的应用程序。应该以下列形式总是使用CMD -

CMD ["executable", "param1", "param2"?]

这是使用CMD的首选方法。Dockerfile文件中只能有一个CMD。如果使用多个CMD,则只会执行最后一个CMD。

ADD 和 COPY

ADD和COPY的作用很像,都是通过把本地的一些文件,添加到我们的docker image里面。例如我们把本地的hello的一个可执行文件拷贝到根目录中,该指令用于将来自源的新文件或目录复制到目的地的容器的文件系统。

ADD hello / #把本地的hello的一个可执行文件拷贝到根目录中
ADD test.tar.gz / #添加到根目录并解压
COPY abc/ /xyz

ADD与COPY的区别是,ADD可以解压缩。

ADD和COPY往往和WORKDIR一起使用。

WORKDIR /root
ADD hello test #/root/test/hello

大部分情况,COPY要比ADD优先去使用。ADD除了COPY以外,还有解压缩的功能。如果要添加远程文件/目录请使用curl或者wget

规则

  • source路径必须在构建的上下文之内。无法使用COPY ../something /something,因为docker构建的第一步是将上下文目录(和子目录)发送到docker守护程序。
  • 如果source是目录,则会复制目录的全部内容,包括文件系统元数据。

ENV

通过设置环境变量来设置一个常量 

ENV MYSQL_VERSION 5.6 #设置常量
RUN apt-get install -y mysql-server="${MYSQL_VERSION}" \&& rm -rf /var/lib/apt/lists/* #引用常量

WORKDIR

用于设定当前工作目录的。与linux下面的cd命令很像。WORKDIR用于为Dockerfile中的RUN,CMD和COPY指令设置工作目录。如果工作目录不存在,它默认将会创建。
我们可以在Dockerfile文件中多次使用WORKDIR。

WORKDIR /test #如果没有会自动创建test目录
WORKDIR demo
RUN pwd # 输出结果应该是/test/demo

使用WORKDIR,而不要使用RUN cd  尽量使用绝对目录!不要使用相对目录。

RUN:执行命令并创建新的Image Layer

CMD:设置容器启动后默认执行的命令和参数

ENTRYPOINT:设置容器启动时运行的命令

CMD和ENTRYPOINT有什么区别呢?

在介绍CMD和ENTRYPOINT区别之前,先介绍Shell和Exce格式

Shell格式,把我们要运行的命令当成shell来执行,如下所示:

RUN apt-get install -y vim
CMD echo "hello docker"
ENTRYPOINT echo "hello docker"

Exec格式,需要特定的格式去指明我们要运行的命令以及命令所跟的参数,如下所示:

RUN [ "apt-get", "install", "-y", "vim" ]
CMD [ "/bin/echo", "hello docker" ]
ENTRYPOINT [ "/bin/echo", "hello docker"]

目前我们还不知道Shell和Exec有什么区别,下面来解释,首先新建两个Dockerfile

Dockerfile1:

FROM ubuntu:xenial
ENV name Docker
ENTRYPOINT echo "hello $name"

Dockerfile2:

FROM ubuntu:xenial
ENV name Docker
ENTRYPOINT ["/bin/echo", "hello $name"]

这两个Dockerfile看起来功能是一样的。

我们在命令行执行第一个Dockerfile

iie4bu@hostdocker:~/ddy/docker1$ docker build -t vincent/ubuntu-entrypoint-shell .
Sending build context to Docker daemon  2.048kB
Step 1/3 : FROM ubuntu:xenial---> 5e8b97a2a082
Step 2/3 : ENV name Docker---> Running in 6be14dd0ab64
Removing intermediate container 6be14dd0ab64---> 0ebb88d446f9
Step 3/3 : ENTRYPOINT echo "hello $name"---> Running in acdad580ef15
Removing intermediate container acdad580ef15---> 37a8a7654a8f
Successfully built 37a8a7654a8f
Successfully tagged vincent/ubuntu-entrypoint-shell:latest

然后我们查看我们的image

iie4bu@hostdocker:~/ddy/docker1$ docker image ls
REPOSITORY                                      TAG                 IMAGE ID            CREATED             SIZE
vincent/ubuntu-entrypoint-shell                 latest              37a8a7654a8f        17 seconds ago      114MB

有了新的image,然后我们创建一个container。如下:

iie4bu@hostdocker:~/ddy/docker1$ docker run vincent/ubuntu-entrypoint-shell
hello Docker
iie4bu@hostdocker:~/ddy/docker1$

然后我们将执行Exec格式的Dockerfile。然后build一个新的image如下:

iie4bu@hostdocker:~/ddy/docker2$ docker build -t vincent/ubuntu-entrypoint-exec .
Sending build context to Docker daemon  2.048kB
Step 1/3 : FROM ubuntu:xenial---> 5e8b97a2a082
Step 2/3 : ENV name Docker---> Using cache---> 0ebb88d446f9
Step 3/3 : ENTRYPOINT ["/bin/echo", "hello $name"]---> Running in 01984afd1b19
Removing intermediate container 01984afd1b19---> 9d4f9618de5d
Successfully built 9d4f9618de5d
Successfully tagged vincent/ubuntu-entrypoint-exec:latest

然后我们创建一个container。如下:

iie4bu@hostdocker:~/ddy/docker2$ docker run vincent/ubuntu-entrypoint-exec
hello $name
iie4bu@hostdocker:~/ddy/docker2$ 

也就是说,它并没有把我们$name替换成我们ENV中定义的常量。如何得到正确结果呢?需要修改Dockerfile,内容如下:

FROM ubuntu:xenial
ENV name Docker
ENTRYPOINT ["/bin/bash", "-c", "echo", "hello $name"]

-c表示后面的是我们的参数

然后重新生成image,然后再次生成container,发现输出结果为空:

iie4bu@hostdocker:~/ddy/docker2$ docker image ls
REPOSITORY                                      TAG                 IMAGE ID            CREATED             SIZE
vincent/ubuntu-entrypoint-exec                  latest              eec8fd1389b2        30 seconds ago      114MB
iie4bu@hostdocker:~/ddy/docker2$ docker run vincent/ubuntu-entrypoint-execiie4bu@hostdocker:~/ddy/docker2$

原因是通过/bin/bash -c去执行命令的时候,要把后面所有的命令作为一个命令来执行。修改Dockerfile如下:

FROM ubuntu:xenial
ENV name Docker
ENTRYPOINT ["/bin/bash", "-c", "echo hello $name"]

重新build 和 run 这样结果就正常输出了:

iie4bu@hostdocker:~/ddy/docker2$ docker build -t vincent/ubuntu-entrypoint-exec .
Sending build context to Docker daemon  2.048kB
Step 1/3 : FROM ubuntu:xenial---> 5e8b97a2a082
Step 2/3 : ENV name Docker---> Using cache---> 0ebb88d446f9
Step 3/3 : ENTRYPOINT ["/bin/bash", "-c", "echo hello $name"]---> Running in 83332f6ed34f
Removing intermediate container 83332f6ed34f---> 02dde803e324
Successfully built 02dde803e324
Successfully tagged vincent/ubuntu-entrypoint-exec:latest
iie4bu@hostdocker:~/ddy/docker2$ docker run vincent/ubuntu-entrypoint-exec
hello Docker
iie4bu@hostdocker:~/ddy/docker2$

CMD

  • 容器启动时默认执行的命令
  • 如果docker run指定了其他命令,CMD命令会被忽略
  • 如果定义了多个CMD,只有最后一个会执行

ENTRYPOINT

  • 让容器以应用程序或者服务的形式运行,例如启动一个数据库服务
  • 不会被忽略,一定会执行
  • 最佳实践:写一个shell脚本作为entrypoint
COPY docker-entrypoint.sh /usr/local/bin
ENTRTPOINT ["docker-entrypoint.sh"]EXPOSE 27017
CMD ["mongod"]

小技巧

如何删除掉已经停止的container的image?

如果一个container已经停止,是无法直接删除这个image的,需要先把这个container删除掉。

命令:docker container rm $(docker ps -qa)

新建Dockerfile,内容如下:

FROM ubuntu:xenial
ENV name Docker
CMD echo "hello $name"

构建这个image

iie4bu@hostdocker:~/ddy/docker3$ docker build -t vincent/ubuntu-cmd-shell .
Sending build context to Docker daemon  2.048kB
Step 1/3 : FROM ubuntu:xenial---> 5e8b97a2a082
Step 2/3 : ENV name Docker---> Using cache---> 0ebb88d446f9
Step 3/3 : CMD echo "hello $name"---> Running in a06dce28b737
Removing intermediate container a06dce28b737---> 04b36269a3c8
Successfully built 04b36269a3c8
Successfully tagged vincent/ubuntu-cmd-shell:latest

查看我们现在有哪些image?

iie4bu@hostdocker:~/ddy/docker3$ docker image ls
REPOSITORY                                      TAG                 IMAGE ID            CREATED              SIZE
vincent/ubuntu-cmd-shell                        latest              04b36269a3c8        About a minute ago   114MB
vincent/ubuntu-entrypoint-exec                  latest              02dde803e324        20 minutes ago       114MB
vincent/ubuntu-entrypoint-shell                 latest              37a8a7654a8f        36 minutes ago       114MB

我们执行ubuntu-cmd-shell

iie4bu@hostdocker:~/ddy/docker3$ docker run vincent/ubuntu-cmd-shell
hello Docker
iie4bu@hostdocker:~/ddy/docker3$ 

可以正常执行。如果我们用-it,那么就不会打印输出hello Docker了

iie4bu@hostdocker:~/ddy/docker3$ docker run -it vincent/ubuntu-cmd-shell /bin/bash
root@bf0f8f7f6de1:/# 

然而,我们使用ubuntu-entrypoint-shell就不会出现这种情况,依然会打印输出hello Docker

iie4bu@hostdocker:~/ddy/docker3$ docker run -it vincent/ubuntu-entrypoint-shell /bin/bash
hello Docker
iie4bu@hostdocker:~/ddy/docker3$

EXPOSE

会把我们运行的container中的端口暴露出来。

构建Dockerfile

iie4bu@hostdocker:~/ddy/hello-world$ docker build -t ddy/hello-world .
Sending build context to Docker daemon  916.5kB
Step 1/3 : FROM scratch--->
Step 2/3 : ADD hello /---> d1a03c513631
Step 3/3 : CMD ["/hello"]---> Running in 7d10f24a5f54
Removing intermediate container 7d10f24a5f54---> 9fe0d93646ea
Successfully built 9fe0d93646ea
Successfully tagged ddy/hello-world:latest
iie4bu@hostdocker:~/ddy/hello-world$ docker images
REPOSITORY                                      TAG                 IMAGE ID            CREATED             SIZE
ddy/hello-world                                 latest              9fe0d93646ea        12 seconds ago      913kB

使用docker history imageID可以查看镜像的层级

iie4bu@hostdocker:~/ddy/hello-world$ docker history 9fe0d93646ea
IMAGE               CREATED              CREATED BY                                      SIZE                COMMENT
9fe0d93646ea        About a minute ago   /bin/sh -c #(nop)  CMD ["/hello"]               0B
d1a03c513631        About a minute ago   /bin/sh -c #(nop) ADD file:ac94667f27379ec68…   913kB

运行镜像

iie4bu@hostdocker:~/ddy/hello-world$ docker run ddy/hello-world
hello docker

说明镜像构建好了。

container

container是通过Image构建,是在image layer(只读)之上建立的container layer(可读可写)。好比是java中类与对象之间的关系。image负责App的存储和分发,container负责运行App。

使用docker run IMAGENAME 可以创建一个container。默认不写tag会指定latest版本

iie4bu@hostdocker:~/ddy/hello-world$ docker run ddy/hello-world

列举正在运行的container:

iie4bu@hostdocker:~$ docker container ls
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

可以发现什么都没有,因为hello-world container运行完hello docker后就退出了,不是一个常驻内存的进程。可以使用docker container ls -a来列举出所有容器包括正在运行的和退出的。

iie4bu@hostdocker:~$ docker container ls -a
CONTAINER ID        IMAGE                                                 COMMAND                  CREATED             STATUS                         PORTS                    NAMES
6d9bcf87eac4        ddy/hello-world                                       "/hello"                 About an hour ago   Exited (0) About an hour ago

Dockerfile中的CMD就是这里的COMMAND命令。

交互式运行容器

命令:docker run -it hello-word

例如我们有一个ubuntu的景象:

iie4bu@hostdocker:~/ddy/hello-world$ docker images
REPOSITORY                                      TAG                 IMAGE ID            CREATED             SIZE
ubuntu                                          xenial              5e8b97a2a082        12 months ago       114MB

尝试交互式运行ubuntu:

iie4bu@hostdocker:~$ docker run -it ubuntu:xenial
root@51f52b351e2c:/# ls
bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var

查看当前container运行:

iie4bu@hostdocker:~/ddy/hello-world$ docker container ls
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
51f52b351e2c        ubuntu:xenial       "/bin/bash"         44 seconds ago      Up 43 seconds                           zealous_spence

当我们退出ubuntu镜像时,使用exit命令,这时docker container ls就不会有这个镜像了,使用docker container ls -a可以看到刚刚的镜像已经退出了。

iie4bu@hostdocker:~$ docker container ls
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
iie4bu@hostdocker:~$ docker container ls -a
CONTAINER ID        IMAGE                                                 COMMAND                  CREATED             STATUS                        PORTS                    NAMES
51f52b351e2c        ubuntu:xenial                                         "/bin/bash"              6 minutes ago       Exited (127) 13 seconds ago                            zealous_spence

我们每创建一个容器,都会在我们之前的image之上多了一层。

docker container ls -a 与 docker ps -a 命令是一样的。

删除一个container命令:

iie4bu@hostdocker:~$ docker container rm 51f52b351e2c
51f52b351e2c

实际上使用命令docker rm 51f52b351e2c 默认就是删除一个container

docker image rm imageID 等同于 docker rmi imageID

docker image ls 等同于 docker images

docker container ls 等同于 docker ps

docker container commit

这条命令的意思是基于某个image创建一个container,然后我们在这个container里面做一些变化,例如安装了一些软件,然后我们可以把已经改变的container给commit一个新的image。这个命令一般可以简写成docker commit

我们先运行一个ubuntu的镜像:

iie4bu@hostdocker:~$ docker run -it ubuntu:xenial
root@803945a2c2d1:/# vim
bash: vim: command not found
root@803945a2c2d1:/#

这个镜像里面没有vim命令,然后我们安装vim

root@803945a2c2d1:/# apt-get update
root@803945a2c2d1:/# apt-get install vim

安装vim成功后,我们将这个container变为image

退出当前容器。查看当前容器:

root@803945a2c2d1:/# exit
exit
iie4bu@hostdocker:~$ docker container ls -a
CONTAINER ID        IMAGE                                                 COMMAND                  CREATED             STATUS                        PORTS                    NAMES
803945a2c2d1        ubuntu:xenial                                         "/bin/bash"              7 minutes ago       Exited (0) 8 seconds ago                               sharp_turing

将当前container commit为一个新的image:

iie4bu@hostdocker:~$ docker commit sharp_turing vincent/ubuntu-vim
sha256:697cdaba05dc77867ea5067b9d729b78f91aa05cbed872897d5e28cc40decd21
iie4bu@hostdocker:~$ docker image ls
REPOSITORY                                      TAG                 IMAGE ID            CREATED             SIZE
vincent/ubuntu-vim                              latest              697cdaba05dc        22 seconds ago      213MB

我们看到我们自己的image已经生成了。我们查看这个image与之前ubuntuimage的层级结构有什么不同。

iie4bu@hostdocker:~$ docker image ls
REPOSITORY                                      TAG                 IMAGE ID            CREATED             SIZE
vincent/ubuntu-vim                              latest              697cdaba05dc        22 seconds ago      213MB
ddy/hello-world                                 latest              9fe0d93646ea        5 hours ago         913kB
<none>                                          <none>              37705341d15d        2 months ago        643MB
prom/prometheus                                 latest              0694fc214c9f        2 months ago        109MB
dgraph/dgraph                                   <none>              a3b60a6ee9a7        3 months ago        144MB
hello-world                                     latest              fce289e99eb9        5 months ago        1.84kB
tomcat                                          latest              78b258e36eed        7 months ago        463MB
<none>                                          <none>              0e2ca16d4311        11 months ago       45.4GB
ubuntu                                          xenial              5e8b97a2a082        12 months ago       114MB
docker.elastic.co/elasticsearch/elasticsearch   6.2.3               d8d340eb391b        15 months ago       542MB
java                                            8                   d23bdf5b1b1b        2 years ago         643MB
iie4bu@hostdocker:~$ docker history 5e8b97a2a082
IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT
5e8b97a2a082        12 months ago       /bin/sh -c #(nop)  CMD ["/bin/bash"]            0B
<missing>           12 months ago       /bin/sh -c mkdir -p /run/systemd && echo 'do…   7B
<missing>           12 months ago       /bin/sh -c sed -i 's/^#\s*\(deb.*universe\)$…   2.76kB
<missing>           12 months ago       /bin/sh -c rm -rf /var/lib/apt/lists/*          0B
<missing>           12 months ago       /bin/sh -c set -xe   && echo '#!/bin/sh' > /…   745B
<missing>           12 months ago       /bin/sh -c #(nop) ADD file:d37ff24540ea7700d…   114MB
iie4bu@hostdocker:~$ docker history 697cdaba05dc
IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT
697cdaba05dc        2 minutes ago       /bin/bash                                       99.3MB
5e8b97a2a082        12 months ago       /bin/sh -c #(nop)  CMD ["/bin/bash"]            0B
<missing>           12 months ago       /bin/sh -c mkdir -p /run/systemd && echo 'do…   7B
<missing>           12 months ago       /bin/sh -c sed -i 's/^#\s*\(deb.*universe\)$…   2.76kB
<missing>           12 months ago       /bin/sh -c rm -rf /var/lib/apt/lists/*          0B
<missing>           12 months ago       /bin/sh -c set -xe   && echo '#!/bin/sh' > /…   745B
<missing>           12 months ago       /bin/sh -c #(nop) ADD file:d37ff24540ea7700d…   114MB

我们看到新的image与5e8b97a2a082的image是一样的,我们只是在5e8b97a2a082的基础上加了一些东西。

这种方式创建image一般并不提倡,因为我们如果发布出去这个image,别人拿到这个image并不知道这个image是怎么产生的,很可能会把不安全的东西放到image中发布出去,这样就有安全问题。

我们一般提倡使用Dockerfile方式。

docker image build

可以简写为docker build。

我们先将上面的ubuntu-vim镜像删除掉:

iie4bu@hostdocker:~$ docker image rm 697
Untagged: vincent/ubuntu-vim:latest
Deleted: sha256:697cdaba05dc77867ea5067b9d729b78f91aa05cbed872897d5e28cc40decd21
Deleted: sha256:91ddbb337bcf4e6a6a13b3be81a86b195fbac5e66823c6be625a8cd46ffdab32

我们新建目录docker-ubuntu-vim,进入这个目录中新建Dockerfile,内容如下:

FROM ubuntu:xenial
RUN apt-get update
RUN apt-get install -y vim

FROM: 必不可少的命令,从某个镜像作为基。如 FROM <image_name> ,或者 FROM <image_name>:<tag>. 如果不加tag,默认为latest。先从本地镜像仓库去搜索基镜像,如过本地没有,在去网上docker registry去寻找。

apt-get install -y vim 如果不加-y,那么会被中断,导致安装不成功。

iie4bu@hostdocker:~/ddy/docker-ubuntu-vim$ docker build -t mydocker_id/ubuntu-vim-new .
Sending build context to Docker daemon  2.048kB
Step 1/3 : FROM ubuntu:xenial---> 5e8b97a2a082
Step 2/3 : RUN apt-get update---> Running in 37b5a57504d0

我们看到直接使用了ubuntu本地的image layer,5e8b97a2a082

在build的过程中,生成了一个临时的container,这个container id为37b5a57504d0,随后会把这个container删除掉,这一过程会在build的整个阶段可能会执行很多次。

查看image:

iie4bu@hostdocker:~/ddy/docker-ubuntu-vim$ docker image ls
REPOSITORY                                      TAG                 IMAGE ID            CREATED             SIZE
mydocker_id/ubuntu-vim-new                      latest              ddad98db69ba        8 minutes ago       213MB

从零开始学习docker(零)简单介绍Dockerfile相关推荐

  1. 【贪玩巴斯】Unity3D初学圣经(一)——学习要求 Unity简单介绍 游戏引擎介绍 课程体系介绍 「1-1 到 1-4 」—— 2021年12月9日

    Unity3D初学圣经 一 --学习要求 & Unity简单介绍 & 游戏引擎介绍 & 课程体系介绍 本文对应视频P1 1-1 到P2 1-4 1.学习要求 2.Unity简单 ...

  2. salesforce lightning零基础学习(一) lightning简单介绍以及org开启lightning

    lightning对于开发salesforce人员来说并不陌生,即使没有做过lightning开发,这个名字肯定也是耳熟能详.原来的博客基本都是基于classic基于配置以及开发,后期博客会以ligh ...

  3. [297]从零开始学习Docker

    这篇文章是我学习 Docker 的记录,大部分内容摘抄自 <<Docker - 从入门到实践>> 一书,并非本人原创. 学习过程中整理成适合我自己的笔记,其中也包含了我自己的实 ...

  4. 从零开始学习docker(十五)Swarm mode 介绍

    撸了今年阿里.头条和美团的面试,我有一个重要发现.......>>> 一般情况下,我们都在一台机器下部署容器,但实际情况下,应用如果只在一台机器上无法满足我们的需求,包含的容器比较多 ...

  5. 从零开始学习docker(十二)介绍Docker Compose基本使用

    撸了今年阿里.头条和美团的面试,我有一个重要发现.......>>> 默认情况下在mac或者Windows安装docker的时候会自动安装docker-compose.对于Linux ...

  6. 从零开始学习docker(十一)介绍Docker Compose yml文件介绍

    撸了今年阿里.头条和美团的面试,我有一个重要发现.......>>> 如果我们有一个App,他由多个container组成,那么这个App的维护会非常繁琐. 包括: 要从Docker ...

  7. 从零开始学习docker(六)部署一个稍微复杂一点的应用

    我们之前讲过部署一个简单的Python程序. 这一节我们将这个Python程序进行一个扩展,连接redis数据库,并对redis进行一些操作, 新建App.py,内容如下: from flask im ...

  8. Docker的简单介绍与安装(Windows10)

    目录 1.什么是Docker 2.Docker的应用场景 3.Docker 的优点 4.Docker 架构 5.Doker安装 Win10 系统 开启 Hyper-V 1.安装 Toolbox 2.运 ...

  9. 从零开始学习docker(十九)Swarm mode 集群服务间通信--RoutingMesh

    撸了今年阿里.头条和美团的面试,我有一个重要发现.......>>> 在上一节中,我们介绍了通过service create部署了wordpress和mysql,我们发现了几个问题: ...

最新文章

  1. 虚拟机类加载机制---类加载器
  2. WSAIoctl 函数详解
  3. 【设计模式:单例模式】使用单例模式加载properties文件
  4. mysql event使用,用MySQL的Event设置定时任务执行sql语句 | 老疯子
  5. 组合赋权法之python
  6. Leetcode-整数反转 C++
  7. PHP分页类的实现,返回结果未渲染,更容易在HTML中使用
  8. java中单,单|的意思,按位操作符详述
  9. 2018年高教社杯A题 高温作业专用服装设计
  10. Enigma密码机初步解析
  11. vant + Vue创建项目全过程
  12. html5画波形图,HTML5创建真实音乐波形图,使用 wavesurfer 快速实现
  13. 从实践角度重新理解BIO和NIO
  14. 裸金属虚拟化解决方案-工业一体机(1)
  15. sphinx使用笔记
  16. 2370 小机房的树
  17. Virus_JS3_PyAnalysisAndSummary
  18. linux无法粘贴文件
  19. List(updated 2023.01.29)
  20. WEBERP测试实录:一 webERP安装

热门文章

  1. asp.net(c#)两时间段每天是星期几,周几(时间段日历显示)的问题解
  2. MySql 自适应哈希索引
  3. java中的void是什么?有什么作用?
  4. Vue的axios与ajax的区别:axios是对ajax的封装
  5. Yii的控制器等名称获取
  6. xml突然变成空白_“侏罗纪中期”出现了型增转变填补食肉性恐龙体型发展当中的空白...
  7. qt geomery的单位是什么_斜管沉淀池的原理是什么?
  8. 当退出python时是否释放全部内存_Python面试题:高级特性考察
  9. html教程自适应,Html-自适应
  10. python3.6 websocket异步高并发_Python3.6 websocket开发