Springboot项目镜像制作&传递环境变量、设置hostname、动态设置JVM参数、cmd&entrypoint区别&docker-entrypoint.sh 用法

实现制作一个springboot 的镜像,并且可以传递环境变量实现动态JVM参数和端口。

0. 准备 & cmd、entrypoint 区别

1. 准备

  1. springboot 项目

一个简单的springboot 项目,默认启动8001 端口,里面只有一个接口。

xxx % curl localhost:8081
index
  1. docker 环境

2. CMD、entrypoint 区别

在Docker中,CMD和ENTRYPOINT都是Dockerfile中用于指定容器启动时运行的命令,但它们之间有重要的区别:
CMD:
用途:CMD是可选的,它提供了一个默认的命令或参数集,可以被docker run命令中的参数覆盖。
执行方式:CMD可以以两种形式存在:
Shell形式:CMD command param1 param2 ...(内部使用/bin/sh -c 运行)
Exec形式:CMD ["executable", "param1", "param2"](不依赖shell,直接执行)
覆盖性:当使用docker run命令时,如果提供了命令,CMD的内容会被替换。

ENTRYPOINT:
用途:ENTRYPOINT是强制性的,它定义了一个容器启动时的入口点,类似于一个固定前缀,不会被docker run命令中的参数覆盖,而是将这些参数附加到ENTRYPOINT后面。
执行方式:ENTRYPOINT也支持两种形式,但通常推荐使用Exec形式,因为它更稳定且不依赖于shell。
Shell形式:ENTRYPOINT command param1 param2 ...(内部使用/bin/sh -c 运行)
Exec形式:ENTRYPOINT ["executable", "param1", "param2"]
组合性:即使docker run提供了命令,这些命令也会作为参数传递给ENTRYPOINT,而不是替换它。

举例来说,如果你有一个Dockerfile,其中设置了ENTRYPOINT ["java", "-jar", "app.jar"],然后运行docker run myimage arg1 arg2,容器将会启动并执行java -jar app.jar arg1 arg2。而如果只有CMD,docker run命令中的参数会替换CMD,不再是默认命令。
总结来说,ENTRYPOINT更像是容器的固定启动脚本,而CMD提供了默认参数,这两者结合使用可以创建出灵活且可配置的容器启动行为。

如果同一个Dockerfile 写了多个CMD或者ENTRYPOINT, 只有最后一个生效。

1. 第一版本: 构建基础能跑的

1. 编写dockerfile

# 使用官方的Java 8运行时作为基础镜像
FROM openjdk:8-jdk-alpine

# 维护者信息
LABEL maintainer="qlq@163.com"

# 设置工作目录
WORKDIR /app

# 将本地的JAR文件复制到容器中的工作目录
COPY app.jar /app/app.jar

# 暴露应用的端口,假设应用默认监听8081端口
EXPOSE 8081

# 使用exec形式的ENTRYPOINT以获得更好的信号处理能力
ENTRYPOINT ["/usr/bin/java", "-jar", "/app/app.jar"]

# 或者直接使用CMD,根据个人偏好和需求选择
# CMD ["java", "-jar", "app.jar"]

2. 构建和运行

xxx % docker build -t qlq_app:latest .
...

xxx % docker run -d -p 8081:8081 qlq_app
9c31ed3c0b3777a6fea2c855d1b8654e5dc949bc957f990d27a315b00384db32

2. 第二版本:增加一个sh 脚本验证cmd、entrypoint 区别

1. 操作-cmd

  1. 准备docker-entrypoint.sh, 内容如下:
#!/bin/bash

# 定义日志文件路径
LOG_FILE="/app/app.log"

echo 'start~~~' >> "$LOG_FILE"

# 使用追加模式(>>)将所有参数输出到日志文件
echo "Parameters passed to the script: $*" >> "$LOG_FILE"
echo "Each parameter on a new line:" >> "$LOG_FILE"
for arg in "$@"; do
    echo "$arg" >> "$LOG_FILE"
done

echo 'end~~~' >> "$LOG_FILE"

