社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  docker

使用 Docker-compose 打包整个网站项目一键部署

马哥Linux运维 • 1 年前 • 216 次点击  

前言

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

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

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

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

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

适合读下去的朋友:

  • 对Docker有基本的了解
  • 同时需要部署多个项目
  • 需要开源项目或者自建项目的整体部署
  • 需要打包部署一整个网站

需要提前准备的

Docker安装并启动(演示版本如下)

  • docker-compose(安装Docker同时会自动安装,如果没有可以自行安装,也很简单)
  • 一个前端项目(这里演示使用React SPA)
  • 一个后端项目(这里使用Express)

如图所示,通过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

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

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

提取Nginx配置到项目中

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

docker exec -it frontend-test /bin/bash

在项目根目录下新建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
新建库和表

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

后端项目启动

下载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可以查看当前所有运行中的服务。

docker compose down

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

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

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

注意点

1、mysql配置

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

自动迁移数据库

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

一些报错信息

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

  • 1、docker拉取镜慢的话,可以考虑国内镜像
  • 2、前端、后端项目可以使用任意的语言,只要构架不同的镜像就可以了。

docker查看日志

docker logs -f --tail 100 containerId

链接:https://juejin.cn/post/6981207521994211359

(版权归原作者所有,侵删)


Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/146737
 
216 次点击