Docker1:部署Node应用

什么事Docker

    docker是一个开源的应用容器引擎,可以为我们提供安全、可移植、可重复的自动化部署的方式。docker采用虚拟化的技术来虚拟化出应用程序的运行环境。此种方式具有以下优势:

       1、 每个部署的应用程序都是一个容器,彼此隔离,互不影响;

       2、 服务器只需要安装docker即可运行构建好的应用程序镜像,不会涉及复杂的服务器环境配置,因为配置都在特定的应用程序所在的镜像中去配置即可;

        3、简化了自动化部署和运维的繁琐流程,只需将构建好的镜像load到服务器的docker中即可运行我们的应用程序;

        4、可以充分利用服务器的系统资源,一台服务器上可以同时运行多个容器;

    docker采用的是c/s架构,Client通过接口与Server进程通信实现容器的构建,运行和发布。docker比较重要的三个核心概念如下:

        镜像(images):一个只读的模板,可以理解为应用程序的运行环境,包含了程序运行所依赖的环境和基本配置,镜像可以按照层级(从基础镜像开始)来构建,每一层包含特定的环境。

        仓库(repository):一个用于存放镜像文件的仓库,如果你对git的仓库熟悉,应该很容易理解,对,就是那个。有私有仓库和公有仓库之分。

        容器(container):一个运行应用程序的虚拟容器,在我们运行镜像时产生。容器包含自己的文件系统+隔离的进程空间和包含其中的进程。

实战开始

1、环境准备

安装docker,未安装的同学,请根据自己的开发环境采用不同的安装方式去安装,具体操作参考教程,不做赘述。

安装成功后,可以通过docker -v查看版本号(尽量使用最新的稳定版本)。

2、项目准备

在你的项目根目录下,添加Dockerfile文件,此文件用来配置我们自定义一个镜像所需要指定的依赖项、环境以及执行的命令等。内容格式如下:

# 指定我们的基础镜像是node,版本是v8.0.0

FROM node:8.0.0 

# 指定制作我们的镜像的联系人信息(镜像创建者)

MAINTAINER EOI

# 将根目录下的文件都copy到container(运行此镜像的容器)文件系统的app文件夹下

ADD . /app/ 

#cd到app文件夹下

WORKDIR /app

# 安装项目依赖包

RUN npm install 

RUN npm rebuild node-sass --force

# 配置环境变量

ENV HOST 0.0.0.0 

ENV PORT 8000

# 容器对外暴露的端口号

EXPOSE 8000

# 容器启动时执行的命令,类似npm run start

CMD ["npm", "start"]

关于Dockerfile文件中的关键字,解释如下:

FROM

MAINTAINER

语法:MAINTAINER解释:MAINTAINER指令允许你给将要制作的镜像设置作者信息。

ADD

语法:ADD解释:ADD指令用于从指定路径拷贝一个文件或目录到容器的指定路径中,是一个文件或目录的路径,也可以是一个url,路径是相对于该Dockerfile文件所在位置的相对路径,是目标容器的一个绝对路径。

WORKDIR

语法:WORKDIR/path/to/workdir 解释:WORKDIR指令用于设置Dockerfile中的RUN、CMD和ENTRYPOINT指令执行命令的工作目录(默认为/目录),该指令在Dockerfile文件中可以出现多次,如果使用相对路径则为相对于WORKDIR上一次的值,例如WORKDIR /data,WORKDIR logs,RUN pwd最终输出的当前目录是/data/logs。

RUN

语法:① RUN #将会调用/bin/sh -c② RUN ["executable","param1","param2"]#将会调用exec执行,以避免有些时候shell方式执行时的传递参数问题,而且有些基础镜像可能不包含/bin/sh解释:RUN指令会在一个新的容器中执行任何命令,然后把执行后的改变提交到当前镜像,提交后的镜像会被用于Dockerfile中定义的下一步操作,RUN中定义的命令会按顺序执行并提交,这正是Docker廉价的提交和可以基于镜像的任何一个历史点创建容器的好处,就像版本控制工具一样。

