有个需求, 需要用户在调试时能方便地将文件拷贝到容器里, 需要做个带ftp功能的容器,
参考了: https://github.com/rlesouef/alpine-sftp
整个工程目录结构:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
. ├── build.py ├── config │ ├── config_arm64v8.yml │ ├── config_redis_commander.yml │ ├── config_x86_gpaas_lite.yml │ ├── config_x86_gpaas_pro.yml │ ├── config_x86_online.yml │ └── config.yml ├── dockerfile ├── download │ ├── font │ │ └── ncc │ │ ├── song │ │ │ └── song.zip │ │ └── yahei │ │ └── yahei.zip │ ├── get-pip.py │ ├── go │ │ ├── go1.10.1.linux-amd64.tar.gz │ │ └── go1.10.1.linux-arm64.tar.gz │ ├── java │ │ ├── apache-tomcat-6.0.48.tar.gz │ │ ├── apache-tomcat-7.0.85.tar.gz │ │ ├── apache-tomcat-8.5.28.tar.gz │ │ ├── apache-tomcat-9.0.5.tar.gz │ │ ├── appupload │ │ │ ├── catalina.properties.appupload │ │ │ └── jfxrt.jar │ │ ├── arthas-boot.jar │ │ ├── etc │ │ │ ├── authfile.properties │ │ │ ├── inputrc │ │ │ └── yhtauthfile.properties │ │ ├── fonts.tar.gz │ │ ├── java_options.sh │ │ ├── jdk-6u45-linux-x64.bin │ │ ├── jdk-7-linux-x64.tar.gz │ │ ├── jdk-8-linux-x64.tar.gz │ │ ├── jdk-8u202-linux-x64.tar.gz │ │ ├── jdk-8u231-linux-arm64-vfp-hflt.tar.gz │ │ ├── maven.tar.gz │ │ ├── mount_app_file_log.sh │ │ ├── phantomjs-2.1.1-linux-x86_64.tar.gz │ │ ├── pinpoint-agent.tar.gz │ │ ├── UnlimitedJCEPolicyJDK7 │ │ │ ├── 121 │ │ │ │ ├── local_policy.jar │ │ │ │ └── US_export_policy.jar │ │ │ ├── local_policy.jar │ │ │ └── US_export_policy.jar │ │ ├── UnlimitedJCEPolicyJDK8 │ │ │ ├── 121 │ │ │ │ ├── local_policy.jar │ │ │ │ └── US_export_policy.jar │ │ │ ├── local_policy.jar │ │ │ └── US_export_policy.jar │ │ └── yyy-probes.tar.gz │ ├── nohup.out │ ├── pip.conf │ ├── public_packages │ │ ├── color.awk │ │ ├── confdownload │ │ │ ├── confcenterdownload │ │ │ ├── confcenterdownload_aarch64 │ │ │ └── confcenterdownload-online │ │ ├── dumb-init_1.2.1_amd64 │ │ ├── dumb-init_1.2.2_aarch64 │ │ ├── entrypoint_ncc.sh │ │ ├── entrypoint.sh │ │ ├── fish_greeting.fish │ │ ├── glibc │ │ │ ├── aarch64 │ │ │ │ ├── glibc-2.26-r1.apk │ │ │ │ ├── glibc-bin-2.26-r1.apk │ │ │ │ └── glibc-i18n-2.26-r1.apk │ │ │ └── x86_64 │ │ │ ├── APKINDEX.tar.gz │ │ │ ├── glibc-2.28-r0.apk │ │ │ ├── glibc-bin-2.28-r0.apk │ │ │ ├── glibc-i18n-2.28-r0.apk │ │ │ └── sgerrand.rsa.pub │ │ ├── go1.10.1.linux-arm64.tar.gz │ │ ├── offline_ncc.sh │ │ ├── offline.sh │ │ └── README.md │ ├── python │ │ ├── get-pip.py │ │ └── pip.conf │ ├── sftp │ │ ├── bindmount.sh │ │ ├── sftp-entrypoint.sh │ │ └── sshd_config │ ├── SimpleHTTPServerWithUpload.py │ ├── supervisor │ │ └── supervisord.conf ├── log └── templates ├── alpine.j2 ├── base_alpine.j2 ├── header.j2 ├── java.j2 ├── nginx.j2 ├── nginx-node.j2 ├── node.j2 ├── openresty.j2 ├── php.j2 ├── python_alpine.j2 ├── python_debian.j2 ├── redis-commander.j2 ├── tomcat8-jdk8-alpine-appupload.j2 ├── tomcat8-jdk8-centos.j2 └── tomcat.j2 |
其中download为各文件下载目录
拿tomcat来作例:
配置文件config_x86_online.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 25 26 27 28 29 30 31 32 33 34 35 36 37 |
registry: - host: ycr.example.com repository: test username: admin password: xxxxxx - image: "tomcat:8-jdk8-alpine-sftp" from_image: ycr.example.com/official/alpine/alpine:latest arch: x86_64 template: tomcat-sftp.j2 alpine_repo: mirrors.aliyun.com confcenterdownload: confcenterdownload-online dumb_init: dumb-init_1.2.1_amd64 alpine_glibc_package_version: 2.28-r0 version: tomcat: "8.5.28" jdk: "8u202" - image: "nginx:1.15-alpine" template: nginx.j2 from_image: ycr.example.com/official/nginx/nginx:1.15.8-alpine-perl arch: x86_64 alpine_repo: mirrors.aliyun.com alpine_glibc_package_version: 2.28-r0 dumb_init: dumb-init_1.2.1_amd64 confcenterdownload: confcenterdownload-online - image: "node:14-alpine" template: node.j2 from_image: ycr.example.com/official/node/node:14.2.0-alpine3.11 arch: x86_64 alpine_repo: mirrors.aliyun.com alpine_glibc_package_version: 2.28-r0 dumb_init: dumb-init_1.2.1_amd64 confcenterdownload: confcenterdownload-online version: node: 14.2.0 |
也可以定义arm64架构的config来构建:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
registry: - host: 172.20.11.11:88 repository: base username: admin password: xxx images: - image: "nginx-node:financial-cloud" template: nginx-node.j2 from_image: arm64v8/nginx:1.15-alpine arch: aarch64 alpine_repo: mirrors.aliyun.com alpine_glibc_package_version: 2.28-r0 dumb_init: dumb-init_1.2.2_aarch64 confcenterdownload: confcenterdownload_aarch64 - image: "tomcat:8-jdk7-alpine-arm64v8" from_image: ycr.xxx.com/official/arm64v8/alpine:latest arch: aarch64 template: tomcat.j2 alpine_repo: mirrors.aliyun.com confcenterdownload: confcenterdownload_aarch64 dumb_init: dumb-init_1.2.2_aarch64 alpine_glibc_package_version: 2.26-r1 version: tomcat: "8.5.28" jdk: 8u231 |
首先Dockerfile, 下面是Dockerfile模板:
base_alpine.j2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 |
FROM {{ from_image }} ENV LANG=en_US.UTF-8 \ LANGUAGE=en_US.UTF-8 \ LC_CTYPE=en_US.UTF-8 \ LC_ALL=en_US.UTF-8 \ TZ="Asia/Shanghai" \ BASE_IMAGE={{ image }} ARG ALPINE_GLIBC_PACKAGE_VERSION="{{ alpine_glibc_package_version }}" ARG DUMB_INIT={{ dumb_init }} ARG CONFCENTERDOWNLOAD={{ confcenterdownload }} ARG BASE_URL={{ base_url }} {# 自定义环境变量 #} {% block custom_env %} {% endblock custom_env %} WORKDIR ${WORKDIR:-/root} RUN set -x \ && sed -i 's/dl-cdn.alpinelinux.org/{{ alpine_repo }}/' /etc/apk/repositories \ && echo 'http://{{ alpine_repo }}/alpine/edge/testing' >> /etc/apk/repositories \ && apk update \ && apk add --no-cache --allow-untrusted --update-cache \ wget curl vim git \ perl make less \ bash bash-doc bash-completion \ tmux fish mdocml-apropos \ busybox-extras \ coreutils \ ca-certificates \ tzdata \ libtool \ gcc \ apk-tools \ netcat-openbsd \ bind-tools \ supervisor \ inotify-tools \ shadow \ openssh \ openssh-sftp-server \ {% block custom_pkg %} {% endblock custom_pkg %} \ && ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \ && echo "Asia/Shanghai" > /etc/timezone \ \ && sed -i -e 's/\/bin\/ash/\/bin\/bash/' /etc/passwd \ \ \ && echo '\ PS1='\''\[\e[01;33m\][\h \u:\[\e[01;34m\]\w\[\e[01;33m\]]\[\e[00m\]\$ '\'' ; \ eval `dircolors -b` ; \ alias ls="ls --color=auto" ; \ alias l="ls -lah" ; \ alias ll="ls -lh" ; \ alias l.="ls -d .* --color=auto" ; \ alias mv="mv -i" ; \ alias rm="rm -i" ; \ ' >> /etc/profile \ && echo '. ~/.bashrc' > /root/.bash_profile \ && echo '. /etc/profile' > /root/.bashrc \ && echo 'set-option -g default-shell /usr/bin/fish' > /root/.tmux.conf \ && mkdir -p /root/.config/fish/functions \ && echo '\ function fish_prompt ;\ if not set -q __fish_prompt_hostname ;\ set -g __fish_prompt_hostname (hostname) ;\ end ;\ set_color -o yellow ;\ echo -n -s "$USER" @ "$__fish_prompt_hostname" " " ;\ set_color -o blue ;\ echo -n (prompt_pwd) ;\ echo -n " # " ;\ set_color normal ;\ end ;\ \ alias l="ls -la" ;\ ' > /root/.config/fish/functions/fish_prompt.fish \ && ln -sf /bin/bash /bin/sh \ \ && echo 'hosts: files mdns4_minimal [NOTFOUND=return] dns mdns4' >> /etc/nsswitch.conf \ \ \ # --- start for glibc --- && ALPINE_GLIBC_BASE_DIR="$BASE_URL/public_packages/glibc/{{ arch }}" \ && ALPINE_GLIBC_BASE_PACKAGE_FILENAME="$ALPINE_GLIBC_BASE_DIR/glibc-$ALPINE_GLIBC_PACKAGE_VERSION.apk" \ && ALPINE_GLIBC_BIN_PACKAGE_FILENAME="$ALPINE_GLIBC_BASE_DIR/glibc-bin-$ALPINE_GLIBC_PACKAGE_VERSION.apk" \ && ALPINE_GLIBC_I18N_PACKAGE_FILENAME="$ALPINE_GLIBC_BASE_DIR/glibc-i18n-$ALPINE_GLIBC_PACKAGE_VERSION.apk" \ && wget $ALPINE_GLIBC_BASE_PACKAGE_FILENAME \ && wget $ALPINE_GLIBC_BIN_PACKAGE_FILENAME \ && wget $ALPINE_GLIBC_I18N_PACKAGE_FILENAME \ && apk add --no-cache --allow-untrusted --force-overwrite \ "glibc-$ALPINE_GLIBC_PACKAGE_VERSION.apk" \ "glibc-bin-$ALPINE_GLIBC_PACKAGE_VERSION.apk" \ "glibc-i18n-$ALPINE_GLIBC_PACKAGE_VERSION.apk" \ \ && rm -rf *.apk \ && /usr/glibc-compat/bin/localedef --force --inputfile POSIX --charmap UTF-8 "$LANG" || true \ && echo "export LANG=$LANG" > /etc/profile.d/locale.sh \ && apk del glibc-i18n || true \ \ && mkdir -p $WORKDIR /usr/local/src/confdownload \ && curl -SL $BASE_URL/public_packages/fish_greeting.fish -o /root/.config/fish/functions/fish_greeting.fish \ && curl -SL $BASE_URL/public_packages/entrypoint.sh -o /usr/local/bin/entrypoint.sh \ && curl -SL $BASE_URL/public_packages/confdownload/$CONFCENTERDOWNLOAD -o /usr/local/src/confdownload/confcenterdownload \ && curl -SL $BASE_URL/public_packages/offline.sh -o /usr/local/bin/offline.sh \ \ && ln -sf /usr/local/src/confdownload/confcenterdownload /usr/local/bin/confcenterdownload \ && ln -sf /usr/local/bin/offline.sh /bin/offline.sh \ \ # for supervisor && curl -SL $BASE_URL/supervisor/supervisord.conf -o /etc/supervisord.conf \ && mkdir -p /etc/supervisor.d /etc/supervisor.user \ \ # for sftp && curl -SL $BASE_URL/sftp/sshd_config -o /etc/ssh/sshd_config \ && curl -SL $BASE_URL/sftp/sftp-entrypoint.sh -o /usr/local/bin/sftp-entrypoint.sh \ && mkdir -p /etc/sftp.d \ && curl -SL $BASE_URL/sftp/bindmount.sh -o /etc/sftp.d/bindmount.sh \ && chmod +x /etc/sftp.d/bindmount.sh \ && sed -i 's/GROUP=1000/GROUP=100/' /etc/default/useradd \ && mkdir -p /var/run/sshd \ && rm -f /etc/ssh/ssh_host_*key* \ && printf '\ sftp-entrypoint.sh "$(env|grep SFTP|cut -d= -f2)" \n\ cat > /etc/supervisor.d/sftp.ini <<EOF\n\ [program:sftp] \n\ command=/usr/sbin/sshd -D -e \n\ priority=888 \n\ redirect_stderr=true \n\ EOF\n\ ' > /etc/supervisor.user/sftp.ini.sh \ \ && printf '\ monitdirs=/etc/supervisor.user/monitdirs \n\ SFTP=$(env|grep SFTP|cut -d= -f2) \n\ SFTP_USER=$(echo $SFTP|cut -d: -f1) \n\ SFTP_DIRS=$(echo $SFTP|cut -d: -f5) \n\ IFS=";" read -a dirs <<< "$SFTP_DIRS" \n\ for dir in ${dirs[@]}; do echo $dir|cut -d, -f1 >> $monitdirs; done \n\ cat > /etc/supervisor.d/chmod.ini <<EOF\n\ [program:chmod] \n\ command=bash -c "while inotifywait -q -r -e create,delete,modify,move,attrib --fromfile $monitdirs; do chown -R $SFTP_USER:users /home/$SFTP_USER/*; done" \n\ priority=999 \n\ redirect_stderr=true \n\ EOF\n\ ' > /etc/supervisor.user/chmod.ini.sh \ && chmod +x /etc/supervisor.user/*.sh \ {% block custom_run %} {% endblock custom_run %} \ && chmod +x /usr/local/bin/* \ && /bin/rm -rf /tmp/* /var/cache/apk/* EXPOSE 22 ENTRYPOINT ["entrypoint.sh"] {% block custom_cmd %} {% endblock custom_cmd %} |
tomcat.j2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 |
{% extends "base_alpine.j2" %} {# ENV 自定义环境变量 #} {% block custom_env %} {% if version and version.jdk %} ENV JAVA_HOME="/usr/local/java" \ CATALINA_HOME="/usr/local/tomcat" \ TOMCAT_VERSION={{ version.tomcat }} \ JAVA_VERSION={{ version.jdk }} \ JAVA_MAJOR={{ version.jdk|string|list|first }} ENV JRE_HOME="${JAVA_HOME}/jre" \ CLASSPATH="${JAVA_HOME}/lib/dt.jar:${JAVA_HOME}/lib/tools.jar" \ PATH="${PATH}:${JAVA_HOME}/bin:${CATALINA_HOME}/lib:${CATALINA_HOME}/bin" {# ENV for appupload #} {% if image.endswith('appupload') %} ENV MAVEN_HOME=/usr/local/maven \ MAVEN_OPTS="-Dfile.encoding=UTF-8 -Xmx512m" \ GOPATH=/usr/local/go \ PATH="$PATH:$MAVEN_HOME/bin:$GOPATH/bin" {% endif %} {% else %} ENV JAVA_MAJOR={{ version.jre }} {% endif %} ENV WORKDIR="/usr/local/tomcat" {% endblock custom_env %} {% block custom_pkg %} ttf-dejavu \ fontconfig \ wqy-zenhei@edge wqy-zenhei \ {# PKG for appupload #} {% if image.endswith('appupload') %} subversion \ zip unzip \ python \ lftp \ pigz \ nodejs nodejs-npm \ axel \ yarn \ {% endif %} {% endblock custom_pkg %} {# RUN #} {% block custom_run %} {% if tag and tag == 'youyunyin' %} {% set apm = 'yyy-probes' %} {% else %} {% set apm = 'pinpoint-agent' %} {% endif %} && mkdir -p /etc/config/download/ /usr/local/{{ apm }} \ && curl -SL $BASE_URL/java/java_options.sh -o /usr/local/bin/java_options.sh \ && curl -SL $BASE_URL/java/arthas-boot.jar -o /usr/local/bin/arthas-boot.jar \ && curl -SL $BASE_URL/java/mount_app_file_log.sh -o /usr/bin/mount_app_file_log.sh \ && wget $BASE_URL/java/{{ apm }}.tar.gz \ && tar -zxvf {{ apm }}.tar.gz --strip-components=1 -C /usr/local/{{ apm }} \ && rm -rf {{ apm }}.tar.gz \ && curl -SL $BASE_URL/java/etc/authfile.properties -o /etc/config/download/authfile.properties \ && curl -SL $BASE_URL/java/etc/yhtauthfile.properties -o /etc/config/download/yhtauthfile.properties \ \ \ && mkdir -p /usr/share/fonts/song \ && cd /usr/share/fonts/song \ && wget $BASE_URL/font/ncc/song/song.zip \ && unzip song.zip && rm -f song.zip \ && mkfontscale && mkfontdir && fc-cache && cd - \ && mkdir -p /usr/share/fonts/MicrosoftYahei && cd /usr/share/fonts/MicrosoftYahei \ && wget $BASE_URL/font/ncc/yahei/yahei.zip \ && unzip yahei.zip && rm -f yahei.zip \ && mkfontscale && mkfontdir && fc-cache && cd - \ \ {% if version and version.jdk %} && mkdir -p $JAVA_HOME \ && curl -SL $BASE_URL/java/jdk-${JAVA_VERSION}-linux-{{ 'x64' if arch == "x86_64" else 'arm64-vfp-hflt' }}.tar.gz -o java.tar.gz \ && tar -zxvf java.tar.gz --strip-components=1 -C $JAVA_HOME/ \ \ && rm -rf $JAVA_HOME/*src.zip \ $JAVA_HOME/lib/missioncontrol \ $JAVA_HOME/lib/visualvm \ $JAVA_HOME/lib/*javafx* \ $JAVA_HOME/jre/lib/ext/jfxrt.jar \ $JAVA_HOME/jre/bin/javaws \ $JAVA_HOME/jre/lib/javaws.jar \ $JAVA_HOME/jre/lib/desktop \ $JAVA_HOME/jre/plugin \ $JAVA_HOME/jre/lib/deploy* \ $JAVA_HOME/jre/lib/*javafx* \ $JAVA_HOME/jre/lib/*jfx* \ \ && rm -rf java.tar.gz* \ && curl -SL $BASE_URL/java/UnlimitedJCEPolicyJDK${JAVA_MAJOR}/local_policy.jar -o $JAVA_HOME/jre/lib/security/local_policy.jar \ && curl -SL $BASE_URL/java/UnlimitedJCEPolicyJDK${JAVA_MAJOR}/US_export_policy.jar -o $JAVA_HOME/jre/lib/security/US_export_policy.jar \ && sed -i 's/#crypto.policy=unlimited/crypto.policy=unlimited/g' /usr/local/java/jre/lib/security/java.security \ \ \ && curl -SL $BASE_URL/java/apache-tomcat-$TOMCAT_VERSION.tar.gz -o tomcat.tar.gz \ && tar -zxvf tomcat.tar.gz --strip-components=1 -C $CATALINA_HOME/ \ && rm -rf tomcat.tar.gz* bin/*.bat $CATALINA_HOME/webapps/* \ && echo 'export PATH="$PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin"' >> /etc/profile \ {% else %} && curl -SL $BASE_URL/java/UnlimitedJCEPolicyJDK${JAVA_MAJOR}/local_policy.jar -o $JAVA_HOME/lib/security/local_policy.jar \ && curl -SL $BASE_URL/java/UnlimitedJCEPolicyJDK${JAVA_MAJOR}/US_export_policy.jar -o $JAVA_HOME/lib/security/US_export_policy.jar \ {% endif %} \ && sed -i '/tomcat.util.scan.StandardJarScanFilter.jarsToSkip=/a bootstrap.jar,commons-daemon.jar,tomcat-juli.jar,bcprov-*.jar,\\' \ $CATALINA_HOME/conf/catalina.properties \ && sed -i -e 's/<Connector port="8080"/& URIEncoding="UTF-8" maxPostSize="-1"/g' \ -e '/protocol="AJP\/1.3"/s/^/<!--/' -e '/protocol="AJP\/1.3"/s/$/-->/' \ -e '/pattern="%/s/.*/\t\tpattern="%{x-forwarded-for}i %h %l %u %t \"%r\" %s %b %{X-traceId}i %D" \/>/' \ -e '/<\/Host>/i \\t<Valve className="org.apache.catalina.valves.RemoteIpValve"\n\t\tremoteIpHeader="x-forwarded-for"\n\t\tproxiesHeader="x-forwarded-by"\n\t\tprotocolHeader="x-forwarded-proto"/>' \ -e '/<\/Host>/i \\t<Resources cachingAllowed="false" cacheMaxSize="0"/>' \ $CATALINA_HOME/conf/server.xml \ \ {% if apm == 'yyy-probes' %} && sed -i '/main()/i set_apm(){\n\tif [[ "${yyy_enable}" != "" && "$(echo $yyy_enable | tr [a-z] [A-Z])" == "TRUE" ]]; \ then\n\t\texport JAVA_OPTS="$JAVA_OPTS -Xbootclasspath/a:/usr/local/yyy-probes/boot/boot.jar -javaagent:/usr/local/yyy-probes/yonyou-yyy.jar"\n\tfi\n}' \ /usr/local/bin/entrypoint.sh \ {% endif %} # && curl -SL $BASE_URL/supervisord/tomcat.ini -o /etc/supervisor.d/tomcat.ini \ && ln -sf /usr/local/bin/entrypoint.sh $CATALINA_HOME/bin/entrypoint.sh \ && rm -rf $CATALINA_HOME/bin/*.bat $CATALINA_HOME/webapps/* \ \ && app_name=$(echo $BASE_IMAGE|cut -d':' -f1) \ && user_ini="/etc/supervisor.user/${app_name}.ini.sh" \ && printf '\ cat > /etc/supervisor.d/tomcat.ini <<EOF\n\ [program:tomcat] \n\ command=/bin/bash -c "$@" \n\ environment=JAVA_OPTS="$JAVA_OPTS",JAVA_HOME="$JAVA_HOME" \n\ directory = $WORKDIR \n\ priority=1 \n\ redirect_stderr=true \n\ EOF\n\ ' > $user_ini \ && chmod +x /etc/supervisor.user/*.sh \ \ \ # for appupload {% if image.endswith('appupload') %} {% if arch == "x86_64" %} && curl -SL $BASE_URL/go/go1.10.1.linux-amd64.tar.gz -o $WORKDIR/go.tar.gz \ {% elif arch == "aarch64" %} && curl -SL $BASE_URL/go/go1.10.1.linux-arm64.tar.gz -o $WORKDIR/go.tar.gz \ {% endif %} && mkdir -p $MAVEN_HOME $GOPATH \ && curl -SL $BASE_URL/java/maven.tar.gz -o $WORKDIR/maven.tar.gz \ && npm config set registry https://registry.npm.taobao.org \ && yarn global add pm2 verdaccio \ && apk add --no-cache --virtual .fetch-deps libressl \ && wget -O /etc/pip.conf $BASE_URL/python/pip.conf \ && wget -O get-pip.py $BASE_URL/python/get-pip.py \ && apk del .fetch-deps \ && python get-pip.py \ --disable-pip-version-check \ --no-cache-dir \ "pip==9.0.1" \ && pip install --no-cache-dir chardet \ && mkdir -p $MAVEN_HOME/local/repo \ && chmod 755 -R $MAVEN_HOME \ && echo -e "StrictHostKeyChecking no\nUserKnownHostsFile /dev/null" >> /etc/ssh/ssh_config \ && curl -SL $BASE_URL/java/appupload/jfxrt.jar -o $JRE_HOME/lib/ext/jfxrt.jar \ && tar -zxvf maven.tar.gz --strip-components=1 -C $MAVEN_HOME/ \ && tar -zxvf go.tar.gz --strip-components=1 -C $GOPATH/ \ && rm -rf maven.tar.gz* go.tar.gz* \ && curl -SL $BASE_URL/java/appupload/catalina.properties.appupload -o $CATALINA_HOME/conf/catalina.properties \ && sed -i '/set_dns/a pm2 start verdaccio' /usr/local/bin/entrypoint.sh \ {% endif %} {% endblock custom_run %} {# CMD #} {% block custom_cmd %} EXPOSE 8080 CMD ["catalina.sh", "run"] {% endblock custom_cmd %} |
sftp-entrypoint.sh改了一下, 把后面启动sshd的删除了, 放到了supervisor管理, 另外增加了传环境变量来支持进行多目录挂载, 比如传:
-e “SFTP=sftp:sftp:1001:100:/usr/local/tomcat,tomcat;/etc/supervisor.d,supervisor.d”
可以将/usr/local/tomcat挂载到/home/sftp/tomcat
也可将/etc/supervisor.d挂载到/home/sftp/supervisor.d
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 |
#!/bin/bash set -e # Paths userConfPath="/etc/sftp/users.conf" userConfPathLegacy="/etc/sftp-users.conf" userConfFinalPath="/var/run/sftp/users.conf" # Extended regular expression (ERE) for arguments reUser='[A-Za-z0-9._][A-Za-z0-9._-]{0,31}' # POSIX.1-2008 rePass='[^:]{0,255}' reUid='[[:digit:]]*' reGid='[[:digit:]]*' reDir='[^:]*' reArgs="^($reUser)(:$rePass)(:e)?(:$reUid)?(:$reGid)?(:$reDir)?$" reArgsMaybe="^[^:[:space:]]+:.*$" # Smallest indication of attempt to use argument reArgSkip='^([[:blank:]]*#.*|[[:blank:]]*)$' # comment or empty line function log() { echo "[entrypoint] $@" } function validateArg() { name="$1" val="$2" re="$3" if [[ "$val" =~ ^$re$ ]]; then return 0 else log "ERROR: Invalid $name \"$val\", do not match required regex pattern: $re" return 1 fi } function createUser() { log "Parsing user data: \"$@\"" IFS=':' read -a args <<< $@ index=0 user="${args[0]}"; validateArg "username" "$user" "$reUser" || return 1 pass="${args[1]}"; validateArg "password" "$pass" "$rePass" || return 1 if [ "${args[2]}" == "e" ]; then chpasswdOptions="-e" index=1 fi uid="${args[$[$index+2]]}"; validateArg "UID" "$uid" "$reUid" || return 1 gid="${args[$[$index+3]]}"; validateArg "GID" "$gid" "$reGid" || return 1 dir="${args[$[$index+4]]}"; validateArg "dirs" "$dir" "$reDir" || return 1 if getent passwd $user > /dev/null; then log "WARNING: User \"$user\" already exists. Skipping." return 0 fi useraddOptions="--no-user-group" if [ -n "$uid" ]; then useraddOptions="$useraddOptions --non-unique --uid $uid" fi if [ -n "$gid" ]; then if ! getent group $gid > /dev/null; then groupadd --gid $gid "group_$gid" fi useraddOptions="$useraddOptions --gid $gid" fi useradd $useraddOptions $user mkdir -p /home/$user chown root:root /home/$user chmod 755 /home/$user # Retrieving user id to use it in chown commands instead of the user name # to avoid problems on alpine when the user name contains a '.' uid="$(id -u $user)" if [ -n "$pass" ]; then echo "$user:$pass" | chpasswd $chpasswdOptions else usermod -p "*" $user # disabled password fi # Add SSH keys to authorized_keys with valid permissions if [ -d /home/$user/.ssh/keys ]; then cat /home/$user/.ssh/keys/* >> /home/$user/.ssh/authorized_keys chown $uid /home/$user/.ssh/authorized_keys chmod 600 /home/$user/.ssh/authorized_keys fi # Make sure dirs exists # format example: $CATALINA_HOME,tomcat;/etc,etc if [ -n "$dir" ]; then IFS=';' read -a dirArgs <<< $dir for dirPath in ${dirArgs[@]}; do resPath=$(echo $dirPath|cut -d',' -f1) desPath=$(echo $dirPath|cut -d',' -f2) if [ -z "$desPath" ]; then desPath=$resPath fi dirPath="/home/$user/$desPath" if [ ! -d "$dirPath" ]; then log "Creating directory: $dirPath" mkdir -p $dirPath chown -R $uid:users $dirPath else log "Directory already exists: $dirPath" fi done fi } # Allow running other programs, e.g. bash if [[ -z "$1" || "$1" =~ $reArgsMaybe ]]; then startSshd=true else startSshd=false fi # Backward compatibility with legacy config path if [ ! -f "$userConfPath" -a -f "$userConfPathLegacy" ]; then mkdir -p "$(dirname $userConfPath)" ln -s "$userConfPathLegacy" "$userConfPath" fi # Create users only on first run if [ ! -f "$userConfFinalPath" ]; then mkdir -p "$(dirname $userConfFinalPath)" # Append mounted config to final config if [ -f "$userConfPath" ]; then cat "$userConfPath" | grep -v -E "$reArgSkip" > "$userConfFinalPath" fi # Append users from STDIN to final config # DEPRECATED on 2017-10-08, DO NOT USE # TODO: Remove code after 6-12 months if [ ! -t 0 ]; then while IFS= read -r user || [[ -n "$user" ]]; do echo "$user" >> "$userConfFinalPath" done fi if $startSshd; then # Append users from arguments to final config for user in "$@"; do echo "$user" >> "$userConfFinalPath" done fi # Check that we have users in config if [[ -f "$userConfFinalPath" && "$(cat "$userConfFinalPath" | wc -l)" > 0 ]]; then # Import users from final conf file while IFS= read -r user || [[ -n "$user" ]]; do createUser "$user" done < "$userConfFinalPath" elif $startSshd; then log "FATAL: No users provided!" exit 3 fi # Generate unique ssh keys for this container, if needed if [ ! -f /etc/ssh/ssh_host_ed25519_key ]; then ssh-keygen -t ed25519 -f /etc/ssh/ssh_host_ed25519_key -N '' fi if [ ! -f /etc/ssh/ssh_host_rsa_key ]; then ssh-keygen -t rsa -b 4096 -f /etc/ssh/ssh_host_rsa_key -N '' fi fi # Source custom scripts, if any if [ -d /etc/sftp.d ]; then for f in /etc/sftp.d/*; do if [ -x "$f" ]; then log "Running $f ..." $f fi done unset f fi |
运行用户自定义的脚本bindmount.sh
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
#!/bin/bash # File mounted as: /etc/sftp.d/bindmount.sh # Just an example (make your own) function bindmount() { user=$1 resdir=$2 desdir=$3 # dest=/home/$user/$desdir if [ ! -d "$desdir" ]; then mkdir -p "$desdir" fi mount --bind $4 "$resdir" "$desdir" chown -R $user:users $resdir $desdir } # Remember permissions, you may have to fix them: # bindmount /data/common /home/dave/common # bindmount /data/common /home/peter/common # bindmount /data/docs /home/peter/docs --read-only # user=$(echo $SFTP | awk -F: '{print $1}') # mountdir=$(echo $SFTP | awk -F: '{print $5}') # #resdir=$CATALINA_HOME # resdir=${dir:-/} # desdir=${mountdir:-data} # mount path which were given # format example: SFTP="sftp:sftp:1001:100:$CATALINA_HOME,tomcat;/etc,etc" user=$(echo $SFTP | awk -F: '{print $1}') mountdir=$(echo $SFTP | awk -F: '{print $5}') if [ -n "$mountdir" ]; then IFS=';' read -a dirArgs <<< $mountdir for dirPath in ${dirArgs[@]}; do resPath=$(echo $dirPath|cut -d',' -f1) desPath=$(echo $dirPath|cut -d',' -f2) if [ -z "$desPath" ]; then desPath=$resPath fi desPath="/home/$user/$desPath" if [ ! -d "$desPath" ]; then echo "Creating directory: $desPath" mkdir -p $desPath chown -R $uid:users $desPath else echo "Directory already exists: $dirPath" fi bindmount $user $resPath $desPath done fi |
总的entrypoint.sh:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 |
#!/bin/sh if [[ ! -z $MESOS_TASK_ID ]]; then AGENT_ID=$(echo "$MESOS_TASK_ID"|cut -d'.' -f 2|cut -d'-' -f 1,2,3) #mesos container else AGENT_ID=$(echo "$LOG_INSTANCE_ID") #k8s container fi ### 1. confcenter confcenter(){ /usr/local/src/confdownload/confcenterdownload if [[ $? -ne 0 ]];then echo -e "Download configuration file error!\n" exit 11 fi } ### 2. set log path set_applog(){ if [[ "X${xxxcloud_replace_path}" != "X" && "X${xxxucloud_replace_value}" != "X" ]]; then paths=(${xxxcloud_replace_path//;/ }) values=(${xxxcloud_replace_value//;/ }) for path in ${paths[@]} do if [[ -f "${path}" ]];then for value in ${values[@]} do env_value=`eval echo '$'"${value}"` if [[ ! -z "${env_value}" ]];then replace_value="%$value%" sed -i "s@${replace_value}@${env_value}@" $path fi done fi done fi # 收集用户应用日志 if [[ "X${developer_app_logs}" != "X" && "X${AGENT_ID}" != "X" ]]; then arr=(${developer_app_logs//;/ }) busiPath=${arr[2]} savePath="/developerMountData/log/datalog" logpath=${savePath}/${arr[0]}/${arr[1]}/$AGENT_ID # path统一为最后面没有/ busiPath=${busiPath%/} mkdir -p $busiPath # 移除原来的日志文件夹 mv "${busiPath}" "${busiPath}_$(date +'%Y%m%d%H%M%S.%N').bak" if [[ $? -eq 0 ]];then mkdir -p $logpath ln -sf $logpath $busiPath fi fi } #### 3. APM for java/tomcat set_apm(){ JAVA_OPTS="$JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -Duser.timezone=GMT+08 -Ddefault.client.encoding=UTF-8 -Dfile.encoding=UTF-8 -Dsun.jnu.encoding=UTF8 -Duser.language=Zh" # ==enable pinpoint or not== if [[ "X${developer_apm_appId}" != "X" && "X${AGENT_ID}" != "X" ]]; then # strip spaces or tabs before or behind the string and cut to left 24 strings APPLICATION_NAME=$(echo "$developer_apm_appId" | awk 'gsub(/^ *| *$/,"")' | cut -b -24) PINPOINT_COLLECTOR_IP=${PINPOINT_COLLECTOR_IP:-10.3.15.29} AGENT_ID_SHORT=$(echo "$AGENT_ID" | cut -b -24) APM_JAR="/usr/local/pinpoint-agent/pinpoint-bootstrap-1.7.4.jar" JAVA_OPTS="$JAVA_OPTS -javaagent:${APM_JAR} -Dpinpoint.agentId=${AGENT_ID_SHORT} -Dpinpoint.applicationName=${APPLICATION_NAME}" # configure pinpoint.config PINPOINT_CONFIG_FILE="/usr/local/pinpoint-agent/pinpoint.config" sed -i "s/profiler.collector.ip=127.0.0.1/profiler.collector.ip=${PINPOINT_COLLECTOR_IP}/g" ${PINPOINT_CONFIG_FILE} # Adjust pointpoint port. COLLECTOR_TCP_PORT=${PINPOINT_COLLECTOR_TCP_PORT:-9994} let COLLECTOR_STAT_PORT=${COLLECTOR_TCP_PORT}+1 let COLLECTOR_SPAN_PORT=${COLLECTOR_TCP_PORT}+2 sed -i "s/profiler.collector.tcp.port=.*/profiler.collector.tcp.port=${COLLECTOR_TCP_PORT}/g" ${PINPOINT_CONFIG_FILE} sed -i "s/profiler.collector.stat.port=.*/profiler.collector.stat.port=${COLLECTOR_STAT_PORT}/g" ${PINPOINT_CONFIG_FILE} sed -i "s/profiler.collector.span.port=.*/profiler.collector.span.port=${COLLECTOR_SPAN_PORT}/g" ${PINPOINT_CONFIG_FILE} # Configure log level for log4j PINPOINT_LOG_CONFIG_FILE="/usr/local/pinpoint-agent/lib/log4j.xml" PINPOINT_LOG_LEVEL=${PINPOINT_LOG_LEVEL:-ERROR} sed -i "s/ERROR/${PINPOINT_LOG_LEVEL}/g" ${PINPOINT_LOG_CONFIG_FILE} # profiler.sampling.rate:采样率(1/n,配置为2就是50%) [[ $SAMPLING_RATE =~ ^-?[0-9]+$ ]] && SAMPLING_RATE=${SAMPLING_RATE} || SAMPLING_RATE=20 sed -i "s/profiler.sampling.rate=.*/profiler.sampling.rate=${SAMPLING_RATE}/g" ${PINPOINT_CONFIG_FILE} SAMPLING_RATE_PERCENT=`awk 'BEGIN{printf "%.2f%%\n",(1/'${SAMPLING_RATE}')*100}'` # RPC log sampling rate if [[ "X$SPAN_TRACE_RATIO" != "X" && $SPAN_TRACE_RATIO =~ ^-?[0-9]+$ ]]; then JAVA_OPTS="$JAVA_OPTS -Dspan.trace.ratio=$SPAN_TRACE_RATIO" else SPAN_TRACE_RATIO="100%" fi # Set Call Stack max depth(if -1 is unlimited and min is 2) [[ $CALLSTACK_MAX_DEPTH =~ ^-?[0-9]+$ ]] && CALLSTACK_MAX_DEPTH=${CALLSTACK_MAX_DEPTH} || CALLSTACK_MAX_DEPTH=64 sed -i "s/profiler.callstack.max.depth=.*/profiler.callstack.max.depth=${CALLSTACK_MAX_DEPTH}/g" ${PINPOINT_CONFIG_FILE} # io.buffering.buffersize [[ $IO_BUFFERSIZE =~ ^-?[0-9]+$ ]] && IO_BUFFERSIZE=${IO_BUFFERSIZE} || IO_BUFFERSIZE=5 sed -i "s/profiler.io.buffering.buffersize=.*/profiler.io.buffering.buffersize=${IO_BUFFERSIZE}/g" ${PINPOINT_CONFIG_FILE} # HTTPCLIENT4_SAMPLING_RATE [[ $HTTPCLIENT4_SAMPLING_RATE =~ ^-?[0-9]+$ ]] && HTTPCLIENT4_SAMPLING_RATE=${HTTPCLIENT4_SAMPLING_RATE} || HTTPCLIENT4_SAMPLING_RATE=1 sed -i "s/profiler.apache.httpclient4.entity.sampling.rate=.*/profiler.apache.httpclient4.entity.sampling.rate=${HTTPCLIENT4_SAMPLING_RATE}/g" ${PINPOINT_CONFIG_FILE} HTTPCLIENT4_SAMPLING_RATE_PERCENT=`awk 'BEGIN{printf "%.2f%%\n",(1/'${HTTPCLIENT4_SAMPLING_RATE}')*100}'` echo "--------------------Pinpoint Enabled--------------------" echo "Pinpoint Application Name: $APPLICATION_NAME" echo "Pinpoint Agent Id: $AGENT_ID" echo "Pinpoint Collector Ip: $PINPOINT_COLLECTOR_IP (can be overided by given ENV \$PINPOINT_COLLECTOR_IP)" echo "Pinpoint Log Level: $PINPOINT_LOG_LEVEL (can be overided by given ENV \$PINPOINT_LOG_LEVEL)" echo "Pinpoint Sampling.Rate: $SAMPLING_RATE_PERCENT (can be overided by given ENV \$SAMPLING_RATE, E.G.: set SAMPLING_RATE to 20, 1/n, then rate will be 5%)" echo "RPC log sampling rate: $SPAN_TRACE_RATIO (can be overided by given ENV \$SPAN_TRACE_RATIO, E.G.: set SAMPLING_RATE to 5, then rate will be 5%)" echo "Call Stack max depth: $CALLSTACK_MAX_DEPTH (can be overided by given ENV \$CALLSTACK_MAX_DEPTH, if -1 is unlimited and min is 2, default is 64)" echo "io.buffering.buffersize: $IO_BUFFERSIZE (can be overided by given ENV \$IO_BUFFERSIZE)" echo "httpclient4.entity.sampling.rate:$HTTPCLIENT4_SAMPLING_RATE_PERCENT (can be overided by given ENV \$HTTPCLIENT4_SAMPLING_RATE, 1 out of n entities will be sampled where n is the rate. (10: 10%))" echo "---------------------------------------------------------" fi export JAVA_OPTS="$JAVA_OPTS" } #### 4. set DNS servers #### 传环境变量DNS_SERVER, 如果DNS_SERVER=default, 则用系统默认DNS; 如果DNS_SERVER为正确的IP,则设置为此IP; 如果不设,则用平台默认DNS set_dns(){ if [[ "X${DNS_SERVER}" != "X" ]]; then dns_lists=`echo $DNS_SERVER | sed "s/[\'\"]//g" | awk 'BEGIN{FS="[ ,;|]+"; OFS=" " } {for(i=1;i<=NF;i++){printf"%s ", $i}}'` #DNS_SERVER=DEFAULT, 则设置k8s默认cluster DNS if [[ "$(echo $dns_lists | awk 'gsub(/^ *| *$/,"")' | tr [a-z] [A-Z])" == "DEFAULT" ]]; then echo "using system default DNS server." #设置用户自定义DNS else for dns_ip in `echo $dns_lists`; do VALID_CHECK=$(echo $dns_ip|awk -F. '$1<=255&&$2<=255&&$3<=255&&$4<=255{print "yes"}') if echo $dns_ip|grep -E "^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$" >/dev/null; then if [ $VALID_CHECK == "yes" ]; then echo "Adding DNS server: $dns_lists" echo "options timeout:1 attempts:1 rotate" > /etc/resolv.conf echo "nameserver $dns_ip" >> /etc/resolv.conf else echo "$dns_ip wrong, please correct the DNS server IP: $dns_ip, using system default DNS now." echo "using system default DNS server." break fi else echo "$dns_ip wrong, please correct the DNS server IP: $dns_ip, using system default DNS now." echo "using system default DNS server." break fi done fi #设置平台默认DNS else echo "using system default DNS server." fi } #### 5. add hosts to /etc/hosts if needed #### 传环境变量ADD_HOST, 格式:host:ip, 多个解析之间用逗号,分号,或竖线分隔 add_host(){ if [[ "X${ADD_HOST}" != "X" ]]; then hosts_list=`echo $ADD_HOST | sed "s/[\'\"]//g" | awk 'BEGIN{FS="[ ,;|]+"; OFS=" " } {for(i=1;i<=NF;i++){printf"%s ", $i}}'` for one_host in `echo $hosts_list`; do echo "$(echo $one_host|awk -F: '{print $2,$1}')" >> /etc/hosts done fi } #### 6. run sftp if needed for debug set_sftp(){ # sftp function can be opened by given an env, for example: # SFTP="sftp:sftp:1001:100:$CATALINA_HOME,tomcat;/etc/nginx,nginx" # which has the following means: # user: sftp, pass: sftp, pid: 1001, gid: 100 # mounted dir1: $CATALINA_HOME, mount to: /home/$user/tomcat # mounted dir2: /etc/nginx, mount to: /home/$user/nginx if [[ "X${SFTP}" != "X" ]]; then sh /etc/supervisor.user/sftp.ini.sh sh /etc/supervisor.user/chmod.ini.sh fi } #### 7. final run run_supervisor(){ if [[ "X$@" != "X" ]]; then app_name=$(echo $BASE_IMAGE|cut -d':' -f1) user_ini="/etc/supervisor.user/${app_name}.ini.sh" if [[ "$@" == "bash" || "$@" == "sh" || "$@" == "fish" ]]; then exec "$@" elif [[ -f "$user_ini" ]]; then sh $user_ini "$@" supervisord --nodaemon --configuration /etc/supervisord.conf fi elif [[ -f "/etc/supervisor.d/sftp.ini" ]]; then supervisord --nodaemon --configuration /etc/supervisord.conf else echo "please give command to run the contaniner." fi } set_dns confcenter set_applog if java -version >/dev/null 2>&1; then source /usr/local/bin/java_options.sh; set_apm; fi add_host set_sftp run_supervisor "$@" |
总构建脚本build.py:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 |
#!/usr/bin/python # -*- coding: utf-8 -*- #import commands import jinja2 import yaml import sys import os import re #import traceback import socket import subprocess import time import json import argparse import logging mdhms=time.strftime('%m-%d-%H-%M',time.localtime(time.time())) logdir='./log' if not os.path.exists(logdir): os.makedirs(logdir) logfile=os.path.join(logdir, 'build_'+mdhms+'.log') logfile_latest=os.path.join(logdir, 'latest.log') logger = logging.getLogger(__name__) logger.setLevel(logging.DEBUG) BASIC_FORMAT = "%(asctime)s - %(levelname)s - %(message)s" DATE_FORMAT = '%m/%d/%Y %H:%M:%S' formatter = logging.Formatter(BASIC_FORMAT, DATE_FORMAT) # StreamHandler stream_handler = logging.StreamHandler() stream_handler.setFormatter(formatter) # stream_handler.setLevel(logging.INFO) # FileHandler file_handler = logging.FileHandler(logfile) file_handler.setFormatter(formatter) file_handler.setLevel(logging.INFO) logger.addHandler(stream_handler) logger.addHandler(file_handler) if os.path.exists('/root/.python_env/lib/python2.7/site-packages/'): sys.path.insert(0, "/root/.python_env/lib/python2.7/site-packages/") try: import docker except: print ("installing docker-py module, please wait a second...") sys.stdout.flush() os.system("pip install docker") import docker # reload(sys) # sys.setdefaultencoding('utf8') current_dir = os.getcwd() download_dir = os.path.join(current_dir,'download') download_http_port = "8899" dockerfile_dir = os.path.join(current_dir, 'dockerfile') if not os.path.exists(dockerfile_dir): os.makedirs(dockerfile_dir) #docker_client = docker.APIClient(base_url='unix://var/run/docker.sock',version='auto',timeout=5) #docker_client = docker.from_env() def get_host_ip(): try: s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.connect(('8.8.8.8', 80)) ip = s.getsockname()[0] finally: s.close() return ip def start_download_http_server(): check_http_process="ps -efa|grep SimpleHTTPServerWithUpload.py|grep -v grep" check_http_port="netstat -antp | grep %s | grep LISTEN >/dev/null 2>&1" % (download_http_port) start_server="nohup python SimpleHTTPServerWithUpload.py %s > /dev/null 2>&1 &" % (download_http_port) http_process = subprocess.call(check_http_process, shell=True) http_port = subprocess.call(check_http_port, shell=True) if http_process != 0 and http_port != 0: os.chdir(download_dir) subprocess.call(start_server, shell=True) os.chdir(current_dir) def stop_download_http_server(): kill_http_server = "kill -9 `ps -efa|grep SimpleHTTPServerWithUpload.py|grep -v grep|awk '{print $2}'`" subprocess.call(kill_http_server, shell=True) def render_dockerfile(item): dockerfile = os.path.join(dockerfile_dir, 'Dockerfile.' + item['arch'] + '-' + item['image'].replace(':', '-')) profile = template_env.get_template(item['template']) content = profile.render(item) with open(dockerfile, 'w') as fp: fp.write(content) return dockerfile class Docker_Client(): def __init__(self): # self.client = docker.DockerClient(version='auto', base_url='unix://var/run/docker.sock') self.client = docker.APIClient(version='auto', **docker.utils.kwargs_from_env()) #self.username = username #self.password = password def build_image(self, path, dockerfile, image, nocache=True, network_mode="host", memory_limit="3MB", buildargs=""): limits = { # Always disable memory swap for building, since mostly # nothing good can come of that. 'memswap': -1 } if memory_limit: limits['memory'] = memory_limit #client = docker.APIClient(version='auto', **docker.utils.kwargs_from_env()) logger.info("--> Building %s" % image) try: build = self.client.build( path=path, dockerfile=dockerfile, tag=image, buildargs=buildargs, decode=True, forcerm=True, container_limits=limits, nocache=nocache, network_mode=network_mode, encoding="utf-8" ) for line in build: logger.debug([line['stream'] if 'stream' in line else line][0]) except Exception as e: logger.error("build %s failed: %s" % (image, e), exc_info=True) sys.exit(1) def push_image(self, image, full_image, registry, username="admin", password="Harbor12345"): # tag image logger.info("--> tag %s to %s" % (image, full_image)) self.client.tag(image, full_image, force=True) try: # login registry self.client.login(username=username, password=password, email=None, registry=registry) # Build a progress setup for each layer, and only emit per-layer # info every 1.5s # layers = {} last_emit_time = time.time() for line in self.client.push(full_image, stream=True, decode=True): # progress = json.loads(line.decode('utf-8')) # # print '-'*5, progress # if 'error' in progress: # logger.error(progress['error'], extra=dict(phase='failed')) # sys.exit(1) # if 'id' not in progress: # continue # if 'progressDetail' in progress and progress['progressDetail']: # layers[progress['id']] = progress['progressDetail'] # else: # layers[progress['id']] = progress['status'] # logger.debug('pushing %s' % layers) # if time.time() - last_emit_time > 1.5: # print 'pushing %s' % layers # last_emit_time = time.time() if time.time() - last_emit_time > 1.5: logger.debug(line) last_emit_time = time.time() logger.info('--> Pushed %s ' % full_image) except Exception as e: logger.error("push_image %s failed: %s" % (full_image, e), exc_info=True) sys.exit(1) if __name__ == '__main__': try: parser = argparse.ArgumentParser(description = 'build') parser.add_argument ('--config', default = "./config/config.yml", type=str, help = 'please input config file.') parser.add_argument ('--enable-http-server', default = "true", type=str, help = 'auto start a http server for image build resources. default true') global args args = parser.parse_args() if args.enable_http_server == "true": start_download_http_server() template_loader = jinja2.FileSystemLoader(searchpath="./templates") template_env = jinja2.Environment(loader=template_loader) template_env.trim_blocks = True config_file = open(args.config) data_config = {} data_config.update(yaml.safe_load(config_file)) download_http_ip = get_host_ip() base_url = 'http://' + download_http_ip + ':' + download_http_port data = {} data.update(data_config) docker_client = Docker_Client() for item in data['images']: item['base_url'] = base_url image = item['image'] # image_tag = image.split(':')[1] dockerfile = render_dockerfile(item) logger.info('-'*20 + image + '-'*20) docker_client.build_image(dockerfile_dir, dockerfile, image) for registry in data['registry']: host = registry['host'] username = registry['username'] password = registry['password'] repository = registry['repository'] full_image = os.path.join(host, repository, image) docker_client.push_image(image, full_image, host, username, password) logger.info('-'*60 + '\n\n') #print("build image: " + full_image) #sys.stdout.flush() # if os.system("docker build --network=host -f %s %s -t %s" % (dockerfile, dockerfile_dir, target_image)) != 0: # print("image %s build failed." % (full_image)) # sys.stdout.flush() # sys.exit(1) # os.system("docker tag %s %s" % (target_image, full_image)) # os.system("docker login %s --username %s --password %s" % (data['registry']['host'], data['registry']['username'], data['registry']['password'])) # if os.system("docker push %s" % (full_image)) != 0: # print("image %s push failed." % (full_image)) # sys.stdout.flush() # sys.exit(1) os.system("ln -sf %s %s" % (os.path.abspath(logfile), os.path.abspath(logfile_latest))) if args.enable_http_server == "true": stop_download_http_server() except Exception as e: logger.error('Faild Info: %s' % e, exc_info=True) if args.enable_http_server == "true": stop_download_http_server() sys.exit(1) |
后期可以基于base-alpine.j2来灵活定制, 如nginx.j2模板
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
{% extends "base_alpine.j2" %} {% block custom_pkg %} {% if image.startswith('nginx-node') %} nodejs \ nodejs-npm \ python \ python-dev \ python3 \ python3-dev \ gcc g++ \ yarn \ {% endif %} {% endblock custom_pkg %} {% block custom_run %} {% if image.startswith('nginx-node') %} && npm config set registry https://registry.npm.taobao.org \ && yarn config set ignore-engines true \ && yarn global add ynpm-tool@3.1.3 cnpm nrm \ {% endif %} && rm -f /var/log/nginx/* \ && app_name=$(echo $BASE_IMAGE|cut -d':' -f1) \ && user_ini="/etc/supervisor.user/${app_name}.ini.sh" \ && printf '\ cat > /etc/supervisor.d/nginx.ini <<EOF\n\ [program:nginx] \n\ command=/bin/bash -c "$@" \n\ EOF\n\ ' > $user_ini \ && chmod +x /etc/supervisor.user/*.sh \ {% endblock custom_run %} {% block custom_cmd %} EXPOSE 80 CMD ["nginx", "-g", "'daemon off;'"] {% endblock custom_cmd %} |
node.j2:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
{% extends "base_alpine.j2" %} {# 自定义环境变量 #} {% block custom_env %} {% if sftp %} ENV SFTP="{{ sftp }}" {% endif %} {% endblock custom_env %} {% block custom_pkg %} yarn \ {% endblock custom_pkg %} {% block custom_run %} {% if arch == "x86_64" %} && [[ !-d "/lib64" ]] && mkdir /lib64 || true \ && ln -sf /lib/libc.musl-x86_64.so.1 /lib64/ld-linux-x86-64.so.2 \ {% endif %} && npm config set unsafe-perm true \ && npm config set registry https://registry.npm.taobao.org \ && yarn config set ignore-engines true \ && yarn global add ynpm-tool@3.1.3 cnpm nrm pm2 \ \ && app_name=$(echo $BASE_IMAGE|cut -d':' -f1) \ && user_ini="/etc/supervisor.user/${app_name}.ini.sh" \ && printf '\ cat > /etc/supervisor.d/node.ini <<EOF\n\ [program:node] \n\ command=/bin/bash -c "$@" \n\ EOF\n\ ' > $user_ini \ && chmod +x /etc/supervisor.user/*.sh \ {% endblock custom_run %} {% block custom_cmd %} CMD [ "node" ] {% endblock custom_cmd %} |
最后执行命令构建:python build.py –config ./config/config_x86_online.yml
权限问题:
现在还有一个问题, 容器运行启来后, 比如java, 用户会在CMD命令里写地堆命令, 比如:
cd /app && mkdir org-api && unzip org-api.jar -d ./org-api/ && java -Xbootclasspath/a:/usr/local/conf $JAVA_OPTS $CATALINA_OPTS -jar org-api.jar
虽然运行sshd之前已经改过权限了, 但是容器运行时执行此命令的用户是root, 修改权限先于上面那一堆命令而运行,从而导致后面新出现的文件, 用sftp用户操作挂载目录出现没权限的问题。
解决此问题的思路:
尝试了supervisor的priority,也不好用,后来用inotify-tools来实时监控文件变化解决, 具体解决方法, 可以定义一个ini文件:
1 2 3 4 5 6 7 8 9 10 11 12 |
monitdirs=/etc/supervisor.user/monitdirs SFTP=$(env|grep SFTP|cut -d= -f2) SFTP_USER=$(echo $SFTP|cut -d: -f1) SFTP_DIRS=$(echo $SFTP|cut -d: -f5) IFS=";" read -a dirs <<< "$SFTP_DIRS" for dir in ${dirs[@]}; do echo $dir|cut -d, -f1 >> $monitdirs; done cat > /etc/supervisor.d/chmod.ini <<EOF [program:chmod] command=bash -c "while inotifywait -q -r -e create,delete,modify,move,attrib --fromfile $monitdirs; do chown -R $SFTP_USER:users /home/$SFTP_USER/*; done" priority=999 redirect_stderr=true EOF |
当用户被挂载的源目录出现变化时, 来更改挂载目标目录的权限
PS:
今天一直构建失败, 之前都是好好的, 查了半天, 原来是alpine淘宝源出问题了, bash都装的不正常, 构建时出现如下报错:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
+ sed -i s/dl-cdn.alpinelinux.org/mirrors.aliyun.com/ /etc/apk/repositories + echo http://mirrors.aliyun.com/alpine/edge/testing + apk update fetch http://mirrors.aliyun.com/alpine/v3.11/main/x86_64/APKINDEX.tar.gz fetch http://mirrors.aliyun.com/alpine/v3.11/community/x86_64/APKINDEX.tar.gz fetch http://mirrors.aliyun.com/alpine/edge/testing/x86_64/APKINDEX.tar.gz v3.11.6-46-gff7db7c636 [http://mirrors.aliyun.com/alpine/v3.11/main] v3.11.6-40-g4ab6ec338e [http://mirrors.aliyun.com/alpine/v3.11/community] v20200428-1425-g87c52a46e8 [http://mirrors.aliyun.com/alpine/edge/testing] OK: 15298 distinct packages available + apk add --no-cache --allow-untrusted --update-cache wget curl vim git perl make less bash bash-doc bash-completion tmux fish mdocml-apropos busybox-extras coreutils ca-certificates tzdata libtool gcc apk-tools netcat-openbsd bind-tools supervisor inotify-tools shadow openssh openssh-sftp-server ttf-dejavu fontconfig wqy-zenhei@edge wqy-zenhei fetch http://mirrors.aliyun.com/alpine/v3.11/main/x86_64/APKINDEX.tar.gz fetch http://mirrors.aliyun.com/alpine/v3.11/community/x86_64/APKINDEX.tar.gz fetch http://mirrors.aliyun.com/alpine/edge/testing/x86_64/APKINDEX.tar.gz (1/92) Installing ncurses-terminfo-base (6.1_p20200118-r4) (2/92) Installing ncurses-libs (6.1_p20200118-r4) (3/92) Installing readline (8.0.1-r0) (4/92) Installing bash (5.0.11-r1) Executing bash-5.0.11-r1.post-install (5/92) Installing pkgconf (1.6.3-r0) (6/92) Installing bash-completion (2.9-r0) (7/92) Installing bash-doc (5.0.11-r1) (8/92) Installing fstrm (0.6.0-r1) (9/92) Installing libgcc (9.2.0-r4) (10/92) Installing krb5-conf (1.0-r1) (11/92) Installing libcom_err (1.45.5-r0) (12/92) Installing keyutils-libs (1.6.1-r0) (13/92) Installing libverto (0.3.1-r1) (14/92) Installing krb5-libs (1.17.1-r0) (15/92) Installing json-c (0.13.1-r0) (16/92) Installing libstdc++ (9.2.0-r4) (17/92) Installing libprotobuf (3.11.2-r1) (18/92) Installing libprotoc (3.11.2-r1) (19/92) Installing protobuf-c (1.3.2-r3) (20/92) Installing xz-libs (5.2.4-r0) (21/92) Installing libxml2 (2.9.10-r3) (22/92) Installing bind-libs (9.14.12-r0) ERROR: bind-libs-9.14.12-r0: package mentioned in index not found (try 'apk update') (23/92) Installing bind-tools (9.14.12-r0) (24/92) Installing busybox-extras (1.31.1-r9) ERROR: bind-tools-9.14.12-r0: package mentioned in index not found (try 'apk update') Executing busybox-extras-1.31.1-r9.post-install (25/92) Installing ca-certificates (20191127-r1) (26/92) Installing libacl (2.2.53-r0) (27/92) Installing libattr (2.4.48-r0) (28/92) Installing coreutils (8.31-r0) (29/92) Installing nghttp2-libs (1.40.0-r0) (30/92) Installing libcurl (7.67.0-r0) (31/92) Installing curl (7.67.0-r0) (32/92) Installing bc (1.07.1-r1) (33/92) Installing libpcre2-32 (10.34-r1) (34/92) Installing fish (3.0.2-r5) Executing fish-3.0.2-r5.post-install (35/92) Installing expat (2.2.9-r1) (36/92) Installing libbz2 (1.0.8-r1) (37/92) Installing libpng (1.6.37-r1) (38/92) Installing freetype (2.10.1-r0) (39/92) Installing libuuid (2.34-r1) (40/92) Installing fontconfig (2.13.1-r2) (41/92) Installing binutils (2.33.1-r0) (42/92) Installing gmp (6.1.2-r1) (43/92) Installing isl (0.18-r0) (44/92) Installing libgomp (9.2.0-r4) (45/92) Installing libatomic (9.2.0-r4) (46/92) Installing mpfr4 (4.0.2-r1) (47/92) Installing mpc1 (1.1.0-r1) (48/92) Installing gcc (9.2.0-r4) (49/92) Installing pcre2 (10.34-r1) (50/92) Installing git (2.24.3-r0) (51/92) Installing git-bash-completion (2.24.3-r0) (52/92) Installing inotify-tools (3.20.1-r1) (53/92) Installing less (551-r0) (54/92) Installing libltdl (2.4.6-r7) (55/92) Installing libtool (2.4.6-r7) (56/92) Installing make (4.2.1-r2) (57/92) Installing mdocml (1.14.5-r1) (58/92) Installing mdocml-apropos (1.14.5-r1) (59/92) Installing libbsd (0.10.0-r0) (60/92) Installing netcat-openbsd (1.130-r1) (61/92) Installing openssh-keygen (8.1_p1-r0) (62/92) Installing libedit (20191211.3.1-r0) (63/92) Installing openssh-client (8.1_p1-r0) (64/92) Installing openssh-sftp-server (8.1_p1-r0) (65/92) Installing openssh-server-common (8.1_p1-r0) (66/92) Installing openssh-server (8.1_p1-r0) (67/92) Installing openssh (8.1_p1-r0) (68/92) Installing perl (5.30.1-r0) (69/92) Installing perl-error (0.17028-r0) (70/92) Installing perl-git (2.24.3-r0) (71/92) Installing git-perl (2.24.3-r0) (72/92) Installing linux-pam (1.3.1-r1) (73/92) Installing shadow (4.7-r1) (74/92) Installing libffi (3.2.1-r6) (75/92) Installing gdbm (1.13-r1) (76/92) Installing sqlite-libs (3.30.1-r2) (77/92) Installing python3 (3.8.2-r0) (78/92) Installing py3-meld3 (2.0.0-r1) (79/92) Installing py3-setuptools (42.0.2-r0) (80/92) Installing supervisor (4.1.0-r0) (81/92) Installing libevent (2.1.11-r0) (82/92) Installing tmux (3.0a-r1) (83/92) Installing encodings (1.0.5-r0) (84/92) Installing libfontenc (1.1.4-r0) (85/92) Installing mkfontscale (1.2.1-r1) (86/92) Installing ttf-dejavu (2.37-r1) (87/92) Installing tzdata (2020a-r0) (88/92) Installing xxd (8.2.0-r0) (89/92) Installing lua5.3-libs (5.3.5-r2) (90/92) Installing vim (8.2.0-r0) (91/92) Installing wget (1.20.3-r0) (92/92) Installing wqy-zenhei (0.9.47-r0) Executing busybox-1.31.1-r9.trigger Executing ca-certificates-20191127-r1.trigger Executing fontconfig-2.13.1-r2.trigger Executing mdocml-apropos-1.14.5-r1.trigger Executing mkfontscale-1.2.1-r1.trigger 2 errors; 325 MiB in 104 packages + true + echo 'export LANG=en_US.UTF-8' + apk del glibc-i18n + true + mkdir -p /usr/local/tomcat /usr/local/src/confdownload + curl -SL http://10.3.15.203:8899/public_packages/fish_greeting.fish -o /root/.config/fish/functions/fish_greeting.fish % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0 curl: (7) Failed to connect to 10.3.15.203 port 8899: Connection refused The command '/bin/sh -c set -x && sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/' /etc/apk/repositories && echo 'http://mirrors.aliyun.com/alpine/edge/testing' >> /etc/apk/repositories && apk update && apk add --no-cache --allow-untrusted --update-cache wget curl vim git perl make less bash bash-doc bash-completion tmux fish mdocml-apropos busybox-extras coreutils ca-certificates tzdata libtool gcc apk-tools netcat-openbsd bind-tools supervisor inotify-tools shadow openssh openssh-sftp-server ttf-dejavu fontconfig wqy-zenhei@edge wqy-zenhei && ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo "Asia/Shanghai" > /etc/timezone && sed -i -e 's/\/bin\/ash/\/bin\/bash/' /etc/passwd && echo ' PS1='\''\[\e[01;33m\][\h \u:\[\e[01;34m\]\w\[\e[01;33m\]]\[\e[00m\]\$ '\'' ; eval `dircolors -b` ; alias ls="ls --color=auto" ; alias l="ls -lah" ; alias ll="ls -lh" ; alias l.="ls -d .* --color=auto" ; alias mv="mv -i" ; alias rm="rm -i" ; ' >> /etc/profile && echo '. ~/.bashrc' > /root/.bash_profile && echo '. /etc/profile' > /root/.bashrc && echo 'set-option -g default-shell /usr/bin/fish' > /root/.tmux.conf && mkdir -p /root/.config/fish/functions && echo ' function fish_prompt ; if not set -q __fish_prompt_hostname ; set -g __fish_prompt_hostname (hostname) ; end ; set_color -o yellow ; echo -n -s "$USER" @ "$__fish_prompt_hostname" " " ; set_color -o blue ; echo -n (prompt_pwd) ; echo -n " # " ; set_color normal ; end ; alias l="ls -la" ; ' > /root/.config/fish/functions/fish_prompt.fish && ln -sf /bin/bash /bin/sh && echo 'hosts: files mdns4_minimal [NOTFOUND=return] dns mdns4' >> /etc/nsswitch.conf && ALPINE_GLIBC_BASE_DIR="$BASE_URL/public_packages/glibc/x86_64" && ALPINE_GLIBC_BASE_PACKAGE_FILENAME="$ALPINE_GLIBC_BASE_DIR/glibc-$ALPINE_GLIBC_PACKAGE_VERSION.apk" && ALPINE_GLIBC_BIN_PACKAGE_FILENAME="$ALPINE_GLIBC_BASE_DIR/glibc-bin-$ALPINE_GLIBC_PACKAGE_VERSION.apk" && ALPINE_GLIBC_I18N_PACKAGE_FILENAME="$ALPINE_GLIBC_BASE_DIR/glibc-i18n-$ALPINE_GLIBC_PACKAGE_VERSION.apk" && wget $ALPINE_GLIBC_BASE_PACKAGE_FILENAME && wget $ALPINE_GLIBC_BIN_PACKAGE_FILENAME && wget $ALPINE_GLIBC_I18N_PACKAGE_FILENAME && apk add --no-cache --allow-untrusted --force-overwrite "glibc-$ALPINE_GLIBC_PACKAGE_VERSION.apk" "glibc-bin-$ALPINE_GLIBC_PACKAGE_VERSION.apk" "glibc-i18n-$ALPINE_GLIBC_PACKAGE_VERSION.apk" && rm -rf *.apk && /usr/glibc-compat/bin/localedef --force --inputfile POSIX --charmap UTF-8 "$LANG" || true && echo "export LANG=$LANG" > /etc/profile.d/locale.sh && apk del glibc-i18n || true && mkdir -p $WORKDIR /usr/local/src/confdownload && curl -SL $BASE_URL/public_packages/fish_greeting.fish -o /root/.config/fish/functions/fish_greeting.fish && curl -SL $BASE_URL/public_packages/entrypoint.sh -o /usr/local/bin/entrypoint.sh && curl -SL $BASE_URL/public_packages/confdownload/$CONFCENTERDOWNLOAD -o /usr/local/src/confdownload/confcenterdownload && curl -SL $BASE_URL/public_packages/offline.sh -o /usr/local/bin/offline.sh && ln -sf /usr/local/src/confdownload/confcenterdownload /usr/local/bin/confcenterdownload && ln -sf /usr/local/bin/offline.sh /bin/offline.sh && curl -SL $BASE_URL/supervisor/supervisord.conf -o /etc/supervisord.conf && mkdir -p /etc/supervisor.d /etc/supervisor.user && curl -SL $BASE_URL/sftp/sshd_config -o /etc/ssh/sshd_config && curl -SL $BASE_URL/sftp/sftp-entrypoint.sh -o /usr/local/bin/sftp-entrypoint.sh && mkdir -p /etc/sftp.d && curl -SL $BASE_URL/sftp/bindmount.sh -o /etc/sftp.d/bindmount.sh && chmod +x /etc/sftp.d/bindmount.sh && sed -i 's/GROUP=1000/GROUP=100/' /etc/default/useradd && mkdir -p /var/run/sshd && rm -f /etc/ssh/ssh_host_*key* && printf 'sftp-entrypoint.sh $(env|grep SFTP|cut -d= -f2) \ncat > /etc/supervisor.d/sftp.ini <<EOF\n[program:sftp] \ncommand=/usr/sbin/sshd -D -e \npriority=999 \nredirect_stderr=true \nEOF\n' > /etc/supervisor.user/sftp.ini.sh && chmod +x /etc/supervisor.user/*.sh && mkdir -p /etc/config/download/ /usr/local/pinpoint-agent && curl -SL $BASE_URL/java/java_options.sh -o /usr/local/bin/java_options.sh && curl -SL $BASE_URL/java/arthas-boot.jar -o /usr/local/bin/arthas-boot.jar && curl -SL $BASE_URL/java/mount_app_file_log.sh -o /usr/bin/mount_app_file_log.sh && wget $BASE_URL/java/pinpoint-agent.tar.gz && tar -zxvf pinpoint-agent.tar.gz --strip-components=1 -C /usr/local/pinpoint-agent && rm -rf pinpoint-agent.tar.gz && curl -SL $BASE_URL/java/etc/authfile.properties -o /etc/config/download/authfile.properties && curl -SL $BASE_URL/java/etc/yhtauthfile.properties -o /etc/config/download/yhtauthfile.properties && mkdir -p /usr/share/fonts/song && cd /usr/share/fonts/song && wget $BASE_URL/font/ncc/song/song.zip && unzip song.zip && rm -f song.zip && mkfontscale && mkfontdir && fc-cache && cd - && mkdir -p /usr/share/fonts/MicrosoftYahei && cd /usr/share/fonts/MicrosoftYahei && wget $BASE_URL/font/ncc/yahei/yahei.zip && unzip yahei.zip && rm -f yahei.zip && mkfontscale && mkfontdir && fc-cache && cd - && mkdir -p $JAVA_HOME && curl -SL $BASE_URL/java/jdk-${JAVA_VERSION}-linux-x64.tar.gz -o java.tar.gz && tar -zxvf java.tar.gz --strip-components=1 -C $JAVA_HOME/ && rm -rf $JAVA_HOME/*src.zip $JAVA_HOME/lib/missioncontrol $JAVA_HOME/lib/visualvm $JAVA_HOME/lib/*javafx* $JAVA_HOME/jre/lib/ext/jfxrt.jar $JAVA_HOME/jre/bin/javaws $JAVA_HOME/jre/lib/javaws.jar $JAVA_HOME/jre/lib/desktop $JAVA_HOME/jre/plugin $JAVA_HOME/jre/lib/deploy* $JAVA_HOME/jre/lib/*javafx* $JAVA_HOME/jre/lib/*jfx* && rm -rf java.tar.gz* && curl -SL $BASE_URL/java/UnlimitedJCEPolicyJDK${JAVA_MAJOR}/local_policy.jar -o $JAVA_HOME/jre/lib/security/local_policy.jar && curl -SL $BASE_URL/java/UnlimitedJCEPolicyJDK${JAVA_MAJOR}/US_export_policy.jar -o $JAVA_HOME/jre/lib/security/US_export_policy.jar && sed -i 's/#crypto.policy=unlimited/crypto.policy=unlimited/g' /usr/local/java/jre/lib/security/java.security && curl -SL $BASE_URL/java/apache-tomcat-$TOMCAT_VERSION.tar.gz -o tomcat.tar.gz && tar -zxvf tomcat.tar.gz --strip-components=1 -C $CATALINA_HOME/ && rm -rf tomcat.tar.gz* bin/*.bat $CATALINA_HOME/webapps/* && echo 'export PATH="$PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin"' >> /etc/profile && sed -i '/tomcat.util.scan.StandardJarScanFilter.jarsToSkip=/a bootstrap.jar,commons-daemon.jar,tomcat-juli.jar,bcprov-*.jar,\\' $CATALINA_HOME/conf/catalina.properties && sed -i -e 's/<Connector port="8080"/& URIEncoding="UTF-8" maxPostSize="-1"/g' -e '/protocol="AJP\/1.3"/s/^/<!--/' -e '/protocol="AJP\/1.3"/s/$/-->/' -e '/pattern="%/s/.*/\t\tpattern="%{x-forwarded-for}i %h %l %u %t \"%r\" %s %b %{X-traceId}i %D" \/>/' -e '/<\/Host>/i \\t<Valve className="org.apache.catalina.valves.RemoteIpValve"\n\t\tremoteIpHeader="x-forwarded-for"\n\t\tproxiesHeader="x-forwarded-by"\n\t\tprotocolHeader="x-forwarded-proto"/>' -e '/<\/Host>/i \\t<Resources cachingAllowed="false" cacheMaxSize="0"/>' $CATALINA_HOME/conf/server.xml && ln -sf /usr/local/bin/entrypoint.sh $CATALINA_HOME/bin/entrypoint.sh && rm -rf $CATALINA_HOME/bin/*.bat $CATALINA_HOME/webapps/* && app_name=$(echo $BASE_IMAGE|cut -d':' -f1) && user_ini="/etc/supervisor.user/${app_name}.ini.sh" && printf 'cat > /etc/supervisor.d/tomcat.ini <<EOF\n[program:tomcat] \ncommand=/bin/bash -c "$@" \nenvironment=JAVA_OPTS="$JAVA_OPTS",JAVA_HOME="$JAVA_HOME" \ndirectory = $WORKDIR \npriority=1 \nredirect_stderr=true \nEOF\n' > $user_ini && chmod +x /etc/supervisor.user/*.sh && chmod +x /usr/local/bin/* && /bin/rm -rf /tmp/* /var/cache/apk/*' returned a non-zero code: 7 |
解决办法:
把淘宝源(mirrors.aliyun.com)换成中科大的源(mirrors.ustc.edu.cn)就好了
0 Comments