Skip to content

Docker部署项目----示例

前言

假设项目是一个前后端分离的项目, 前端是vue或者react, 后端是express 或者 Egg或者别的

  • 1、通过docker Hub
  • 2、通过离线docker save + docker load
  • 3、自己搭建docker仓库

windows上要用docker,需要先安装并且docker处于起动状态

一、docker赖部署Node项目

(一)部署无外部依赖的Node项目

无外部依赖指的是仅仅只有Node环境就可以运行,没有依赖与数据库,redis,等等一些影响node项目起动的其他环境

1. 流程概览

(1)先pull一个已经存在的node镜像 (2)在本地创建一个可运行的node项目 (3)根目录创建Dockerfile文件和.dockerignore文件,文件中声明基于上面pull的node镜像来构建自己的镜像 (4)然后在Dockerfile文件所在的目录下运行docker build -t <product_name> .命令来构建Image. (5)运行容器,查看效果 (6)将我们的镜像发布到仓库,以便随时复用 (7)在其他地方要使用时,直接pull镜像进行使用即可

2. 具体实现

1、用express创建一个node项目

image.png 本地启动项目,npm start,查看页面 image.png

2、项目根目录创建Dockerfile文件和.dockerignoredocker忽略文件

Dockerfile文件用来创建镜像 .dockerignore文件用来告诉docker,在ADD . xxxCOPY时候,忽略某些文件

注意!!!

  • ==如果我们的项目要运行时,需要依赖某些软件环境,比如nginx,mysql,redis,nodejs等,那么我们就可以将已经有这些环境的其他镜像作为源镜像,从而来构建最终我们要的镜像 这里Dockerfile第一行代码FROM xxx就是这个意思。由于这里的项目需要依赖nodejs,所以这里的基础源镜像就是nodejs镜像==

