[3.12]修改为分步生成镜像的方式;更新脚本文件及Makefile文件

This commit is contained in:
2020-09-04 15:42:30 +08:00
parent 47bf6fd974
commit 152264f327
17 changed files with 436 additions and 70 deletions
+10 -2
View File
@@ -1,4 +1,12 @@
.git
.gitignore
README.md
LICENSE
./alpine
./Makefile
*.yml
*.yaml
./LICENSE
./README.md
./img
+1 -1
View File
@@ -1,4 +1,4 @@
*.DS_Store
.DS_Store
.AppleDouble
.LSOverride
+36 -50
View File
@@ -1,68 +1,54 @@
# Ver: 1.1 by Endial Fang (endial@126.com)
# Ver: 1.2 by Endial Fang (endial@126.com)
#
FROM colovu/alpine-builder as builder
FROM colovu/abuilder as builder
# ARG参数使用"--build-arg"指定,如 "--build-arg apt_source=tencent"
# sources.list 可使用版本:default / tencent / ustc / aliyun / huawei
ARG apt_source=default
ARG apt_source=tencent
# 编译镜像时指定本地服务器地址,如 "--build-arg local_url=http://172.29.14.108/dist-files/"
# 编译镜像时指定用于加速的本地服务器地址
ARG local_url=""
ARG gosu_ver=1.12
RUN set -eux; \
dpkgArch="$(dpkg --print-architecture | awk -F- '{ print $NF }')"; \
if [ -n "${local_url}" ]; then \
wget -O /usr/local/bin/gosu "${local_url}/gosu/gosu-${dpkgArch}"; \
wget -O /usr/local/bin/gosu.asc "${local_url}/gosu/gosu-${dpkgArch}.asc"; \
else \
wget -O /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/${gosu_ver}/gosu-$dpkgArch"; \
wget -O /usr/local/bin/gosu.asc "https://github.com/tianon/gosu/releases/download/${gosu_ver}/gosu-$dpkgArch.asc"; \
fi; \
\
# 安装软件包需要使用的GPG证书
export GPG_KEYS="0xB42F6819007F00F88E364FD4036A9C25BF357DD4"; \
export GNUPGHOME="$(mktemp -d)"; \
for key in ${GPG_KEYS}; do \
gpg --batch --keyserver ha.pool.sks-keyservers.net --recv-keys "${key}"|| \
gpg --batch --keyserver pgp.mit.edu --recv-keys "${key}" || \
gpg --batch --keyserver keys.gnupg.net --recv-keys "${key}" || \
gpg --batch --keyserver keyserver.pgp.com --recv-keys "${key}"; \
done; \
gpg --batch --verify "/usr/local/bin/gosu.asc" "/usr/local/bin/gosu"; \
command -v gpgconf > /dev/null && gpgconf --kill all; \
\
chmod +x /usr/local/bin/gosu; \
\
appVersion=1.12; \
appName=gosu-"$(dpkg --print-architecture | awk -F- '{ print $NF }')"; \
appKeys="0xB42F6819007F00F88E364FD4036A9C25BF357DD4"; \
appUrls=" \
${local_url}/gosu \
https://github.com/tianon/gosu/releases/download/${appVersion} \
"; \
download_pkg install ${appName} "${appUrls}" -g "${appKeys}"; \
chmod +x /usr/local/bin/${appName}; \
# 验证安装的应用软件是否正常
gosu nobody true;
${appName} nobody true;
# 镜像生成
# 镜像生成 ========================================================================
FROM alpine:3.12
ARG apt_source=default
LABEL \
"Version"="v3.12" \
"Description"="Alpine image for Alpine 3.12." \
"Dockerfile"="https://github.com/colovu/docker-alpine" \
"Vendor"="Endial Fang (endial@126.com)"
LABEL "Version"="v3.12" \
"Description"="Alpine image for Alpine 3.12." \
"Dockerfile"="https://github.com/colovu/docker-alpine" \
"Vendor"="Endial Fang (endial@126.com)"
COPY sources/* /etc/apk/
COPY prebuilds /
RUN select_source ${apt_source}
RUN install_pkg bash tini tzdata; \
cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime; \
apk del tzdata;
RUN apk add --no-cache libintl; \
apk add --no-cache --virtual .locale_build git cmake make musl-dev gcc gettext-dev; \
git clone https://gitlab.com/rilian-la-te/musl-locales; \
cd musl-locales && cmake -DLOCALE_PROFILE=OFF -DCMAKE_INSTALL_PREFIX:PATH=/usr . && make && make install; \
cd .. && rm -r musl-locales; \
apk del .locale_build; \
rm -rf /var/cache/apk/*;
RUN set -eux; \
cp /etc/apk/repositories.${apt_source} /etc/apk/repositories; \
\
apk update; \
apk upgrade --no-cache; \
apk add --no-cache bash tini; \
\
rm -rf /var/cache/apk/*; \
rm -rf /root/.cache; \
rm -rf /tmp/*;
COPY --from=builder /usr/local/bin/gosu-amd64 /usr/local/bin/gosu
COPY --from=builder /usr/local/bin/gosu /usr/local/bin/
WORKDIR /
WORKDIR /srv/data
ENV LANG=en_US.UTF-8 \
LANGUAGE=en_US.UTF-8 \
LC_ALL=en_US.UTF-8
CMD []
+1 -1
View File
@@ -1,6 +1,6 @@
MIT License
Copyright (c) 2017 endial
Copyright (c) 2020 Endial Fang (endial@126.com)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
+6 -3
View File
@@ -1,15 +1,18 @@
# Ver: 1.3 by Endial Fang (endial@126.com)
# Ver: 1.4 by Endial Fang (endial@126.com)
#
# 当前 Docker 镜像的编译脚本
app_name := colovu/alpine
# 生成镜像TAG,类似:<镜像名>:<分支名>-<Git ID> 或 <镜像名>:latest-<年月日>-<时分秒>
# 生成镜像TAG,类似:
# <镜像名>:<分支名>-<Git ID> # Git 仓库且无文件修改直接编译
# <镜像名>:<分支名>-<年月日>-<时分秒> # Git 仓库有文件修改后的编译
# <镜像名>:latest-<年月日>-<时分秒> # 非 Git 仓库编译
current_subversion:=$(shell if [[ -d .git ]]; then git rev-parse --short HEAD; else date +%y%m%d-%H%M%S; fi)
current_tag:=$(shell if [[ -d .git ]]; then git rev-parse --abbrev-ref HEAD | sed -e 's/master/latest/'; else echo "latest"; fi)-$(current_subversion)
# Sources List: default / tencent / ustc / aliyun / huawei
build-arg:=--build-arg apt_source=tencent
build-arg:=--build-arg apt_source=aliyun
# 设置本地下载服务器路径,加速调试时的本地编译速度
local_ip:=`ifconfig -a|grep inet|grep -v 127.0.0.1|grep -v inet6|awk '{print $$2}'|tr -d "addr:"`
+36 -13
View File
@@ -1,26 +1,42 @@
# 简介
# Alpine
简单、高性能、小体积的基础系统镜像,本镜像基于[Alpine系统](http://www.alpinelinux.org)。
简单、高性能、小体积的基础 [Alpine](http://www.alpinelinux.org) 系统镜像,用于为其他应用提供基础镜像
使用说明可参照:[官方说明](https://wiki.alpinelinux.org)
**版本信息:**
- 3.12、latest
- 3.11
**镜像信息:**
* 镜像地址:colovu/alpine:latest
* 依赖镜像:alpine:TAG
* 依赖镜像:alpine:3.12
**与官方镜像差异:**
- 增加 `default、tencent、ustc、aliyun、huawei` 源配置文件,可在编译时通过 `ARG` 变量`apt_source`进行选择
- 增加常用 Shell 脚本文件
- 更新已安装的软件包
- 增加`locales`,并设置默认编码格式为`en_US.utf8`
- 增加bash
- 增加gosu
- 设置默认时区信息为 `Asia/Shanghai`
## **TL;DR**
Docker 快速启动命令:
```shell
$ docker run -it colovu/alpine /bin/bash
```
---
@@ -29,34 +45,35 @@
**下载镜像:**
```shell
docker pull colovu/alpine:latest
$ docker pull colovu/alpine:latest
```
- latest:为镜像的TAG,可针对性选择不同的TAG进行下载
- latest:为镜像的 TAG,可针对性选择不同的 TAG 进行下载
- 不指定 TAG 时,默认下载 latest 镜像
**查看镜像:**
```shell
docker images
$ docker images
```
**命令行方式运行容器:**
```shell
docker run -it --rm colovu/alpine:latest /bin/sh
$ docker run -it --rm colovu/alpine:latest /bin/bash
```
- `-it`:使用交互式终端启动容器
- `--rm`:退出时删除容器
- `colovu/alpine:latest`:包含版本信息的镜像名称
- `/bin/sh`:在容器中执行`/bin/sh`命令;如果不执行命令,容器会在启动后立即结束并退出。
- `/bin/bash`:在容器中执行`/bin/bash`命令;如果不执行命令,容器会在启动后立即结束并退出。
以该方式启动后,直接进入容器的命令行操作界面。如果需要退出,直接使用命令`exit`退出。
**后台方式运行容器:**
```shell
docker run -d --name test colovu/alpine:latest tail /dev/stderr
$ docker run -d --name test colovu/alpine:latest tail /dev/stderr
```
- `--name test`:命名容器为`test`
@@ -69,12 +86,18 @@ docker run -d --name test colovu/alpine:latest tail /dev/stderr
以该方式启动后,如果想进入容器,可以使用以下命令:
```shell
docker exec -it test /bin/sh
$ docker exec -it test /bin/bash
```
- `-it`:使用交互式执行
- `test`:之前启动的容器名
- `/bin/sh`:执行的命令
- `/bin/bash`:执行的命令
## 更新记录
- 3.12、latest
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2020 Endial Fang (endial@126.com)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+106
View File
@@ -0,0 +1,106 @@
#!/bin/bash
# Ver: 1.0 by Endial Fang (endial@126.com)
[[ ${ENV_DEBUG:-false} = true ]] && set -x
MODULE="$(basename "$0")"
RESET='\033[0m'
BOLD='\033[1m'
# 前景色
BLACK='\033[38;5;0m'
RED='\033[38;5;1m'
GREEN='\033[38;5;2m'
YELLOW='\033[38;5;3m'
BLUE='\033[38;5;4m'
MAGENTA='\033[38;5;5m'
CYAN='\033[38;5;6m'
WHITE='\033[38;5;7m'
# 背景色
ON_BLACK='\033[48;5;0m'
ON_RED='\033[48;5;1m'
ON_GREEN='\033[48;5;2m'
ON_YELLOW='\033[48;5;3m'
ON_BLUE='\033[48;5;4m'
ON_MAGENTA='\033[48;5;5m'
ON_CYAN='\033[48;5;6m'
ON_WHITE='\033[48;5;7m'
# 函数列表
# 打印输出到 STDERR 设备
stderr_print() {
printf "%b\\n" "${*}" >&2
}
# 输出实际日志信息
# 参数:
# $1 - 日志类型
# $2 - 日志信息
LOG() {
stderr_print "${ENV_DEBUG:+${CYAN}${MODULE:-} ${MAGENTA}$(date "+%T.%2N ")}${RESET}${*}"
}
# 输出调试类日志信息,尽量少使用
# 参数:
# $1 - 日志类型
# $2 - 日志信息
LOG_D() {
local -r bool="${ENV_DEBUG:-false}"
shopt -s nocasematch
if [[ "$bool" = 1 || "$bool" =~ ^(yes|true)$ ]]; then
LOG "${BLUE}DEBUG${RESET} ==> ${*}"
fi
}
# 输出提示信息类日志信息
# 参数:
# $1 - 日志类型
# $2 - 日志信息
LOG_I() {
LOG "${GREEN}INFO ${RESET} ==> ${*}"
}
# 输出警告类日志信息至sterr
# 参数:
# $1 - 日志类型
# $2 - 日志信息
LOG_W() {
LOG "${YELLOW}WARN ${RESET} ==> ${*}"
}
# 输出错误类日志信息至sterr,并退出脚本
# 参数:
# $1 - 日志类型
# $2 - 日志信息
LOG_E() {
LOG "${RED}ERROR${RESET} ==> ${*}"
}
# 打印包含包含Logo的欢迎信息
# 全局变量:
# APP_NAME
print_image_welcome_page() {
[[ -n "${APP_NAME}" ]] && github_url="/docker-${APP_NAME}"
LOG_I ' ____ _ '
LOG_I ' / ___|___ | | _____ ___ _ '
LOG_I '| | / _ \| |/ _ \ \ / / | | | '"Docker : ${BOLD}${APP_NAME:-undefined}${RESET}"
LOG_I '| |__| (_) | | (_) \ V /| |_| | '"Version: ${BOLD}${APP_VERSION:-0.0}${RESET}"
LOG_I ' \____\___/|_|\___/ \_/ \__,_| '"PowerBy: ${BOLD}Endial@126.com${RESET}"
LOG_D " Project Repo: https://github.com/colovu/${github_url}"
LOG_I ""
}
# 根据需要打印欢迎信息
# 全局变量:
# ENV_DISABLE_WELCOME_MESSAGE
# APP_NAME
docker_print_welcome() {
if [[ "$(id -u)" = "0" ]]; then
print_image_welcome_page
fi
}
+5
View File
@@ -0,0 +1,5 @@
#!/bin/bash
# Ver: 1.0 by Endial Fang (endial@126.com)
. /usr/local/scripts/functions
+157
View File
@@ -0,0 +1,157 @@
#!/bin/bash
# shell 执行参数,分别为 -e(命令执行错误则退出脚本) -u(变量未定义则报错) -x(打印实际待执行的命令行)
. /usr/local/scripts/functions
print_usage() {
LOG "Usage: download_pkg <COMMAND> <PACKAGE-NAME> \"<URLS>\" [OPTIONS]"
LOG ""
LOG "Download and install Third-Part packages"
LOG ""
LOG "Commands:"
LOG " install Download and install a package."
LOG " unpack Download and unpack a package."
LOG ""
LOG "Options:"
LOG " -g, --checkpgp Package release bucket."
LOG " -s, --checksum SHA256 verification checksum."
LOG " -h, --help Show this help message and exit."
LOG ""
LOG "PACKAGE-NAME: Name with extern name"
LOG "URLS: String with URL list"
LOG ""
LOG "Examples:"
LOG " - Unpack package"
LOG " \$ download_pkg unpack redis-5.0.8.tar.gz \"http://download.redis.io/releases/\""
LOG ""
LOG " - Verify and Install package"
LOG " \$ download_pkg install redis-5.0.8.tar.gz \"http://download.redis.io/releases/\" --checksum 42cf86a114d2a451b898fcda96acd4d01062a7dbaaad2801d9164a36f898f596"
LOG ""
}
check_pgp() {
local name_asc=${1:?missing asc file name}
local name=${2:?missing file name}
local keys="${3:?missing key id}"
GNUPGHOME="$(mktemp -d)"
if which gpg >/dev/null 2>&1; then
for key in $keys; do
gpg --batch --keyserver ha.pool.sks-keyservers.net --recv-keys "${key}" ||
gpg --batch --keyserver pgp.mit.edu --recv-keys "${key}" ||
gpg --batch --keyserver keys.gnupg.net --recv-keys "${key}" ||
gpg --batch --keyserver keyserver.pgp.com --recv-keys "${key}";
done
gpg --batch --verify "$name_asc" "$name"
command -v gpgconf > /dev/null && gpgconf --kill all
fi
}
# 获取并解析参数
ARGS=$(getopt -o g:s:h -l "checkpgp:,checksum:,help" -n "download-pkg" -- "$@")
if [ $? -ne 0 ];
then
exit 1
fi
eval set -- "$ARGS";
while true; do
case "$1" in
-g|--checkpgp)
shift
if [ -n "$1" ]; then
PACKAGE_KEYS=$1
shift
fi
;;
-s|--checksum)
shift
if [ -n "$1" ]; then
PACKAGE_SHA256=$1
shift
fi
;;
-h|--help)
print_usage
exit 0
;;
--)
shift
break
;;
esac
done
# 检测输入的命令是否合法
case "$1" in
install|unpack) ;;
*)
error "Unrecognized command: $1"
print_usage
exit 1
;;
esac
# 检测输入参数是否足够,需要至少提供软件包名称 及 下载路径
if [ $# -lt 3 ]; then
print_usage
exit 1
fi
INSTALL_ROOT=/usr/local
CACHE_ROOT=/tmp
PACKAGE="$2"
PACKAGE_URLS=$3
cd $INSTALL_ROOT
LOG_I "Downloading $PACKAGE package"
for url in $PACKAGE_URLS; do
LOG_D "Try $url/$PACKAGE"
if wget -O "$CACHE_ROOT/$PACKAGE" "$url/$PACKAGE" && [ -s "$CACHE_ROOT/$PACKAGE" ]; then
if [ -n "$PACKAGE_KEYS" ]; then
wget -O "$CACHE_ROOT/$PACKAGE.asc" "$url/$PACKAGE.asc"
if [ ! -e "$CACHE_ROOT/$PACKAGE.asc" ]; then
wget -O "$CACHE_ROOT/$PACKAGE.asc" "$url/$PACKAGE.sig"
fi
fi
success=1
break
fi
done
if [ "$PACKAGE_SHA256" ]; then
LOG_I "Verifying package integrity"
echo "$PACKAGE_SHA256 *$CACHE_ROOT/$PACKAGE" | sha256sum -c -
fi
if [ -e "$CACHE_ROOT/$PACKAGE.asc" ]; then
LOG_I "Verifying package with PGP"
check_pgp "$CACHE_ROOT/$PACKAGE.asc" "$CACHE_ROOT/$PACKAGE" "$PACKAGE_KEYS"
fi
# If the tarball has too many files, it can trigger a bug
# in overlayfs when using tar. Install bsdtar in the container image
# to workaround it. As the overhead is too big (~40 MB), it is not added by
# default. Source: https://github.com/coreos/bugs/issues/1095
# 安装或解压软件
case "$1" in
install)
LOG_I "Installing $PACKAGE"
cp $CACHE_ROOT/$PACKAGE /usr/local/bin/
;;
unpack)
if ! tar tzf $CACHE_ROOT/$PACKAGE >/dev/null 2>&1; then
LOG_E "Invalid or corrupt '$PACKAGE' package."
exit 1
fi
LOG_I "Unpacking $PACKAGE"
if which bsdtar >/dev/null 2>&1; then
bsdtar -xf $CACHE_ROOT/$PACKAGE
else
tar xzf $CACHE_ROOT/$PACKAGE
fi
;;
esac
+51
View File
@@ -0,0 +1,51 @@
#!/bin/sh
# shell 执行参数,分别为 -e(命令执行错误则退出脚本) -u(变量未定义则报错) -x(打印实际待执行的命令行)
set -eux
print_usage() {
echo "Usage: install_pkg <PACKAGE-NAME>"
echo ""
echo "Download and install packages"
echo ""
echo "Options:"
echo " -h, --help Show this help message and exit."
echo ""
echo "Examples:"
echo " - Unpack package"
echo " \$ install_pkg bash curl"
echo ""
}
if [ $# -lt 1 ]; then
print_usage
exit 1
fi
case "$1" in
-h|--help)
print_usage
exit 0
;;
esac
retry=0
max=2
until [ $retry -gt $max ]; do
set +e
(
apk update --no-cache &&
apk upgrade --no-cache &&
apk add --no-cache "$@"
)
CODE=$?
set -e
if [ $CODE -eq 0 ]; then
break
fi
if [ $retry -eq $max ]; then
exit $CODE
fi
echo "APK failed, retrying"
retry=$(($retry + 1))
done
rm -r /var/cache/apk/* /root/.cache /tmp/* || :
+6
View File
@@ -0,0 +1,6 @@
#!/bin/sh
# Ver: 1.0 by Endial Fang (endial@126.com)
#
# shell 执行参数,分别为 -e(命令执行错误则退出脚本) -u(变量未定义则报错) -x(打印实际待执行的命令行)
set -eux
cp /etc/apk/repositories.${1:-default} /etc/apk/repositories