docker-compose统一部署前后端项目(可多个)

2,644 阅读11分钟

使用Dockerfile方式部署,参考教程

Docker-部署SpringBoot后端项目

Docker-部署Vue前端项目

需要记住的点:

  • 各服务容器中的端口映射 “主机端口:容器端口“ 主机端口可以改变,容器端口使用各服务的默认端口
  • 各服务的容器之间是相互隔离互不影响的
  • 使用docker部署多个项目时,只需保证使用的各服务容器映射的主机端口不同即可,各服务容器中使用默认端口;
  • 如果修改了某个服务挂载在主机的配置文件,只需重启单个服务容器即可生效:docker restart 容器名称
  • 如果修改了docker-compose.yml文件,则需要使用docker-compose down 命令,将相关的服务全部删除,再重新执行docker-compose up命令重新启动,修改才会生效
  • 需要部署的项目之间可以拥有一套独立的服务配置环境,只需保证各服务容器的端口映射的主机端口不同即可,

参考链接:

Docker 入门教程

一、环境准备

1.环境

宿主主机:虚拟机

宿主主机系统:centos7

宿主主机系统环境:默认虚拟主机上已安装好docker、docker-compose软件环境

2.概念

(本地)主机:本地使用的电脑

 宿主主机:部署了docker环境的主机(虚拟机、服务器或本地主机)

镜像(Image):Docker 镜像(Image),就相当于是一个 root 文件系统。比如官方镜像 ubuntu:16.04 就包含了完整的一套 Ubuntu16.04 最小系统的 root 文件系统。

容器(Container):镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的类和实例一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。

仓库(Repository):仓库可看成一个代码控制中心,用来保存镜像。

二、文件准备

1.构建文件的目录结构

可以提前在本地主机上将需要部署的项目的目录结构和项目文件准备好,然后统一上传到宿主主机上(即部署了docker环境的主机)。

**项目整体文件:**一个项目的目录结构如下,

  • amieemc

    • env
    • server
    • web

    Dockerfile

    docker-compose.yml

amieemc  # 项目的整体文件夹
	|- env # 1.项目依赖的环境文件夹,通过挂载该数据卷关联容器中的文件
		|- nginx #1.1 nginx文件夹
			|- conf
				|- nginx.conf # 1.1.1 nginx的配置文件所在的文件夹,用于挂载到nginx容器中进行配置关联
			|- logs # 1.1.2 nginx的日志文件夹
		|- postgres # 1.2 postgres 数据库文件夹
			|- data # 1.2.1 postgres的数据文件夹,和postgres容器的数据文件进行关联,防止因删除容器导致数据丢失
		|- redis # 1.3 redis文件夹
			|- data # 1.3.1 redis的数据文件夹,和redis容器的数据文件进行关联,防止因删除容器导致数据丢失
  |- server # 2.后端项目的代码文件夹
		|- ... # 2.1 后端项目的代码文件
	|- web # 3.前端项目的代码文件夹
		- ... #3.1 前端项目的代码文件
	|- docker-compose.yml # 4.进行统一部署的docker-compose.yml配置文件
	|- Dockerfile # 5.用来构建项目镜像的Dockerfile配置文件

**后端项目文件:**以AMI项目为例,因为部署的系统为Linux系统,所以后端项目server中的文件如下:

前端项目文件:文件内容如下,即为通过npm run build打包之后dist中的文件

2.配置文件的内容

2.1 后端项目的镜像配置文件Dockerfile

Dockerfile文件的内容:

FROM java:8  # 项目依赖的镜像和版本号
VOLUME /tmp  # 定义匿名数据卷。在启动容器时忘记挂载数据卷,会自动挂载到匿名卷。
EXPOSE 8005  # 后端项目所使用的的容器中的端口号,要和application.yml中的server.port相同
WORKDIR /usr/local/amieemc # 指定后端项目在容器的工作目录,不需要提前创建
COPY server/ami-eemc-0.0.1.jar /usr/local/amieemc # 拷贝宿主机上后端项目的jar文件到所在容器中的工作目录下
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/usr/local/amieemc/ami-eemc-0.0.1.jar"]

COPY指令详解:

COPY <源地址> <目标地址>

源地址:以Dockerfile所在的目录作为当前的上下文目录,来得到的源地址;

目标地址:后端项目在容器中的工作目录;