/usr/bin/java -jar /app/app.jar
  1. 编写Dockerfile
# 使用官方的Java 8运行时作为基础镜像
FROM openjdk:8-jdk-alpine

# 维护者信息
LABEL maintainer="qlq@163.com"

# 设置工作目录
WORKDIR /app

# 将本地的文件复制到容器中的工作目录
COPY app.jar /app/app.jar
COPY docker-entrypoint.sh /app/docker-entrypoint.sh

RUN chmod +x /app/docker-entrypoint.sh

# 改用root启动
USER root

# 使用exec形式的ENTRYPOINT以获得更好的信号处理能力
# ENTRYPOINT ["/bin/sh", "/app/docker-entrypoint.sh"]

# 或者直接使用CMD,根据个人偏好和需求选择
CMD ["/bin/sh", "/app/docker-entrypoint.sh"]
  1. 构建后执行-正常执行启动
# 构建
docker build -t app_cmd:latest .

# 启动
docker run -d -p 8081:8081 app_cmd
05f08bf21e7df4852b8e4bb146503280ec1f7fbbe1a3bf051883b0bd084ab022

# 测试
xxx % docker ps
CONTAINER ID   IMAGE                    COMMAND                   CREATED         STATUS         PORTS                                                      NAMES
05f08bf21e7d   app_cmd                  "/bin/sh /app/docker…"   4 seconds ago   Up 3 seconds   0.0.0.0:8081->8081/tcp                                     pedantic_merkle
17d8e50240b9   portainer/portainer-ce   "/portainer"              6 weeks ago     Up 4 hours     0.0.0.0:8000->8000/tcp, 0.0.0.0:9000->9000/tcp, 9443/tcp   portainer
xxx % curl localhost:8081
index%
# 进入容器查看日志
/app # cat app.log
start~~~
Parameters passed to the script:
Each parameter on a new line:
end~~~
  1. 尝试启动传递其他命令
# 启动传递其他命令
xxx % docker run -d -p 8081:8081 app_cmd sh -c "cat /app/app.log"
bff4d7c8144db99664fb46f4c04fe1d2b8e448e8d1675dbdae77ebac61459f44
# 查看容器日志
xxx % docker logs bff4d7c8144db99664fb46f4c04fe1d2b8e448e8d1675dbdae77ebac61459f44
cat: can't open '/app/app.log': No such file or directory
# 查看容器,可以看到。 命令被覆盖, 也就是Dockerfile CMD 指定的命令没有执行,被自己的sh -c "cat /app/app.log" 覆盖
xxx % docker ps -a
CONTAINER ID   IMAGE                         COMMAND                   CREATED          STATUS                      PORTS                                                      NAMES
bff4d7c8144d   app_cmd                       "sh -c 'cat /app/app…"   11 seconds ago   Exited (1) 10 seconds ago                                                              interesting_agnesi

2. 操作-entrypoint

  1. 操作都相同,只是Dockerfile 启动缓存entrypoint
# 使用官方的Java 8运行时作为基础镜像
FROM openjdk:8-jdk-alpine

# 维护者信息
LABEL maintainer="qlq@163.com"

# 设置工作目录
WORKDIR /app

# 将本地的文件复制到容器中的工作目录
COPY app.jar /app/app.jar
COPY docker-entrypoint.sh /app/docker-entrypoint.sh

RUN chmod +x /app/docker-entrypoint.sh

# 改用root启动
USER root

# 使用exec形式的ENTRYPOINT以获得更好的信号处理能力
ENTRYPOINT ["/bin/sh", "/app/docker-entrypoint.sh"]
  1. 正常启动-没问题
  2. 尝试启动传递其他命令
