From 4cc361b29d9a681deefcff2a0657f04790168298 Mon Sep 17 00:00:00 2001 From: Endial Fang Date: Mon, 19 Jul 2021 15:35:03 +0800 Subject: [PATCH] =?UTF-8?q?[feat:12.4]=E6=9B=B4=E6=96=B0=E4=BD=BF=E7=94=A8?= =?UTF-8?q?=E6=96=B0=E7=9A=84=E7=BC=96=E8=AF=91=E8=84=9A=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 121 +++++++++++------- README.md | 73 +++++++---- .../bin/{comm-postgresql.sh => common.sh} | 8 +- customer/usr/local/bin/entry.sh | 38 +++--- .../local/bin/{comm-env.sh => environment.sh} | 3 + customer/usr/local/bin/init.sh | 15 +-- customer/usr/local/bin/run.sh | 24 ++-- customer/usr/local/bin/setup.sh | 24 ++-- customer/usr/sbin/create_user | 10 +- customer/usr/sbin/prepare_env | 6 +- docker-compose.yml | 7 +- 11 files changed, 192 insertions(+), 137 deletions(-) rename customer/usr/local/bin/{comm-postgresql.sh => common.sh} (99%) rename customer/usr/local/bin/{comm-env.sh => environment.sh} (98%) diff --git a/Dockerfile b/Dockerfile index 0e21ec8..237a8ee 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,18 +1,31 @@ -# Ver: 1.4 by Endial Fang (endial@126.com) +# Ver: 1.8 by Endial Fang (endial@126.com) # -# 预处理 ========================================================================= -ARG registry_url="registry.cn-shenzhen.aliyuncs.com" -FROM ${registry_url}/colovu/dbuilder as builder +# 可变参数 ======================================================================== -# sources.list 可使用版本:default / tencent / ustc / aliyun / huawei +# 设置当前应用名称及版本 +ARG app_name=postgresql +ARG app_version=12.4 + +# 设置默认仓库地址,默认为 阿里云 仓库 +ARG registry_url="registry.cn-shenzhen.aliyuncs.com" + +# 设置 apt-get 源:default / tencent / ustc / aliyun / huawei ARG apt_source=aliyun # 编译镜像时指定用于加速的本地服务器地址 ARG local_url="" -ENV APP_NAME=postgresql \ - APP_VERSION=12.4 + +# 0. 预处理 ====================================================================== +FROM ${registry_url}/colovu/dbuilder as builder + +# 声明需要使用的全局可变参数 +ARG app_name +ARG app_version +ARG registry_url +ARG apt_source +ARG local_url # 选择软件包源(Optional),以加速后续软件包安装 RUN select_source ${apt_source}; @@ -21,19 +34,22 @@ RUN select_source ${apt_source}; RUN install_pkg bison flex libedit-dev libxml2-dev libxslt-dev zlib1g-dev libreadline-dev uuid-dev \ libperl-dev libicu-dev libxslt1-dev libssl-dev libldap2-dev libkrb5-dev libpam0g-dev libselinux1-dev; +# 设置工作目录 +WORKDIR /tmp + # 下载并解压软件包 RUN set -eux; \ - appName="${APP_NAME}-${APP_VERSION}.tar.bz2"; \ + appName="${app_name}-${app_version}.tar.bz2"; \ sha256="bee93fbe2c32f59419cb162bcc0145c58da9a8644ee154a30b9a5ce47de606cc"; \ - [ ! -z ${local_url} ] && localURL=${local_url}/${APP_NAME}; \ + [ ! -z ${local_url} ] && localURL=${local_url}/${app_name}; \ appUrls="${localURL:-} \ - https://ftp.postgresql.org/pub/source/v${APP_VERSION} \ + https://ftp.postgresql.org/pub/source/v${app_version} \ "; \ download_pkg unpack ${appName} "${appUrls}" -s "${sha256}"; -# 源码编译: 编译后将配置文件模板拷贝至 /usr/local/${APP_NAME}/share/${APP_NAME} 中 +# 源码编译 RUN set -eux; \ - APP_SRC="/usr/local/${APP_NAME}-${APP_VERSION}"; \ + APP_SRC="/tmp/${app_name}-${app_version}"; \ cd ${APP_SRC}; \ \ # update "DEFAULT_PGSOCKET_DIR" to "/var/run/postgresql" (matching Debian) @@ -49,7 +65,7 @@ RUN set -eux; \ # configure options taken from: # https://anonscm.debian.org/cgit/pkg-postgresql/postgresql.git/tree/debian/rules?h=9.5 ./configure \ - --prefix=/usr/local/${APP_NAME} \ + --prefix=/usr/local/${app_name} \ --build="$gnuArch" \ --enable-integer-datetimes \ --enable-thread-safety \ @@ -84,77 +100,90 @@ RUN set -eux; \ # 删除编译生成的多余文件 RUN set -eux; \ find /usr/local -name '*.a' -delete; \ - rm -rf /usr/local/${APP_NAME}/include; + rm -rf /usr/local/${app_name}/include; -# 检测并生成依赖文件记录;repmgr 相关资源也是放置在 ${APP_NAME} 路径下 +# 检测并生成依赖文件记录 RUN set -eux; \ - find /usr/local/${APP_NAME} -type f -executable -exec ldd '{}' ';' | \ + find /usr/local/${app_name} -type f -executable -exec ldd '{}' ';' | \ awk '/=>/ { print $(NF-1) }' | \ sort -u | \ - xargs -r dpkg-query --search | \ + xargs -r dpkg-query --search 2>/dev/null | \ cut -d: -f1 | \ - sort -u >/usr/local/${APP_NAME}/runDeps; + sort -u >/usr/local/${app_name}/runDeps; -# 镜像生成 ======================================================================== -FROM ${registry_url}/colovu/debian:10 +# 1. 生成镜像 ===================================================================== +FROM ${registry_url}/colovu/debian:buster -# sources.list 可使用版本:default / tencent / ustc / aliyun / huawei -ARG apt_source=aliyun +# 声明需要使用的全局可变参数 +ARG app_name +ARG app_version +ARG registry_url +ARG apt_source +ARG local_url -# 编译镜像时指定用于加速的本地服务器地址 -ARG local_url="" - -ENV APP_NAME=postgresql \ - APP_USER=postgres \ +# 镜像所包含应用的基础信息,定义环境变量,供后续脚本使用 +ENV APP_NAME=${app_name} \ APP_EXEC=postgres \ - APP_VERSION=12.4 + APP_VERSION=${app_version} ENV APP_HOME_DIR=/usr/local/${APP_NAME} \ APP_DEF_DIR=/etc/${APP_NAME} -ENV PATH="${APP_HOME_DIR}/bin:${APP_HOME_DIR}/sbin:${PATH}" \ +ENV PATH="${APP_HOME_DIR}/sbin:${APP_HOME_DIR}/bin:${PATH}" \ LD_LIBRARY_PATH="${APP_HOME_DIR}/lib" LABEL \ - "Version"="v${APP_VERSION}" \ - "Description"="Docker image for ${APP_NAME}(v${APP_VERSION})." \ - "Dockerfile"="https://github.com/colovu/docker-${APP_NAME}" \ + "Version"="v${app_version}" \ + "Description"="Docker image for ${app_name}(v${app_version})." \ + "Dockerfile"="https://github.com/colovu/docker-${app_name}" \ "Vendor"="Endial Fang (endial@126.com)" +# 从预处理过程中拷贝软件包(Optional),可以使用阶段编号或阶段命名定义来源 +COPY --from=0 /usr/local/${APP_NAME} /usr/local/${APP_NAME} +# 拷贝应用使用的客制化脚本,并创建对应的用户及数据存储目录 +COPY customer / +RUN set -eux; \ + prepare_env; -# 选择软件包源 +# 选择软件包源(Optional),以加速后续软件包安装 RUN select_source ${apt_source} -# 从预处理过程中拷贝软件包(Optional) -COPY --from=builder /usr/local/${APP_NAME}/ /usr/local/${APP_NAME} - # 安装依赖的软件包及库(Optional) RUN install_pkg `cat /usr/local/${APP_NAME}/runDeps`; -COPY customer / -RUN create_user && prepare_env - # 执行预处理脚本,并验证安装的软件包 RUN set -eux; \ override_file="/usr/local/overrides/overrides-${APP_VERSION}.sh"; \ [ -e "${override_file}" ] && /bin/bash "${override_file}"; \ - gosu ${APP_USER} ${APP_EXEC} --version ; \ - gosu --version; + ${APP_EXEC} --version ; # 默认提供的数据卷 VOLUME ["/srv/conf", "/srv/data", "/srv/datalog", "/srv/cert", "/var/log"] -# 默认使用gosu切换为新建用户启动,必须保证端口在1024之上 +# 默认non-root用户启动,必须保证端口在1024之上 EXPOSE 5432 +# 关闭基础镜像的健康检查 +#HEALTHCHECK NONE + # 应用健康状态检查 +#HEALTHCHECK --interval=30s --timeout=30s --retries=3 \ +# CMD curl -fs http://localhost:8080/ || exit 1 +#HEALTHCHECK --interval=10s --timeout=10s --retries=3 \ +# CMD netstat -ltun | grep 8080 HEALTHCHECK CMD PGPASSWORD="${PG_POSTGRES_PASSWORD:-${PG_PASSWORD}}" psql -h 127.0.0.1 -d postgres -U postgres -At -c "select version();" || exit 1 -# 容器初始化命令,默认存放在:/usr/local/bin/entry.sh -ENTRYPOINT ["entry.sh"] +# 使用 non-root 用户运行后续的命令 +USER 1001 -# 应用程序的服务命令,必须使用非守护进程方式运行。如果使用变量,则该变量必须在运行环境中存在(ENV可以获取) -CMD ["${APP_EXEC}", "--config-file=${PG_CONF_FILE}", "--hba_file=${PG_HBA_FILE}"] +# 设置工作目录 +WORKDIR /srv/data + +# 容器初始化命令 +ENTRYPOINT ["/usr/local/bin/entry.sh"] + +# 应用程序的启动命令,必须使用非守护进程方式运行 +CMD ["/usr/local/bin/run.sh"] diff --git a/README.md b/README.md index b11aef3..b8746ce 100644 --- a/README.md +++ b/README.md @@ -8,13 +8,17 @@ **版本信息:** -- 12、latest +- 12.4、latest - 10 **镜像信息:** -* 镜像地址:registry.cn-shenzhen.aliyuncs.com/colovu/postgres:12 +* 镜像地址: + - 阿里云: registry.cn-shenzhen.aliyuncs.com/colovu/postgres:12.4 + - DockerHub:colovu/postgres:12.4 + * 依赖镜像:debian:buster +> 后续相关命令行默认使用`[Docker Hub](https://hub.docker.com)`镜像服务器做说明 ## TL;DR @@ -22,13 +26,26 @@ Docker 快速启动命令: ```shell -$ docker run -d -e ALLOW_ANONYMOUS_LOGIN=yes registry.cn-shenzhen.aliyuncs.com/colovu/postgres:12 +# 从 Docker Hub 服务器下载镜像并启动 +$ docker run -d -e ALLOW_ANONYMOUS_LOGIN=yes --name imgname colovu/colovu/postgres:12.4 + +# 从 Aliyun 服务器下载镜像并启动 +$ docker run -d -e ALLOW_ANONYMOUS_LOGIN=yes registry.cn-shenzhen.aliyuncs.com/colovu/postgres:12.4 ``` +- `colovu/imgname:`:镜像名称及版本标签;标签不指定时默认使用`latest` + + + + Docker-Compose 快速启动命令: ```shell -$ curl -sSL https://raw.githubusercontent.com/colovu/docker-postgres/master/docker-compose.yml > docker-compose.yml +# 从 Gitee 下载 Compose 文件 +$ curl -sSL -o https://gitee.com/colovu/docker-postgres/raw/master/docker-compose.yml + +# 从 Github 下载 Compose 文件 +$ curl -sSL https://raw.githubusercontent.com/colovu/docker-postgres/master/docker-compose.yml $ docker-compose up -d ``` @@ -94,7 +111,7 @@ services: #### 通过默认方式启动 ```shell -$ docker run --name some-postgres -e POSTGRES_PASSWORD=mysecretpassword -d registry.cn-shenzhen.aliyuncs.com/colovu/postgres:12 +$ docker run --name some-postgres -e POSTGRES_PASSWORD=mysecretpassword -d colovu/postgres:12.4 ``` - 由容器执行默认的`entrypoint.sh`脚本,并生成默认的用户及数据文件 @@ -106,7 +123,7 @@ $ docker run --name some-postgres -e POSTGRES_PASSWORD=mysecretpassword -d regis #### 通过`psql`命令方式启动 ```shell -$ docker run -it --rm --network some-network registry.cn-shenzhen.aliyuncs.com/colovu/postgres:12 psql -h some-postgres -U postgres +$ docker run -it --rm --network some-network colovu/postgres:12.4 psql -h some-postgres -U postgres psql (10.12.0) Type "help" for help. @@ -131,7 +148,7 @@ version: '3.1' services: db: - image: registry.cn-shenzhen.aliyuncs.com/colovu/postgres:12 + image: colovu/postgres:12.4 restart: always environment: POSTGRES_PASSWORD: example @@ -217,7 +234,7 @@ $ docker run -d \ -e POSTGRES_PASSWORD=mysecretpassword \ -e PGDATA=/var/lib/postgresql/data/pgdata \ -v /custom/mount:/var/lib/postgresql/data \ - colovu/postgres:latest + colovu/postgres:12.4 ``` 该变量并不是为Docker定义的数据卷,而是由`postgres`服务本身使用(参考 [PostgreSQL docs](https://www.postgresql.org/docs/11/app-postgres.html#id-1.9.5.14.7)),entrypoing.sh脚本只是传输该值。 @@ -229,7 +246,7 @@ $ docker run -d \ 作为敏感信息通过环境变量传输的可选替代方案,可以增加`_FILE`在部分环境变量末尾,以使容器的初始化脚本通过加载文件的方式,获取相关变量。例如,可以通过加载文件的方式加载密码: ```shell -$ docker run --name some-postgres -e POSTGRES_PASSWORD_FILE=/run/secrets/postgres-passwd -d colovu/postgres:latest +$ docker run --name some-postgres -e POSTGRES_PASSWORD_FILE=/run/secrets/postgres-passwd -d colovu/postgres:12.4 ``` 支持该方式的变量为: `POSTGRES_INITDB_ARGS`, `POSTGRES_PASSWORD`, `POSTGRES_USER`, `POSTGRES_DB`。 @@ -254,19 +271,19 @@ $ docker run --name some-postgres -e POSTGRES_PASSWORD_FILE=/run/secrets/postgre ```shell $ # 获取配置文件模板,存储为当前目录的my-postgres.conf - $ docker run -i --rm colovu/postgres:latest cat /usr/share/postgresql/postgresql.conf.sample > my-postgres.conf + $ docker run -i --rm colovu/postgres:12.4 cat /usr/share/postgresql/postgresql.conf.sample > my-postgres.conf $ # 个性化修改配置信息,至少增加`listen_addresses='*'`以确保其他容器可以访问 $ echo "listen_addresses='*'" >> my-postgres.conf $ # 使用定制后的配置文件启动容器 - $ docker run -d --name some-postgres -v "$PWD/my-postgres.conf":/etc/postgresql/postgresql.conf -e POSTGRES_PASSWORD=mysecretpassword colovu/postgres:latest -c 'config_file=/etc/postgresql/postgresql.conf' + $ docker run -d --name some-postgres -v "$PWD/my-postgres.conf":/etc/postgresql/postgresql.conf -e POSTGRES_PASSWORD=mysecretpassword colovu/postgres:12.4 -c 'config_file=/etc/postgresql/postgresql.conf' ``` - 在命令行中设置相应参数。entrypoint.sh基本会将所有的启动时传递给Docker的配置参数传递给postgres服务进程。从官方 [docs](https://www.postgresql.org/docs/current/static/app-postgres.html)文档可以看出,所有在 `.conf`文件中的配置项都可以使用`-c`进行设置。 ```shell - $ docker run -d --name some-postgres -e POSTGRES_PASSWORD=mysecretpassword colovu/postgres:latest -c 'shared_buffers=256MB' -c 'max_connections=200' + $ docker run -d --name some-postgres -e POSTGRES_PASSWORD=mysecretpassword colovu/postgres:12.4 -c 'shared_buffers=256MB' -c 'max_connections=200' ``` > 注意:配置文件至少修改`listen_addresses='*'`以确保其他容器可以访问 @@ -281,10 +298,10 @@ $ docker run --name some-postgres -e POSTGRES_PASSWORD_FILE=/run/secrets/postgre 导出模板文件: ```shell -docker run -i --rm colovu/postgres:latest cat /usr/share/postgresql/postgresql.conf.sample > my-postgres.conf +docker run -i --rm colovu/postgres:12.4 cat /usr/share/postgresql/postgresql.conf.sample > my-postgres.conf ``` -- 使用的镜像:colovu/postgres-ubuntu:v10.12 +- 使用的镜像:colovu/postgres:12.4 - 原始文件:/usr/share/postgresql/postgresql.conf.sample - 导出后文件:my-postgres.conf @@ -295,7 +312,7 @@ docker run -i --rm colovu/postgres:latest cat /usr/share/postgresql/postgresql.c PostgreSQL镜像使用的Ubuntu基础镜像默认的Locale配置为`en_US.UTF-8`,可以使用一个简单的 Dockerfile来设置为不同的Locale。比如设置为 `de_DE.utf8`: ```dockerfile -FROM colovu/postgres:latest +FROM colovu/postgres:12.4 RUN localedef -i de_DE -c -f UTF-8 -A /usr/share/locale/locale.alias de_DE.UTF-8 ENV LANG de_DE.utf8 ``` @@ -317,11 +334,11 @@ ENV LANG de_DE.utf8 本镜像允许使用变参`--user`指定运行时的用户信息。但需要注意的是,`postgres`可以允许使用任何UID执行(只需要与数据库目录所属账户一致),`initdb`需要确保该UID实际存在(指定的用户需要在容器的`/etc/passwd`文件中存在): ```shell -$ docker run -it --rm --user www-data -e POSTGRES_PASSWORD=mysecretpassword colovu/postgres:latest +$ docker run -it --rm --user www-data -e POSTGRES_PASSWORD=mysecretpassword colovu/postgres:12.4 The files belonging to this database system will be owned by user "www-data". ... -$ docker run -it --rm --user 1000:1000 -e POSTGRES_PASSWORD=mysecretpassword colovu/postgres:latest +$ docker run -it --rm --user 1000:1000 -e POSTGRES_PASSWORD=mysecretpassword colovu/postgres:12.4 initdb: could not look up effective user ID 1000: user does not exist ``` @@ -332,7 +349,7 @@ initdb: could not look up effective user ID 1000: user does not exist 2. 如果宿主系统存在相应的用户,可以使用只读绑定将`/etc/passwd`文件映射为容器内对应文件: ```shell - $ docker run -it --rm --user "$(id -u):$(id -g)" -v /etc/passwd:/etc/passwd:ro -e POSTGRES_PASSWORD=mysecretpassword colovu/postgres:latest + $ docker run -it --rm --user "$(id -u):$(id -g)" -v /etc/passwd:/etc/passwd:ro -e POSTGRES_PASSWORD=mysecretpassword colovu/postgres:12.4 The files belonging to this database system will be owned by user "jsmith". ... ``` @@ -341,14 +358,14 @@ initdb: could not look up effective user ID 1000: user does not exist ```shell $ docker volume create pgdata - $ docker run -it --rm -v pgdata:/var/lib/postgresql/data -e POSTGRES_PASSWORD=mysecretpassword colovu/postgres:latest + $ docker run -it --rm -v pgdata:/var/lib/postgresql/data -e POSTGRES_PASSWORD=mysecretpassword colovu/postgres:12.4 The files belonging to this database system will be owned by user "postgres". ... ( once it's finished initializing successfully and is waiting for connections, stop it ) $ docker run -it --rm -v pgdata:/var/lib/postgresql/data colovu/postgres:latest bash chown -R 1000:1000 /var/lib/postgresql/data - $ docker run -it --rm --user 1000:1000 -v pgdata:/var/lib/postgresql/data colovu/postgres:latest + $ docker run -it --rm --user 1000:1000 -v pgdata:/var/lib/postgresql/data colovu/postgres:12.4 LOG: database system was shut down at 2017-01-20 00:03:23 UTC LOG: MultiXact member wraparound protections are now enabled LOG: autovacuum launcher started @@ -401,7 +418,7 @@ ALLOW_EMPTY_PASSWORD=yes 通过配置环境变量`PG_PASSWORD`,可以启用基于密码的用户认证功能。命令行使用参考: ```shell -$ docker run -d -e PG_USERNAME=postgres -e PG_PASSWORD=colovu colovu/postgres:latest +$ docker run -d -e PG_USERNAME=postgres -e PG_PASSWORD=colovu colovu/postgres:12.4 ``` 使用 Docker-Compose 时,`docker-compose.yml`应包含类似如下配置: @@ -418,13 +435,23 @@ services: ### 容器安全 -本容器默认使用应用对应的运行时用户及用户组运行应用,以加强容器的安全性。在使用非`root`用户运行容器时,相关的资源访问会受限;应用仅能操作镜像创建时指定的路径及数据。使用`Non-root`方式的容器,更适合在生产环境中使用。 +本容器默认使用`non-root`运行应用,以加强容器的安全性。在使用`non-root`用户运行容器时,相关的资源访问会受限;应用仅能操作镜像创建时指定的路径及数据。使用`non-root`方式的容器,更适合在生产环境中使用。 + + + +如果需要切换为`root`方式运行应用,可以在启动命令中增加`-u root`以指定运行的用户。 ## 注意事项 -- 容器中 PostgreSQL 启动参数不能配置为后台运行,只能使用前台运行方式 +- 容器中应用的启动参数不能配置为后台运行,如果应用使用后台方式运行,则容器的启动命令会在运行后自动退出,从而导致容器退出 + + + +## 更新记录 + +- 2021/1/1 (1.0): 初始版本 diff --git a/customer/usr/local/bin/comm-postgresql.sh b/customer/usr/local/bin/common.sh similarity index 99% rename from customer/usr/local/bin/comm-postgresql.sh rename to customer/usr/local/bin/common.sh index b4c9e23..d5bad9b 100644 --- a/customer/usr/local/bin/comm-postgresql.sh +++ b/customer/usr/local/bin/common.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Ver: 1.0 by Endial Fang (endial@126.com) +# Ver: 1.1 by Endial Fang (endial@126.com) # # 应用通用业务处理函数 @@ -8,6 +8,7 @@ . /usr/local/scripts/libfile.sh . /usr/local/scripts/libfs.sh +. /usr/local/scripts/liblog.sh . /usr/local/scripts/libos.sh . /usr/local/scripts/libservice.sh . /usr/local/scripts/libvalidations.sh @@ -713,6 +714,11 @@ postgresql_custom_init() { LOG_I "Custom init for ${APP_NAME} already done before, skipping initialization." fi fi + + # 绑定所有 IP 及 指定端口 ,启用远程访问 + postgresql_enable_remote_connections + postgresql_conf_set "port" "${PG_PORT_NUMBER}" + } # 初始化 Master 节点数据库 diff --git a/customer/usr/local/bin/entry.sh b/customer/usr/local/bin/entry.sh index 6d4f9b9..2a72e7c 100755 --- a/customer/usr/local/bin/entry.sh +++ b/customer/usr/local/bin/entry.sh @@ -1,37 +1,29 @@ #!/bin/bash -# Ver: 1.0 by Endial Fang (endial@126.com) +# Ver: 1.2 by Endial Fang (endial@126.com) # # 容器入口脚本 # 设置 shell 执行参数,可使用'-'(打开)'+'(关闭)控制。常用: -# -e: 命令执行错误则报错; -u: 变量未定义则报错; -x: 打印实际待执行的命令行; -o pipefail: 设置管道中命令遇到失败则报错 +# -e: 命令执行错误则报错(errexit); -u: 变量未定义则报错(nounset); -x: 打印实际待执行的命令行; -o pipefail: 设置管道中命令遇到失败则报错 set -eu set -o pipefail -. /usr/local/bin/comm-${APP_NAME}.sh # 应用专用函数库 - -. /usr/local/bin/comm-env.sh # 设置环境变量 +. /usr/local/scripts/libcommon.sh # 加载通用函数库 LOG_I "** Processing entry.sh **" -if ! is_sourced; then - # 替换命令行中的变量 - set -- $(eval echo "$@") - - [ "${1:0:1}" = '-' ] && set -- "${APP_EXEC:-}" "$@" - +if [[ "$*" = "/usr/local/bin/run.sh" ]]; then print_image_welcome - print_command_help "$@" - if [ "$1" = "${APP_EXEC}" ] && is_root; then - /usr/local/bin/setup.sh - - LOG_I "Restart with non-root user: ${APP_USER}\n" - exec gosu "${APP_USER}" "$0" "$@" - fi - - [ "$1" = "${APP_EXEC}" ] && /usr/local/bin/init.sh - - LOG_I "Start container with command: $@" - exec tini -- "$@" + LOG_I "** Starting ${APP_NAME} setup **" + /usr/local/bin/setup.sh + /usr/local/bin/init.sh + LOG_I "** ${APP_NAME} setup finished! **" fi + +# 检测是否仅打印帮助信息 +[ "${1:0:1}" = '-' ] && set -- "${APP_EXEC:-/bin/bash}" "$@" +print_command_help "$@" + +LOG_I "Start container with command: $@" +exec "$@" diff --git a/customer/usr/local/bin/comm-env.sh b/customer/usr/local/bin/environment.sh similarity index 98% rename from customer/usr/local/bin/comm-env.sh rename to customer/usr/local/bin/environment.sh index 54892a7..7cb3df5 100644 --- a/customer/usr/local/bin/comm-env.sh +++ b/customer/usr/local/bin/environment.sh @@ -112,5 +112,8 @@ export PGCONNECT_TIMEOUT="${PGCONNECT_TIMEOUT:-10}" # 内部变量 export PG_FIRST_BOOT="yes" +export APP_DAEMON_USER="${APP_NAME}" +export APP_DAEMON_GROUP="${APP_NAME}" + # 个性化变量 diff --git a/customer/usr/local/bin/init.sh b/customer/usr/local/bin/init.sh index 937c4cd..24cd936 100755 --- a/customer/usr/local/bin/init.sh +++ b/customer/usr/local/bin/init.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Ver: 1.0 by Endial Fang (endial@126.com) +# Ver: 1.2 by Endial Fang (endial@126.com) # # 应用初始化脚本 @@ -8,13 +8,14 @@ set -eu set -o pipefail -. /usr/local/bin/comm-${APP_NAME}.sh # 应用专用函数库 - -. /usr/local/bin/comm-env.sh # 设置环境变量 +. /usr/local/bin/common.sh # 应用专用函数库 +. /usr/local/bin/environment.sh # 设置环境变量 LOG_I "** Processing init.sh **" -trap "postgresql_stop_server" EXIT +trap "${APP_NAME}_stop_server" EXIT + +${APP_NAME}_verify_minimum_env # 执行应用预初始化操作 ${APP_NAME}_custom_preinit @@ -25,8 +26,4 @@ ${APP_NAME}_default_init # 执行用户自定义初始化脚本 ${APP_NAME}_custom_init -# 绑定所有 IP 及 指定端口 ,启用远程访问 -postgresql_enable_remote_connections -postgresql_conf_set "port" "${PG_PORT_NUMBER}" - LOG_I "** Processing init.sh finished! **" diff --git a/customer/usr/local/bin/run.sh b/customer/usr/local/bin/run.sh index fcbb526..c37cbe0 100755 --- a/customer/usr/local/bin/run.sh +++ b/customer/usr/local/bin/run.sh @@ -1,27 +1,29 @@ #!/bin/bash -# Ver: 1.0 by Endial Fang (endial@126.com) +# Ver: 1.3 by Endial Fang (endial@126.com) # # 应用启动脚本 # 设置 shell 执行参数,可使用'-'(打开)'+'(关闭)控制。常用: -# -e: 命令执行错误则报错; -u: 变量未定义则报错; -x: 打印实际待执行的命令行; -o pipefail: 设置管道中命令遇到失败则报错 +# -e: 命令执行错误则报错(errexit); -u: 变量未定义则报错(nounset); -x: 打印实际待执行的命令行; -o pipefail: 设置管道中命令遇到失败则报错 set -eu set -o pipefail -. /usr/local/bin/comm-${APP_NAME}.sh # 应用专用函数库 - -. /usr/local/bin/comm-env.sh # 设置环境变量 +. /usr/local/bin/common.sh # 应用专用函数库 +. /usr/local/bin/environment.sh # 设置环境变量 LOG_I "** Processing run.sh **" + +readonly START_COMMAND="$(command -v ${APP_EXEC})" + +# 确保应用运行在前台 flags=("--config-file=${PG_CONF_FILE}" "--hba_file=${PG_HBA_FILE}") [[ -z "${APP_EXTRA_FLAGS:-}" ]] || flags=("${flags[@]}" "${APP_EXTRA_FLAGS[@]}") -START_COMMAND=("postgres") +# 增加 "@" 以使用用户在命令行添加的扩展标识 +flags=("${flags[@]}" "$@") LOG_I "** Starting ${APP_NAME} **" -if is_root; then - exec gosu "${APP_USER}" tini -s -- "${START_COMMAND[@]}" "${flags[@]}" -else - exec tini -s -- "${START_COMMAND[@]}" "${flags[@]}" -fi +#is_root && flags=("-u" "$APP_DAEMON_USER" "${flags[@]}") +LOG_I "Command: ${START_COMMAND[@]} ${flags[@]}" +exec "${START_COMMAND[@]}" "${flags[@]}" diff --git a/customer/usr/local/bin/setup.sh b/customer/usr/local/bin/setup.sh index 8b51233..45e04a4 100755 --- a/customer/usr/local/bin/setup.sh +++ b/customer/usr/local/bin/setup.sh @@ -1,16 +1,18 @@ #!/bin/bash -# Ver: 1.0 by Endial Fang (endial@126.com) +# Ver: 1.2 by Endial Fang (endial@126.com) # # 应用环境及依赖文件设置脚本 # 设置 shell 执行参数,可使用'-'(打开)'+'(关闭)控制。常用: -# -e: 命令执行错误则报错; -u: 变量未定义则报错; -x: 打印实际待执行的命令行; -o pipefail: 设置管道中命令遇到失败则报错 +# -e: 命令执行错误则报错(errexit); -u: 变量未定义则报错(nounset); -x: 打印实际待执行的命令行; -o pipefail: 设置管道中命令遇到失败则报错 set -eu set -o pipefail -. /usr/local/bin/comm-${APP_NAME}.sh # 应用专用函数库 +. /usr/local/scripts/libcommon.sh # 加载通用函数库 +. /usr/local/scripts/libfs.sh # 加载文件操作函数库 +. /usr/local/scripts/libos.sh # 加载系统管理函数库 -. /usr/local/bin/comm-env.sh # 设置环境变量 +. /usr/local/bin/environment.sh # 设置环境变量 LOG_I "** Processing setup.sh **" @@ -22,8 +24,6 @@ for dir in ${APP_DIRS}; do ensure_dir_exists ${dir} done -${APP_NAME}_verify_minimum_env - # 检测指定文件是否在配置文件存储目录存在,如果不存在则拷贝(新挂载数据卷、手动删除都会导致不存在) # PG 将使用默认模板生成配置文件,并放置在PGDATA目录 #LOG_I "Check config files in: ${APP_CONF_DIR}" @@ -32,17 +32,15 @@ ${APP_NAME}_verify_minimum_env # : #fi -LOG_I "Ensure directory ownership: ${APP_USER}" -for dir in ${APP_DIRS}; do - configure_permissions_ownership "$dir" -u "${APP_USER}" -g "${APP_USER}" -done +#LOG_I "Ensure directory ownership: ${APP_USER}" +#for dir in ${APP_DIRS}; do +# configure_permissions_ownership "$dir" -u "${APP_USER}" -g "${APP_USER}" +#done # 解决 PostgreSQL 目录权限过于开放,无法初始化问题:FATAL: data directory "/srv/data/postgresql" has group or world access LOG_D "Lack of permissions on data directory: ${PG_DATA_DIR}" chmod 0700 ${PG_DATA_DIR} -# 解决使用gosu后,nginx: [emerg] open() "/dev/stdout" failed (13: Permission denied) -LOG_D "Change permissions of stdout/stderr to 0622" -chmod 0622 /dev/stdout /dev/stderr +is_root && ensure_user_exists "$APP_DAEMON_USER" -g "$APP_DAEMON_GROUP" LOG_I "** Processing setup.sh finished! **" diff --git a/customer/usr/sbin/create_user b/customer/usr/sbin/create_user index 08a4659..5d307b1 100755 --- a/customer/usr/sbin/create_user +++ b/customer/usr/sbin/create_user @@ -1,10 +1,12 @@ #!/bin/bash +# Ver: 1.2 by Endial Fang (endial@126.com) +# # shell 执行参数,分别为 -e(命令执行错误则退出脚本) -u(变量未定义则报错) -x(打印实际待执行的命令行) set -eux -groupadd --gid 998 --system ${APP_USER} -useradd --gid 998 --uid 999 --shell /bin/bash --home /srv/data/${APP_NAME} --system ${APP_USER} -#useradd --gid 998 --uid 999 --shell /usr/sbin/nologin --home /srv/data/${APP_NAME} --system ${APP_USER} +groupadd --gid 1001 --system ${APP_USER} +useradd --gid 1001 --uid 1001 --shell /bin/bash --home /srv/data/${APP_NAME} --system ${APP_USER} +#useradd --gid 1001 --uid 1001 --shell /usr/sbin/nologin --home /srv/data/${APP_NAME} --system ${APP_USER} -# 如果需要 sudo 权限,需要安装 su 软件包:apk add sudo +# 如果需要 sudo 权限,需要在 Dockerfile 中安装 su 软件包:RUN install_pkg sudo #sed -i -e 's/^\sDefaults\s*secure_path\s*=/# Defaults secure_path=/' /etc/sudoers #echo "${APP_USER} ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers diff --git a/customer/usr/sbin/prepare_env b/customer/usr/sbin/prepare_env index 05ce3b1..2f346d2 100755 --- a/customer/usr/sbin/prepare_env +++ b/customer/usr/sbin/prepare_env @@ -1,10 +1,10 @@ #!/bin/bash +# Ver: 1.3 by Endial Fang (endial@126.com) +# # shell 执行参数,分别为 -e(命令执行错误则退出脚本) -u(变量未定义则报错) -x(打印实际待执行的命令行) set -eux APP_DIRS=" \ - /usr/local/${APP_NAME} \ - /etc/${APP_NAME} \ /srv/conf/${APP_NAME} \ /srv/data/${APP_NAME} \ /srv/datalog/${APP_NAME} \ @@ -14,4 +14,4 @@ APP_DIRS=" \ /srv/cert/${APP_NAME}" mkdir -p ${APP_DIRS} -chown -Rf ${APP_USER}:${APP_USER} ${APP_DIRS}; +chmod -R g+rwX ${APP_DIRS} /usr/local/${APP_NAME} diff --git a/docker-compose.yml b/docker-compose.yml index 816a22a..eadc612 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,14 +1,13 @@ version: '3.8' -# Docker-Compose 单容器使用参考 YAML 配置文件 -# 更多配置参数请参考镜像 README.md 文档中说明 +# Docker-Compose 方式启动容器的 YAML 配置文件 +# 当前配置仅保证可以启动容器;更多配置参数请参考镜像 README.md 文档中说明 services: postgres: - image: 'registry.cn-shenzhen.aliyuncs.com/colovu/postgres:12' + image: 'registry.cn-shenzhen.aliyuncs.com/colovu/postgres:12.4' ports: - 5432:5432 environment: - # ALLOW_ANONYMOUS_LOGIN is recommended only for development. - ALLOW_ANONYMOUS_LOGIN=yes - ENV_DEBUG=yes