作为一个连docker门都没有迈进去的小白,在docker以及docker-compose这两者的使用之中真的是很迷惑。初始理解中,dokcer = docker-compose, 只是名字变了,换汤不换药,相信自己,抱着这种态度下去,真的就能看到不一样的风景。
现在开始这个探索旅程,同一的项目用docker部署和docker-compose部署,两者差异对比,然后去理解这两者的异同,因为是自我的实践,文章可能就是琐碎平常,更主要的目的是记录一下过程。
在开始之前我们先把常用的命令写一下,因为会反复用到。
# 查看docker下的镜像
sudo docker images
# 查看docker下所有生成的容器
sudo docker ps -a
# 创建一个名为image_name的镜像
sudo docker build -t image_name .
# 创建运行生成依赖镜像image_name名为container_name的容器,并且挂载在8000端口
sudo docker run -d --name container_name -p 8000:8000 image_name
# 查看日志
sudo docker logs -f container_name
# 进入容器
sudo docker exec -it container_name /bin/bash
(坑一:这个命名必须是要在容器启动的时候才能用!!!!)
# 删除容器
sudo docker rm container_name
# 删除镜像
sudo docker rmi image_name
# 停止容器运行
sudo docker stop container_name
(注意:删除容器前必须停止容器运行,删除镜像前必须删除使用有该镜像的所有容器)
# 查看docker-compose下的镜像
sudo /usr/local/bin/docker-compose images
# 查看docker-compose下的容器
sudo /usr/local/bin/docker-compose ps -a
# 进入容器
sudo /usr/local/bin/docker-compose exec container-name /bin/bash
# 构建启动
sudo /usr/local/bin/docker-compose up [-d] [server-name]
-d: 这个是挂在后台运行
server-name: 启动名为server-name的服务
# 重启
sudo /usr/local/bin/docker-compose restart [server-name]
# 查看日志
sudo /usr/local/bin/docker-compose logs -f container-name
其实运行比较后,其实会发现在查看镜像以及容器这一块,docker和docker-compose其实是不太一样的,docker是包含了所有的镜像和容器,但是docker-compose则是只关注于有它生成的镜像和容器。
但是不管是用docker部署还是用docker-compose部署,都是可以用docker的命令操作,其实在一定意义上,docker-compose其实是对docker 提供的api进行了封装使用而且。
docker-compose.yml
文件中定义。整体的来说:
docker-compose 是一个用来把docker自动化的东西
有了 docker-compose 你可以把所有繁复的 docker 操作全都一条命令,自动化的完成。
在 docker-compose.file 里面写好配置,你只需要写好后 ,只运行一句 docker-compose up -d 即可
对与docker和docker-compose的关系嵌套来说,个人觉得应该像这个图:
从层级的方面上,docker-compose > docker, 一个docker-compose下的docker-compose.yml文件可以包含多个依赖docker镜像的应用服务。
从颗粒度的方面上,docker 的颗粒度要远小于docker-compose, docker-compose 需要依赖与docker 底层的api及依赖。
部署一个简简单单的前端vue.js项目,通过使用docker以及docker-compose来做对比。
在撰写 Dockerfile 的时候,要经常提醒自己,这并不是在写 Shell 脚本,而是在定义每一层该如何构建。
镜像是多层存储,每一层的东西并不会在下一层被删除,会一直跟随着镜像。因此镜像构建时,一定要确保每一层只添加真正需要添加的东西,任何无关的东西都应该清理掉。
# 使用镜像node
FROM node:latest
# 指定工作目录
WORKDIR /app
# 下面这两句是复制package.json到工作目录下,如果package.json没有改变过,那么会使用之前下载的缓存记录,改变后,会重新build项目依赖
COPY package.json .
RUN npm install
# 下面是执行生成dist文件,如果你在本地已经生成,代码已经上传了可不用执行
COPY ..
RUN npm build
FROM nginx:latest
# 复制nginx.conf(这个文件记得提前写好在路径下) 替换到容器的/etc/nginx/nginx.conf下
COPY nginx.conf /etc/nginx/nginx.conf
# 复制dist/ 到容器的/usr/share/nginx/html目录下
COPY dist/ /usr/share/nginx/html
Dockerfile的存放目录:项目最外层
写好Dockerfile文件后,然后就可以直接用docker命令运行了。
docker 运行 Dockerfile文件
sudo docker build -t fronted .
sudo docker run -d --name fronted -p 80:80 fronted:latest
依次运行上面两条目录,就会启动项目,第一个命令是构建一个名为fronted的镜像,第二个命令是指在后台运行一个依赖镜像fronted,运行端口是80,容器名为fronted的项目,这个时候网页打开80端口即可看到自己部署的前端项目。
version: '3'
services:
negative_nginx:
build: ./negative_fronted
image: nginx:latest
container_name: negative_nginx
volumes:
- ./nginx/negative/conf:/etc/nginx/conf.d
- ./negative_fronted/dist:/usr/share/nginx/html
ports:
- "8080:80"
文件目录和项目位于同一层。
- ./nginx/negative/conf:/etc/nginx/conf.d
注意:
build: 使用了项目里面的Dockerfile文件,
volumes:挂载数据,就是把宿主机的数据挂载在容器里面。
ports: 使用8080端口监听80
其实如果注意到上面的Dockerfile文件,其实这里volumes和上面的COPY操作其实是一样的。
然后注意一下- ./nginx/negative/conf:/etc/nginx/conf.d这一条命令,前面的./nginx/negative/conf如果宿主机没有此目录执行docker-compose后会自动生成,但是最后还是报错,这是一个坑,因为你没有在这个目录下写一个默认的conf文件去替代容器里面的文件,导致会报错。
所以在宿主机的这个目录下最好写一个默认的nginx配置nginx.conf。
大致如下,这个看个人定义,我就很简单的写了:
然后记住里面需要填写的文件路径是你刚才挂载在容器里面的路径哦!!!!
server {
listen 80;
server_name localhost;
location / {
root /usr/share/nginx/html; index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
写好docker-compose.yml和需要的nginx配置后,使用这个万能的命令
sudo /usr/local/bin/docker-compose up -d
这个命令十分强大,它将尝试自动完成包括构建镜像,(重新)创建服务,启动服务,并关联服务相关容器的一系列操作。
链接的服务都将会被自动启动,除非已经处于运行状态。
可以说,大部分时候都可以直接通过该命令来启动一个项目。
如果没有执行任何的错误,你会发现你在网页打开网址:8080,发现项目也成功运行了。
个人理解上来看,通过docker部署和docker-compose部署下来发现,其实说二者的区别,可以大致上理解成Dockerfile和docker-compose.yml的构建.
Dockerfile 记录单个镜像的构建过程, docker-compse.yml 记录一个项目(project, 一般是多个镜像)的构建过程。
docker-compose可以更好的对项目进行管理,一个文件下添加多个服务,通过指顶服务来快速开启,不需要再像docker一样一个个步骤构建启动,简单方便。