# 启动
xxx % docker run -d -p 8081:8081 app_entry sh -c "cat /app/app.log"
d644cb6be72757959296d97b56588d14c3aa6206f6eb2bfced2c2ff683fc4818
# 查看容器状态
xxx % docker ps
CONTAINER ID   IMAGE                    COMMAND                   CREATED         STATUS         PORTS                                                      NAMES
d644cb6be727   app_entry                "/bin/sh /app/docker…"   3 seconds ago   Up 2 seconds   0.0.0.0:8081->8081/tcp                                     gracious_proskuriakova
# 进容器查看日志
/app # cat app.log
start~~~
Parameters passed to the script: sh -c cat /app/app.log
Each parameter on a new line:
sh
-c
cat /app/app.log
end~~~

3. 两者结合

  1. Dockerfile
# 使用官方的Java 8运行时作为基础镜像
FROM openjdk:8-jdk-alpine

# 维护者信息
LABEL maintainer="qlq@163.com"

# 设置工作目录
WORKDIR /app

# 将本地的文件复制到容器中的工作目录
COPY app.jar /app/app.jar
COPY docker-entrypoint.sh /app/docker-entrypoint.sh

RUN chmod +x /app/docker-entrypoint.sh

# 改用root启动
USER root

# 使用exec形式的ENTRYPOINT以获得更好的信号处理能力
ENTRYPOINT ["/bin/sh", "/app/docker-entrypoint.sh"]
CMD ["default", "argument"]
  1. 构建
docker build -t app_entry_cmd:latest .
  1. 正常执行然后查看容器内日志 (可以看到cmd 作为 参数传进去了)
# 执行
docker run -d -p 8081:8081 app_entry_cmd
# 容器内查看日志
/app # cat app.log
start~~~
Parameters passed to the script: default argument
Each parameter on a new line:
default
argument
end~~~
  1. 增加外部参数调用(可以看到覆盖默认的cmd参数)
# 执行
docker run -d -p 8081:8081 app_entry_cmd arg1 arg2 arg3

# 容器内查看日志
/app # cat app.log
start~~~
Parameters passed to the script: arg1 arg2 arg3
Each parameter on a new line:
arg1
arg2
arg3
end~~~

4. docker 查看镜像的cmd 和 entrypoint&docker-entrypoint.sh 用法

docker-entrypoint.sh 一般默认的规约是作为容器的ENTRYPOINT, 是个不成文的约定吧。

1. 查看rabbitMQ 的详情: 可以看到cmd、entrypoint

​ 进容器内部也可以看到 docker-entrypoint.sh 文件。