ENTRYPOINT 指令详解:类似于 CMD 指令,但其不会被 docker run 的命令行参数指定的指令所覆盖,而且这些命令行参数会被当作参数送给 ENTRYPOINT 指令指定的程序。

即运行后端项目时所要执行的指令。

ENTRYPOINT ["<executeable>","<param1>","<param2>",...]

executeable:可执行的程序指令;

param1:执行指定的executeable程序时,传递的参数,可以有多个数;

在执行docker run时会自动执行上述的ENTRYPOINT 指定的指令,以上述为例docker run时会执行一下命令,来启动后端项目:

java -Djava.security.egd=file:/dev/./urandom -jar /usr/local/amieemc/ami-eemc-0.0.1.jar

Dockerfile指令解释可参考:Docker Dockerfile

2.2 统一部署的配置文件docker-compose.yml

docker-compose.yml文件的内容:

version: '3' # docker-compose的版本号
services:
  amieemc: # 服务名唯一,配置amieemc后台服务
    build: # 启动服务时先将build指令中的Dockerfile打包成镜像,再去运行镜像,镜像名会带有前缀(当前的目录名)
      context: . #指定Dockerfile所在的上下文目录,"."表示当前目录
      dockerfile: Dockerfile # Dockerfile文件名称
    container_name: amieemc_v1 # 容器名称
    volumes: 
      - /project/amieemc/server:/usr/local/amieemc # 挂载宿主机上的amieemc后端文件目录到容器中对应的目录下,需要提前创建好主机上的目录
    ports:
      - "0.0.0.0:8005:8005" # 宿主主机端口号:容器端口号
    depends_on: # amieemc服务依赖的其他服务,按照指定的顺序先启动依赖的服务,再启动后端项目服务
      - postgres
      - redis
      - nginx
  # 配置redis
  redis:
    image: redis:latest # redis镜像 
    container_name: amieemc_v1_redis # redis镜像的容器名称
    ports:
      - "0.0.0.0:6379:6379" # 主机端口和容器端口的映射,后台项目服务中application.yml中的redis配置的端口,要为主机端口
    volumes:
      - /project/amieemc/env/redis/data:/data # 挂载Redis存储数据目录到容器中,持久化数据库数据,避免因容器停止导致数据丢失的情况
    command: "redis-server --appendonly yes" #此命令用来覆盖容器默认命令
  # 配置postgres
  postgres:
    image: postgres:latest
    container_name: amieemc_v1_postgres
    ports:
      - "0.0.0.0:5432:5432"
    volumes:
      - /project/amieemc/env/psotgres/data:/data/db # 挂载postgres数据目录到容器中,持久化数据库数据 
    environment: # 配置postgres的环境变量
      POSTGRES_PASSWORD: root # 设置postgres的连接(即数据库)密码,默认用户名为postgres,其他数据库可以手动设置用户名和密码
  # 配置nginx
  nginx:
    image: nginx:latest
    container_name: amieemc_v1_nginx
    ports:
      - "0.0.0.0:8090:80" # 注意此处配置的端口要和/project/amieemc/env/nginx/conf/nginx.conf文件中监听的端口一致
    volumes:
      - /project/amieemc/web:/usr/local/nginx/html
      - /project/amieemc/env/nginx/conf/nginx.conf:/etc/nginx/nginx.conf
      - /project/amieemc/env/nginx/logs:/var/log/nginx

说明:

(1)文件中的amieemc即为后端项目的服务名,通过Dockerfile构建后端项目的镜像,然后通过docker run运行后端项目的容器来启动后端项目。

(2)文件内容中,后端项目服务amieemc的配置中,端口映射ports需要注意,后面的容器端口号、Dockerfile文件中的EXPOSE 端口号以及后端项目中的application.yml中的server.port端口号三者要保持一致,映射的宿主主机端口号可以不同,宿主主机端口号即为外部访问时需要用到的端口号,容器端口号是服务在容器中使用的端口号。

(3)后端项目服务通过depends_on依赖的其他服务中,端口号的配置也为“宿主主机端口号:容器端口号“,容器端口号为服务在容器中的端口号,一般使用服务默认的,尽量不要修改,映射的宿主主机端口号(外部访问使用)可以不同,外部在访问服务时使用的是映射的宿主主机的端口号。

(3)由于各容器之间是相互隔离的,对于部署多项目的情况,各项目依赖的其他服务在容器中的端口可以一致,因为互不影响,但是映射的宿主主机的端口必须不能重复,因为外部访问时使用的是宿主主机的端口,如果出现重复会报错,导致端口冲突。