ENV

语法:ENV解释:ENV指令用于设置环境变量,在Dockerfile中这些设置的环境变量也会影响到RUN指令,当运行生成的镜像时这些环境变量依然有效,如果需要在运行时更改这些环境变量可以在运行docker run时添加–env=参数来修改。 注意:最好不要定义那些可能和系统预定义的环境变量冲突的名字,否则可能会产生意想不到的结果。

EXPOSE

语法:EXPOSE[ ...]解释:EXPOSE指令用来告诉Docker这个容器在运行时会监听哪些端口,Docker在连接不同的容器(使用–link参数)时使用这些信息。

CMD

语法: ①CMD["executable","param1","param2"]#将会调用exec执行,首选方式②CMD["param1","param2"]#当使用ENTRYPOINT指令时,为该指令传递默认参数③CMD [ | ]#将会调用/bin/sh -c执行解释:CMD指令中指定的命令会在镜像运行时执行,在Dockerfile中只能存在一个,如果使用了多个CMD指令,则只有最后一个CMD指令有效。当出现ENTRYPOINT指令时,CMD中定义的内容会作为ENTRYPOINT指令的默认参数,也就是说可以使用CMD指令给ENTRYPOINT传递参数。注意:RUN和CMD都是执行命令,他们的差异在于RUN中定义的命令会在执行docker build命令创建镜像时执行,而CMD中定义的命令会在执行docker run命令运行镜像时执行,另外使用第一种语法也就是调用exec执行时,命令必须为绝对路径。

其中还有其他的一些关键字:USER、ENTRYPOINT、VOLUME、ONBUILD等,如果你有兴趣可以自行研究。

在项目根目录下添加.dockerignore文件,此文件的作用类似.gitignore文件,可以忽略掉添加进镜像中的文件,写法、格式和.gitignore一样,一行代表一个忽略。本项目添加的忽略如下:

.DS_Store 

npm-debug.log* 

selenium-debug.log

.nuxt/ 

/package-lock.json 

*.tar 

*.md 

# Editor directoriesandfiles 

.idea 

*.suo 

*.ntvs* 

*.njsproj 

*.sln

构建镜像

查看目前本地docker的镜像

> docker images

REPOSITORY          TAG                IMAGE ID            CREATED            SIZE

cd 到项目根目录下,执行以下命令

> docker build -t deploy:1.0 

deploy是镜像名,1.0是镜像的版本号,到此你已经成功构建了一个新的镜像,你可以通过docker images,查看你的镜像。

> docker images

REPOSITORY          TAG                IMAGE ID            CREATED            SIZE 

deploy              1.0                d8f0875e967b        3 minutes ago        2.11GB

启动镜像,测试是否成功。

> docker run -d -p 9000:8000 deploy:1.0

8aec5ee037bb253901d2c2e02c7be546580546c493576139f3789fb660f3401d

> docker ps -a

CONTAINER ID    IMAGE        COMMAND          CREATED          STATUS        PORTS                  NAMES

8aec5ee037bb    deploy:1.0  "npm start"    57 seconds ago    Up 56 seconds  0.0.0.0:9000->8000/tcp amazing_bassi

docker run -d -p 9000:8000 deploy:1.0中-d表示后台运行,-p 9000:8000表示指定本地的9000端口隐射到容器内的8000端口。 deploy:1.0为我们要运行的镜像。通过docker ps -a查看docker的进程(容器的运行本身就是一种特殊的进程)运行情况,发现我们的容器已经在运行。本地可以访问localhost:9000。

通过docker logs可以查看我们容器内应用进程的运行日志。docker logs

> docker logs 8aec5ee037bb

npm info it worked if it ends with ok  

npm info using [email protected]  

npm info using [email protected]  

npm info lifecycle [email protected]~prestart: [email protected] 

 npm info lifecycle [email protected]~start: [email protected]  