Docker 提供了两种方法来创建基础镜像,

  • 一种是通过引入tar包的形式(from 已有的基础镜像),

  • 另外一种是通过一个空白的镜像来一步一步构建(FROM scratchscratch是Docker保留镜像,镜像仓库中的任何镜像都不能使用这个名字,使用FROM scratch表明我们要构建镜像中的第一个文件层。

  • 在Dockerfile文件写入如下内容

Dockerfile
# 基础镜像为node:12.20.2版本
FROM node:12.20.2

# 声明作者
LABEL maintainer="ljh"

# 环境变量设置为生产环境
ENV NODE_ENV production

# 拷贝package.json文件到镜像中的/home/docker-serve-demo1目录
ADD package.json /home/docker-serve-demo1

# 将工作目录切换到改目录,类似cd命令
WORKDIR /home/docker-serve-demo1

# 安装依赖
RUN npm install 

# 将当前目录下的所有内容拷贝到镜像中的/home/docker-serve-demo1目录
ADD . /home/docker-serve-demo1

# 对外暴露端口
EXPOSE 3000

# 程序启动脚本
CMD ["npm","start"]
  • .dockerignore文件写入如下内容
shell
# Logs
logs
*.log
npm-debug.log*
# Runtime data
pids
*.pid
*.seed
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
# nyc test coverage
.nyc_output
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# node-waf configuration
.lock-wscript
# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules
jspm_packages
# Optional npm cache directory
.npm
# Optional REPL history
.node_repl_history
.idea
.node_modules
node_modules
.vscode

3、构建镜像

Dockerfile文件所在目录下使用docker build命令构建镜像,注意最后的.不能省略,代表是当前路径,它指定镜像构建的上下文。

shell
docker build -t express-docker-demo .

-t express-docker-demo为镜像指定名称为express-docker-demo, tag不指定默认为latest Image_20220112142012.png

4、构建镜像完成,本地测试结果

run一下刚刚构建的镜像,启动实例(容器)

shell
docker run -it -d -p 3001:3000 express-docker-demo

其中: -d表示后台运行, -p 3001:3000表示将容器的3000端口映射到宿主机(本地)的3001端口,express-docker-demo为刚刚创建的镜像名称

接着,查看容器是否启动

shell
docker ps

image.png 看到容器已经完美运行

查看容器的IP,方便以后nginx代理服务

shell
docker inspect b2e8fef52b06

在出来的结果列表内找到:"IPAddress": "172.17.0.2"

image.png

在宿主机(本地windows)环境浏览器输入:http://127.0.0.1:3001即可访问容器服务image.png

如果此时本地无法打开。可以查看日志docker logs -f b2e8fef52b06。根据日志修改对应出现的对方。

5、将镜像push到docker Hub

shell
# 登录docker Hub
docker login
# 添加tag express-docker-demo 为镜像名  xiaoli123fendou 为dochubHub的username  xiaoli123fendou/express-docker-demo:0.0.1为push到docker Hub的xiaoli123fendou/express-docker-demo存储库,版本为0.0.1
docker tag express-docker-demo xiaoli123fendou/express-docker-demo:0.0.1
# push到docker Hub
docker push xiaoli123fendou/express-docker-demo:0.0.1
# 退出登录docker Hub
docker logout

6、将镜像以静态文件的形式迁移到服务器

保存镜像为tar文件到当前目录

shell
docker save -o express-docker-demo.tar express-docker-demo:0.0.1

然后,拷贝镜像tar文件到目标服务器

在目标服务器加载拷贝过来的tar文件为镜像

shell
docker load -i express-docker-demo.tar

至此,目标服务器就多了一个docker镜像,可以run了

(二)部署Egg(有依赖代表)

一般后端项目都会有一些项目启动的依赖,比如:数据库、其他服务等

针对有项目启动依赖的服务,一般可以有几种部署场景: 其中:

  • 场景一很为为很常见,一般公司都为此种方式
  • 场景二和场景三多为个人网站,其中场景三也有可能为一些小公司内部项目

场景一:服务的依赖存在专门的服务器,例如:数据库服务器,redis服务器等

这类后台服务在部署时候就很简单,不用考虑去部署数据库,缓存等,只用在项目中区分好开发、测试、生产环境,然后在各个环境中配置各个依赖对应的地址即可,这种方式来部署egg项目参考上一节 “部署无依赖的Nodejs项目”

场景二:服务的依赖和后台服务存在同一台服务器,且是同一容器

这类后台服务,在编写Dockerfile文件时候,需要基于操纵系统的镜像来创建镜像,一个镜像中同时要安装多个软件,如:Nginx,mysql,redis,示例如下:

构建一个含有多个软件环境的镜像的Dockerfile文件示例

Dockerfile
FROM centos:centos7
MAINTAINER ztd "770960546@qq.com"
# 准备工作创建文件夹
RUN \
mkdir -p /opt/tools \
&& mkdir -p /etc/redis \
&& mkdir /opt/logs \
&& mkdir -p /data/mysql
# 复制文件
COPY softwares/jdk-8u102-linux-x64.tar.gz /opt/tools
COPY softwares/redis-3.2.8.tar.gz /opt/tools
COPY softwares/apache-tomcat-7.0.70.tar.gz /opt/tools
COPY redis.conf /etc/redis/redis.conf
COPY supervisord.conf /etc/supervisord.conf
COPY program.conf /etc/program.conf
# 复制数据库文件
COPY softwares/libaio-0.3.107-10.el6.x86_64.rpm /opt/tools
COPY softwares/MySQL-client-5.6.23-1.rhel5.x86_64.rpm /opt/tools
COPY softwares/MySQL-devel-5.6.23-1.rhel5.x86_64.rpm /opt/tools
COPY softwares/MySQL-server-5.6.23-1.rhel5.x86_64.rpm /opt/tools
# 复制nginx安装文件
COPY softwares/nginx-1.13.7.tar.gz /opt/tools
#COPY nginx.conf /opt/tools/nginx.conf
# 安装 sshd 修改密码
RUN \
yum install passwd openssl openssh-server -y \
&& ssh-keygen -q -t rsa -b 2048 -f /etc/ssh/ssh_host_rsa_key -N '' \
&& ssh-keygen -q -t ecdsa -f /etc/ssh/ssh_host_ecdsa_key -N '' \
&& ssh-keygen -t dsa -f /etc/ssh/ssh_host_ed25519_key -N '' \
&& sed -i "s/#UsePrivilegeSeparation.*/UsePrivilegeSeparation no/g" /etc/ssh/sshd_config \
&& sed -i "s/UsePAM.*/UsePAM no/g" /etc/ssh/sshd_config \
&& echo 123456 | passwd --stdin root \
&& echo root: 123456|chpasswd \
&& rm -rf /var/cache/yum/*
# 安装redis
RUN \
yum install gcc -y \
&& cd /opt/tools \
&& tar -xzf redis-3.2.8.tar.gz \
&& rm -rf redis-3.2.8.tar.gz \
&& cd redis-3.2.8 && yum -y install tcl && make && make install \
&& cd /opt/tools \
&& rm -rf redis-3.2.8 \
&& rm -rf /var/cache/yum/*
# 安装mysql
RUN \
yum -y install perl perl-devel perl-Module-Install.noarch net-tools \
&& cd /opt/tools \
&& rpm -ivh libaio-0.3.107-10.el6.x86_64.rpm \
&& rpm -ivh MySQL-server-5.6.23-1.rhel5.x86_64.rpm \
&& rpm -ivh MySQL-client-5.6.23-1.rhel5.x86_64.rpm \
&& rpm -ivh MySQL-devel-5.6.23-1.rhel5.x86_64.rpm \
&& chown -R mysql:mysql /data/mysql \
&& /etc/init.d/mysql start \
&& mysqltmppwd=`cat /root/.mysql_secret | cut -b 87-102` \
&& mysqladmin -u root -p${mysqltmppwd} password "123456" \
&& mysql -uroot -p123456 -e"grant all privileges on *.* to root@'%' identified by '123456' with grant option" \
&& mysql -uroot -p123456 -e"flush privileges" \
&& /etc/init.d/mysql stop \
&& rm -rf libaio-0.3.107-10.el6.x86_64.rpm \
&& rm -rf MySQL-client-5.6.23-1.rhel5.x86_64.rpm \
&& rm -rf MySQL-devel-5.6.23-1.rhel5.x86_64.rpm \
&& rm -rf MySQL-server-5.6.23-1.rhel5.x86_64.rpm \
&& rm -rf /var/cache/yum/* \
&& sed -i -e "10a datadir = /data/mysql" /usr/my.cnf
# 安装 nginx
RUN \
yum -y install gcc-c++ zlib zlib-devel openssl openssl--devel pcre pcre-devel \
&& cd /opt/tools \
&& tar -zxv -f nginx-1.13.7.tar.gz \
&& rm -rf nginx-1.13.7.tar.gz \
&& cd nginx-1.13.7 \
&& ./configure --with-http_stub_status_module \
&& make && make install \
&& cd .. \
&& rm -rf nginx-1.13.7 \
&& rm -rf /var/cache/yum/*
# && echo "daemon off" >> /usr/local/nginx/conf/nginx.conf
# && cp -rf /opt/tools/nginx.conf /usr/local/nginx/conf/nginx.conf
# 安装supervisor
RUN \
yum -y install python-setuptools \
&& easy_install supervisor \
&& rm -rdf /var/cache/yum/*
# 设置java环境变量
RUN \
cd /opt/tools \
&& tar -zxvf jdk-8u102-linux-x64.tar.gz \
&& rm -rf jdk-8u102-linux-x64.tar.gz \
&& tar -zxvf apache-tomcat-7.0.70.tar.gz \
&& rm -rf apache-tomcat-7.0.70.tar.gz \
&& echo 'export JAVA_HOME=/opt/tools/jdk1.8.0_102' >> /etc/profile \
&& echo 'export PATH=$JAVA_HOME/bin:$PATH' >> /etc/profile \
&& echo 'export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar' >> /etc/profile \
&& source /etc/profile
# 设置环境变量
EXPOSE 22 80 3306 6379
CMD /usr/bin/supervisord -c /etc/supervisord.conf
#CMD /usr/sbin/init

场景三:服务的依赖和后台服务存在同一台服务器,但是处于不同容器

这类后台服务,可以有两种部署方式: (1)将依赖和后台服务按谁依赖谁的先后顺序,一 一用docker部署启动,每个依赖的服务和后台的服务都是相互独立的,映射端口后,后台服务项目中的数据库器地址就是宿主机的地址,端口为映射时候暴露出来的宿主机端口 (2)更推荐的方式就是docker-compose,编写好docker-compose.yml文件后,一个命令可以按照依赖关系部署所有的依赖项和后台服务,维护方便,具体见下文章节

1. 流程概览

这里针对一 一手动部署每一个依赖服务项后,载部署Egg服务

(1)部署redis (2)部署mysql (3)部署Egg

2. 具体实现

1、部署redis

bash
# 拉取redis镜像
docker pull redis
# 启动容器
docker run -itd --name redis-server -p 6379:6379 redis

2.1、部署mysql

bash
# 拉取mysql镜像
docker pull mysql:8.0.27

# 宿主机创建mysql映射目录`/home/www/blog/mysql`
mkdir -p /home/www/blog/mysql

# 启动容器
docker run -itd -p 33006:3306 --name blog-mysql -e MYSQL_DATABASE=blog-2021 -e MYSQL_USER=blog -e MYSQL_PASSWORD=123456 -e MYSQL_ROOT_PASSWORD=root -v /home/www/blog/mysql:/var/lib/mysql mysql:8.0.27

然后Navicat连接数据库,或者进入容器命令操作也可以

host:宿主机IP
port: 上一步暴露的端口 33006
用户名:`blog` 上一步设置的`MYSQL_USER=blog` 或者 root `MYSQL_ROOT_PASSWORD=root`
密码:`123456` 上一步设置的`MYSQL_PASSWORD=123456`, 如果username=root,则password=root,因为`MYSQL_ROOT_PASSWORD=root`

登录成功后,可以看到上一步上传的数据库blog-2021 (MYSQL_DATABASE=blog-2021),导入表后可用 image.png

查看宿主机映射容器的目录,发现已经有很多内容了 image.png

其中: MYSQL_ROOT_PASSWORD=123456 即root账户的密码为123456。 MYSQL_ALLOW_EMPTY_PASSWORD 即允许密码为空。 MYSQL_RANDOM_ROOT_PASSWORD 随机一个root账户密码。

参考文章:docker启动mysql并设置root密码

2.2、部署MongoDB

1)创建容器

bash
docker pull mongo
# 如果加需要验证就加--auth,不需要验证,就去掉。默认mongodb是不使用用户认证
docker run --name  my-mongo  -p 27017:27017  -d mongo --auth

2)进入容器设置用户

bash
docker exec -it <ID> /bin/bash   # 进入容器

mongo
use admin
db.createUser({user:"root",pwd:"root",roles:[{role:'root',db:'admin'}]})   # 创建用户,此用户创建成功,则后续操作都需要用户认证
exit

或者直接进入admin

bash
docker exec -it <ID> mongo admin

db.createUser({user:"root",pwd:"root",roles:[{role:'root',db:'admin'}]})   # 创建用户,此用户创建成功,则后续操作都需要用户认证
exit

刚铎操作参考:Docker搭建Mongodb

3、部署Egg

1)配置Egg内mysql /config/

js
module.exports = (appInfo) => ({
  //   mysql配置
  sequelize: {
    baseDir: "my_model", // egg项目的app目录内,mysql的sequelize模型对应的目录名称
    delegate: "myModel", // 修改mysql的model调用的模型名称,会与mongooDB冲突,用的时候app.myModel.xxx
    dialect: "mysql", // 可选值有: mysql, mariadb, postgres, mssql
    database: "blog-2021",
    host: "180.76.177.217", // 宿主机IP
    logging:false, // sequelize打印日志的类型,这里设置不显示日志,默认会将每一次操纵数据库的sql语句打印出来
    port: 33006, // 容器暴露给宿主机的端口
    username: "blog", // 用户名
    password: "123456", // 密码
    define: { // model的全局配置
       timestamps: true, // 添加create,update,delete时间戳
       // paranoid: true, // 添加软删除
       freezeTableName: true, // 防止修改表名为复数
       underscored: false // 防止驼峰式字段被默认转为下划线
     },
    dialectOptions: { // 让读取date类型数据时返回字符串而不是UTC时间
      // 正确显示时间
      dateStrings: true,
      typeCast: true,
    },
    pool: {
      // 连接池
      max: 5,
      min: 0,
      acquire: 30000,
      idle: 10000,
    },
    timezone: "+08:00", //改为标准时区, 由于orm用的UTC时间,这里必须加上东八区,否则取出来的时间相差8小时
  }
}

2)配置egg内MongoDB

js
module.exports = appInfo => ({
  mongoose: {
    client: {
      url: "mongodb://180.76.177.217:27017/app_test",
      options: {
        useUnifiedTopology: true
      }
      // plugins: [createdPlugin, [updatedPlugin, pluginOptions]],
    }
  }
});

3)配置Egg内redis

js
module.exports = appInfo => ({
  redis: {
    client: {
      port: 6379, // 容器暴露给宿主机的端口
      host: "180.76.177.217", // 宿主机Host
      password: null, 
      db: 0
    }
  }
});

4)修改package.json启动脚本命令 去掉--daemon --title=egg-server-example参数

image.png5)编写Dockerfile文件 项目根目录新建Dockerfile文件和.dockerignore文件 /Dockerfile文件

shell
FROM node:12.18.2

LABEL version="1.0.0"
LABEL prodName="blog_serve"

ENV NODE_ENV production
# 这个是容器中的文件目录
RUN mkdir -p /usr/src/app

# 拷贝package.json文件到工作目录
# !!重要:package.json需要单独添加。
# Docker在构建镜像的时候,是一层一层构建的,仅当这一层有变化时,重新构建对应的层。
# 如果package.json和源代码一起添加到镜像,则每次修改源码都需要重新安装npm模块,这样木有必要。
# 所以,正确的顺序是: 添加package.json;安装npm模块;添加源代码。
COPY package.json /usr/src/app/package.json

WORKDIR /usr/src/app

# 安装npm依赖(使用淘宝的镜像源)
# 如果使用的境外服务器,无需使用淘宝的镜像源,即改为`RUN npm i`。
RUN npm i --production --registry=https://registry.npm.taobao.org

# 拷贝所有源代码到工作目
COPY . /usr/src/app

# 暴露端口
EXPOSE 7001

CMD [ "npm", "start:docker" ]

/.dockerignore文件

shell
node_modules
.eslintignore
.eslintrc
*.md
.gitignore
.github
.template
logs/**/*
postman/**/*

特别注意:Dockerfile中,package.json需要单独添加,不要和源代码一起COPY到容器工作目录。 因为,Docker在构建镜像的时候,是一层一层构建的,仅当这一层有变化时,重新构建对应的层。 如果package.json和源代码一起添加到镜像,则每次修改源码都需要重新安装npm模块,这样木有必要。 所以,正确的顺序是: 添加package.json;安装npm模块;添加源代码。

6)构建Egg镜像