xxx % docker inspect fb11f4e0a6b6
[
    {
        "Id": "sha256:fb11f4e0a6b6fa0d04d5a997ac9ad91c3950dfe8954e30f541fae35de7a02cc6",
        "RepoTags": [
            "hub.c.163.com/library/rabbitmq:management"
        ],
        "RepoDigests": [
            "hub.c.163.com/library/rabbitmq@sha256:c588cd42513f67a4c54cdb58303c4f56ccea4ddd32c2dbfea6e15c3668d54314"
        ],
        "Parent": "",
        "Comment": "",
        "Created": "2017-08-17T18:49:07.435927944Z",
        "Container": "877e376f642c7f6872818857767cab5b37544c52d4ae30602e28c2109ccabf58",
        "ContainerConfig": {
            "Hostname": "b3b330cec4cc",
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "ExposedPorts": {
                "15671/tcp": {},
                "15672/tcp": {},
                "25672/tcp": {},
                "4369/tcp": {},
                "5671/tcp": {},
                "5672/tcp": {}
            },
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": [
                "PATH=/usr/lib/rabbitmq/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
                "GOSU_VERSION=1.10",
                "RABBITMQ_LOGS=-",
                "RABBITMQ_SASL_LOGS=-",
                "RABBITMQ_VERSION=3.6.11",
                "RABBITMQ_DEBIAN_VERSION=3.6.11-1",
                "HOME=/var/lib/rabbitmq"
            ],
            "Cmd": [
                "/bin/sh",
                "-c",
                "#(nop) ",
                "EXPOSE 15671/tcp 15672/tcp"
            ],
            "ArgsEscaped": true,
            "Image": "sha256:eeb9f873546cd6b77562f875aefbfc56bab3f2f7f8a47f0b06d9b5eb51c37464",
            "Volumes": {
                "/var/lib/rabbitmq": {}
            },
            "WorkingDir": "",
            "Entrypoint": [
                "docker-entrypoint.sh"
            ],
            "OnBuild": [],
            "Labels": {}
        },
        "DockerVersion": "17.03.2-ce",
        "Author": "",
        "Config": {
            "Hostname": "b3b330cec4cc",
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "ExposedPorts": {
                "15671/tcp": {},
                "15672/tcp": {},
                "25672/tcp": {},
                "4369/tcp": {},
                "5671/tcp": {},
                "5672/tcp": {}
            },
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": [
                "PATH=/usr/lib/rabbitmq/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
                "GOSU_VERSION=1.10",
                "RABBITMQ_LOGS=-",
                "RABBITMQ_SASL_LOGS=-",
                "RABBITMQ_VERSION=3.6.11",
                "RABBITMQ_DEBIAN_VERSION=3.6.11-1",
                "HOME=/var/lib/rabbitmq"
            ],
            "Cmd": [
                "rabbitmq-server"
            ],
            "ArgsEscaped": true,
            "Image": "sha256:eeb9f873546cd6b77562f875aefbfc56bab3f2f7f8a47f0b06d9b5eb51c37464",
            "Volumes": {
                "/var/lib/rabbitmq": {}
            },
            "WorkingDir": "",
            "Entrypoint": [
                "docker-entrypoint.sh"
            ],
            "OnBuild": [],
            "Labels": {}
        },
        "Architecture": "amd64",
        "Os": "linux",
        "Size": 123727273,
        "VirtualSize": 123727273,
        "GraphDriver": {
            "Data": {
                "LowerDir": "/var/lib/docker/overlay2/497f3e9e83addeb470091b482e265ef7f5cdbd79e8625a905fedea8c09947a45/diff:/var/lib/docker/overlay2/32e2e530bbf46db672efa4e20716e3e77cc82d090343df0e60795ae641296644/diff:/var/lib/docker/overlay2/c8f06059a4c7f6c27f89d7f213fdd8dc3d072435a269de44094c65344e3ecf57/diff:/var/lib/docker/overlay2/37c80b17edc7f10653ce860b8fb4ff176e14a2a7597d589df4a3e925fbeeb59c/diff:/var/lib/docker/overlay2/b540da80b28ce2e2fc0c90e3d7a55a4176d996c6fa6ff6e7897c07bf618b1c5c/diff:/var/lib/docker/overlay2/172c2cc503f1592b118f3c4ec9d33ce47cd76926195a959be96c81d4f79602c5/diff:/var/lib/docker/overlay2/7cb75cd98f107f2943ec8e2c62779cd5b600ade64d7678343283153990979fb1/diff:/var/lib/docker/overlay2/88b075b0d07ac8db854ca2bddd09efc71c220a601c72b76e6fca53cb86fe5b9e/diff:/var/lib/docker/overlay2/c36eae1bb17acc9c62e71a3482f681b39e3f47f1d9182ccb90a701c9581447b5/diff:/var/lib/docker/overlay2/16a3b893e3ee41b05517ae956352ed7ee5aa51f1c8390b4e351823759e5e4e0f/diff:/var/lib/docker/overlay2/25f314e67ff6db2576eee170998062bcd8ef08b4e7f742ec9067c43ac1c20258/diff:/var/lib/docker/overlay2/8eeac5a5c1f484cec00940cd8c98794ec591c26ad311c990a323726f99112f59/diff:/var/lib/docker/overlay2/153eebc683924191c39646054d95b1ec0b4da937b5c7f4b91da42885cd4b3254/diff",
                "MergedDir": "/var/lib/docker/overlay2/e10ffb7662a639a7ab8f7b97db10d35915ad095243dec160c47e9b30da14bcfc/merged",
                "UpperDir": "/var/lib/docker/overlay2/e10ffb7662a639a7ab8f7b97db10d35915ad095243dec160c47e9b30da14bcfc/diff",
                "WorkDir": "/var/lib/docker/overlay2/e10ffb7662a639a7ab8f7b97db10d35915ad095243dec160c47e9b30da14bcfc/work"
            },
            "Name": "overlay2"
        },
        "RootFS": {
            "Type": "layers",
            "Layers": [
                "sha256:eb78099fbf7fdc70c65f286f4edc6659fcda510b3d1cfe1caa6452cc671427bf",
                "sha256:54941f24e370c04208be9442119185303b696a38c42998648b2bdd16825957c0",
                "sha256:88d342d3fd370a0d3d9c1140b23cb436491cdac62fdc3233cd657c2c9dfdb4d0",
                "sha256:f470bb60dd6ce2f4b2011080d52f0fd5e3ea5fea652fc296d7c5d9b2412cf090",
                "sha256:816c1661a4c6c6ab91f7c839aff27c7a098c12916b77e3e85f55fa57a2e13a83",
                "sha256:e9f373b59af0d96326d93601662bf5a90b43d5943d4229034fce439b5cff4d44",
                "sha256:f4ea331ee3a51c8534a4fdf17412176d98932f515b523d2b92c52508b253e642",
                "sha256:e847abd1a23965b6019c79d46f33203d9a6564545232746491f2634d3fbb5ecb",
                "sha256:284605e8c05898078109f43699038bbb46ead329cbb871792f76c16b683e15dc",
                "sha256:516229927aa61bb9515eddefab90ffaa7483401f39dcd1b8978b08f8e515ca76",
                "sha256:d23ea6f1414e50962032e5d078b13e97bc0b14ff3aec9bcc63d4664af67c933f",
                "sha256:15f319f2f139a1eed09420fae8337633aa7e002d3a6cb5e34188978f66041261",
                "sha256:ea7f2a59b7a0cf567cd5f305ad4b992be40bade9baec9b930ced968c2cea65cf",
                "sha256:adf3a737c13661970c890c53a4492d49f0722b4dc5c8790f897f1808a34bb4a2"
            ]
        },
        "Metadata": {
            "LastTagTime": "0001-01-01T00:00:00Z"
        }
    }
]

