使用Docker构建Apollo

Apollo 编译打包

Apollo的Github网址,编译打包构建 可参考分布式部署指南

由于只有一台服务器,采用docker构造伪分布式的方式搭建,脚本链接可见

Dockerfile 构建文件

FROM maven:alpine
MAINTAINER Swire Chen <idoop@msn.cn>

ENV VERSION=1.1.1 \
    PORTAL_PORT=8070 \
    DEV_ADMIN_PORT=8090 \
    FAT_ADMIN_PORT=8091 \
    UAT_ADMIN_PORT=8092 \
    PRO_ADMIN_PORT=8093 \
    DEV_CONFIG_PORT=8080 \
    FAT_CONFIG_PORT=8081 \
    UAT_CONFIG_PORT=8082 \
    PRO_CONFIG_PORT=8083

ARG APOLLO_URL=https://github.com/ctripcorp/apollo/archive/v${VERSION}.tar.gz

COPY docker-entrypoint /usr/local/bin/docker-entrypoint
COPY healthcheck    /usr/local/bin/healthcheck

RUN wget ${APOLLO_URL} -O apollo.tar.gz && tar -zxf apollo.tar.gz && \
    rm apollo.tar.gz && test -e apollo-${VERSION} && \
    sed -e "s/db_password=/db_password=toor/g"  \
        -e "s/^dev_meta.*/dev_meta=http:\/\/localhost:${CONFIG_DEV_PORT}/" \
        -e "s/^fat_meta.*/fat_meta=http:\/\/localhost:${CONFIG_FAT_PORT}/" \
        -e "s/^uat_meta.*/uat_meta=http:\/\/localhost:${CONFIG_UAT_PORT}/" \
        -e "s/^pro_meta.*/pro_meta=http:\/\/localhost:${CONFIG_PRO_PORT}/" -i apollo-${VERSION}/scripts/build.sh && \
    bash apollo-${VERSION}/scripts/build.sh && rm -rf /root/.m2 && \
    mkdir /apollo-admin/dev /apollo-admin/fat /apollo-admin/uat /apollo-admin/pro /apollo-config/dev /apollo-config/fat /apollo-config/uat /apollo-config/pro /apollo-portal -p && \
    mv apollo-${VERSION}/apollo-portal/target/apollo-portal-${VERSION}-github.zip  \
       apollo-${VERSION}/apollo-adminservice/target/apollo-adminservice-${VERSION}-github.zip \
       apollo-${VERSION}/apollo-configservice/target/apollo-configservice-${VERSION}-github.zip / && \
    rm -rf apollo-${VERSION} && \
    chmod +x /usr/local/bin/docker-entrypoint /usr/local/bin/healthcheck

HEALTHCHECK --interval=5m --timeout=3s CMD bash /usr/local/bin/healthcheck

EXPOSE 8070 8080 8081 8082 8083 8090 8091 8092 8093

ENTRYPOINT ["docker-entrypoint"]
  • 通过sed替换脚本apollo-${VERSION}/scripts/build.sh中的dev_meta等4个环境的元数据链接

  • 通过打包脚本apollo-${VERSION}/scripts/build.sh编译构建

  • 分别创建apollo-portal,apollo-adminservice,apollo-configservice下面的dev,fat,uat,pro目录

  • 将apollo-portal,apollo-adminservice,apollo-configservice的zip包拷贝到根目录/下面

docker-entrypoint 入口脚本

docker-entrypoint 为各环境的apollo启动的脚本,内容如下

#!/bin/bash
set -e
set -x

