docker部署静态项目 - 用实践理解docker
本文入门尝试,利用 docker 环境,运行 nginx,部署静态网站项目,从而理解docker
。
服务器端项目的尝试,在后一篇文章。 练习两个项目,类似全栈部署,相信对docker
会自然理解和基本使用了
Docker 是什么
Docker 是一个让应用和操作平台解耦的开源的应用容器引擎,其让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,该容器包含了应用程序的代码、运行环境、依赖库、配置文件等必需的资源,通过容器就可以实现方便快速并且与平台解耦的自动化部署方式,无论你部署时的环境如何,容器中的应用程序都会运行在同一种环境下。(更多详情请移步 docker 官网查看 docker)。
核心是解耦应用和平台,让其可移植,脱离操作系统
静态网站项目
建一个文件夹demo
,里面建一个文件夹dist
,增加index.html
和index.css
文件,随便写点什么。
创建nginx
配置文件
项目根目录下,创建nginx文件夹
,该文件夹下新建文件default.conf
。
该配置文件location
定义了首页的指向为 /usr/share/nginx/html/index.html
,所以可以一会把 dist
的静态资源放到/usr/share/nginx/html
目录下。
server { listen 80; server_name localhost; #charset koi8-r; access_log /var/log/nginx/host.access.log main; error_log /var/log/nginx/error.log error; # index.html的位置 location / { root /usr/share/nginx/html; index index.html index.htm; } #error_page 404 /404.html; # redirect server error pages to the static page /50x.html # error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/share/nginx/html; } }
拉取nginx
公共镜像
拉取nginx
公共镜像:
docker pull nginx
镜像名称组成结构:REPOSITORY[:TAG]
,TAG 默认为 latest
,其他镜像命令:
- 搜索镜像 -
docker search [REPOSITORY[:TAG]]
- 拉取镜像 -
docker pull [REPOSITORY[:TAG]]
- 查看镜像列表 -
docker image ls
- 删除镜像 -
docker image rm [REPOSITORY[:TAG]]
或docker rmi [REPOSITORY[:TAG]]
创建Dockerfile
文件
一般自定义构建镜像,是基于Dockerfile
文件构建。
项目根目录下,创建Dockerfile
文件
FROM nginx COPY dist/ /usr/share/nginx/html/ COPY nginx/default.conf /etc/nginx/conf.d/default.conf
FROM nginx
是基于nginx:latest
镜像而构建的。COPY dist/ /usr/share/nginx/html/
是将项目根目录下dist
文件夹下的所有文件复制到镜像中/usr/share/nginx/html/
目录下。COPY nginx/default.conf /etc/nginx/conf.d/default.conf
同理也是复制到镜像中,用本地的default.conf
配置来替换nginx镜像
里的默认配置。
自定义构建应用镜像
基于Dockerfile
文件,自定义构建应用镜像:
docker build -t static_nginx_image .
-t
是给镜像命名.
是基于当前目录的Dockerfile
来构建镜像
基于镜像启动容器
启动容器,访问
docker run -p 3333:80 -d --name static_nginx_container static_nginx_image
docker run
是基于镜像启动一个容器-p 3333:80
是端口映射,将宿主的 3333 端口映射到容器的 80 端口-d
是后台方式运行--name
容器名,便于用docker ps
查看其进程
镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的类和实例一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。
正因为是,类与实体的关系,可以基于同一镜像,构建多个容器。
比如上面的,再来个容器docker run -p 3334:80 -d --name static_nginx_container2 static_nginx_image
,访问
修改内容,需要重新构建镜像和启动容器
现在因为需要,修改网页的内容,此时就需要重新构建镜像和启动容器,因为上次构建镜像的时候,将未修改前的dist
复制到镜像里了。
按照以下步骤,重新构建镜像和启动容器:
# 查看所有进程 docker ps # 停止静态容器 docker stop web_container # 删除静态容器 - 前提是容器处于停止状态 docker rm web_container # 删除静态镜像 - 前提是没有容器使用该镜像 docker rmi web_image # 重新构建静态镜像,加了接口就不是静态项目了,改个名 docker build -t web_image . # 重新构建静态容器 docker run -p 3333:80 -d --name web_container web_image
此时访问http://localhost:3333,发现更新了
改进 - 无需重新构建镜像
正如上面,如果修改网页的内容,或者改了nginx
配置,就需要重新构建镜像和容器,着实麻烦,怎么改进呢?
在构建镜像的时候 不把 Nginx 配置或者项目内容复制到镜像中,而是直接挂载到宿主机上,这样每次修改配置后,直接重启容器即可~
1. 去掉 COPY
将之前静态项目的Dockerfile
修改下,去掉后面的COPY
FROM nginx # COPY dist/ /usr/share/nginx/html/ # COPY nginx/default.conf /etc/nginx/conf.d/default.conf
2. 带参数 - 重新运行容器
docker run \ -p 3333:80 \ -d --name web_container \ --mount type=bind,source=$HOME/others/code/docker_dist/nginx,target=/etc/nginx/conf.d \ --mount type=bind,source=$HOME//others/code/docker_dist/dist,target=/usr/share/nginx/html \ nginx
--mount type=bind,source={sourceDir},target={targetDir}
将宿主机的sourceDir
挂载到容器的targetDir
目录上。
主要将之前COPY
的配置文件和dist
文件夹,直接挂载到容器里。
命令太长,可以折行写,末尾是反斜杠+回车
,为了方便,可以在根目录下,新建文件container.sh
,将上面复制进去,执行的时候sh container.sh
于是,重新生成镜像和启动容器
docker stop web_container docker rm web_container # 先停止之前的容器,删掉镜像 docker rmi web_image # 项目路径下,重新生成网站镜像,这里就没有COPY了 docker build -t web_image . # 项目路径下,重新启动容器 sh container.sh
以后修改nginx
配置,就重启容器就好docker restart web_container
,而修改内容则不需要重启容器,会自动更新。
可移植性和解耦的表现
任意电脑,拉取项目和安装docker
,然后拉取nginx
镜像,运行之后的构建镜像和容器的命令,即可成功访问页面。
不需要管不同操作系统下,怎么安装nginx
,这就是解耦。
同理Node、数据库等等,也可以这样。