2. 查看上面 app_entry_cmd 镜像的cmd、entrypoint

​ 可以看到能和自己Dockerfile 中声明的CMD 和 ENTRYPOINT 对应上。

qiao-zhi@qiao-zhideMacBook-Pro tmp % docker inspect app_entry_cmd
[
    {
        "Id": "sha256:16ca5c639a17db1a0f61498b3fc977ce35035c216ab4fec9b9cc3f1bc118932d",
        "RepoTags": [
            "app_entry_cmd:latest"
        ],
        "RepoDigests": [],
        "Parent": "",
        "Comment": "buildkit.dockerfile.v0",
        "Created": "2024-05-09T15:12:03.496072777Z",
        "Container": "",
        "ContainerConfig": {
            "Hostname": "",
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": null,
            "Cmd": null,
            "Image": "",
            "Volumes": null,
            "WorkingDir": "",
            "Entrypoint": null,
            "OnBuild": null,
            "Labels": null
        },
        "DockerVersion": "",
        "Author": "",
        "Config": {
            "Hostname": "",
            "Domainname": "",
            "User": "root",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/lib/jvm/java-1.8-openjdk/jre/bin:/usr/lib/jvm/java-1.8-openjdk/bin",
                "LANG=C.UTF-8",
                "JAVA_HOME=/usr/lib/jvm/java-1.8-openjdk",
                "JAVA_VERSION=8u212",
                "JAVA_ALPINE_VERSION=8.212.04-r0"
            ],
            "Cmd": [
                "default",
                "argument"
            ],
            "ArgsEscaped": true,
            "Image": "",
            "Volumes": null,
            "WorkingDir": "/app",
            "Entrypoint": [
                "/bin/sh",
                "/app/docker-entrypoint.sh"
            ],
            "OnBuild": null,
            "Labels": {
                "maintainer": "qlq@163.com"
            }
        },
        "Architecture": "amd64",
        "Os": "linux",
        "Size": 121434700,
        "VirtualSize": 121434700,
        "GraphDriver": {
            "Data": {
                "LowerDir": "/var/lib/docker/overlay2/ku69j15l65pocazc2ev2mj29k/diff:/var/lib/docker/overlay2/4trwseu9aepinl1bwihsu8fyh/diff:/var/lib/docker/overlay2/ktu86m63blp9c7rarafvfhu3q/diff:/var/lib/docker/overlay2/41058cb29f4e8971087a5c955e649ff7c3a6d1a5af53153f563679b2545c9270/diff:/var/lib/docker/overlay2/13137b164b8529e7d981b9b882926cd8b4a06c20f7a4373258b7f29dcccf279d/diff:/var/lib/docker/overlay2/d33f9d0e332ca61edb2e025fd6851fab8f8e0ea82ec8f168878d9de64b1fde4c/diff",
                "MergedDir": "/var/lib/docker/overlay2/ow2hvpx0j6khynbvmstw7czgx/merged",
                "UpperDir": "/var/lib/docker/overlay2/ow2hvpx0j6khynbvmstw7czgx/diff",
                "WorkDir": "/var/lib/docker/overlay2/ow2hvpx0j6khynbvmstw7czgx/work"
            },
            "Name": "overlay2"
        },
        "RootFS": {
            "Type": "layers",
            "Layers": [
                "sha256:f1b5933fe4b5f49bbe8258745cf396afe07e625bdab3168e364daf7c956b6b81",
                "sha256:9b9b7f3d56a01e3d9076874990c62e7a516cc4032f784f421574d06b18ef9aa4",
                "sha256:ceaf9e1ebef5f9eaa707a838848a3c13800fcf32d7757be10d4b08fb85f1bc8a",
                "sha256:f160dca9bc02791c6b22203afd735197dce5960385c920ddfa0d9800e16f9d17",
                "sha256:643be441a85d47717541963d68b9a1cfb7a79f4f6ddef5022396452526abf26e",
                "sha256:33b27dcbef4c83860491699ebd42644598ee60422f48475750e3f1de76dc8ea6",
                "sha256:7cabbb46baf13365bba454e7f022421b7186216f79555ef8793396a6a872a7d6"
            ]
        },
        "Metadata": {
            "LastTagTime": "2024-05-09T15:17:28.758064656Z"
        }
    }
]

