java的微服务,用docker-compose构建镜像、运行容器。在此过程中,需要调试。
1. 调试遇到的问题
以下是走过的弯路
- 认为需要容器保持运行,才能“登录”容器查看COPY ADD运行环境等
- 认为sh: can’t open ‘test.sh’: No such file or directory运行容器时错误,是文件COPY 或ADD或WORKDIR命令执行遇到错误
2. 调试Dockerfile
2.1 容器调试无需容器保持运行
docker image ls
看到构造的镜像,docker run -it <image-id> sh
可以登录到容器shell环境,即使没有进程让容器保持运行(通常认为容器需要有一个进程让它保持运行,才能登录)
[root@wonderland-01 project_name]# docker run -it aip/aip-gateway sh
/apprun/module-name/publish # cat /etc/shells 从文件内容看没有bash只有sh
# valid login shells
/bin/sh
/bin/ash
/apprun/module-name/publish # ls .
bash和sh的区别:
https://blog.csdn.net/wht1995316/article/details/115837282
2.2 COPY/ADD的shell脚本文件的bash不存在
Dockerfile运行容器
FROM openjdk:8-alpine
ARG APP
ADD aip-gateway.tar /apprun/${APP}/publish/
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
&& echo 'Asia/Shanghai' >/etc/timezone
WORKDIR /apprun/${APP}/publish
COPY sh/test.sh /apprun/${APP}/publish/test.sh
RUN sed -i "s/ENVIRONMENT=.*/ENVIRONMENT=dev/g" env.properties
CMD /apprun/${APP}/publish/control.sh restart
ARG APP
声明一个变量APP,此后Dockerfile可以用它。需要在docker-compose.yml中定义,也可以用默认值ARG APP aip-platform
甚至ARG APP ""
ADD
和COPY
将host文件加入到容器,区别,如果ADD
的是tar,会自动执行解压;COPY
原封不动复制。其他文件,二者相同WORKDIR
,类似于chdir,相当于从这个命令之后的CMD
或RUN
,都是在这个目录中执行,登录容器后的pwd也是WORKDIR
指定的目录。- docker-compose指定外部网络为bridge(见下面),这样不会创建别名网络,讨论见:https://github.com/docker/compose/issues/3012
CMD
启动容器,由于jar包启动用sh脚本,而这个脚本是bash脚本,而不是sh脚本,所以上述基础镜像不行。
2.3 openjdk的
version: "3"
services:
aip-gateway:
build:
context: ./aip-gateway
dockerfile: Dockerfile
args:
APP: aip-gateway
hostname: aip-gateway
container_name: aip-gateway
image: aip/aip-gateway:${AIP_VERSION}
volumes:
- ./logs/aip-gateway:/data/logs/aiplatform/aip-gateway
- ./app/aip-gateway/publish:/apprun/aip-gateway/publish
ports:
- "9816:9816"
env_file:
- ./env/aip-gateway.env
restart: always
networks:
bridge:
external: true
目录结构
project_name
├── docker-compose.yml
└── module_name
├── Dockerfile
├── xxx.jar
└── xxx.tar
参考nacos的容器Dockerfile
因为openjdk基础镜像不能运行bash脚本(只有sh),而且也不能用yum安装,无奈之下发现nacos的Dockerfile:
FROM centos:7.9.2009
MAINTAINER pader "huangmnlove@163.com"
# set environment
ENV MODE="cluster" \
PREFER_HOST_MODE="ip"\
BASE_DIR="/home/nacos" \
CLASSPATH=".:/home/nacos/conf:$CLASSPATH" \
CLUSTER_CONF="/home/nacos/conf/cluster.conf" \
FUNCTION_MODE="all" \
JAVA_HOME="/usr/lib/jvm/java-1.8.0-openjdk" \
NACOS_USER="nacos" \
JAVA="/usr/lib/jvm/java-1.8.0-openjdk/bin/java" \
JVM_XMS="1g" \
JVM_XMX="1g" \
JVM_XMN="512m" \
JVM_MS="128m" \
JVM_MMS="320m" \
NACOS_DEBUG="n" \
TOMCAT_ACCESSLOG_ENABLED="false" \
TIME_ZONE="Asia/Shanghai"
ARG NACOS_VERSION=2.1.1
ARG HOT_FIX_FLAG=""
WORKDIR $BASE_DIR
RUN set -x \
&& yum update -y \
&& yum install -y java-1.8.0-openjdk java-1.8.0-openjdk-devel wget iputils nc vim libcurl
RUN wget https://github.com/alibaba/nacos/releases/download/${NACOS_VERSION}${HOT_FIX_FLAG}/nacos-server-${NACOS_VERSION}.tar.gz -P /home
RUN tar -xzvf /home/nacos-server-${NACOS_VERSION}.tar.gz -C /home \
&& rm -rf /home/nacos-server-${NACOS_VERSION}.tar.gz /home/nacos/bin/* /home/nacos/conf/*.properties /home/nacos/conf/*.example /home/nacos/conf/nacos-mysql.sql
RUN yum autoremove -y wget \
&& ln -snf /usr/share/zoneinfo/$TIME_ZONE /etc/localtime && echo $TIME_ZONE > /etc/timezone \
&& yum clean all
ADD bin/docker-startup.sh bin/docker-startup.sh
ADD conf/application.properties conf/application.properties
# set startup log dir
RUN mkdir -p logs \
&& cd logs \
&& touch start.out \
&& ln -sf /dev/stdout start.out \
&& ln -sf /dev/stderr start.out
RUN chmod +x bin/docker-startup.sh
EXPOSE 8848
ENTRYPOINT ["bin/docker-startup.sh"]
从centos:7.9.2009基础镜像开始,于是有了如下的Dockerfile:
FROM centos:7.9.2009
MAINTAINER ai "ai@b.com"
ENV BASE_DIR="/home" \
JAVA_HOME="/usr/lib/jvm/java-1.8.0-openjdk" \
JAVA="/usr/lib/jvm/java-1.8.0-openjdk/bin/java" \
TIME_ZONE="Asia/Shanghai" \
PORT=8080
ADD aip-gateway.tar $BASE_DIR
RUN set -x \
&& yum update -y \
&& yum install -y java-1.8.0-openjdk java-1.8.0-openjdk-devel wget iputils nc vim libcurl
RUN ln -sf /usr/share/zoneinfo/$TIME_ZONE /etc/localtime \
&& echo $TIME_ZONE >/etc/timezone
WORKDIR $BASE_DIR
COPY sh/test.sh .
RUN sed -i "s/ENVIRONMENT=.*/ENVIRONMENT=dev/g" env.properties
RUN sed -i "s/START_CMD=.*/START_CMD=\"java \$ARGS -jar \$EXEC_DIR\/\$JAR \$OPTIONS > \/dev\/null 2>\&1\"/g" env.properties
EXPOSE $PORT
CMD ./control.sh restart