even

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

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

注意点

  1. 对于生成镜像来讲,每run一次,都会生成新的image Layer, 为了避免无用的分层,合并多条命令成一行,为了美观, 复杂的run请用反斜线换行
  2. 大部份情况下,copy优于add, add除了copy还有额外的功能(解压)添加远程文件/目录 请使用curl或wget
  3. 用dockerfile对镜像进行打包后,可以查看镜像的分层,docker image history [image id]
  4. 如果需要在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

#注意:如果使用的是外部已经定义好的网络,这样可以方便容器的访问,那么配置外部的网络需要按下面配置
  networks:
    myweb:
      external:  # 这个关键字是声明外面的字段,在compose down的时候会跳过关闭该字段的配置, name表示的是外部网络的名字
        name: mysql_default

注意:相当于在容器内共用一个网络,这里候访问容器内的其他服务用的是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文件

 

posted on 2022-02-19 15:29  even_blogs  阅读(55)  评论(0编辑  收藏  举报