本文入门尝试,利用 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、数据库等等,也可以这样。