前言:
现在朋友们对“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容器窗口,可以看到三个容器启动成功:
数据库数据存储的卷也创建成功如下:
在浏览器中输入前端应用地址:,从后端获取数据和显示成功如下:
谢谢观看!