使用 Docker-compose 一键打包部署项目!真心不错啊

ab168778f87dbc6d89200babaeaf7ebf.gif关注公众号,回复“1024”获取2TB学习资源!

前言

我们常常见到很多比较棒的开源项目,但在本地安装运行的话就会很复杂,要配置不同的环境,安装不同的依赖,好一点的会用docker直接拉取,或者打包好。

这些无疑都会增加初学者上手的成本,所以这篇文章总结了下目前比较常用的解决方法之一:

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

而docker-compose作为docker容器的编排工具,可以帮助我们实现管理多个docker容器。

其实整体的过程并不难,但要配置完成,也要很多步骤,这篇文章主要是从实战的角度,将整个过程串起来。涉及的知识点包括:nginx、docker、docker-compose、node、mysql也需要了解下。

适合读下去的朋友:

  • 对Docker有基本的了解

  • 同时需要部署多个项目

  • 需要开源项目或者自建项目的整体部署

  • 需要打包部署一整个网站

需要提前准备的

Docker安装并启动(演示版本如下)526f8d7658b092a617f4a04d854c1186.png

  • docker-compose(安装Docker同时会自动安装,如果没有可以自行安装,也很简单)

  • 一个前端项目(这里演示使用React SPA)

  • 一个后端项目(这里使用Express)

651ba38a64c18e0e175212f6c0df5ada.png

如图所示,通过docker-componse.yml文件一次启动不同的容器,然后他们都可以对外提供服务。

前端项目构建

前端项目处理

首先我们通过CRA下载一个项目模版,为了可以模拟实际的项目需要,对下载的模版做一些处理,让这个项目可以

  • 1、区分当前项目是预发环境还是生产环境

  • 2、引入Axios可以请求接口

接着我们打包yarn build:prod,打包后的文件夹build就是我们要部署的静态资源。

拉取Nginx镜像部署

我们通过Docker部署前面打包的静态资源,当前项目的路径是

/Users/user/Desktop/mine/fronted-demo2/build

直接运行下面命令行,启动前端服务

docker run -d -p 80:80 -v /Users/user/Desktop/mine/fronted-demo2/build:/usr/share/nginx/html --name frontend-test nginx
9612d46555d8ad52abeaecf3f4eb283c.png

通过本机80端口访问,发现当前服务是生产环境,并且由于后端服务没有部署,此时数据库拿到的数据为空。e063f49989fee2ae33f18b871cf8243f.png

测试,我们切换路由,发现页面404了,是因为单页面应用路由在前端,需要nginx转发下,接着我们用项目中的Nginx配置覆盖容器中的配置

提取Nginx配置到项目中

首先,我们进入上一步的Docker容器,可以看到Nginx的路径。

docker exec -it frontend-test /bin/bash
893246f7a1553fea8201893b4c2107c4.png

在项目根目录下新建nginx/default.conf

server {
    listen  80;
    server_name  localhost;
    underscores_in_headers  on;
    root /home/frontend;
    location / {
      try_files $uri $uri/ @router;
      index index.html;
    }
    location @router {
      rewrite ^.*$ /index.html last;
    }
}

然后通过挂载的方式,启动容器,发现访问正常。

编写Dockerfile文件
FROM nginx

WORKDIR /home/frontend

COPY build .

COPY ./nginx/default.conf /etc/nginx/conf.d/default.conf

EXPOSE 80

在项目根目录下,新建Dockerfile文件,其中包括基础镜像、工作目录、将项目copy到镜像,将Nginx配置文件复制到镜像中。

构建前端服务镜像并启动
docker build -t frontend .

docker images

docker run -d -p 80:80 --name frontend-v1 frontend

可以发现前端服务的镜像已经打包完成并启动,打开本地80端口访问,测试完毕可以删除,然后留镜像frontend备用。也可以将镜像推送镜像仓库,后面直接通过远程来拉取也可以。

主意:如果之前的Docker容器启动,需要先关掉,否则会报端口被占用,如果不删除,就需要修改重新启动容器的名字。

数据库启动

拉取并启动数据库、连接数据库
docker run -p 3306:3306 --restart=always --privileged=true --name mysql -v /Users/user/Desktop/mysql/data:/var/lib/mysql -v /Users/user/Desktop/mysql/my.cnf:/etc/mysql/my.cnf -e MYSQL_ROOT_PASSWORD="123456" -d mariadb

一行命令启动Mariadb,这里选择Mariadb是由于我m1的电脑,不支持mysql镜像,所以改成了Mariadb,使用是一样。上面的命令除了启动数据库服务,还设置了数据的一些配置,密码,将数据库的数据放在了本地。

[mysqld]
skip-name-resolve
user=root
character-set-server=utf8
default_authentication_plugin=mysql_native_password
sql_mode=ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
lower_case_table_names=1 #忽略表名大小写

[client]
default-character-set=utf8
[mysql]
default-character-set=utf8
新建库和表

