docker——发布一个应用程序

来源:互联网 发布:form表单提交到数据库 编辑:程序博客网 时间:2024/06/05 13:26

docker——发布一个java应用程序

一、安装docker

使用docker之前,需要在物理机上安装docker。安装过程可参考docker官网,安装完成之后,运行docker。不同的操作系统,docker的安装和启动不同。

二、待发布的java程序说明

需要发布的java服务目录结构如下:

docker-test/    |-bin/    |  |-server.sh    |-etc/    |  |-config.edn    |  |-logback.xml    |-target/    |  |-docker-test.jar    |  |-docker-test-standalone.jar    |-Dockerfile

Dockerfile

Dockerfile用来定义一个docker容器(container)的运行环境。

# 指定基础镜像openjdk8,用于运行java程序。FROM openjdk:8# 指定容器内的工作目录WORKDIR /app/# 将Dockerfile所在目录(docker-test)的bin目录复制到容器内(/app/bin/)COPY bin bin# 将docker-test目录下的etc目录复制到容器内(/app/etc/)COPY etc etc# 将target下以standalone.jar结尾的jar包复制到容器内的lib目录下(/app/lib/docker-test-standalone.jar).COPY target/*standalone.jar lib/# 将docker容器内的lib目录下的jar包名字写入到lib.txt(/app/lib.txt)RUN ls lib/ > lib.txt# 在docker容器内新建logs目录(/app/logs/)RUN mkdir logs# 将物理机时间时区挂在到容器中,这样容器时间与物理机系统时间一致RUN ln -snf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

server.sh

server.sh为java服务启动脚本,内容如下:

#!/bin/bash## java服务启动日志记录文件在容器内的路径LOGFILE=/app/logs/start.log## 进入容器内的bin目录cd /app/bin## 从/app/lib.txt文件中读取要运行的jar文件。JAR=$(cat ../lib.txt)## 运行程序java ${JAVA_OPTS} -cp ../etc:../lib/${JAR} clojure.main -e "(use 'pay.system)(-main)" >> ${LOGFILE} 2>&1

注意这些目录都是针对docker容器内的目录。

config.edn

java程序运行时所需要的配置文件:

{ ;; 提供给网页通信的web服务 :outer-server       {:host "0.0.0.0" :port 8035 :join? false} ;; 提供给内部服务,用于接收其他服务器消息的web服务地址 :inner-server       {:host "0.0.0.0" :port 8042 :join? false} }

0.0.0.0表示该docker容器接收访问端口8035和端口8042的所有ip。

logback.xml

logback日志配置:

<?xml version="1.0" encoding="UTF-8"?><configuration>    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">        <encoder>            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %-10contextName %logger{36} - %msg%n</pattern>        </encoder>    </appender>    <!-- 按照每天生成日志文件 -->    <appender name="LOG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">        <!-- 拦截debug级别的日志-->        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">            <level>debug</level>        </filter>        <file>/app/logs/docker-test.log</file>        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">            <fileNamePattern>/app/logs/docker-test.log.%d{yyyy-MM-dd}</fileNamePattern>            <!-- 日志文件保留天数-->            <maxHistory>180</maxHistory>        </rollingPolicy>        <!-- 这里使用普通的输出格式-->        <encoder>            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>        </encoder>    </appender>           <!-- 这里是运行日志 -->    <logger name="app" level="info" additivity="false">        <appender-ref ref="LOG_FILE" />    </logger>    <root level="info">        <appender-ref ref="LOG_FILE" />    </root></configuration>

注意,日志文件的路径为docker容器内的路径/app/logs/docker-test.log而不是物理机上的文件路径。

三、打包程序的docker镜像

进入到docker-test目录,执行下面命令:

docker build -t docker-test:0.1.0

很多时候,我们会迭代发布好多镜像,就需要为这些镜像打上tag(经常用版本号作为tag),此时要带上-t参数。如果不带tag,则会默认使用latest作为TAG。

这样打包后的镜像被放在本地,可以使用下面命令查看本地镜像:

docker images -a

可以使用命令删除一个本地镜像:

docker rmi docker-test:0.1.0

四、运行docker容器

docker run -itd –name docker-test -e JAVA_OPTS=’-Xmx368m -Dfile.encoding=UTF-8 -Duser.timezone=GMT+08’ -p 8035:8035 -p 8042:8042 -v
/Users/admin/docker-test/logs:/app/logs -v /Users/admin/docker-test/etc:/app/etc
docker-test:0.1.0 /app/bin/server.sh

-d:表示在后台运行该docker容器
-i:表示保留STDIN(标准输入),用于控制台交互 。
-t:分配tty设备,该可以支持终端登录 。
-p:指定端口或ip映射,将物理机上的8035端口与docker容器的8035端口映射;将物理机上的8042端口与docker容器的8042端口映射。
-v:给容器挂载存储卷,挂载到容器的某个目录。这里讲物理机上的/Users/admin/docker-test/logs目录挂载到docker容器的/app/logs目录,这样程序输出的在logback.xml中指定的日志,实际上被写入到物理机/Users/admin/docker-test/logs目录下对应的日志文件中。
-e:用于指定环境变量,比如例子中就设定了jvm运行时的参数(JAVA_OPTS),在启动java程序时用到。注意-Duser.timezone=GMT+08用于解决jvm时区与系统时区不一致,导致日志文件中输出的时间为标准时区的时间,而不是本地时间。

目录挂载的目的

  • 挂载日志目录:因为程序运行的日志文件会非常之大,如果不将物理机的目录挂在容器内,那么日志将存储在容器内,而且是存储在内存中,永不了多久,内存就会爆掉。
  • 挂载配置文件目录:挂载配置文件,使得可以在物理机上修改配置文件,然后重新运行容器,达到改变配置的目的。

docker-test:0.1.0 /app/bin/server.sh:运行docker-test:0.1.0镜像的/app/bin/server.sh脚本。

至此,一个容器便启动成功。可以尝试访问物理机地址的8035或8042端口,验证是否程序是否正常运行。

但这样运行的话,容器其实是阻塞在运行脚本/app/bin/server.sh的状态(因为在脚本中,并没有指定程序在后台运行),此时我们不能通过docker的attch命令进入到容器。

可以通过如下命令运行docker容器:

docker run -itd –name docker-test -e JAVA_OPTS=’-Xmx368m -Dfile.encoding=UTF-8 -Duser.timezone=GMT+08’ -p 8035:8035 -p 8042:8042 -v
/Users/admin/docker-test/logs:/app/logs -v /Users/admin/docker-test/etc:/app/etc
docker-test:0.1.0 /bin/bash

这样容器内会启动/bin/bash终端,通过命令:

docker ps -a

可以找到容器ID(containerID),通过命令:

docker attach containerID

可以进入到该容器,此时界面和普通的unix命令行界面一样。在容器内的命令行界面中,输入命令:

./bin/server.sh

即可启动java程序。

可以使用如下命令查看镜像的容器是否启动成功(在STATUS中如果为up..则启动成功,如果为exit…则未启动成功):

docker ps -a

五、其他常用docker命令

停止容器

docker stop containerID

删除容器

docker rm containerID

进入容器

首先通过docker ps -a命令可以查看到正在运行的容器ID(CONTAINER ID)。如果容器内的进程是以后台运行的方式启动的,则可以使用命令:

docker attach containerId

进入容器。

如果容器内的进程不是以后台方式启动的,那么就无法通过attach命令进入,可使用命令:

docker exec -it containerID /bin/bash

进入。

阅读全文
0 0