咸鱼

咸鱼是以盐腌渍后,晒干的鱼

0%

Docker部署&编排自己的Java Web服务

在Docker中构建包含Java应用程序的镜像有两种方法:

1. 使用Dockerfile构建镜像

可以编写一个Dockerfile,在其中定义构建镜像的所有步骤,比如安装JDK,复制Jar包,设置启动命令等。然后使用docker build命令构建镜像。

优点是可以自定义每个构建步骤,灵活控制镜像的内容。

2. 在docker-compose中构建镜像

可以在docker-compose.yml的services下面直接定义build参数,在这里构建镜像。

优点是归集了应用程序的镜像构建和运行设置在一个文件,方便管理。

3. 如何选择???

对于哪种方式更好,需要根据具体情况决定:

  • 如果需要自动化定制镜像构建,则Dockerfile更灵活
  • 如果仅仅是简单构建jar文件的镜像,则docker-compose更方便

另外,也可以结合两者,在docker-compose中使用Dockerfile构建定制镜像。

一、构建运行Java jar文件的简单Dockerfile

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 基础镜像使用官方的OpenJDK镜像
FROM openjdk:8

# 设置maintainer
MAINTAINER xxx

# 将jar包复制到容器里
COPY /path/to/your-app.jar /opt/app.jar

# 暴露端口
EXPOSE 8080

# 设置容器内的工作目录
WORKDIR /opt

# 定义默认执行命令,启动jar包
ENTRYPOINT ["java", "-jar", "app.jar"]

使用步骤:

  1. 将该Dockerfile和your-app.jar放在同一目录下

  2. 构建镜像:

1
docker build -t your-image-name .
  1. 运行容器:
1
docker run -p 8080:8080 your-image-name

这会一个包含 jar的镜像,并在容器内启动该jar应用。

可以根据需要修改基础镜像,添加更多构建步骤等。这是一个简单的Java应用Docker化的示例,可以作为参考。

二、使用docker-compose构建运行

1
2
3
4
5
6
7
8
9
10
11
version: '3'
services:

app:
image: app
build:
context: .
dockerfile: Dockerfile
ports:
- "8080:8080"
restart: always

这个docker-compose.yml假设在同一目录下存在:

  • Dockerfile,用于构建镜像
  • app.jar,Java应用的jar包

Dockerfile可以类似之前的示例:

1
2
3
FROM openjdk:8
COPY app.jar /opt/app.jar
CMD ["java", "-jar", "/opt/app.jar"]

构建和运行:

1
2
docker-compose build
docker-compose up

这会构建一个名为app的镜像,并启动一个容器运行app.jar。

docker-compose使得通过一个文件就可以定义镜像构建流程和运行参数,方便管理。

可以根据需要调整Dockerfile,添加更多服务等。这是一个简单可运行的docker-compose Java应用示例。

三、Spring Boot应用连接docker-compose中的redis服务:

如果Java应用程序依赖redis服务,可以在docker-compose.yml中定义两个服务:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
version: '3'

services:

myredis:
image: redis:alpine
networks:
- mynet
ports:
- "6379:6379"

app:
build:
context: .
dockerfile: Dockerfile
networks:
- mynet
ports:
- "8080:8080"
depends_on:
- myredis
networks:
mynet:
driver: bridge

这里添加了一个myredis服务,使用官方的redis镜像。

app服务通过depends_on指明它依赖myredis服务。

这样在启动容器时,会先启动myredis容器,然后再启动app容器。

在Spring Boot应用中,通过redis.host属性指定redis服务的主机名:

1
2
spring.redis.host=myredis
spring.redis.port=6379

这样Spring Boot应用就可以通过主机名myredis连接到docker-compose网络中的myredis服务了。

也可以直接使用域名redis访问,如果两个容器在同一个网络中,Docker会处理服务名的解析。

使用Docker网络和服务名,可以方便地在应用程序中引用其他服务,而不需要硬编码IP和端口。

四、挂载宿主机的数据

使用 volumes 在 docker-compose 中将宿主机上的 MongoDB 数据目录映射到 MongoDB 服务容器里:

1
2
3
4
5
6
7
8
version: '3'

services:

mongodb:
image: mongo:4.2
volumes:
- /path/to/host/mongodb:/data/db

上面我将宿主机上的 /path/to/host/mongodb 目录挂载到了容器内的 /data/db目录。

这个 /data/db 是 MongoDB 的默认数据目录。

这样当 MongoDB 服务启动时,就可以访问宿主机上已有的 MongoDB 数据文件了。

每次启动该服务时,都会使用宿主机上该目录下最新的 MongoDB 数据。

需要注意:

  1. 宿主机上的 MongoDB 数据目录必须与容器内的映射目录匹配,权限正确

  2. 如果要用已有的数据启动,需要配置 MongoDB 服务不要重新初始化数据

  3. 可以考虑用 docker volume 而不是直接映射宿主机目录,增强可移植性

这样以来,我们就可以非常方便的使用 docker-compose 来管理 MongoDB 服务,并持久化存储数据了。