function startENV()
{
    targetENV=${1}
    targetDb=${2}
    targetDbUser=${3}
    targetDbPwd=${4}
    targetAdminPort=${5}
    targetConfigPort=${6}
    targetEnvAddr=${7}

  #容器重启后无需再重复解压配置
  if [[ ! -d "/apollo-config/${targetENV}/scripts" ]];then
    unzip /apollo-configservice-${VERSION}-github.zip -d /apollo-config/${targetENV}
    #DB
    sed -i -e "/^SERVER_PORT=.*$/a\export JAVA_OPTS=\"\$JAVA_OPTS -Dspring.datasource.url=${targetDb} \"" /apollo-config/${targetENV}/scripts/startup.sh
    sed -i -e "/^SERVER_PORT=.*$/a\export JAVA_OPTS=\"\$JAVA_OPTS -Dspring.datasource.username=${targetDbUser} \"" /apollo-config/${targetENV}/scripts/startup.sh
    sed -i -e "/^SERVER_PORT=.*$/a\export JAVA_OPTS=\"\$JAVA_OPTS -Dspring.datasource.password=${targetDbPwd} \"" /apollo-config/${targetENV}/scripts/startup.sh
    #Server Port
    if [[ -n "${targetConfigPort}" ]];then
      sed -i -e "s/^SERVER_PORT=.*$/SERVER_PORT=${targetConfigPort}/" /apollo-config/${targetENV}/scripts/startup.sh
        if [[ -n "${PORTAL_DB}" ]];then
          sed -i -r "/-D${targetENV}_meta=.*$/d" /apollo-portal/scripts/startup.sh
          sed -i -e "/^SERVER_PORT=.*$/a\export JAVA_OPTS=\"\$JAVA_OPTS -D${targetENV}_meta=http://localhost:${targetConfigPort}/\"" /apollo-portal/scripts/startup.sh
        fi
    fi
    #Server Distribute
    if [[ -n "${targetEnvAddr}" ]];then
      sed -i -e "/^SERVER_PORT=.*$/a\export JAVA_OPTS=\"\$JAVA_OPTS -Deureka.instance.ip-address=${targetEnvAddr} \"" /apollo-config/${targetENV}/scripts/startup.sh
    fi
  fi
  /apollo-config/${targetENV}/scripts/startup.sh

  if [[ "${ONLY_CONFIG}" != [tT][rR][uU][eE] ]];then
    if [[ ! -d "/apollo-admin/${targetENV}/scripts" ]];then
      unzip /apollo-adminservice-${VERSION}-github.zip -d /apollo-admin/${targetENV}

      #DB
      sed -i -e "/^SERVER_PORT=.*$/a\export JAVA_OPTS=\"\$JAVA_OPTS -Dspring.datasource.url=${targetDb} \"" /apollo-admin/${targetENV}/scripts/startup.sh
      sed -i -e "/^SERVER_PORT=.*$/a\export JAVA_OPTS=\"\$JAVA_OPTS -Dspring.datasource.username=${targetDbUser} \"" /apollo-admin/${targetENV}/scripts/startup.sh
      sed -i -e "/^SERVER_PORT=.*$/a\export JAVA_OPTS=\"\$JAVA_OPTS -Dspring.datasource.password=${targetDbPwd} \"" /apollo-admin/${targetENV}/scripts/startup.sh
      #Server Port
      if [[ -n "${targetAdminPort}" ]];then
        sed -i -e "s/^SERVER_PORT=.*$/SERVER_PORT=${targetAdminPort}/" /apollo-admin/${targetENV}/scripts/startup.sh
      fi
      #Server Distribute
      if [[ -n "${targetEnvAddr}" ]];then
        sed -i -e "/^SERVER_PORT=.*$/a\export JAVA_OPTS=\"\$JAVA_OPTS -Deureka.instance.ip-address=${targetEnvAddr} \"" /apollo-admin/${targetENV}/scripts/startup.sh
      fi
    fi
    /apollo-admin/${targetENV}/scripts/startup.sh
  fi
}

function startPortal()
{
  if [[ ! -d "/apollo-portal/scripts" ]];then
    unzip /apollo-portal-${VERSION}-github.zip -d /apollo-portal
    sed -i -e "/^SERVER_PORT=.*$/a\export JAVA_OPTS=\"\$JAVA_OPTS -Dspring.datasource.url=${PORTAL_DB} \"" /apollo-portal/scripts/startup.sh
    if [[ -n "${PORTAL_DB_USER}" ]];then
      sed -i -e "/^SERVER_PORT=.*$/a\export JAVA_OPTS=\"\$JAVA_OPTS -Dspring.datasource.username=${PORTAL_DB_USER} \"" /apollo-portal/scripts/startup.sh
    fi
    if [[ -n "${PORTAL_DB_PWD}" ]];then
      sed -i -e "/^SERVER_PORT=.*$/a\export JAVA_OPTS=\"\$JAVA_OPTS -Dspring.datasource.password=${PORTAL_DB_PWD} \"" /apollo-portal/scripts/startup.sh
    fi
    if [[ -n "${PORTAL_PORT}" ]];then
      sed -i -e "s/^SERVER_PORT=.*$/SERVER_PORT=${PORTAL_PORT}/" /apollo-portal/scripts/startup.sh
    fi

    if [[ -n "${DEV_URL}" ]];then
        sed -i -r "/-Ddev_meta=.*$/d" /apollo-portal/scripts/startup.sh
        sed -i -e "/^SERVER_PORT=.*$/a\export JAVA_OPTS=\"\$JAVA_OPTS -Ddev_meta=${DEV_URL}/\"" /apollo-portal/scripts/startup.sh
    fi
    if [[ -n "${FAT_URL}" ]];then
        sed -i -r "/-Dfat_meta=.*$/d" /apollo-portal/scripts/startup.sh
        sed -i -e "/^SERVER_PORT=.*$/a\export JAVA_OPTS=\"\$JAVA_OPTS -Dfat_meta=${FAT_URL}/\"" /apollo-portal/scripts/startup.sh
    fi
    if [[ -n "${UAT_URL}" ]];then
        sed -i -r "/-Duat_meta=.*$/d" /apollo-portal/scripts/startup.sh
        sed -i -e "/^SERVER_PORT=.*$/a\export JAVA_OPTS=\"\$JAVA_OPTS -Duat_meta=${UAT_URL}/\"" /apollo-portal/scripts/startup.sh
    fi
    if [[ -n "${PRO_URL}" ]];then
        sed -i -r "/-Dpro_meta=.*$/d" /apollo-portal/scripts/startup.sh
        sed -i -e "/^SERVER_PORT=.*$/a\export JAVA_OPTS=\"\$JAVA_OPTS -Dpro_meta=${PRO_URL}/\"" /apollo-portal/scripts/startup.sh
    fi
  fi
}


