docker快速入门教程_nvcr.io-程序员宅基地

技术标签: 5—Linux学习  1—Python学习  docker  

1 虚拟机和容器相关概念说明

1.1 虚拟机

虚拟可以解决环境配置方面的一些麻烦,但是虚拟机也有很多的缺点:

  • 资源占用多:虚拟机会单独占用一部分内存和硬盘空间,其他程序不能够使用这些资源,即使虚拟机里的应用程序使用的内存只有1MB,虚拟机依然需要几百MB内存才能运行
  • 冗余步骤多
  • 启动慢

1.2 Linux容器:

由于虚拟机存在这些缺点,Linux 发展出了另一种虚拟化技术:Linux 容器(Linux Containers,缩写为 LXC)。

Linux 容器不是模拟一个完整的操作系统,而是对进程进行隔离。或者说,在正常进程的外面套了一个保护层。对于容器里面的进程来说,它接触到的各种资源都是虚拟的,从而实现与底层系统的隔离。

由于容器是进程级别的,相比虚拟机有很多优势。

  • 启动快
  • 资源占用少
  • 体积小:容器只要包含用到的组件即可,而虚拟机是整个操作系统的打包,所以容器文件比虚拟机文件要小很多。

总之,容器有点像轻量级的虚拟机,能够提供虚拟化的环境,但是成本开销小得多

1.3 Docker 是什么?

Docker属于 Linux 容器的一种封装,提供简单易用的容器使用接口。它是目前最流行的 Linux 容器解决方案。

Docker 将应用程序该程序的依赖打包在一个文件里面。运行这个文件,就会生成一个虚拟容器。程序在这个虚拟容器里运行,就好像在真实的物理机上运行一样。有了 Docker,就不用担心环境问题。

总体来说,Docker 的接口相当简单,用户可以方便地创建和使用容器,把自己的应用放入容器。容器还可以进行版本管理复制分享修改,就像管理普通的代码一样。

1.4 Docker 的用途

Docker 的主要用途,目前有三大类。

(1)提供一次性的环境。比如,本地测试他人的软件、持续集成的时候提供单元测试和构建的环境。

(2)提供弹性的云服务。因为 Docker 容器可以随开随关,很适合动态扩容和缩容。

(3)组建微服务架构。通过多个容器,一台机器可以跑多个服务,因此在本机就可以模拟出微服务架构。

2 docker的安装、添加用户组和启动

2.1 docker在不同系统中的安装

2.2 验证docker是否安装成功的命令

docker versiondocker info

2.3 把docker添加到用户组中