> [email protected] start /app  > node ./server/index.jsServer listening on 0.0.0.0:8000  DONE  Compiled successfully in 9310ms06:55:56  > Open http://0.0.0.0:8000

docker stop 可以停止容器运行

docker start 可以启动容器运行

docker restart 可以重启容器

docker rm -f可以强制删除在运行的容器

上传镜像(这里用上传到公共仓库来演示)

没注册DockerHub的同学,请注册DockerHub

登录docker

> docker login

Username: XXX

Password: XXXLogin

 Succeeded

docker tag /上传之前必须给镜像打上tag,namespace可以指定为你的docker Id

> docker tag deploy:1.0 lzqs/deploy:1.0

docker push /将镜像上传至docker的公共仓库

> docker push lzqs/deploy:1.0

上传成功后,docker logout 退出,登录 https://hub.docker.com/ 查看上传的镜像。

下载镜像

通过docker pull /下载我们的镜像。

> docker pull lzqs/deploy:1.0

生产部署

前面说了,我们可以将上传到仓库的镜像下载下来部署,但是如果镜像比较大或者部署环境压根无法联网,你是不是要跪了。所以我们采取另一种方法,将开发好的镜像直接打包保存到安装盘里面,到客户生产环境再将镜像包上传并加载到服务器的docker中即可。

在开发环境打包,docker save / .tar

> docker save lzqs/deploy:1.0 > deploy.tar

这里ls会发现目录下生成了deploy.tar的文件。部署时将此文件copy到生产环境服务器上。

确保生产服务器上已经安装了docker,若没装,请参考相关文档,若不装,对不起小生也无力了,然后在服务器上加载上传的镜像包deploy.tar。

> docker load < deploy.tar

007ab444b234: Loading layer [==================================================>] 129.3 MB/129.3 MB  

4902b007e6a7: Loading layer [==================================================>] 45.45 MB/45.45 MB 

 bb07d0c1008d: Loading layer [==================================================>] 126.8 MB/126.8 MB  

ecf5c2e2468e: Loading layer [==================================================>] 326.6 MB/326.6 MB  

7b3b4fef39c1: Loading layer [==================================================>] 352.3 kB/352.3 kB  

677f02386f07: Loading layer [==================================================>] 137.2 kB/137.2 kB  

7333bb4665b8: Loading layer [==================================================>] 55.66 MB/55.66 MB  

e292e64ffb88: Loading layer [==================================================>] 3.757 MB/3.757 MB  

ee76d0e6f6d9: Loading layer [==================================================>] 1.436 GB/1.436 GB  

33dca533c6e5: Loading layer [==================================================>] 331.8 kB/331.8 kB  

24630015679d: Loading layer [==================================================>] 35.18 MB/35.18 MB  

Loaded image: lzqs/deploy:1.0

加载成功后,docker images即可看到加载的镜像

> docker images

REPOSITORY          TAG                IMAGE ID            CREATED            SIZE

lzqs/deploy        1.0                d8f0875e967b        About an hour ago  2.115 GB

运行lzqs/deploy镜像,成功后,在外部访问服务器的9000端口, <服务器的IP>:9000

> docker run -d -p 9000:8000 lzqs/deploy

1d0db9a5d0c8826171e501b0e86afd444fca8144b1105e63dae8d621bdda7a77

> docker ps -a

CONTAINER ID  IMAGE          COMMAND      CREATED              STATUS            PORTS                    NAMES

1d0db9a5d0c8  lzqs/deploy:1.0 "npm start"  About a minute ago  Up About a minute  0.0.0.0:9000->8000/tcp goofy_curran

docker exec -it /bin/bash 可以进入容器中执行,方便我们查看内部文件和调试

>dockerexec-it 1d0db9a5d0c8 /bin/bash

root@1d0db9a5d0c8:/app#

打完收工,可以再外边访问了

你可能感兴趣的:(Docker1:部署Node应用)