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

智能推荐

oracle 12c 集群安装后的检查_12c查看crs状态-程序员宅基地

文章浏览阅读1.6k次。安装配置gi、安装数据库软件、dbca建库见下:http://blog.csdn.net/kadwf123/article/details/784299611、检查集群节点及状态:[root@rac2 ~]# olsnodes -srac1 Activerac2 Activerac3 Activerac4 Active[root@rac2 ~]_12c查看crs状态

解决jupyter notebook无法找到虚拟环境的问题_jupyter没有pytorch环境-程序员宅基地

文章浏览阅读1.3w次,点赞45次,收藏99次。我个人用的是anaconda3的一个python集成环境,自带jupyter notebook,但在我打开jupyter notebook界面后,却找不到对应的虚拟环境,原来是jupyter notebook只是通用于下载anaconda时自带的环境,其他环境要想使用必须手动下载一些库:1.首先进入到自己创建的虚拟环境(pytorch是虚拟环境的名字)activate pytorch2.在该环境下下载这个库conda install ipykernelconda install nb__jupyter没有pytorch环境

国内安装scoop的保姆教程_scoop-cn-程序员宅基地

文章浏览阅读5.2k次,点赞19次,收藏28次。选择scoop纯属意外,也是无奈,因为电脑用户被锁了管理员权限,所有exe安装程序都无法安装,只可以用绿色软件,最后被我发现scoop,省去了到处下载XXX绿色版的烦恼,当然scoop里需要管理员权限的软件也跟我无缘了(譬如everything)。推荐添加dorado这个bucket镜像,里面很多中文软件,但是部分国外的软件下载地址在github,可能无法下载。以上两个是官方bucket的国内镜像,所有软件建议优先从这里下载。上面可以看到很多bucket以及软件数。如果官网登陆不了可以试一下以下方式。_scoop-cn

Element ui colorpicker在Vue中的使用_vue el-color-picker-程序员宅基地

文章浏览阅读4.5k次,点赞2次,收藏3次。首先要有一个color-picker组件 <el-color-picker v-model="headcolor"></el-color-picker>在data里面data() { return {headcolor: ’ #278add ’ //这里可以选择一个默认的颜色} }然后在你想要改变颜色的地方用v-bind绑定就好了,例如:这里的:sty..._vue el-color-picker

迅为iTOP-4412精英版之烧写内核移植后的镜像_exynos 4412 刷机-程序员宅基地

文章浏览阅读640次。基于芯片日益增长的问题,所以内核开发者们引入了新的方法,就是在内核中只保留函数,而数据则不包含,由用户(应用程序员)自己把数据按照规定的格式编写,并放在约定的地方,为了不占用过多的内存,还要求数据以根精简的方式编写。boot启动时,传参给内核,告诉内核设备树文件和kernel的位置,内核启动时根据地址去找到设备树文件,再利用专用的编译器去反编译dtb文件,将dtb还原成数据结构,以供驱动的函数去调用。firmware是三星的一个固件的设备信息,因为找不到固件,所以内核启动不成功。_exynos 4412 刷机

Linux系统配置jdk_linux配置jdk-程序员宅基地

文章浏览阅读2w次,点赞24次,收藏42次。Linux系统配置jdkLinux学习教程,Linux入门教程(超详细)_linux配置jdk

随便推点

matlab(4):特殊符号的输入_matlab微米怎么输入-程序员宅基地

文章浏览阅读3.3k次,点赞5次,收藏19次。xlabel('\delta');ylabel('AUC');具体符号的对照表参照下图:_matlab微米怎么输入

C语言程序设计-文件(打开与关闭、顺序、二进制读写)-程序员宅基地

文章浏览阅读119次。顺序读写指的是按照文件中数据的顺序进行读取或写入。对于文本文件,可以使用fgets、fputs、fscanf、fprintf等函数进行顺序读写。在C语言中,对文件的操作通常涉及文件的打开、读写以及关闭。文件的打开使用fopen函数,而关闭则使用fclose函数。在C语言中,可以使用fread和fwrite函数进行二进制读写。‍ Biaoge 于2024-03-09 23:51发布 阅读量:7 ️文章类型:【 C语言程序设计 】在C语言中,用于打开文件的函数是____,用于关闭文件的函数是____。

Touchdesigner自学笔记之三_touchdesigner怎么让一个模型跟着鼠标移动-程序员宅基地

文章浏览阅读3.4k次,点赞2次,收藏13次。跟随鼠标移动的粒子以grid(SOP)为partical(SOP)的资源模板,调整后连接【Geo组合+point spirit(MAT)】,在连接【feedback组合】适当调整。影响粒子动态的节点【metaball(SOP)+force(SOP)】添加mouse in(CHOP)鼠标位置到metaball的坐标,实现鼠标影响。..._touchdesigner怎么让一个模型跟着鼠标移动

【附源码】基于java的校园停车场管理系统的设计与实现61m0e9计算机毕设SSM_基于java技术的停车场管理系统实现与设计-程序员宅基地

文章浏览阅读178次。项目运行环境配置:Jdk1.8 + Tomcat7.0 + Mysql + HBuilderX(Webstorm也行)+ Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。项目技术:Springboot + mybatis + Maven +mysql5.7或8.0+html+css+js等等组成,B/S模式 + Maven管理等等。环境需要1.运行环境:最好是java jdk 1.8,我们在这个平台上运行的。其他版本理论上也可以。_基于java技术的停车场管理系统实现与设计

Android系统播放器MediaPlayer源码分析_android多媒体播放源码分析 时序图-程序员宅基地

文章浏览阅读3.5k次。前言对于MediaPlayer播放器的源码分析内容相对来说比较多,会从Java-&amp;amp;gt;Jni-&amp;amp;gt;C/C++慢慢分析,后面会慢慢更新。另外,博客只作为自己学习记录的一种方式,对于其他的不过多的评论。MediaPlayerDemopublic class MainActivity extends AppCompatActivity implements SurfaceHolder.Cal..._android多媒体播放源码分析 时序图

java 数据结构与算法 ——快速排序法-程序员宅基地

文章浏览阅读2.4k次,点赞41次,收藏13次。java 数据结构与算法 ——快速排序法_快速排序法