这里可以进入容器中操作数据库,还可以使用客户端连接数据库efac77b63b5f28ee707bac2cdc5d0fe3.png

后端项目启动

下载Express项目模版并连接数据库

这里配置数据库,写好项目接口,确保本地启动服务正常。

拉起镜像,部署镜像

部署服务,我们选择使用pm2,为了区分生产环境和预发环境,我们在根目录下新建pm2.config.js,然后通过传入不同的参数,启动对应的环境

module.exports = {
  apps : [
      {
        name: "myapp",
        script: "./bin/www",
        watch: true,
        env: {
            "NODE_ENV": "development"
        },
        env_production: {
            "NODE_ENV": "production",
        }
      }
  ]
}
  • 启动预发环境pm2 start pm2.config.js --env development

  • 启动生产环境pm2 start pm2.config.js --env production

  • 再项目中通过process.env.NODE_ENV读取

编写Dockerfile并构建新的镜像
FROM keymetrics/pm2

RUN mkdir -p /home/backend

WORKDIR /home/backend

COPY ./ /home/backend

RUN yarn install

ENV NPM_CONFIG_LOGLEVEL warn

EXPOSE 9000

CMD ["pm2-runtime", "start", "pm2.config.js", "--env", "production"]

然后构建镜像docker build -t backend .

docker-compose.yml 配置

截止目前,我们有了三个Docker镜像,分别是前端服务的镜像,后端服务的镜像和数据库的镜像。然后我们编写docker-compose.yml来同时启动这三个服务,并且保证三者的启动顺序。

编写docker-compose配置文件

新建一个目录,然后再目录下新建docker-compose.yml和目录mysql,mysql中包含了mysql的数据和日志信息,这样就不用重启服务导致数据库信息丢失

version: '3'

networks:
  app-web:
   driver: bridge

services:
  mysql:
    image: mariadb
    ports:
     - 3306:3306
    command: --default-authentication-plugin=mysql_native_password
    restart: always
    networks:
     - app-web
    environment:
     - TZ=Asia/Shanghai
     - MYSQL_USER=root
     - MYSQL_ROOT_PASSWORD=123456
    volumes:
     - ./mysql/data:/var/lib/mysql
     - ./mysql/my.cnf:/etc/mysql/my.cnf
     - /etc/localtime:/etc/localtime
  backend:
    image: backend
    ports:
     - 9000:9000
    depends_on:
     - mysql
    networks:
     - app-web
  frontend:
    image: frontend
    ports:
     - 80:80
    depends_on:
     - backend

看到这个配置不要怕,拆分开,其实很简单,整个配置文件就是一个完整的项目,包括了mysql、backend、frontend,每个部分和配置Dockerfile差不多,增加了depends_on,很好理解,前置的服务需要提前部署,networks,让不同的容器在相同的网络中运行。当然这只是提供了最基础的配置,更复杂的配置需要根据使用场景来完善。

启动服务
docker compose up -d

-d #是以守护进程的方式运行,通过docker ps可以查看当前所有运行中的服务。
5d9adbd914ccdeffbd9fde8c2c93ad55.png
docker compose down

#停止当前集群下的所有服务,并删除容器。

到这里,我们的docker-compose整体打包部署一个网站已经完成了,过程中可能存在各种各样的坑,但只要配置报错日志进行查询,就能一一解决。

如果需要重新部署一套,或者发布新版本,只需要更新docker-compose.yml就可以了

注意点

1、mysql配置

数据库和项目的一些信息需要灵活配置,根据自己的需要。

自动迁移数据库

我们发现,一些新的数据库表,没有进行初始化,导致需要手动处理,在项目中我们可以用脚本去,或者使用一些数据库封装的orm进行自动迁移。

一些报错信息
b225871929b629b1bc1153a4b79bac13.png

解决办法,修改mysql配置host为mysql

ee58982ecbe333bec1313577588a7149.png
  • 1、docker拉取镜慢的话,可以考虑国内镜像

  • 2、前端、后端项目可以使用任意的语言,只要构架不同的镜像就可以了。

docker查看日志

docker logs -f --tail 100 containerId

作者:前端中后台 

链接:juejin.cn/post/6981207521994211359

0ec5f0797e7bdd52646f1fbe55d41054.png

15f386f3137b44da89c6ed8a9c12a2d6.png

推荐阅读 点击标题可跳转

谁再说不熟悉 Zabbix 监控系统,就把这个给他扔过去!

这款 Linux、数据库、Redis统一管理平台,有点牛逼!

使用 Docker 搭建本地开发环境!真心强啊

微软出手了!拯救“四分五裂”的 Markdown

卧槽!外包员工上班戴耳机被开除。。。

构建你的第一个仪表盘!Grafana 中文入门教程

af75f1875e965dbd9b54d6ff3e1f0b84.png

转发 关注

点亮下方“在看”图标

更多人看到

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值