5. 结论

容器的启动脚本可以用cmd,也可以用entrypoint, 也可以两者结合。

外部命令:(sh -c "cat /app/app.log" 可以理解为自己定义的新命令)

docker run -d -p 8081:8081 app_entry sh -c "cat /app/app.log"

如果是cmd,外部的命令会替换cmd 指定的脚本,也就是cmd 指定的将不会执行;

如果是 entrypoint :外部命令会作为参数传递给自己的entrypoint 命令;

也可以两者结合,两者结合的情况下:cmd 会作为参数传递给entrypoint的程序,如果有外部命令,外部命令会覆盖cmd然后继续传给entrypoint 作为参数。

3. 终版-传递环境变量、设置hostsname,脚本动态调整启动服务参数

1. 设置环境变量启动java 程序

  1. Dockerfile
# 使用官方的Java 8运行时作为基础镜像
FROM openjdk:8-jdk-alpine

# 维护者信息
LABEL maintainer="qlq@163.com"

# 设置工作目录
WORKDIR /app

# 将本地的文件复制到容器中的工作目录
COPY app.jar /app/app.jar
COPY docker-entrypoint.sh /app/docker-entrypoint.sh

RUN chmod +x /app/docker-entrypoint.sh

# 改用root启动
USER root

# 使用exec形式的ENTRYPOINT以获得更好的信号处理能力
ENTRYPOINT ["/bin/sh", "/app/docker-entrypoint.sh"]
  1. docker-entrypoint.sh

读取环境变量,然后设置JVM 参数

#!/bin/bash

# 定义日志文件路径
LOG_FILE="/app/app.log"
echo 'start~~~' >> "$LOG_FILE"

