龙空技术网

使用Docker Compose部署Angular前端和Spring Boot后端应用

SimpleIsTheBest 88

前言:

现在朋友们对“dockercompose部署springboot”大致比较注意,大家都需要学习一些“dockercompose部署springboot”的相关资讯。那么小编同时在网摘上收集了一些有关“dockercompose部署springboot””的相关资讯,希望咱们能喜欢,咱们一起来了解一下吧!

代码下载

本文章所有代码可从Github下载。地址:GitHub - YuRui1113/book-management-system: An Angular client and Spring Boot rest API with basic CRUD functions

概述

Docker Compose“是用于定义和运行多容器Docker应用程序的工具”。Docker Compose 配置文件(通常名为 docker-compose.yaml、docker-compose.yaml 或 compose.yaml、compose.yml,官方建议最好用compose.yaml)。它允许您同时定义多个服务,一键启动所有应用和服务,对于项目运行环境的配置和项目测试还是很有帮助的。

本文创建了一个Angular前端和一个Spring Boot后端应用以及后端用到的PostgreSQL数据库,我们将使用Docker Compose部署这两个应用和用到的PostgreSQL数据库。

代码仓库提供了两个应用:

rest-api/ – 使用Spring Boot开发的提供了基本的CRUD功能的REST API应用WebFront/ - 使用Angular实现的包含了数据列表的显示、分页和基本的CRUD功能的Web应用

本文将使用Docker Compose创建数据库、前端和后端三个容器。

创建前后端应用Dockerfile创建后端应用Dockerfile

在Spring Boot后端应用根目录下创建Dockerfile文件(/rest-api/Dockerfile),内容如下:

FROM openjdk:17-jdk-alpineEXPOSE 8080LABEL org.opencontainers.image.authors="*****@hotmail.com"COPY target/rest-api-0.0.1-SNAPSHOT.jar rest-api-0.0.1-SNAPSHOT.jarENTRYPOINT ["java", "-jar", "/rest-api-0.0.1-SNAPSHOT.jar"]
创建前端应用nginx配置文件

对于Angular前端应用,它将使用nginx作为web服务器。首先在Angular前端应用根目录下创建nginx配置文件(/WebFront/nginx/nginx.conf),内容如下:

user nginx;worker_processes auto;error_log /var/log/nginx/error.log warn;pid /var/run/nginx.pid;events{  worker_connections 1024;}http{  server  {        location /    {      #### Gzip Settings  ####      gzip on;      gzip_min_length   1100;      gzip_vary         on;      gzip_proxied      expired no-cache no-store private auth;      gzip_types        text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript;      gzip_comp_level   5;      #### Serve Angular Application ####      root /usr/share/nginx/html;      # Resolve 404 error when refreshing page      try_files $uri $uri/ /index.html;      add_header Cache-Control "no-store, no-cache, must-revalidate";      proxy_http_version 1.1;      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;      proxy_set_header X-Forwarded-Proto $scheme;      proxy_set_header X-Forwarded-Port $server_port;    }  }  include /etc/nginx/mime.types;  default_type application/octet-stream;  log_format main '$remote_addr - $remote_user [$time_local] "$request" '  '$status $body_bytes_sent "$http_referer" '  '"$http_user_agent" "$http_x_forwarded_for"';  access_log /var/log/nginx/access.log main;  sendfile on;  keepalive_timeout 30m;  include /etc/nginx/conf.d/*.conf;}
创建前端应用Dockerfile

最后创建前端应用Dockerfile文件(/WebFront/Dockerfile),内容如下:

######  Use NgInx alpine image  ###### FROM nginx:stable-alpine# Remove default nginx websiteRUN rm -rf /usr/share/nginx/html/*# Remove default nginx configurationRUN rm /etc/nginx/conf.d/default.conf# Copy nginx config file for resolving 404 error when refreshing pageCOPY ./nginx/nginx.conf /etc/nginx/nginx.conf# Copy dist folder fro build stage to nginx public folderCOPY ./dist/web-front /usr/share/nginx/html# Start NgInx serviceCMD ["nginx", "-g", "daemon off;"]
创建compose.yaml

在代码根目录下创建名为compose.yaml的文本文件。

然后创建环境变量文件.env,主要用来保存数据库连接信息,正常数据库连接信息属于私密敏感信息,需要分开独立保存,内容如下:

POSTGRES_USER=taylorPOSTGRES_PASSWORD=secret
定义数据库容器所需的Volume

Docker 容器运行image中定义的软件堆栈。Image由一组只读层组成,这些只读层在称为联合文件系统的文件系统上工作。当我们启动一个新容器时,Docker 会在映像层的顶部添加一个读写层,允许容器像在标准 Linux 文件系统上一样运行。

因此,容器内的任何文件更改都会在读写层中创建一个工作副本。但是,当容器被停止或删除时,该读写层包括容器内的所有更改将丢失。

如果我们想在每次运行容器之间保留数据,Docker 卷和绑定挂载可以提供帮助。

卷是保存 Docker 容器生成和使用的数据的首选机制。绑定挂载依赖于主机的目录结构和操作系统,但卷完全由 Docker 管理。

此外,卷通常是更好的选择,因为它将数据保存在容器的可写层中,不会增加使用它的容器的大小,并且卷的内容存在于给定容器的生命周期之外。

为保证数据库数据在容器重新创建仍然存在,需要创建数据库容器所需要的卷,代码如下:

version: '3.8'services:  volumes:  db-data:    driver: local

默认驱动类型为“local”。它表示启动容器服务使用定义卷时,每个服务容器都使用自己的本地卷。使用本地卷驱动程序,则任何容器都不能共享此数据。

定义PostgreSQL数据库容器创建

首先创建数据库初始化脚本文件(/db/init.sql),它包括创建所用到的表和插入初始化数据,代码如下:

CREATE TABLE public.books (	id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY,	author varchar(100) NOT NULL,	isbn varchar(20) NOT NULL,	publication_year int2 NULL,	title varchar(250) NOT NULL,	CONSTRAINT uk_isbn UNIQUE (isbn));INSERT INTO public.books(author, isbn, publication_year, title)VALUES('Abraham Stackhouse', '989-28-3705-007-2', 2001, 'Ballinby Boys');INSERT INTO public.books(author, isbn, publication_year, title)VALUES('Amelia Wangerin, Jr.', '989-28-79-11297-4', 2002, 'Nothing But Capers');INSERT INTO public.books(author, isbn, publication_year, title)VALUES('Anastasia Inez', '989-28-79-11297-8', 2003, 'Alanna Saves the Day');INSERT INTO public.books(author, isbn, publication_year, title)VALUES('Arthur McCrumb', '989-28-79-18127-7', 2004, 'Post Alley');INSERT INTO public.books(author, isbn, publication_year, title)VALUES('Arturo Hijuelos', '989-28-79-82197-5', 2005, 'Thatchwork Cottage');INSERT INTO public.books(author, isbn, publication_year, title)VALUES('Bernard Hopf', '989-28-79-05638-4', 2006, 'Zero over Twelve');INSERT INTO public.books(author, isbn, publication_year, title)VALUES('Bianca Thompson', '989-28-654-5018-9', 2007, 'Portmeirion');INSERT INTO public.books(author, isbn, publication_year, title)VALUES('Bravig Lewisohn', '989-28-79-69807-2', 2008, 'Rystwyth');INSERT INTO public.books(author, isbn, publication_year, title)VALUES('Burton Malamud', '989-28-79-69807-4', 2009, 'The Mallemaroking');INSERT INTO public.books(author, isbn, publication_year, title)VALUES('Carolyn Segal', '989-28-79-05670-4', 2010, 'Can I Be Honest?');INSERT INTO public.books(author, isbn, publication_year, title)VALUES('Charles Fenimore', '989-28-79-82749-6', 2011, 'No More Lightning');INSERT INTO public.books(author, isbn, publication_year, title)VALUES('Clifford Wolitzer', '989-28-3705-987-7', 2012, '9803 North Millworks Road');

首次启动容器时,默认会执行docker-entrypoint-initdb.d目录下的.sh、.sql和.sql.gz的脚本;如果有多个按文件名的按字母顺序执行。我们可以将数据库初始化脚本文件/db/init.sql挂载到数据库容器的/docker-entrypoint-initdb.d/目录下:

volumes:         # Create database and populate initial data    - ./db/init.sql:/docker-entrypoint-initdb.d/init.sql

使用如下代码监控数据库容器的健康状况:

healthcheck:	test: ["CMD-SHELL", "pg_isready -d book_database -U taylor"]	interval: 5s	timeout: 5s	retries: 5

数据库配置包括密码保存在.env环境变量文件里,下面代码来定义使用的环境变量文件:

env_file: 	- .env

完整创建数据库image代码如下:

version: '3.8'services:  database:    container_name: db    image: postgres:15.2    restart: always    healthcheck:      test: ["CMD-SHELL", "pg_isready -d book_database -U taylor"]      interval: 5s      timeout: 5s      retries: 5    ports:      - '15432:5432'    env_file:       - .env    environment:      - POSTGRES_DB=book_database    volumes:      - db-data:/var/lib/postgresql/data      # Create database and populate initial data      - ./db/init.sql:/docker-entrypoint-initdb.d/init.sqlvolumes:  db-data:    driver: local
定义后端应用容器创建

创建后端容器里使用的image我们直接从代码编译生成,使用build字段来实现,如下代码所示:

build: /rest-api/

它会使用/rest-api/Dockerfile来编译生成image。

同时后端应用依赖于数据库容器,需要数据库容器先于后端应用容器启动成功,这主要使用depends_on字段实现:

depends_on:		database:		condition: service_healthy

它将使用数据库容器中的healthcheck命令来检查容器健康状况。

后端需要传入数据库连接信息,这里使用${variable name}来获取环境变量文件里的配置信息并替换。

创建后端容器代码如下:

backend:    container_name: rest-api    build: /rest-api/    restart: always    depends_on:      database:        condition: service_healthy    ports:      - '8080:8080'    env_file:       - .env    environment:      - spring.profiles.active=docker      - spring.datasource.url=jdbc:postgresql://db:5432/book_database      - spring.datasource.username=${POSTGRES_USER}      - spring.datasource.password=${POSTGRES_PASSWORD}
定义前端应用容器创建

同样前端容器image也是直接从代码编译生成,使用build字段如下代码所示:

build: /WebFront/

它会使用/WebFront/Dockerfile来编译生成image,同时它依赖于后端容器创建。

frontend:    container_name: angular-web-client    build: /WebFront/    ports:      - '8081:80'    depends_on:      - backend
构建前端和后端分发包

前端和后端容器创建需要提前构建前端和后端分发包。

构建后端应用

进入代码根目录,使用以下命令构建后端应用:

cd rest-apimvn clean package

查看target目录下是否生成了jar文件来验证构建成功。

构建Angular前端应用

进入代码根目录,使用以下命令构建前端应用:

cd WebFrontnpm installng build -c development

查看是否dist\web-front目录下是否已生成分发包。

使用docker compose创建和启动容器

要使用Docker Compose创建和启动容器,首先我们需要在当前机器上安装Docker Desktop。安装完毕后,我们启动Docker Desktop:

在代码根目录下,运行docker compose up命令:

可以看到数据库初始化脚本执行成功,数据库容器启动成功:

后端REST API应用也启动成功:

打开Docker Desktop容器窗口,可以看到三个容器启动成功:

数据库数据存储的卷也创建成功如下:

在浏览器中输入前端应用地址:,从后端获取数据和显示成功如下:

谢谢观看!

标签: #dockercompose部署springboot