shell
docker build -t blog_egg_serve:1.0.0 .

构建好后,将镜像push到docker Hub,或者保存镜像到本地

bash
# 登录docker Hub
docker login
# 添加tag express-docker-demo 为镜像名  blog_egg_serve:1.0.0 为dochubHub的username  xiaoli123fendou/express-docker-demo:0.0.1为push到docker Hub的xiaoli123fendou/express-docker-demo存储库,版本为0.0.1
docker tag blog_egg_serve xiaoli123fendou/blog_egg_serve:1.0.0
# push到docker Hub
docker push xiaoli123fendou/blog_egg_serve:1.0.0
# 退出登录docker Hub
docker logout

保存镜像到本地

bash
# 保存到本地
docker save -o blog_egg_serve.tar blog_egg_serve:1.0.0
# 在目标服务器加载拷贝过来的tar文件为镜像
docker load -i blog_egg_serve.tar

这样,目标服务器宿主机就以已经有了blog_egg_serve:1.0.0镜像

7)运行容器,测试是否成功 要将运行日志映射到宿主机服务器本地,方便查看

bash
# 宿主机创建映射目录
mkdir -p /home/www/blog/serve/logs
# 运行容器
docker run -p 7001:7001 -d --name egg-server -v /home/www/blog/serve/logs:/usr/src/app/logs  blog_egg_serve:1.0.0