Docker需要用户具有sudo 权限,为了避免每次使用docker命令都输入sudo,可以把用户加入 Docker 用户组(官方文档

sudo usermod -aG docker $USER

2.4 启动docker

Docker 是服务器----客户端架构。命令行运行docker命令的时候,需要本机有 Docker 服务。如果这项服务没有启动,可以用下面的命令启动(官方文档)。

  • service 命令的用法

sudo service docker start

  • systemctl 命令的用法

sudo systemctl start docker

3 image文件(镜像文件)

1、Docker的镜像文件

Docker应用程序及其依赖打包在 image 文件里面。只有通过这个文件,才能生成 Docker 容器image 文件可以看作是容器的模板。Docker 根据 image 文件生成容器的实例。同一个 image 文件,可以生成多个同时运行的容器实例。

image 是二进制文件。实际开发中,一个 image 文件往往通过继承另一个 image 文件,加上一些个性化设置而生成。举例来说,你可以在 Ubuntu 的 image 基础上,往里面加入 Apache 服务器,形成你的 image。

注意:

image镜像创建的实例container容器,因此,同一个image文件可以生成多个同时运行的容器,容器可以删除,并不会把镜像删除!

2、列出本机的所有镜像文件

docker image ls

docker images

3、删除 image 文件

docker image rm [imageName]

image 文件通用的,一台机器的 image 文件拷贝到另一台机器,照样可以使用。一般来说,为了节省时间,我们应该尽量使用别人制作好的 image 文件,而不是自己制作。即使要定制,也应该基于别人的 image 文件进行加工,而不是从零开始制作。

为了方便共享,image 文件制作完成后,可以上传到网上的仓库。Docker 的官方仓库Docker Hub 是最重要、最常用的 image 仓库。此外,出售自己制作的 image 文件也是可以的。

4 实例:hello-world镜像

4.1 查看和删除本地已经有的镜像

1、查看本机当前有哪些镜像:

docker image ls

(base) shl@zhihui-mint:~$ docker image ls
REPOSITORY                TAG                 IMAGE ID            CREATED             SIZE
<none>                    <none>              c3c7ef3f55e6        2 months ago        6.76GB
nvcr.io/nvidia/tensorrt   20.09-py3           b1386993f571        5 months ago        5.75GB
hello-world               latest              bf756fb1ae65        14 months ago       13.3kB
(base) shl@zhihui-mint:~$ 

由于,我们要演示hello-world镜像,我们先删除它

2、删除镜像

docker rm imageName

如下,我们删除hello-world镜像

(base) shl@zhihui-mint:~$ docker image rm hello-world
Error response from daemon: conflict: unable to remove repository reference "hello-world" (must force) - container b9f6617d1ee5 is using its referenced image bf756fb1ae65
(base) shl@zhihui-mint:~$ 

4.2 删除镜像的时候报错:Error response from daemon: conflict: unable to remove repository reference

删除的时候报错了,我们看到说hello-world镜像,依赖b9f6617d1ee5容器,因此,如果要删除hello-world镜像需要先删除这个依赖的b9f6617d1ee5容器

1、删除镜像依赖的容器

(base) shl@zhihui-mint:~$ docker rm b9f6617d1ee5
b9f6617d1ee5
(base) shl@zhihui-mint:~$ 

依赖的容器可能不只一个,如果有多个,用同样的方法删除!

2、之后再删除指定名子的image镜像,即可:

docker image rm hello-world

也可以指定镜像的版本号:

docker image rm hello-world:latest

3、具体删除过程如下

(base) shl@zhihui-mint:~$ docker image rm hello-world
Untagged: hello-world:latest
Untagged: hello-world@sha256:1a523af650137b8accdaed439c17d684df61ee4d74feac151b5b337bd29e7eec
Untagged: hello-world@sha256:8c5aeeb6a5f3ba4883347d3747a7249f491766ca1caa47e5da5dfcf6b9b717c0
Deleted: sha256:bf756fb1ae65adf866bd8c456593cd24beb6a0a061dedf42b26a993176745f6b
Deleted: sha256:9c27e219663c25e0f28493790cc0b88bc973ba3b1686355f221c38a36978ac63
(base) shl@zhihui-mint:~$

4、再次查看,此时hello-world镜像已经被删除

(base) shl@zhihui-mint:~$ docker image ls
REPOSITORY                TAG                 IMAGE ID            CREATED             SIZE
<none>                    <none>              c3c7ef3f55e6        2 months ago        6.76GB
nvcr.io/nvidia/tensorrt   20.09-py3           b1386993f571        5 months ago        5.75GB
(base) shl@zhihui-mint:~$ 

参考删除镜像依赖的容器

4.3 列出所有的容器

1、 列出所有运行或没有运行的容器 docker ps -a

docker ps -a

(base) shl@zhihui-mint:~$ docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                    PORTS               NAMES
dc0d85ad579f        c3c7ef3f55e6        "/bin/sh -c 'cmake  …"   2 months ago        Exited (2) 2 months ago                       fervent_solomon
fb290564f3f7        c3c7ef3f55e6        "/bin/sh -c 'cmake  …"   2 months ago        Exited (2) 2 months ago                       gracious_tu
c82060ce8175        c3c7ef3f55e6        "/bin/sh -c 'cmake  …"   2 months ago        Exited (2) 2 months ago                       silly_volhard
0ecdbc939f4b        c3c7ef3f55e6        "/bin/sh -c 'cmake  …"   2 months ago        Exited (2) 2 months ago                       confident_nash
e389c1150a0f        c3c7ef3f55e6        "/bin/sh -c 'cmake  …"   2 months ago        Exited (2) 2 months ago                       sweet_rhodes
a1985afa6eeb        c3c7ef3f55e6        "/bin/sh -c 'cmake  …"   2 months ago        Exited (2) 2 months ago                       dazzling_bardeen
97de8f36fbb2        c3c7ef3f55e6        "/bin/sh -c 'cmake  …"   2 months ago        Exited (2) 2 months ago                       confident_chaum
259c012fd055        c3c7ef3f55e6        "/bin/sh -c 'cmake  …"   2 months ago        Exited (2) 2 months ago                       fervent_bardeen
a9a1d44d0bee        c3c7ef3f55e6        "/bin/sh -c 'cmake  …"   2 months ago        Exited (2) 2 months ago                       flamboyant_benz
fa9df3e92577        c3c7ef3f55e6        "/bin/sh -c 'cmake  …"   2 months ago        Exited (2) 2 months ago                       beautiful_zhukovsky
fc329df9dcf3        03b55962b0b5        "/bin/sh -c 'wget ht…"   2 months ago        Exited (9) 2 months ago                       busy_bassi
(base) shl@zhihui-mint:~$ 

2、停止所有的容器

停止container,这样才能够删除其中的images:,停止所有的容器:

docker stop $(docker ps -a -q)

(base) shl@zhihui-mint:~$ docker stop $(docker ps -a -q)
dc0d85ad579f
fb290564f3f7
c82060ce8175
0ecdbc939f4b
e389c1150a0f
a1985afa6eeb
97de8f36fbb2
259c012fd055
a9a1d44d0bee
fa9df3e92577
fc329df9dcf3
(base) shl@zhihui-mint:~$ 

3、删除所有的容器

如果想要删除所有container的话再加一个指令 ,狠心把容器都删除掉了,因为光停止还是不能删除镜像。

docker rm $(docker ps -a -q)

4、删除对应的image 镜像

相关容器关闭后,删除对应的images,通过image的id来指定删除谁

docker rmi ID 或 `docker image rm [imageName]

要删除全部image的话

docker rmi $(docker images -q)

4.4 把docker的镜像源换成国内镜像源

由于,下面用到的hello-world会到官网下载,但是速度比较慢,因此我们可以通过把镜像源改为国内的,提高镜像下载的速度!

我在Ubuntu18.04配置docker国内镜像源如下(参考):

1、创建一个/etc/docker/daemon.json文件,我的该目录下没有daemon.json文件:

sudo vim /etc/docker/daemon.json

2、添加如下内容:

{
    
  "registry-mirrors": ["https://docker.mirrors.ustc.edu.cn"]
}

3、重启docker服务

sudo service docker restart

4、使用下面的命令查看是否生效

docker info|grep Mirrors -A 1

5、输出如下信息,则表示配置成功,再次docker pull速度就会很快了!

(base) shl@zhihui-mint:~$ docker info|grep Mirrors -A 1
WARNING: No swap limit support
(base) shl@zhihui-mint:~$ sudo vim /etc/docker/daemon.json
(base) shl@zhihui-mint:~$ service docker restart
(base) shl@zhihui-mint:~$ docker info|grep Mirrors -A 1
WARNING: No swap limit support
 Registry Mirrors:
  https://docker.mirrors.ustc.edu.cn/
(base) shl@zhihui-mint:~$ 

4.5 实例:hello-world镜像

下面,我们通过最简单的 image 文件"hello world",感受一下 Docker。

1、将hello-world的 image 文件从仓库抓取到本地

docker image pull library/hello-world

(base) shl@zhihui-mint:~$ docker image ls
REPOSITORY                TAG                 IMAGE ID            CREATED             SIZE
<none>                    <none>              c3c7ef3f55e6        2 months ago        6.76GB
nvcr.io/nvidia/tensorrt   20.09-py3           b1386993f571        5 months ago        5.75GB
(base) shl@zhihui-mint:~$ 
(base) shl@zhihui-mint:~$ docker image pull library/hello-world
Using default tag: latest
latest: Pulling from library/hello-world
0e03bdcc26d7: Pull complete 
Digest: sha256:7e02330c713f93b1d3e4c5003350d0dbe215ca269dd1d84a4abc577908344b30
Status: Downloaded newer image for hello-world:latest
docker.io/library/hello-world:latest
(base) shl@zhihui-mint:~$ docker image ls
REPOSITORY                TAG                 IMAGE ID            CREATED             SIZE
<none>                    <none>              c3c7ef3f55e6        2 months ago        6.76GB
nvcr.io/nvidia/tensorrt   20.09-py3           b1386993f571        5 months ago        5.75GB
hello-world               latest              bf756fb1ae65        14 months ago       13.3kB
(base) shl@zhihui-mint:~$ 

上面代码中,docker image pull是抓取 image 文件的命令。library/hello-worldimage 文件仓库里面的位置,其中libraryimage 文件所在的组hello-worldimage 文件的名字

由于 Docker 官方提供的 image 文件,都放在library组里面,所以它的是默认组,可以省略。因此,上面的命令可以写成下面这样。

docker image pull hello-world

2、先查看一下当前有没有运行的container容器:

docker container ls

docker ps

列出当前运行的容器:


(base) shl@zhihui-mint:~$ docker container ls
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
(base) shl@zhihui-mint:~$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
(base) shl@zhihui-mint:~$ 

3、从hello-world镜像生成一个容器,并运行它

docker container run hello-world

运行hello-world镜像文件,其实就是从这个image生成一个container容器实例:

docker container run命令会从image 文件,生成一个正在运行的容器实例

注意,docker container run命令具有自动抓取 image 文件的功能。如果发现本地没有指定的 image 文件,就会从仓库自动抓取。因此,前面的docker image pull命令并不是必需的步骤。

如果运行成功,输出如下信息:

(base) shl@zhihui-mint:~$ docker container run hello-world

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/

(base) shl@zhihui-mint:~$ docker container ls
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
(base) shl@zhihui-mint:~$ docker ps

输出这段提示以后,hello world就会停止运行容器自动终止。因此我们查看的哪些正在运行的容器时,hello-world生成的容器已经终止!

4、如果想要列出所有的容器,包括已经终止的容器:

docker container ls -a

(base) shl@zhihui-mint:~$ docker container ls -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                     PORTS               NAMES
d93acb74ecfe        hello-world         "/hello"            9 minutes ago       Exited (0) 9 minutes ago                       charming_jang
(base) shl@zhihui-mint:~$ 

有些容器不会自动终止,因为提供的是服务。比如,安装运行 Ubuntu 的 image,就可以在命令行体验 Ubuntu 系统。

docker container run -it ubuntu bash

对于那些不会自动终止的容器,必须使用docker container kill 命令手动终止。

docker container kill [containID]

5 container容器文件:

image 文件生成的容器实例本身也是一个文件,称为容器文件。也就是说,一旦容器生成,就会同时存在两个文件:image 文件容器文件。而且关闭容器并不会删除容器文件只是容器停止运行而已

1、列出本机正在运行的容器

docker container lsdocker ps

2、列出本机所有容器,包括终止运行的容器

docker container ls --all

上面命令的输出结果之中,包括容器的 ID。很多地方都需要提供这个 ID,比如上一节终止容器运行的docker container kill命令。

3、删除容器文件

终止运行的容器文件,依然会占据硬盘空间,可以使用docker container rm命令删除。

docker container rm [containerID]

(base) shl@zhihui-mint:~$ docker container ls -all
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                      PORTS               NAMES
f6294aa75c40        hello-world         "/hello"            29 minutes ago      Exited (0) 29 minutes ago                       nice_dirac
(base) shl@zhihui-mint:~$ docker container rm f6294aa75c40
f6294aa75c40
(base) shl@zhihui-mint:~$ docker container ls -all
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                    PORTS               NAMES
dc0d85ad579f        c3c7ef3f55e6        "/bin/sh -c 'cmake  …"   2 months ago        Exited (2) 2 months ago                       fervent_solomon
(base) shl@zhihui-mint:~$ 

6 Dockerfile文件

学会使用 image 文件以后,接下来的问题就是,如何可以生成 image 文件?如果你要推广自己的软件,势必要自己制作 image 文件。

这就需要用到 Dockerfile 文件。它是一个文本文件,用来配置 image。Docker 根据 该文件生成二进制的 image 文件

下面通过一个实例,演示如何编写 Dockerfile 文件。

7 实例:制作自己的 Docker 容器

7.1 准备工作

7.1.1 克隆代码

下面我以 koa-demos 项目为例,介绍怎么写 Dockerfile 文件,实现让用户在 Docker 容器里面运行 Koa 框架。

作为准备工作,请先下载源码

$ git clone https://github.com/ruanyf/koa-demos.git
$ cd koa-demos

7.1.2 安装npm工具

由于下面编写的Dockerfile文件中会用到npm命令,因此我们需要先安装一下:

在build建立之前,需要先安装npm:

1、在Ubuntu18.04上安装npm参考:https://blog.csdn.net/wangtaoking1/article/details/78005038

(base) shl@zhihui-mint:~/koa-demos$ sudo apt install nodejs-dev
正在读取软件包列表... 完成
正在分析软件包的依赖关系树
正在读取状态信息... 完成 
您也许需要运行“apt --fix-broken install”来修正上面的错误。
下列软件包有未满足的依赖关系:
 nodejs-dev : 依赖: libssl1.0-dev (>= 1.0.2) 但是它将不会被安装
              依赖: libuv1-dev (>= 1.15.0) 但是它将不会被安装
              依赖: nodejs (= 8.10.0~dfsg-2ubuntu0.4) 但是它将不会被安装
 ros-melodic-librviz-tutorial : 依赖: ros-melodic-rviz 但是它将不会被安装
 ros-melodic-pluginlib : 依赖: ros-melodic-class-loader 但是它将不会被安装
 ros-melodic-rqt-rviz : 依赖: ros-melodic-rviz 但是它将不会被安装
 ros-melodic-rviz-plugin-tutorials : 依赖: ros-melodic-rviz 但是它将不会被安装
 ros-melodic-rviz-python-tutorial : 依赖: ros-melodic-rviz 但是它将不会被安装
E: 有未能满足的依赖关系。请尝试不指明软件包的名字来运行“apt --fix-broken install”(也可以指定一个解决办法)(base) shl@zhihui-mint:~/koa-demos$ sudo apt --fix-broken install

先修正上面的错误:sudo apt install --fix-broken

2、安装好npm之后,做好准备工作:

(base) shl@zhihui-mint:~/koa-demos$ node -v
v8.17.0
(base) shl@zhihui-mint:~/koa-demos$ npm -v
6.13.4
(base) shl@zhihui-mint:~/koa-demos$ du --max-depth=1 -h
832K	./.git
92K	./demos
996K	.
(base) shl@zhihui-mint:~/koa-demos$ ls
demos  Dockerfile  logo.png  package.json  package-lock.json  README.md
(base) shl@zhihui-mint:~/koa-demos$ 

7.2 编写Dockerfile文件

1、首先,在项目的根目录下,新建一个文本文件.dockerignore,写入下面的内容。

.git
node_modules
npm-debug.log

上面代码表示,这三个路径要排除,不要打包进入 image 文件。如果你没有路径要排除,这个文件可以不新建。

2、然后,在项目的根目录下,新建一个文本文件Dockerfile,写入下面的内容。

FROM node:8.4
COPY . /app
WORKDIR /app
RUN npm install --registry=https://registry.npm.taobao.org
EXPOSE 3000

上面代码一共五行,含义如下。

  • FROM node:8.4:该 image 文件继承官方的 node image,冒号表示标签,这里标签是8.4,即8.4版本的 node。
  • COPY . /app:将当前目录下的所有文件(除了.dockerignore排除的路径),都拷贝进入 image 文件的/app目录。
  • WORKDIR /app:指定接下来的工作路径为/app。
  • RUN npm install:在/app目录下,运行npm install命令安装依赖。注意,安装后所有的依赖,都将打包进入 image 文件。
  • EXPOSE 3000:将容器 3000 端口暴露出来, 允许外部连接这个端口。

7.3 创建 image 文件

有了 Dockerfile 文件以后,就可以使用docker image build命令创建 image 文件了。

docker image build -t koa-demo .
# 或者
docker image build -t koa-demo:0.0.1 .

上面代码中,-t参数用来指定image 文件名字,后面还可以用冒号指定标签。如果不指定,默认的标签就是latest。最后的那个点表示 Dockerfile 文件所在的路径,上例是当前路径,所以是一个点。

如果运行成功,就可以看到新生成的 image 文件koa-demo了。

(base) shl@zhihui-mint:~/koa-demos$ docker image build -t koa-demo .
Sending build context to Docker daemon    318kB
Step 1/5 : FROM node:8.4
 ---> 386940f92d24
Step 2/5 : COPY . /app
 ---> Using cache
 ---> c1a000787102
Step 3/5 : WORKDIR /app
 ---> Using cache
 ---> 27f49f07b13c
Step 4/5 : RUN ["npm", "install"]
 ---> Using cache
 ---> 8b827c8f4fa2
Step 5/5 : EXPOSE 3000/tcp
 ---> Using cache
 ---> 550298705df4
Successfully built 550298705df4
Successfully tagged koa-demo:latest
(base) shl@zhihui-mint:~/koa-demos$ 

可以看出,build建立镜像文件的步骤,就是执行我们编写的Dockerfile文件中内容的步骤!

docker image ls

base) shl@zhihui-mint:~/koa-demos$ docker images
REPOSITORY                TAG                 IMAGE ID            CREATED             SIZE
koa-demo                  latest              550298705df4        20 minutes ago      676MB
<none>                    <none>              c3c7ef3f55e6        2 months ago        6.76GB
nvcr.io/nvidia/tensorrt   20.09-py3           b1386993f571        5 months ago        5.75GB
hello-world               latest              bf756fb1ae65        14 months ago       13.3kB
node                      8.4                 386940f92d24        3 years ago         673MB
(base) shl@zhihui-mint:~/koa-demos$ 

7.4 生成容器

1、docker container run命令会从 image 文件生成容器。

docker container run -p 8000:3000 -it koa-demo /bin/bash
# 或者
docker container run -p 8000:3000 -it koa-demo:0.0.1 /bin/bash

# 也可以通过-v参数,把本地的路径映射到docker容器中的目录,这样当容器被删除的时候,保存到本地的路径中的文件也不会被删除
# docker container run -p 8000:3000 -v /home/shl/shl_res/3_data/Aachen-Day-Night:/app -it koa-demo /bin/bash 

上面命令的各个参数含义如下:

  • -p参数容器3000 端口映射到本机8000 端口
  • -it参数容器的 Shell映射到当前的 Shell,然后你在本机窗口输入的命令,就会传入容器。
  • koa-demo:0.0.1:image 文件的名字(如果有标签,还需要提供标签,默认是 latest 标签)。
  • /bin/bash容器启动以后,内部第一个执行的命令。这里是启动 Bash,保证用户可以使用 Shell。
    如果一切正常,运行上面的命令以后,就会返回一个命令行提示符。

运行结果如下:

(base) shl@zhihui-mint:~/koa-demos$ docker container ls 
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
(base) shl@zhihui-mint:~/koa-demos$ docker container run -p 8000:3000 -it koa-demo /bin/bash
root@50eeaecac940:/app# ls
Dockerfile  README.md  demos  logo.png	node_modules  package-lock.json  package.json
root@50eeaecac940:/app# 

这表示你已经在容器里面了,返回的提示符就是容器内部的 Shell 提示符50eeaecac940是容器的ID

2、此时启动的容器,就相当于是一个微核的linux:

root@50eeaecac940:/app# ls
Dockerfile  README.md  demos  logo.png	node_modules  package-lock.json  package.json
root@50eeaecac940:/app# cd /home/
root@50eeaecac940:/home# ls
node
root@50eeaecac940:/home# apt -h
apt 1.0.9.8.4 for amd64 compiled on Dec 11 2016 09:48:19
Usage: apt [options] command

CLI for apt.
Basic commands: 
 list - list packages based on package names
 search - search in package descriptions
 show - show package details

 update - update list of available packages

 install - install packages
 remove  - remove packages

 upgrade - upgrade the system by installing/upgrading packages
 full-upgrade - upgrade the system by removing/installing/upgrading packages

 edit-sources - edit the source information file
root@50eeaecac940:/home# 

3、此时你再打开一个终端,就可以查看到正在运行的容器:

(base) shl@zhihui-mint:~$ docker container ls
CONTAINER ID        IMAGE               COMMAND             CREATED              STATUS              PORTS                    NAMES
50eeaecac940        koa-demo            "/bin/bash"         About a minute ago   Up About a minute   0.0.0.0:8000->3000/tcp   epic_germain
(base) shl@zhihui-mint:~$ 

4、执行下面的命令。

root@50eeaecac940:/app# node demos/01.js

root@50eeaecac940:/app# ls demos/
01.js  03.js  05.js  07.js  09.js  11.js  13.js  15.js	17.js  19.js  21.js
02.js  04.js  06.js  08.js  10.js  12.js  14.js  16.js	18.js  20.js  template.html
root@50eeaecac940:/app# node demos/01.js 

这时,Koa 框架已经运行起来了。打开本机的浏览器,访问 http://127.0.0.1:8000,网页显示"Not Found",这是因为这个 demo 没有写路由。

在这里插入图片描述

你也可以运行其他的js文件,如下是运行:root@50eeaecac940:/app# node demos/02.js,在浏览器中打开的结果:

在这里插入图片描述

这个例子中,Node 进程运行在Docker 容器的虚拟环境里面,进程接触到的文件系统网络接口都是虚拟的,与本机的文件系统和网络接口是隔离的,因此需要定义容器物理机端口映射(map)。因为已经将容器的端口3000映射到本机的8000端口,因此只要容器运行,就可以通过本机的8000端口访问到容器的3000端口,从而访问容器的服务!

现在,在容器的命令行,按下 Ctrl + c 停止 Node 进程,然后按下Ctrl + d(或者输入exit退出容器。此外,也可以用docker container kill终止容器运行。

在本机的另一个终端窗口,查出容器的 ID

docker container ls

停止指定的容器运行

docker container kill [containerID]

容器停止运行之后,并不会消失,用下面的命令删除容器文件。

查出容器的 ID
$ docker container ls --all

删除指定的容器文件
$ docker container rm [containerID]
也可以使用docker container run命令的–rm参数,在容器终止运行后自动删除容器文件。

$ docker container run --rm -p 8000:3000 -it koa-demo /bin/bash

7.5 CMD 命令

上一节的例子里面,容器启动以后,需要手动输入命令node demos/01.js。我们可以把这个命令写在 Dockerfile 里面,这样容器启动以后,这个命令就已经执行了,不用再手动输入了。

FROM node:8.4
COPY . /app
WORKDIR /app
RUN npm install --registry=https://registry.npm.taobao.org
EXPOSE 3000
CMD node demos/01.js

上面的 Dockerfile 里面,多了最后一行CMD node demos/01.js,它表示容器启动后自动执行node demos/01.js。

你可能会问,RUN命令与CMD命令的区别在哪里?简单说,RUN命令image 文件的构建阶段执行,执行结果都会打包进入 image 文件;CMD命令则是在容器启动后执行。另外,一个 Dockerfile可以包含多个RUN命令,但是只能有一个CMD命令

注意 :

指定了CMD命令以后,docker container run命令就不能附加命令了(比如前面的/bin/bash),否则它会覆盖CMD命令。现在,启动容器可以使用下面的命令。

docker container run --rm -p 8000:3000 -it koa-demo:0.0.1

7.6 发布 image 文件

容器运行成功后,就确认了 image 文件的有效性。这时,我们就可以考虑把 image 文件分享到网上,让其他人使用。

1、首先,去hub.docker.comcloud.docker.com注册一个账户。然后,用下面的命令登录

docker login

2、接着,为本地的 image 标注用户名和版本。

docker image tag [imageName] [username]/[repository]:[tag]

实例

docker image tag koa-demos:0.0.1 ruanyf/koa-demos:0.0.1

也可以不标注用户名,重新构建一下 image 文件。

docker image build -t [username]/[repository]:[tag] .

3 、最后,发布 image 文件。

docker image push [username]/[repository]:[tag]

发布成功以后,登录 hub.docker.com,就可以看到已经发布的 image 文件

8 其他有用的命令

1、docker container start

docker container run命令是新建容器,每运行一次,就会新建一个容器。同样的命令运行两次,就会生成两个一模一样的容器文件。如果希望重复使用容器,就要使用docker container start命令,它用来启动已经生成、已经停止运行的容器文件。

(base) shl@zhihui-mint:~/test$ docker container kill 50eeaecac940
50eeaecac940
(base) shl@zhihui-mint:~/test$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
(base) shl@zhihui-mint:~/test$ docker container start 50eeaecac940
50eeaecac940
(base) shl@zhihui-mint:~/test$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                    NAMES
50eeaecac940        koa-demo            "/bin/bash"         17 hours ago        Up 3 seconds        0.0.0.0:8000->3000/tcp   epic_germain
(base) shl@zhihui-mint:~/test$ 

3、docker container exec

docker container exec命令用于进入一个正在运行docker 容器

docker container exec -it [containerID] /bin/bash

(base) shl@zhihui-mint:~$ docker container ls
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                    NAMES
50eeaecac940        koa-demo            "/bin/bash"         17 hours ago        Up 17 hours         0.0.0.0:8000->3000/tcp   epic_germain
(base) shl@zhihui-mint:~$ docker container exec -it 50eeaecac940 /bin/bash
root@50eeaecac940:/app# ls
Dockerfile  README.md  demos  logo.png	node_modules  package-lock.json  package.json
root@50eeaecac940:/app# 

在本机上重开启一个终端,进入一个正在运行容器的bash,这种就是使用docker run的时候没有使用-it参数的时候,进入正在运行容器的bash!

4、docker container cp

docker container cp命令用于从正在运行的 Docker 容器里面,将文件 或 目录拷贝到本机

docker container cp [containID]:[/path/to/file] [local-path]

先查看容器中有哪些文件:

root@50eeaecac940:/app# ls
Dockerfile  README.md  demos  logo.png	node_modules  package-lock.json  package.json
root@50eeaecac940:/app# pwd   
/app

把容器中的文件或目录拷贝到本机系统中:

(base) shl@zhihui-mint:~/test$ ls
(base) shl@zhihui-mint:~/test$ pwd
/home/shl/test
(base) shl@zhihui-mint:~/test$ docker container cp 50eeaecac940:/app/logo.png /home/shl/test
(base) shl@zhihui-mint:~/test$ ls
logo.png
(base) shl@zhihui-mint:~/test$ docker container cp 50eeaecac940:/app/demos /home/shl/test
(base) shl@zhihui-mint:~/test$ ls
demos  logo.png
(base) shl@zhihui-mint:~/test$ ls demos/
01.js  03.js  05.js  07.js  09.js  11.js  13.js  15.js  17.js  19.js  21.js
02.js  04.js  06.js  08.js  10.js  12.js  14.js  16.js  18.js  20.js  template.html
(base) shl@zhihui-mint:~/test$ 

5、把本地文件或目录拷贝到容器中(参考

先查目录文件大小:

(base) shl@zhihui-mint:~/shl_res/3_data/Aachen-Day-Night$ du --max-depth=1 -h aachen/
24K	aachen/queries
2.2G	aachen/3D-models
3.0G	aachen/images
5.2G	aachen/
(base) shl@zhihui-mint:~/shl_res/3_data/Aachen-Day-Night$ cd aachen/

拷贝命令:

docker ps 本地路径 [container ID] : 容器路径

docker cp /home/shl/shl_res/3_data/Aachen-Day-Night/aachen 0ec87e3e109a:/app/datasets

成功拷贝可以发现磁盘空间也变小了,此时的容器

在这里插入图片描述

可以在容器中查看到文件已经被从本地拷贝到容器中:

在这里插入图片描述

6、把本地的目录或文件映射到docker容器中(参考):

docker run -it --rm -p 8888:8888 -v 本地目录: docker容器中的目录 hloc:latest
在这里插入图片描述

使用:-v参数进行映射,可以看到本地目录映射到容器目录之后,此时之前容器在该目录下的文件看不到了!

注意:

之所以看不到之前的容器,是因为使用了--rm参数,这个参数的意思,就是当运行一个容器的时候,如果容器已经存在,就删除创建一个新的容器!

9 docker常用命令总结

9.1 docker相关

1、查看docker版本信息

docker versinodocker info

2、docker添加到用户组,不用使用docker时每次输入sudo

sudo usermod -aG docker $USER

3、启动docker

sudo service docker startsudo systemctl start docker

9.2 image镜像相关命令

1、查看本机有哪些镜像文件

docker imagesdockr image ls

2、删除镜像文件

docker image rm [imageName]docker image rm [imageName]:[tag]

或:

docker rmi ID

3、强制删除镜像

docker image rm -f [imageName]docker image rm -f [imageName]:[tag]

或:

docker rmi -f ID

9.3 container容器相关命令

1、列出所有正在运行的容器

docker psdocker container ls

2、列出所有容器,包括终止运行的容器

docker container ls -adocker container ls --all

或:

docker ps -adocker ps --all

3、先远程仓库抓取镜像到本地

docker image pull library/[imageName]

或:

docker image pull [imageName]

4、运行容器

docker container run [imageName]

实例:

docker container run -p 8000:3000 -it koa-demo /bin/bash

5、停止运行容器

docker container kill [containerID] 或 在容器中输入:exit 或 直接在容器中按Ctrl+D 快捷键

使用这种方式,之前的容器就会被释放,你在容器中安装的环境,传入的文件都没有了,当你再次启动一个容器的时候,就会从新从镜像中安装,因此最好把需要的环境一开始就写到Dockerfile文件中,这样就可以把需要的环境都编译到image文件中!

退出容器之后,在容器中安装的额

6、删除容器

docker container rm [containerID]

7、重新运行终止的容器

docker container start [containerID]

8、进入一个正在运行容器的终端

docker container exec -it [containerID] /bin/bash

9、把容器中的文件或目录拷贝到本机

docker container cp [containID]:[/path/to/file] [local-path]

9.4 构建自己的image镜像

1、在.dockerignore中,编写不打包到image中的文件路径

.git
node_modules
npm-debug.log

2、编写Dockerfile文件

FROM node:8.4
COPY . /app
WORKDIR /app
RUN npm install --registry=https://registry.npm.taobao.org
EXPOSE 3000

3、创建image文件

docker image build -t koa-demo .
# 或者
docker image build -t koa-demo:0.0.1 .

创建成功后查看自己创建的镜像:

docker images

4 、用自己创建的镜像生成容器

docker container run -p 8000:3000 -it koa-demo /bin/bash
# 或者
docker container run -p 8000:3000 -it koa-demo:0.0.1 /bin/bash

参考:https://ruanyifeng.com/blog/2018/02/docker-tutorial.html


创作不易,观众老爷们请留步… 动起可爱的小手,点个赞再走呗 (๑◕ܫ←๑)
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_41010198/article/details/114311523

智能推荐

什么是内部类?成员内部类、静态内部类、局部内部类和匿名内部类的区别及作用?_成员内部类和局部内部类的区别-程序员宅基地

文章浏览阅读3.4k次,点赞8次,收藏42次。一、什么是内部类?or 内部类的概念内部类是定义在另一个类中的类;下面类TestB是类TestA的内部类。即内部类对象引用了实例化该内部对象的外围类对象。public class TestA{ class TestB {}}二、 为什么需要内部类?or 内部类有什么作用?1、 内部类方法可以访问该类定义所在的作用域中的数据,包括私有数据。2、内部类可以对同一个包中的其他类隐藏起来。3、 当想要定义一个回调函数且不想编写大量代码时,使用匿名内部类比较便捷。三、 内部类的分类成员内部_成员内部类和局部内部类的区别

分布式系统_分布式系统运维工具-程序员宅基地

文章浏览阅读118次。分布式系统要求拆分分布式思想的实质搭配要求分布式系统要求按照某些特定的规则将项目进行拆分。如果将一个项目的所有模板功能都写到一起,当某个模块出现问题时将直接导致整个服务器出现问题。拆分按照业务拆分为不同的服务器,有效的降低系统架构的耦合性在业务拆分的基础上可按照代码层级进行拆分(view、controller、service、pojo)分布式思想的实质分布式思想的实质是为了系统的..._分布式系统运维工具

用Exce分析l数据极简入门_exce l趋势分析数据量-程序员宅基地

文章浏览阅读174次。1.数据源准备2.数据处理step1:数据表处理应用函数:①VLOOKUP函数; ② CONCATENATE函数终表:step2:数据透视表统计分析(1) 透视表汇总不同渠道用户数, 金额(2)透视表汇总不同日期购买用户数,金额(3)透视表汇总不同用户购买订单数,金额step3:讲第二步结果可视化, 比如, 柱形图(1)不同渠道用户数, 金额(2)不同日期..._exce l趋势分析数据量

宁盾堡垒机双因素认证方案_horizon宁盾双因素配置-程序员宅基地

文章浏览阅读3.3k次。堡垒机可以为企业实现服务器、网络设备、数据库、安全设备等的集中管控和安全可靠运行,帮助IT运维人员提高工作效率。通俗来说,就是用来控制哪些人可以登录哪些资产(事先防范和事中控制),以及录像记录登录资产后做了什么事情(事后溯源)。由于堡垒机内部保存着企业所有的设备资产和权限关系,是企业内部信息安全的重要一环。但目前出现的以下问题产生了很大安全隐患:密码设置过于简单,容易被暴力破解;为方便记忆,设置统一的密码,一旦单点被破,极易引发全面危机。在单一的静态密码验证机制下,登录密码是堡垒机安全的唯一_horizon宁盾双因素配置

谷歌浏览器安装(Win、Linux、离线安装)_chrome linux debian离线安装依赖-程序员宅基地

文章浏览阅读7.7k次,点赞4次,收藏16次。Chrome作为一款挺不错的浏览器,其有着诸多的优良特性,并且支持跨平台。其支持(Windows、Linux、Mac OS X、BSD、Android),在绝大多数情况下,其的安装都很简单,但有时会由于网络原因,无法安装,所以在这里总结下Chrome的安装。Windows下的安装:在线安装:离线安装:Linux下的安装:在线安装:离线安装:..._chrome linux debian离线安装依赖

烤仔TVの尚书房 | 逃离北上广?不如押宝越南“北上广”-程序员宅基地

文章浏览阅读153次。中国发达城市榜单每天都在刷新,但无非是北上广轮流坐庄。北京拥有最顶尖的文化资源,上海是“摩登”的国际化大都市,广州是活力四射的千年商都。GDP和发展潜力是衡量城市的数字指...

随便推点

java spark的使用和配置_使用java调用spark注册进去的程序-程序员宅基地

文章浏览阅读3.3k次。前言spark在java使用比较少,多是scala的用法,我这里介绍一下我在项目中使用的代码配置详细算法的使用请点击我主页列表查看版本jar版本说明spark3.0.1scala2.12这个版本注意和spark版本对应,只是为了引jar包springboot版本2.3.2.RELEASEmaven<!-- spark --> <dependency> <gro_使用java调用spark注册进去的程序

汽车零部件开发工具巨头V公司全套bootloader中UDS协议栈源代码,自己完成底层外设驱动开发后,集成即可使用_uds协议栈 源代码-程序员宅基地

文章浏览阅读4.8k次。汽车零部件开发工具巨头V公司全套bootloader中UDS协议栈源代码,自己完成底层外设驱动开发后,集成即可使用,代码精简高效,大厂出品有量产保证。:139800617636213023darcy169_uds协议栈 源代码

AUTOSAR基础篇之OS(下)_autosar 定义了 5 种多核支持类型-程序员宅基地

文章浏览阅读4.6k次,点赞20次,收藏148次。AUTOSAR基础篇之OS(下)前言首先,请问大家几个小小的问题,你清楚:你知道多核OS在什么场景下使用吗?多核系统OS又是如何协同启动或者关闭的呢?AUTOSAR OS存在哪些功能安全等方面的要求呢?多核OS之间的启动关闭与单核相比又存在哪些异同呢?。。。。。。今天,我们来一起探索并回答这些问题。为了便于大家理解,以下是本文的主题大纲:[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JCXrdI0k-1636287756923)(https://gite_autosar 定义了 5 种多核支持类型

VS报错无法打开自己写的头文件_vs2013打不开自己定义的头文件-程序员宅基地

文章浏览阅读2.2k次,点赞6次,收藏14次。原因:自己写的头文件没有被加入到方案的包含目录中去,无法被检索到,也就无法打开。将自己写的头文件都放入header files。然后在VS界面上,右键方案名,点击属性。将自己头文件夹的目录添加进去。_vs2013打不开自己定义的头文件

【Redis】Redis基础命令集详解_redis命令-程序员宅基地

文章浏览阅读3.3w次,点赞80次,收藏342次。此时,可以将系统中所有用户的 Session 数据全部保存到 Redis 中,用户在提交新的请求后,系统先从Redis 中查找相应的Session 数据,如果存在,则再进行相关操作,否则跳转到登录页面。此时,可以将系统中所有用户的 Session 数据全部保存到 Redis 中,用户在提交新的请求后,系统先从Redis 中查找相应的Session 数据,如果存在,则再进行相关操作,否则跳转到登录页面。当数据量很大时,count 的数量的指定可能会不起作用,Redis 会自动调整每次的遍历数目。_redis命令

URP渲染管线简介-程序员宅基地

文章浏览阅读449次,点赞3次,收藏3次。URP的设计目标是在保持高性能的同时,提供更多的渲染功能和自定义选项。与普通项目相比,会多出Presets文件夹,里面包含着一些设置,包括本色,声音,法线,贴图等设置。全局只有主光源和附加光源,主光源只支持平行光,附加光源数量有限制,主光源和附加光源在一次Pass中可以一起着色。URP:全局只有主光源和附加光源,主光源只支持平行光,附加光源数量有限制,一次Pass可以计算多个光源。可编程渲染管线:渲染策略是可以供程序员定制的,可以定制的有:光照计算和光源,深度测试,摄像机光照烘焙,后期处理策略等等。_urp渲染管线

推荐文章

热门文章

相关标签