# 1. 处理默认参数
# 使用追加模式(>>)将所有参数输出到日志文件
echo "Parameters passed to the script: $*" >> "$LOG_FILE"
echo "Each parameter on a new line:" >> "$LOG_FILE"
for arg in "$@"; do
    echo "$arg" >> "$LOG_FILE"
done

echo 'end~~~' >> "$LOG_FILE"

# 2. 处理java 相关参数
# 2.1 默认的Java选项
DEFAULT_JAVA_OPTS="-Xms256m -Xmx256g"
# 检查JAVA_OPTS环境变量是否存在
if [ -z "${JAVA_OPTS}" ]; then
    echo "JAVA_OPTS is not set. Using default settings: ${DEFAULT_JAVA_OPTS}" >> "$LOG_FILE"
    JAVA_OPTS="${DEFAULT_JAVA_OPTS}"
else
    echo "JAVA_OPTS is set to: ${JAVA_OPTS}" >> "$LOG_FILE"
fi
# 2.2 默认的端口
DEFAULT_SERVER_PORT='8081'
if [ -z "${SERVER_PORT}" ]; then
    echo "SERVER_PORT is not set. Using default SERVER_PORT: ${DEFAULT_SERVER_PORT}" >> "$LOG_FILE"
    SERVER_PORT="${DEFAULT_SERVER_PORT}"
else
    echo "SERVER_PORT is set to: ${SERVER_PORT}" >> "$LOG_FILE"
fi

# 执行Java应用,使用最终确定的信息
/usr/bin/java -jar ${JAVA_OPTS} -Dserver.port=${SERVER_PORT} /app/app.jar
  1. 打包运行测试
# build
docker build -t app:latest .

# run 默认设置
xxx % docker run -d -p 8081:8081 app
aed44593836eca3e3f5e727bfe5abe8024214d8528311634158fb9a3b458c85d
xxx % docker ps
CONTAINER ID   IMAGE                    COMMAND                   CREATED         STATUS         PORTS                                                      NAMES
aed44593836e   app                      "/bin/sh /app/docker…"   3 seconds ago   Up 2 seconds   0.0.0.0:8081->8081/tcp                                     confident_ardinghelli
xxx % curl localhost:8081
index
# 查看启动日志
/app # cat app.log
start~~~
Parameters passed to the script:
Each parameter on a new line:
end~~~
JAVA_OPTS is not set. Using default settings: -Xms256m -Xmx256g
SERVER_PORT is not set. Using default SERVER_PORT: 8081
/app # ps -ef
PID   USER     TIME  COMMAND
    1 root      0:00 /bin/sh /app/docker-entrypoint.sh
    7 root      0:10 /usr/bin/java -jar -Xms256m -Xmx256g -Dserver.port=8081 /app/app.jar
   52 root      0:00 sh
   69 root      0:00 ps -ef
/app # jps -lv
7 /app/app.jar -Xms256m -Xmx256g -Dserver.port=8081
90 sun.tools.jps.Jps -Dapplication.home=/usr/lib/jvm/java-1.8-openjdk -Xms8m
  1. 自己设置环境变量、主机名称然后启动
# 启动
xxx tmp % docker run -d -p 8082:8082 \
    -e JAVA_OPTS="-Xmx100m -Xms100m" \
    -e SERVER_PORT=8082 \
    --hostname 8082host \
    app
9f2c71511097005bc523db236ce75b7952fac52470afb6d5cce592ebd10a0f2c
xxx tmp % docker ps
CONTAINER ID   IMAGE                    COMMAND                   CREATED         STATUS         PORTS                                                      NAMES
9f2c71511097   app                      "/bin/sh /app/docker…"   3 seconds ago   Up 3 seconds   0.0.0.0:8082->8082/tcp                                     beautiful_kilby
17d8e50240b9   portainer/portainer-ce   "/portainer"              6 weeks ago     Up 5 hours     0.0.0.0:8000->8000/tcp, 0.0.0.0:9000->9000/tcp, 9443/tcp   portainer
xxx tmp % curl localhost:8082
index
# 外部查看容器传递的环境变量
docker inspect 9f2c71511097 