if [ "$#" == "0" ];then
# portal
    if [[ -n "${PORTAL_DB}" ]];then
        startPortal
    fi

# dev
      if [[ -n "${DEV_URL}" ]];then
          echo "conn remote dev server."
      elif [[ -n "${DEV_DB}" ]];then
          startENV dev ${DEV_DB} ${DEV_DB_USER} ${DEV_DB_PWD} ${DEV_ADMIN_PORT} ${DEV_CONFIG_PORT} ${DEV_LB}
      fi

# fat
      if [[ -n "${FAT_URL}" ]];then
          echo "conn remote fat server."
      elif [[ -n "${FAT_DB}" ]];then
          startENV fat ${FAT_DB} ${FAT_DB_USER} ${FAT_DB_PWD} ${FAT_ADMIN_PORT} ${FAT_CONFIG_PORT} ${FAT_LB}
      fi

# uat
      if [[ -n "${UAT_URL}" ]];then
          echo "conn remote fat server."
      elif [[ -n "${UAT_DB}" ]];then
          startENV uat ${UAT_DB} ${UAT_DB_USER} ${UAT_DB_PWD} ${UAT_ADMIN_PORT} ${UAT_CONFIG_PORT} ${UAT_LB}
      fi

# pro
      if [[ -n "${PRO_URL}" ]];then
          echo "conn remote pro server."
      elif [[ -n "${PRO_DB}" ]];then
          startENV pro ${PRO_DB} ${PRO_DB_USER} ${PRO_DB_PWD} ${PRO_ADMIN_PORT} ${PRO_CONFIG_PORT} ${PRO_LB}

      fi
# portal若是早于config服务启动,则有概率会不更新状态,显示一直找不到config
      if [[ -n "${PORTAL_DB}" ]];then
          /apollo-portal/scripts/startup.sh
      fi

# healthcheck
    loop=1
    while [ ${loop} -eq 1 ]
    do
        /usr/local/bin/healthcheck || exit 1
        sleep 300
    done

else
    exec "$@"
fi

主要作用是动态替换dev,fat,uat,pro环境的数据库配置信息,以及eureka的配置信息。

docker-compose 配置文件

version: '2'
services:
  apollo:
    image: apollo:latest
    container_name: apollo
    volumes:
      - /tmp/logs:/opt/logs
    ports:
      - 8081:8081
      - 8091:8091
      - 8070:8070
    environment:
      PORTAL_DB: jdbc:mysql://172.17.0.4:3306/ApolloPortalDB?characterEncoding=utf8
      PORTAL_DB_USER: root
      PORTAL_DB_PWD: pwd

      DEV_DB: jdbc:mysql://172.17.0.4:3306/ApolloConfigDB?characterEncoding=utf8
      DEV_DB_USER: root
      DEV_DB_PWD: pwd
      DEV_CONFIG_PORT: 8081
      DEV_ADMIN_PORT: 8091
      DEV_IP: 118.25.48.129

    extra_hosts:
      - "dev.meta:118.25.48.129"
      - "apollo.meta:118.25.48.129"
  • 配置 日志挂载到主机/tmp/logs 目录下

  • 端口 8081,8091,8070的映射

  • 不配置 network_mode,使用默认的 bridge 桥接模式

  • 启动Apollo的portal和dev环境,尤其要注意DEV_IP: 118.25.48.129,配置eureka.instance.ip-address

  • extra_hosts的docker中域名映射,会增加到/etc/hosts文件中,可不设置

Apollo 运行

使用 docker-compose 命令

# 启动 apollo
docker-compose up -d
# 关闭 apollo
docker-compose down

Apollo 配置页面

查看eureka中的apollo-configservice、apollo-adminservice服务注册

apollo的运行页面

文章目录
  1. Apollo 编译打包
  2. Dockerfile 构建文件
  3. docker-entrypoint 入口脚本
  4. docker-compose 配置文件
  5. Apollo 运行
  6. Apollo 配置页面