2.3 前后端项目相关的配置文件的内容

(1)后端项目的配置文件主要是:database.properties、application.yml、config.properties和logback.xml文件。

database.properties:修改数据库的IP地址、端口号,数据库名称、用户名和密码;IP即为宿主主机的ip,端口号和密码为docker-compose.yml文件中配置的postgres服务的宿主主机端口号和密码,用户名默认为postgres。

application.yml:修改redis的相关配置,ip为宿主主机的ip,端口号为docker-compose.yml文件中配置的redis服务的宿主主机的端口号。

**config.properties:**该配置文件主要是修改verify对应的机器码,需要把项目部署到宿主主机上去之后,通过执行(使用Linux命令执行)verify.sh文件得到机器码,然后替换掉该配置文件中verify对应的值。

logback.xml:该文件主要修改日志文件的路径,原来项目部署在windows系统中,日志文件的路径是“盘符:/logs”,当部署到Linux系统上时,需要去掉“盘符:/”,只保留logs即可。

(2)前端项目配置文件的修改

前端项目相关的配置文件主要是web文件夹中的serverConfig.js和nginx的配置文件nginx.conf;

serverConfig.js:该文件中主要修改对应的后端服务的"ip:端口号“,ip为宿主主机的ip,端口号为docker-compose.yml文件中项目服务配置的ports中的宿主主机的端口号。

nginx.conf:该文件主要修改前端项目对应的端口号,端口号为docker-compose.yml文件中nginx服务配置的ports中的宿主主机的端口号。

三、部署

1.上传项目文件到宿主主机

首先在宿主主机的系统根目录(非root目录,是“/”)下创建一个文件夹,用来存放项目文件,此处以project文件夹为例,如下:

通过文件上传工具(此处使用的是finalshell),将本地主机上的项目文件amieemc上传到project文件夹下,然后通过命令窗口使用cd命令进入到docker-compose.yml所在的文件夹内(此处为amieemc项目文件夹)。

1.1 后端AMI项目获取机器码

通过cd命令进入到后端项目的server文件夹内,执行"./verify.sh"命令获取到机器码,然后复制到config.properties文件中的verify对应的内容。

如果提示没有文件的执行权限,可通过“chmod +x verify.sh”命令修改文件的权限,再执行文件。

# 修改文件的执行权限
chmod +x verify.sh 
# 运行文件
./verify.sh

1.2 启动服务

在docker-compose.yml所在的目录下,执行下面的命令启动服务,启动命令中使用“-d”参数,服务会在后台运行,可以通过命令查看服务的启动日志;不加“-d”,服务的启动信息会在当前窗口中显示出来;

# 启动服务,-d后台运行
docker-compose up -d
# 查看服务启动日志
docker-compose logs -f

首次启动成功之后,可以通过以下命令查看对应的镜像和容器信息

# 查看全部镜像
docker images
# 查看运行中的容器
docker ps 
# 查看全部的容器(运行或不运行的)
docker ps -a

首次启动成功之后,由于在postgres中还没有创建对应的数据库和表,所以后端项目服务会报错,其他服务正常,此时,需要通过数据库工具(如navicate for premium),连接上该项目的postgres服务,然后创建好数据库并导入对应的数据库表,再次重新启动postgres服务才行。

# 重启单个服务的容器
docker restart amieemc_v1_postgres(容器名称)

至此,整个前后端项目就部署完成了,可以通过在浏览器中输入“http://宿主主机ip:前端项目(即为nginx服务)映射的宿主主机端口号"(如此例为:http://宿主主机ip:8090),来访问项目。

1.3 重启单个服务

挂载点的配置文件的修改:由于容器中的配置文件挂载到了宿主主机中对应的配置文件,所以服务容器在运行时加载的是挂载点中的文件,当挂载点中的文件修改之后,如nginx的配置文件和后端项目的配置文件,可以通过重启对应的服务容器来使修改生效。

# 重启单个服务的容器
docker restart 容器名称

1.4 删除项目的全部服务

docker-compose.yml和Dockerfile文件的修改:当这两个配置文件修改之后,要想使修改之后的内容生效,需要先把原来的容器删除之后,再重新启动才可以。

注意:执行对应项目的docker-compose命令时,都需要进入每个项目对应的docker-compose.yml所在的文件夹内才可以

# 删除某个项目的全部服务的容器
docker-compose down

参考链接


Docker 命令大全