访问接口

js
http://180.76.177.217:7001/api/blog/getGroupBySecoundClassify?firstMenuId=1

Egg部署完毕

Egg部署特别注意

用Docker部署Egg项目时候,需要去掉启动命令中的--daemon参数,否则启动不成功 用Docker部署Egg项目时候,需要去掉启动命令中的--daemon参数,否则启动不成功 用Docker部署Egg项目时候,需要去掉启动命令中的--daemon参数,否则启动不成功

官方部署文档:https://eggjs.org/zh-cn/core/deployment.html

image.png

二、docker-nginx部署前端项目

1. 流程概览

  • (1)宿主机拉取nginx镜像
  • (2)运行nginx容器,并验证nginx是否启动成功
  • (3)宿主机和容器目录映射
  • (4)上传打包后的项目文件,或配置文件 到宿主机相应的映射目录
  • (5)重启nginx容器,验证重启成功

2. 具体实现

1、宿主机拉取nginx镜像

安装之前我们先从Docker Hub 上查找下是否存在nginx镜像,运行docker search nginx命令,查看后选择start数最多是nginx镜像,然后pull

bash
# 查询并选择用户量最大的镜像
docker search nginx

# 拉取镜像
docker pull nginx:latest

# 查看本地的镜像
docker images

2、运行nginx容器,验证是否启动成功

