1、docker的安装
安装常用依赖
yum update #更新一下yum这样可以获取些新的源
yum -y install gcc gcc-c++ autoconf pcre pcre-devel make automake
yum -y install wget httpd-tools vim
安装docker
// 步骤一 安装所需要的软件包
yum install -y yum-utils device-mapper-persistent-data lvm2
// 步骤二 设置稳定的安装源
// 官方,速度可能会比较慢
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
// 阿里源,速度比较快
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
// 步骤三 安装最新版本的 Docker Engine-Community 和 containerd,或者转到下一步安装特定版本
yum install docker-ce docker-ce-cli containerd.io -y
具体参看 菜鸟教程
启动docker
systemctl start docker
查看docker的版本信息
docker info
docker version
2、image镜像
Docker把应用程序及其依赖, 打包在image文件里面。只有通过这个文件,才能生成docker容器
docker image ls | docker images #查看所有镜像
docker search [imageName] #查找指定的镜像 如docker image search mysql 表示查找mysql的镜像
docker image history [imageName|imageId] #查看镜像历史,可以理解为git log,查看每次的更改
docker image inspect [imageName] #显示一个或者多个镜像的祥细信息 docker image inspect nginx 可以查看里面的选项ExposedPorts表示该镜像对外暴露的端口号
docker image pull [imageName] # 拉取镜像
docker rmi [imageId | imageName] # 删除镜像
docker image push <username>/<repository>:<tag> #上传镜像,需要先注册hub.docker.com
docker image prune #docker使用一段时间后,系统一般都会残存一些临时的、没有被使用的镜像文件,可以通过以下命令进行清理
注意: 如果 docker_images 出现REPOSITORY是<none>的情况, 可以运行docker image prune 删除。
docker 变更镜像(提高下载速度)
cd /etc/docker
touch daemon.json
vim daemon.json
#输入下面的配置, 也可以使用其他有效的地址
{
"registry-mirrors": ["https://registry.docker-cn.com"]
}
# systemctl restart docker
3、container容器
docker run 命令会从 image 文件, 生成一个正在运行的容器实例, 注意docker run 容器后面跟的通常是linux执行的命令
docker container run 命令具有自动抓取 image 文件的功能,如果发现本地没有指定的 image 文件, 就会从仓库自动抓取
输出提示后, helloworld就会停止运行, 容器自动停止(以hello-world这个容器为例)
有些容器不会自动终止
关闭容器并不会删除容器文件,只是容器停止运行
docker container [ps|ls] # 列出当前所有活动的容器
docker container [ps|ls] -a # 列出当前所有的容器包括已经停止的容器
docker container [ps|ls] -a -q # 列出当前所有容器的包含已经停止的容器的containerId
docker container run -p <当前电脑端口>:<软件默认的端口> -v <hostPath>:<containerPath> -d --rm --name <containerName> <imageName>
-p 表示端口映射, 如果nginx 81:80表示电脑上81端口就可以访问容器内的nginx的80端口
-P 表示 --publish-all 大写的P表示启动服务后,让系统自动指定映射的端口,查看端口信息可以使用docker container ps进行查看
-v 定义数据卷,文件映射
-d 后台运行
-e 设置环境变量 如 -e name='test' 如mysql的启动需要指定登录密码 docker run -p 3307:3306 -d -e MYSQL_ROOT_PASSWORD=123456 --rm --name mysql1 mysql
--rm 表示容器停止后会自动删除
--name 定义容器名称
--restart 定义重启策略 always unless-stopped
#如果遇到启动的时候立马退出,可以把通过docker ps -a查看指定的id,并且通过log的形式把日志打印出来分析原因
docker container run -it mysql /bin/bash
-i 以交互式的形式启动
-t 启动一个终端
用这种方法就可以实现交互
docker [container] logs [id | name] #打印出指定id或name的日志 --follow表示跟随打印
docker [container] stop [id | name] # 停止指定的容器任务
docker [container] kill [id | name] # 强行kill掉指定的容器任务
docker [container] rm [id | name] # 删除指定的容器任务
docker rm $(docker ps -a -q) #表示删除所有的容器任务
docker system prune -f #表示删除已经exists的容器
docker [container] exec -it [id | name] /bin/bash #表示进入指定的已在运行的容器内部
docker [container] run --rm nginx # 表示当任务停止后,会自动删除,而不需要手动删除容器
docker [container] inspect <id | name> # 查看容器的信息,如ip等信息
docker [container] status [id | name] # 查看容器的状态,如 cpu的使用率等
docker [container] update -m 500m --memory-swap -1 [id] #对该容器的运行的内存进行重新分配 可以用 docker [container] stats [id]进行查看
docker [container] port <id | name> # 查看该容器的端口映射关系
容器之间的使用link进行互联
# 这里的mysql1是表示容器的别名
docker run -p 3307:3306 -d -e MYSQL_ROOT_PASSWORD=123456 --rm --name mysql1 mysql:latest
# 创建另外一个容器依赖于上面的容器
docker run --link mysql1:db --name -d centos: centos:latest
# 第二个容器依赖于第一个容器,那么,db是在第二个容器中对第一个容器的别外,--link第一个参数是第一个容器的别名,这时会在容器2中的/etc/host中产生一个映射关系
4、Dockerfile制作镜像
在Dockerfile定义所要执行的命令, 使用docker build创建镜像, 过程中会按照Dockerfile所定义的内容打开临时性容器(使用docker commit 进行提交), 生成一个新的镜像,中间过程为commit操作
执行的命令越多, 最终得到的容器应用镜像越大,所以要做优化
自定义镜像有两种方式
方式一: 通过镜像启动容器,然后在容器里安装对应的服务,然后再把这个容器docker commit 变成新的镜像
方式二: 编写Dockerfile文件, 把安装和配置步骤一步步写出来,然后构建镜像
FROM 构建的新镜像是基于哪个镜像 FROM node
MAINTAINER 镜像维护者姓名或邮箱 MAINTAINER even
LABEL 定义标签,相当于代码中的注释 LABEL author=even LABLE email=***@qq.com
RUN 构建镜像时运行的shell命令, 每运行一次run,对于image来说都会生成新的一层,所以尽量少分层,可以一个run,执行多个语句用 &&\ 或者 \ (换行) && 进行换行 RUN yum install pm2 g
CMD CMD设置容器启动后默认执行的命令及其参数(只能执行一次), 但CMD能够被docker run后面跟的命令行参数替换(即在docker run指定了,在cmd里就无效了) CMD npm i && npm run prd-dev && npx pm2 log
ENTRYPOINT 设置container启动时执行的操作(相对于cmd前执行,可以执行多条记录), 可以写个shell脚本进行执行 COPY test.sh /usr/local/bin \ ENTRYPOINT ['test.sh']
EXPOSE 对外暴露的服务器运行的端口 EXPORT 3000
ENV 设置容器内的环境变量 ENV MYSQL_ROOT_PASSWORD 12345 注意:如果需要在run中使用,用的是shell的语法 "${MYSQL_ROOT_PASSWORD}"
ADD 拷贝文件或目录到镜像中, 如果是URL或者压缩包会自动下载和解压 ADD /var/html/www
COPY 拷贝文件或工程到镜像 copy ./app /app
ENTRYPOINT 配置容器启动时运行的命令 ENTRYPOINT /bin/bash -c '/start.sh'
WORKDIR 为 RUN CMD ENTRYPOINT COPY ADD 设置工作目录 WORKDIR /app
USER 为 RUN CMD和ENTRYPOINT执行命令指定运行用户 USER root
VOLUME 指定窗口挂载点到鹤自动生成的目录或其他容器 VOLUME['/var/lib/mysql']
HEALTHCHECK 健康检查 HEALTHCHECK --INTERVAL=5M --timeout=3s --retries=3 CMS curl -f http://localhost
ARG 在构建镜像时指定一些参数 ARG user
注意点
- 对于生成镜像来讲,每run一次,都会生成新的image Layer, 为了避免无用的分层,合并多条命令成一行,为了美观, 复杂的run请用反斜线换行
- 大部份情况下,copy优于add, add除了copy还有额外的功能(解压)添加远程文件/目录 请使用curl或wget
- 用dockerfile对镜像进行打包后,可以查看镜像的分层,docker image history [image id]
- 如果需要在dockerfile中安装软件可以使用 apk 举例 apk add git (APK 是 Alpine Linux 中的包管理器) 表示安装git软件
.dockerignore文件
表示排除, 不要打包到image中的文件路径
.git
node_modules
Dockerfile的使用示例
FROM node:16.16.0
MAINTAINER even
COPY . /app
WORKDIR /app
USER root
RUN npm config set registry https://registry.npm.taobao.org \
&& npm i pm2 -g && npm install --production
EXPOSE 3000
ENV MYSQL_ROOT_PASSWORD 123456
CMD npm start
注意:在构建镜像的时候,尽量指定node的版本,以免版本更新导致的不必要的错误
创建镜像
#在app目录下
docker build -f dockerfile.test -t express-app[:1.0.0] .
# -f表示指定打包镜像的文件,默认是DockerFile(可省略)
# -t是表示标签,指的是 express-app
# [:1.0.0]表示版本号(可省略)
# . 表示的是当前目录
Dockerfile的多阶段构建案例
以上案例表示,阶段在需要在gcc环境中进行打包,然后在阶段二中运行,那么执行copy --from 是从第一阶段是把包拷贝过来做为第二个阶段运行的基础,这样就不用把gcc环境打包进入运行的包体中,可以节省空间
提高dockerfile构建效率
# 阶段一: 创建基础镜像
FROM node AS base
# 设置环境变量
ENV APP_PATH=/app
# 配置工作目录
WORKDIR $APP_PATH
# 阶段二: 创建安装镜像
FROM base AS install
# 拷贝指定的package.json到配置中
COPY package.json ./
# 安装node项目依赖, 如果需要编译,如ts编译等可以在这个阶段完成
RUN yarn config set registry 'https://registry.npm.taobao.org' && yarn
# 阶段三: 构建项目
FROM base
# 拷贝 装依赖阶段 生成的 node_modules 文件夹到工作目录下
COPY --from=install $APP_PATH/node_modules $APP_PATH/node_modules
# 将当前目录下的所有文件(除了.dockerignore排除的路径),都拷贝进入镜像的工作目录下
COPY . .
# 启动
CMD node index.js
方式二
# 阶段一: 创建基础镜像 alpine的镜像体积相对来说比较小
FROM node:16.16.0-alpine AS base
# 设置环境变量
ENV APP_PATH=/app
# 配置工作目录
WORKDIR $APP_PATH
EXPOSE 3000
# 拷贝指定的package.json到配置中
COPY package.json ./
# 安装node项目依赖, 如果需要编译,如ts编译等可以在这个阶段完成
RUN yarn config set registry 'https://registry.npm.taobao.org' && yarn
# 将当前目录下的所有文件(除了.dockerignore排除的路径),都拷贝进入镜像的工作目录下
COPY . .
# 启动
CMD node index.js
注意:以上两种方式的区别在于,前者会生成一个无用的image需要手动去除,方式二不会,但是方式一生成的包体更小些,因为不包含与代码逻辑无关的逻辑,如果yarn的配置等
在容器外如果没有使用暴露的端口,那么在Dockerfile中就没有必要一定要暴露,docker中的内网可访问即可, 另外需要注意时序
5、数据盘
删除容器的时候, 容器层里创建的文件也会被删除, 如果有些数据你想永久保存, 比如web服务器的日志, 数据库管理系统中的数据,可以为容器创建一个数据盘
docker内部提供了docker volume进行数据盘的管理工作
docker volume --help #查看数据盘命令的相关信息
docker volume create [数据卷名称] #创建数据盘 docker volume create test-volume
docker volume ls # 查看所有数据盘列表
docker volume inspect [数据卷名称] #查看指定数据盘的相关信息 docker volume inspect test-volume
docker volume rm [数据卷名称] # 删除指定的数据卷 docker volume rm test-volume
docker volume prune #移除掉本地没有被使用的数据卷
进行数据盘的挂载
#创建数据盘
docker volume create nginx_conf
#进行数据盘的挂载以nginx为例【可以声明完数据盘后放数据盘的名称也可以放路径】
docker run -p 80:80 -d -v nginx_conf:/etc/nginx/conf.d --name nginx nginx #这里的nginx_conf是docker volume create的数据盘
docker run -p 80:80 -d -v /home/test:/etc/nginx/conf.d --name nginx nginx #这里是使用路径,相当于是bind mount, 可以使用docker inspect nginx里的mounted进行查看
#docker挂载多个数据盘
docker run --name nginx -p 80:80 -v /home/docker-nginx/nginx.conf:/etc/nginx/nginx.conf -v /home/docker-nginx/log:/var/log/nginx -v /home/docker-nginx/conf.d/default.conf:/etc/nginx/conf.d/default.conf -d nginx
#进行数据盘的删除, 需要删除所有占用的容器后才能删除
docker volume rm nginx_conf
#查看当前没有被引用的数据盘,即在列表下可以进行删除操作
docker volume ls -f dangling=true
#一键删除所有未被引用的数据盘
docker volume prune
docker 要查看容器绑定的数据盘,可以在inspect里查看Mounts里的相关数据,显示的是数据盘的信息
也可以创建一个数据盘容器,并且做好数据盘的映射, 那么以后再起容器时,继承这个数据盘的配置,那么就可以减少数据盘的配置, 这种情况主要使用在数据盘需要放在一起的应用
#创建数据盘容器, 以下表示创建一个叫logger的容器,但不启动
docker create -v /mnt:/mnt --name logger centos
#启动一个新的容器,并且继承这个容器里的数据盘配置,那么相当于指定了 -v /mnt:/mnt这个配置
docker run --volumes-from logger --name ####
注意:在容器之间时间是不同步的,如果希望容器之间进行时间同步,可以采用数据盘的绑定方式
-v /etc/localtime:/etc/localtime 进行纠正
6、网络
安装docker时, 它会自动创建三个网络, bridge(创建容器时默认连接到此网络), none, host
- None: 该模式关闭了容器的网络功能, 对外界完全隔离
- host: 容器将不会虚拟出自己的网卡, 配置自己的ip等, 而是使用宿主机的IP和端口
- bridge: 桥接网络, 此模式会为每一个容器分配IP
可以使用 --net 标志来指定容器的网络应连接到哪些网络
docker network ls #列出当前的所有网络
docker inspect [networkName] #查看对应的网络信息 docker inspect bridge 可以在Containers里查看桥连都有哪些机器
docker run -p 3306:3306 -d --rm --network bridge --name nginx nginx 这个语句表示起动指定容器,并且使用bridge容器
创建自定义网络
创建多个自定义网络, 每个网络IP范围均不相同
docker自定义网络里面有个DNS服务, 可以通过容器名称访问主机
docker network create --driver bridge [myweb] #创建名称为myweb的自定义网络 --driver简写 -d
docker network inspect [myweb] #查看自定义网络中的主机
docker run -p 80:80 -d --rm -net myweb --name nginx1 nginx #启动容器时指定网络为自定义的网络
docker network connect [myweb] [containerName] #对已启动的容器进行调整网络,但是调整了网络后,旧的网络还在, 如果不需要旧的网络,那么就可以使用断开的功能
docker network disconnect [myweb] [containerName] #把指定容器从指定的网络中断开
docker network rm [myweb] #删除指定网络, 但是网络中有服务,那么则不能删除
7、compose的使用
docker-compose的配置选项可以参看: https://docs.docker.com/compose/compose-file/
Compose 通过一个配置文件来管理多个Docker容器
在配置文件中, 所有的容器通过services来定义, 然后使用docker-compose脚本启动,停止和重启应用和应用中的服务以及所有的依赖服务的容器
步骤:
- 运行docker-componse up, Componse将启动并运行整个应用程序配置文件组成
- services 可以定义需要的服务,每个服务都有自己的名字, 使用的镜像, 挂载的数据卷所属的网络和依赖的其他服务
- networks是应用的网络, 在它下面可以定义使用的网络名称, 类性
- volumes是数据卷,可以在此定义数据卷, 然后挂载到不同有服务上面使用
安装 componse
# 运行下载命令
curl -L "https://github.com/docker/compose/releases/download/v2.3.4/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
# 如果需要替换其他版本,请修改2.3.4,最新发行的版本地址:https://github.com/docker/compose/releases
# 将可执行权限应用于二进制文件:
chmod +x /usr/local/bin/docker-compose
# 创建软链
ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
# 测试是否安装成功
docker-compose --version
可参考查看 菜鸟教程
yml文件说明:
yaml是专门用来写配置文件的语言, 非常简洁和强大, 远比JSON格式方便
在 docker-compose.yml 中定义组成应用程序的服务, 以便它们可以在隔离的环境中一起运行
基本规则:
大小写敏感,
冒号后面有空格
使用缩进表示层级关系,
缩进时不允许使用tab键, 缩进的空格数目不重要, 只要相同层级的元素左侧对齐即可,
#号表示注释, 从这个字符一直到行尾, 都会被解析忽略
{
version: 2,
name: test,
list:
-a
-b
-c
}
会被转化成
{
version: 2, name: 'test', list: [a, b, c]
}
docker-compose的基本语法结构
version: "3.8"
services: # 容器
servicename: # 服务名字,这个名字也是内部 bridge网络可以使用的 DNS name
image: # 镜像的名字
command: # 可选,如果设置,则会覆盖默认镜像里的 CMD命令
environment: # 可选,相当于 docker run里的 --env
volumes: # 可选,相当于docker run里的 -v
networks: # 可选,相当于 docker run里的 --network
ports: # 可选,相当于 docker run里的 -p
servicename2:
volumes: # 可选,相当于 docker volume create
networks: # 可选,相当于 docker network create
docker-compose.yml 示例
version: '2' # 注意:这个是使用的是docker-compose的版本 https://docs.docker.com/compose/compose-file/compose-versioning/ services: # 定义服务 my-server: #定义服务名称 build: #需要构建本地的镜像,需要依靠Dockerfile context: './app/my-server' #当前应用的路径 dockerfile: Dockerfile #构建的文件名称,文件名称可以更改,默认是Dockerfile ports: - "8080:3000" environment: #配置环境变量 - "check=checkText" #注意这里要用=号,如果用冒号,那么程序内部将读取不到相关的信息 depends_on: #表示依赖的容器,需要等nginx1容器启动后再启动该服务 - nginx1 nginx1: image: nginx # 设定镜像
restart: always # 表示如果发生错误保持一直重启; 如果是 on-failure:5 自动重启,失败的话重启5次后停止 ports: - "80:80" # 定义端口映射 networks: - "myweb" # 这个网络与下面定义的网络是一一对应的 volumes: - "mydata:/data" #这里的mydata是表示下面定义的数据卷 - "/home/html:/usr/share/nginx/html" #表示把本地的/home/html文件目录映射到容器里面的/usr/share/nginx/html下面 networks: #创建一个自定义网络 myweb: # 定义自定义网络的名称 driver: bridge volumes: # 创建一个本地数据卷 mydata: # 数据卷的名称为mydata driver: local #驱动为本地驱动,相当于放在本地磁盘上
注意:文件名一定是 docker-compose.yml, 如果是开源的项目,为了防止一些密码泄露,可以使用.env文件,在docker-compose中使用${变量名}来引用变量名,变量在.env文件中定义,如需指定env的文件名可以使用 --env-file .\testenv 如果需要查看配置是否正确,可以使用docker-compose config进行验证
compose的相关命令
docker-compose up #启动所有服务
docker-compose up -d #后台启动所有服务
docker-compose ps #打印所有容器
docker-compose stop #停止所有服务
docker-compose start #重新启动停止的服务
docker-compose logs -f #持续跟踪所有日志
docker-compose exec [containerName] bash #进入指定的容器的服务系统
docker-compose rm [containerName] #删除指定容器的服务(网络不会被删除)
docker-compose down 删除所有的网络和容器
docker-compose up -d --build #可以实现代码热更新,且不中断服务
docker-compose的水平扩展
docker-compose up -d --scale test-serve=3
#前提是已有一个test-serve的服务在运行了
# --scale表示对已启动的服务进行水平扩展
# test-serve是对应的是docker-compose文件中的服务名称
# 注意:如果docker-compose中的test-serve有定义ports,那么会失败,因为一个服务不能同时映射多个服务到本地的端口
项目布署示例
项目文件夹结构
images
├── assets // assets-server的静态的文件assets文件夹的本地映射
├── data-server // 一个node服务
│ ├── Dockerfile // data-server服务的Dockerfile文件
│ ├── package.json
│ ├── src // data-server的核心代码文件夹
│ │ └── index.js
│ └── yarn.lock
├── docker-compose.yml // docker-compose配置清单
├── assets-server // 另一个node服务
│ ├── assets
│ ├── Dockerfile
│ ├── nodemon.json
│ ├── package.json
│ ├── README.MD
│ ├── source // 服务的核心代码区
│ ├── tsconfig.json
│ └── yarn.lock
├── mysql // mysql的本地化文件夹
│ ├── data // mysql的本地化数据
│ └── log //mysql的log文件夹
└── nginx // nginx的本地化文件夹
├── config // nginx的配置文件夹
│ └── default.conf // nginx的配置文件
└── logs // nginx的log文件夹
node服务的Dockerfile文件内容展示
FROM node:14
COPY . /assets-server
WORKDIR /assets-server
EXPOSE 8080
RUN npm config set registry https://registry.npm.taobao.org # 把npm的镜像改成淘宝镜像,这样速度会快些
RUN npm i pm2 -g && npm install
RUN npm run prestart
CMD pm2 start dist/index.js && npx pm2 log
node服务的mysql连接配置示例
const express = require('express')
const mysql = require('mysql2')
const server = express()
const admin = express.Router()
const connection = mysql.createConnection({
host: process.env.DbHost || '127.0.0.1', #读取的是环境变量里的地址,方便docker-compose进行配置
port: '3306',
user: process.env.DbUser || 'root', #读取的是环境变量里的user
password: process.env.DbPassword || '', #读取的是环境变量里的password
database: 'even',
})
注意:这些环境变量都需要在docker-compose中进行配置
nginx的配置清单
server {
listen 80;
server_name ###.####.com;
#access_log /var/log/nginx/host.access.log main;
location ~ ^/assets {
root /home;
add_header Cache-Control no-cache;
proxy_buffers 8 4k;
proxy_buffer_size 4k;
proxy_busy_buffers_size 16k;
proxy_max_temp_file_size 0;
proxy_temp_file_write_size 1024m;
}
location / {
proxy_pass http://editor:8080; # 注意,这里的editor对应的是docker-compose里的services下的服务名称,通过这种方式进行读取对应的地址
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size 2000m;
gzip on;
gzip_comp_level 5;
gzip_types application/json;
}
location ~ ^/admin {
proxy_pass http://check:3000; #注意, 这里的editor对应的是docker-compose里的services下的服务名称
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size 2000m;
gzip on;
gzip_comp_level 5;
gzip_types application/json;
}
}
注意:上面那样配置依赖于服务的启动,即docer-compose配置下的depends_on这个配置
docker-compose.yml配置清单
version: '2'
services:
check:
build:
context: ./data-server
networks:
- myweb
environment:
- DbHost=db #这个db是需要传到node应用中的环境变量的mysql,host配置,这里的db是指下在的mysql服务的db, 并且这里的端口是内部端口而不是暴露出来的端口
- DbUser=root
- DbPassword=123456
depends_on:
- db
editor:
build:
context: ./edu-assets-server
networks:
- myweb
volumes:
- ./assets:/edu-assets-server/assets #这个相当于Dockerfile里的文件资源路径的映射到本地的assets文件
nginx-server:
image: nginx
ports:
- 80:80
- 443:443 如果有开通https服务,记得开该端口
networks:
- myweb
volumes:
- ./nginx/config:/etc/nginx/conf.d #本地化些配置文件以及log文件,以及静态文件的映射地址
- ./nginx/logs:/var/log/nginx
- ./assets:/home/assets
depends_on: #这个关系到nginx的配置中的http://editor:8080, http://check:3000的配置
- editor
- check
db:
image: mysql
restart: always
ports:
- 3306:3306
networks:
- myweb
volumes:
- ./mysql/log:/var/log/mysql # 数据持久化
- ./mysql/data:/var/lib/mysql
- ./mysql/init:/docker-entrypoint-initdb.d # 初始化mysql数据库,init目录下放着项目的sql语句
environment:
- MYSQL_ROOT_PASSWORD=123456
redis:
image: redis
restart: always
ports:
- 6379:6379
networks:
- myweb
volumes:
- ./redis/conf/redis.conf:/etc/redis/redis.conf
- ./redis/data:/data
- ./redis/log:/var/log/redis
command: redis-server /etc/redis/redis.conf
networks: #创建一个自定义网络
myweb: # 定义自定义网络的名称
driver: bridge
#注意:如果使用的是外部已经定义好的网络,这样可以方便容器的访问,那么配置外部的网络需要按下面配置
注意:相当于在容器内共用一个网络,这里候访问容器内的其他服务用的是docker-compose下的services名称 + 端口号, 在文件本地化时要注意,会以本地的文件的内容替代容器内的文件夹,如果本地没有,容器内有,那么会被删除,所以需要做好文件的备份
当然除了使用同一网络访问外面的服务,那么也可以使用link如下
web:
links:
- db
- db:database
- redis
docker-compose的使用示例(以下仅展示一些用法,具体的用法以上面为主)
version: '3' services: editor-server: build: context: . dockerfile: Dockerfile image: editor-server # 依赖于当前 Dockerfile 创建镜像 container_name: editor-server ports: - 8081:3000 # 宿主机通过 8081 访问 editor-redis: image: redis # 引用官网 redis 镜像 container_name: editor-redis ports: - 6378:6379 # 宿主机可以用 127.0.0.1:6378 即可连接容器中的数据库 environment: - TZ=Asia/Shanghai # 设置时区 editor-mysql: image: mysql # 引用官网 mysql 镜像 container_name: editor-mysql restart: always privileged: true # 高权限,执行下面的 mysql/init command: --default-authentication-plugin=mysql_native_password # 解决无法远程访问的问题 ports: - 3305:3306 # 宿主机可以用 127.0.0.1:3305 即可连接容器中的数据库 volumes: - .docker-volumes/mysql/log:/var/log/mysql # 数据持久化 - .docker-volumes/mysql/data:/var/lib/mysql - ./mysql/init:/docker-entrypoint-initdb.d/ # 初始化 sql environment: - MYSQL_DATABASE=testdb # 初始化容器时创建数据库 - MYSQL_ROOT_PASSWORD=Mysql_2019 # - MYSQL_USER=shuangyue #创建 test 用户 # - MYSQL_PASSWORD=shuangyue #设置 test 用户的密码 - TZ=Asia/Shanghai # 设置时区 editor-mongo: image: mongo # 引用官网 mongo 镜像 container_name: editor-mongo restart: always volumes: - '.docker-volumes/mongo/data:/data/db' # 数据持久化 environment: - MONGO_INITDB_DATABASE=testdb # - MONGO_INITDB_ROOT_USERNAME=root # - MONGO_INITDB_ROOT_PASSWORD=123456 - TZ=Asia/Shanghai # 设置时区 ports: - '27016:27017' # 宿主机可以用 127.0.0.1:27016 即可连接容器中的数据库
8、 docker 启动相关数据库
docker 容器启动 redis
从github上下载对应的redis.conf(注意要把第一句无用的描述删除)
docker run -p 6379:6379 -v /home/images/redis/data:/data -v /home/images/redis/conf/redis.conf:/etc/redis/redis.conf -d --name redis redis redis-server /etc/redis/redis.conf
# 注意,最后是表示镜像启动后执行的语句 日志放在/var/log/redis下,有需要可以进行绑定
如果不指定conf,那么也可以通过以下命令来指定密码
docker run -p 6379:6379 -v /home/images/redis/data:/data -v /home/images/redis/conf/redis.conf:/etc/redis/redis.conf -d --name redis redis redis-server --requirepass test
注意:需要外部可访问redis, 还需要更改一下配置 bind 0.0.0.0 #改成0.0.0.0,使redis可以外部访问
bind 0.0.0.0 #改成0.0.0.0,使redis可以外部访问
daemonize no #用守护线程的方式启动
requirepass 你的密码 #给redis设置密码
appendonly yes #redis持久化 默认是no
docker 容器启动 mysql
初始化mysql的时候,如果有需要初始化mysql数据库的情况下,那么就需要创建一个镜像,Dockerfile的内容如下
FROM mysql:5.7
EXPOSE 3306
COPY ./init.sql /docker-entrypoint-initdb.d/
ENV MYSQL_ROOT_PASSWORD=check(注意:这里的密码设定就是后续需要登录的密码设定)
运行Dockerfile文件
docker build -t mydb . #这时会创建一个mydb的镜像
#启动该镜像
docker run -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 -v /home/mysql/data:/var/lib/mysql --rm -d --name mysql mydb
#因为所有的mysql容器被启动的时候,都会执行镜像中docker-entrypoint-initdb.d下的所有sql语句,这样就可以达到初始化mysql的目的,同时绑定数据盘就是为了同步数据库的数据到本地
#最后正常启动mysql的容器即可
docker run -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 -v /home/mysql/data:/var/lib/mydql (...log, 本地时间等) -d --rm --name mysql mysql:5.7
注意:也可以通过docker-compose绑定数据盘与docker-entrypoint-initdb.d进而实现初始化数据库
9、docker布置vue的前端项目
因为vue项目是静态页面,所以需要进行打包,并且不需要启动服务, 所以首先需要进行打包
如果服务器中有node环境,就可以直接进行打包,但是如果没有node环境,并且没有打算安装node环境,可以用以下方法利用docker镜像进行打包
步骤一:在vue项目中添加Dockerfile文件
FROM node:16.16.0
ENV APP_PATH=/app
WORKDIR ${APP_PATH}
COPY package.json ./
COPY .npmrc ./
RUN yarn config set registry 'https://registry.npm.taobao.org' && yarn
COPY . .
RUN yarn run build
CMD cp -a ${APP_PATH}/dist /output # 把打包好的文件拷贝的指定的目录下
步骤二:构建Docker镜像(需要cd到目录的根路径下)
docker build -t my-vue-app .
步骤三:运行命令即可从Docker容器中复制构建好的Vue项目文件
docker run --rm -v /path/to/local/output/dir:/output my-vue-app
注意:其中 /path/to/local/output/dir就替换为本地存储构建的文件的目录
步骤四:配置nginx
server{
listen 80;
server_name ****;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl;
server_name ****;
client_max_body_size 0;
#ssl on;
ssl_certificate /etc/nginx/cert/****.crt;
ssl_certificate_key /etc/nginx/cert/****.key;
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
ssl_prefer_server_ciphers on;
access_log /var/log/nginx/www.access.log;
error_log /var/log/nginx/www.error.log;
location / {
root /home/static/dist;
index index.html;
try_files $uri $uri/ /index.html;
}
}
注意:try_files的意思是,拿到请求的地址进行匹配,如果匹配不到,就把请求的地址当作目录,并且到指定的目录下去匹配默认文件,如果还是匹配不到就访问根目录下的/index.html文件