# 容器内部查看信息
xxx tmp % docker exec -it 9f2c71511097 sh
# 启动日志
/app # cat app.log
start~~~
Parameters passed to the script:
Each parameter on a new line:
end~~~
JAVA_OPTS is set to: -Xmx100m -Xms100m
SERVER_PORT is set to: 8082
# java 进程信息
/app # jps -lv
64 sun.tools.jps.Jps -Dapplication.home=/usr/lib/jvm/java-1.8-openjdk -Xms8m
7 /app/app.jar -Xmx100m -Xms100m -Dserver.port=8082
# 环境变量
/app # env
JAVA_ALPINE_VERSION=8.212.04-r0
HOSTNAME=8082host
SHLVL=1
HOME=/root
JAVA_VERSION=8u212
TERM=xterm
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/lib/jvm/java-1.8-openjdk/jre/bin:/usr/lib/jvm/java-1.8-openjdk/bin
JAVA_OPTS=-Xmx100m -Xms100m
LANG=C.UTF-8
JAVA_HOME=/usr/lib/jvm/java-1.8-openjdk
PWD=/app
SERVER_PORT=8082
# 主机名称
/app # hostname
8082host

2. 设置网络,多个容器可以互相访问

1. 创建桥接网络

1. 创建自定义网络: 首先,使用 docker network create 命令创建一个自定义的Docker网络。例如,创建一个名为 my_network 的桥接网络:
# 创建
docker network create my_network

# 查看
xxx tmp % docker network ls
NETWORK ID     NAME         DRIVER    SCOPE
8668a26df163   bridge       bridge    local
1135abf81b7e   host         host      local
d462de8fcc37   my_network   bridge    local
2357d5b05bcd   none         null      local

# 查看详细信息
xxx tmp %  docker network inspect my_network
[
    {
        "Name": "my_network",
        "Id": "d462de8fcc3734136d0ba33231de22123a98091c2d2bc7e10b1cbb938c92fe4a",
        "Created": "2024-05-09T08:30:19.530915045Z",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "172.18.0.0/16",
                    "Gateway": "172.18.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {},
        "Options": {},
        "Labels": {}
    }
]

2. 启动两个容器&测试

  1. 启动
docker run -d -p 8082:8082 \
    -e JAVA_OPTS="-Xmx100m -Xms100m" \
    -e SERVER_PORT=8082 \
    --hostname 8082host \
    --network my_network \
    app
    
docker run -d -p 8083:8083 \
    -e JAVA_OPTS="-Xmx100m -Xms100m" \
    -e SERVER_PORT=8083 \
    --hostname 8083host \
    --network my_network \
    app    
  1. 测试
1. 查看
xxx tmp % docker ps | grep app
4febe1c700fd   app                      "/bin/sh /app/docker…"   13 seconds ago   Up 13 seconds   0.0.0.0:8083->8083/tcp                                     stupefied_hamilton
8667b58f2c43   app                      "/bin/sh /app/docker…"   50 seconds ago   Up 49 seconds   0.0.0.0:8082->8082/tcp                                     frosty_chebyshev
2. 查看容器详细信息
docker inspect 4febe1c700fd
# 输出
...
"Networks": {
                "my_network": {
                    "IPAMConfig": null,
                    "Links": null,
                    "Aliases": [
                        "4febe1c700fd",
                        "8083host"
                    ],
                    "MacAddress": "02:42:ac:12:00:03",
                    "NetworkID": "d462de8fcc3734136d0ba33231de22123a98091c2d2bc7e10b1cbb938c92fe4a",
                    "EndpointID": "b6118332fc47744d6321f07da2d289002fe28cd20c0126827d3d85d96ae96582",
                    "Gateway": "172.18.0.1",
                    "IPAddr
...
3. 容器内部ping
可以用主机名称互相ping 通,证明可以访问到
ping 8082host
ping 8083host
posted @ 2024-05-09 22:51  QiaoZhi  阅读(85)  评论(0编辑  收藏  举报