bash
docker run --name nginx-vue -p 8001:80 -d nginx

image.png

3、宿主机和容器目录映射

若容器目录没有映射到宿主机,也就是直接将打包后的资源和nginx配置文件放到制作的镜像中,运行了容器,当下一次项目或nginx配置要做更改,则必须重新build镜像,然后运行新容器,这样非常的麻烦。docker容器目录映射到宿主机,就是为了解决这一问题的

如果我们想修改nginx的配置,想更改nginx中的资源文件,就是将容器中的目录和本机目录做映射,以达到修改本机目录文件就影响到容器中的文件,同样,修改容器内文件也能同步更改宿主机映射文件。

注意: nginx镜像内部各个文件的默认位置 容器内html默认目录:/usr/share/nginx/html 容器内nginx.conf默认位置:/etc/nginx/nginx.conf 容器内conf.d默认位置:/etc/nginx/conf.d (是目录,不是文件) 容器内nginx日志logs默认位置:/var/log/nginx,里面有各种日志文件

centos7宿主机nginx各个文件默认位置: 宿主机html默认目录:/usr/local/nginx/html 宿主机nginx.conf默认位置:/usr/local/nginx/conf/nginx.conf 宿主机logs默认位置:/usr/local/nginx/logs 宿主机nginx可执行文件默认位置:/usr/local/nginx/sbin/nginx,最后的nginx就是可执行文件

具体步骤如下: (1)先查看nginx容器内nginx配置文件长什么样

bash
docker exec <ID> bash # 进入nginx容器

cat /etc/nginx/nginx.conf # 查看容器内nginx配置文件

发现配置文件默认是进行了拆分的,

image.pnginclude /etc/nginx/conf.d/*.conf; 默认是加载/etc/nginx/conf.d/目录下所有的以.conf结尾的文件,并且/etc/nginx/conf.d/目录下有一个default.conf配置文件,那么我们要做的,就是挂载/etc/nginx/conf.d/目录到宿主机即可,若原有配置文件也要修改,也可以将原有的nginx.conf也挂载到配置文件

(2)宿主机内新建需要映射的文件目录,用于和容器进行映射挂载

bash
mkdir -p /home/www/nginx/conf /home/www/nginx/conf/conf.d /home/www/nginx/html /home/www/nginx/logs

(3)将nginx默认的配置文件拷贝过来方便直接使用

bash
docker cp 5f07c5049a26:/etc/nginx/nginx.conf /home/www/nginx/conf 
docker cp 5f07c5049a26:/etc/nginx/conf.d/default.conf /home/www/nginx/conf/conf.d/default.conf

其他文件按需要拷贝即可 (4)映射并重新启动nginx

  • docker运行容器时提供了参数-v (volumes)可以用来与宿主机绑定挂载目录,参数格式为:-v 宿主机目录:容器目录

例如:

bash
docker run -d --name nginx-vue \ 
-v /home/www/nginx/conf/nginx.conf:/etc/nginx/nginx.conf \ # 将宿主机中的nginx.conf挂载到容器的/etc/nginx/nginx.conf
-v /home/www/nginx/conf/conf.d:/etc/nginx/conf.d \ # 将宿主机中的conf.d挂载到容器的/etc/nginx/conf.d
-v /home/www/nginx/html:/usr/share/nginx/html \  # 将宿主机的html目录挂载到容器的 /usr/share/nginx/html
-v /home/www/nginx/logs:/var/log/nginx \ # 将宿主机的logs挂载到容器的/var/log/nginx,可以在宿主机查看容器日志了
-p 8001:80 nginx

# 确保宿主机内的映射文件或目录存在后,运行如下命令,启动容器
# 1.先删除旧容器
docker rm -f <id> 

# 2.再启动新容器
docker run -idt -p 80:80 -p 443:443 --name nginx-vue -v /home/www/nginx/conf/nginx.conf:/etc/nginx/nginx.conf -v /home/www/nginx/html:/usr/share/nginx/html -v /home/www/nginx/logs:/var/log/nginx -v /home/www/nginx/conf/conf.d:/etc/nginx/conf.d nginx:latest

这样docker中的nginx就会加载宿主机中对应的文件目录了,这样我们就可以很方便的在宿主机中对docker中的nginx进行配置了。 也就是说,要更改容器内的web资源,或nginx配置文件,只需要更改宿主机上对应的目录里面的文件内容即可

特别注意:

  • 映射目录时,宿主机的目录需要创建(位置无限制),容器的目录一般为安装软件的默认目录或文件
  • 宿主机文件的映射文件,可以从容器内copy,然后修改,防止报错

4、上传web打包的项目文件到宿主机html目录

由于上一步已经将宿主机的/home/www/nginx/html目录映射到了容器的/usr/share/nginx/html,所以,只需要将静态资源上传到宿主机的/home/www/nginx/html目录下,容器对应目录便可以同步改变。

image.png

访问页面8001端口

image.png

web+nginx+docker部署完成

三、docker componse“一键部署所有”

使用docker-compose同时管理多个服务,只需要一行命令docker compose up -d,就可以启动一个包含后端项目、前端项目、数据库的完整服务

1、准备工作

  • 安装好docker环境,并docker处于启动状态;
  • 安装好docker-compose(安装Docker同时会自动安装,如果没有可以自行安装)
  • 一个前端项目(这里为nuxt,比如vue或react等都行)
  • 一个后台node服务(这里为egg,默认前后端分离)

参考这篇:docker-compose部署nodejs+eggjs+mysql+redis+nginx项目