diff --git a/.dockerignore b/.dockerignore index b3e8a3d..c0b11c0 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,4 +1,12 @@ .git .gitignore -README.md -LICENSE \ No newline at end of file + +./alpine +./Makefile + +*.yml +*.yaml + +./LICENSE +./README.md +./img diff --git a/.gitignore b/.gitignore index f90d29d..5de64e7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ -*.DS_Store +.DS_Store .AppleDouble .LSOverride diff --git a/Dockerfile b/Dockerfile index 85d32c1..4966f40 100644 --- a/Dockerfile +++ b/Dockerfile @@ -17,11 +17,10 @@ ARG local_url="" ENV APP_NAME=postgresql \ APP_EXEC=postgres \ APP_USER=postgres \ - APP_GROUP=postgres \ APP_VERSION=${app_ver} # 定义应用基础目录信息,该常量在容器内可使用 -ENV APP_BASE_DIR=/usr/lib/${APP_NAME}/${APP_VERSION} \ +ENV APP_HOME_DIR=/usr/lib/${APP_NAME}/${app_ver} \ APP_DEF_DIR=/etc/${APP_NAME} \ APP_CONF_DIR=/srv/conf/${APP_NAME} \ APP_DATA_DIR=/srv/data/${APP_NAME} \ @@ -33,36 +32,33 @@ ENV APP_BASE_DIR=/usr/lib/${APP_NAME}/${APP_VERSION} \ # 设置应用需要的特定环境变量 ENV \ - PATH="${APP_BASE_DIR}/bin:${PATH}" + PATH="${APP_HOME_DIR}/bin:${PATH}" LABEL \ - "Version"="v${APP_VERSION}" \ - "Description"="Docker image for ${APP_NAME} ${APP_VERSION}." \ + "Version"="v${app_ver}" \ + "Description"="Docker image for ${APP_NAME}(v${app_ver})." \ "Dockerfile"="https://github.com/colovu/docker-${APP_NAME}" \ "Vendor"="Endial Fang (endial@126.com)" # 拷贝默认 Shell 脚本至容器相关目录中 COPY prebuilds / -# 镜像内应用安装脚本 -# 以下脚本可按照不同需求拆分为多个段,但需要注意各个段在结束前需要清空缓存 -# set -eux: 设置 shell 执行参数,分别为 -e(命令执行错误则退出脚本) -u(变量未定义则报错) -x(打印实际待执行的命令行) -RUN set -eux; \ - \ -# 设置程序使用静默安装,而非交互模式;类似tzdata等程序需要使用静默安装 +# 镜像内相应应用及依赖软件包的安装脚本;以下脚本可按照不同需求拆分为多个段,但需要注意各个段在结束前需要清空缓存 +RUN \ +# 设置程序使用静默安装,而非交互模式;默认情况下,类似 tzdata/gnupg/ca-certificates 等程序配置需要交互 export DEBIAN_FRONTEND=noninteractive; \ \ +# 设置 shell 执行参数,分别为 -e(命令执行错误则退出脚本) -u(变量未定义则报错) -x(打印实际待执行的命令行) + set -eux; \ + \ # 更改源为当次编译指定的源 cp /etc/apt/sources.list.${apt_source} /etc/apt/sources.list; \ \ -# 设置容器入口脚本的可执行权限 - chmod +x /usr/local/bin/entrypoint.sh; \ - \ # 为应用创建对应的组、用户、相关目录 - APP_DIRS="${APP_DEF_DIR:-} ${APP_CONF_DIR:-} ${APP_DATA_DIR:-} ${APP_CACHE_DIR:-} ${APP_RUN_DIR:-} ${APP_LOG_DIR:-} ${APP_CERT_DIR:-} ${APP_WWW_DIR:-} ${APP_DATA_LOG_DIR:-} ${APP_BASE_DIR:-${APP_DATA_DIR}}"; \ + export APP_DIRS="${APP_DEF_DIR:-} ${APP_CONF_DIR:-} ${APP_DATA_DIR:-} ${APP_CACHE_DIR:-} ${APP_RUN_DIR:-} ${APP_LOG_DIR:-} ${APP_CERT_DIR:-} ${APP_DATA_LOG_DIR:-} ${APP_HOME_DIR:-${APP_DATA_DIR}}"; \ mkdir -p ${APP_DIRS}; \ - groupadd -r -g 998 ${APP_GROUP}; \ - useradd -r -g ${APP_GROUP} -u 999 -s /bin/bash -d ${APP_DATA_DIR} ${APP_USER}; \ + groupadd -r -g 998 ${APP_USER}; \ + useradd -r -g ${APP_USER} -u 999 -s /bin/bash -d ${APP_DATA_DIR} ${APP_USER}; \ \ # 应用软件包及依赖项。相关软件包在镜像创建完成时,不会被清理 appDeps=" \ @@ -72,6 +68,7 @@ RUN set -eux; \ libnss-wrapper \ xz-utils \ "; \ + savedAptMark="$(apt-mark showmanual) ${appDeps}"; \ \ \ \ @@ -81,7 +78,6 @@ RUN set -eux; \ gnupg \ libicu-dev \ "; \ - savedAptMark="$(apt-mark showmanual) ${appDeps}"; \ apt-get update; \ apt-get install -y --no-install-recommends ${fetchDeps}; \ \ @@ -100,7 +96,7 @@ RUN set -eux; \ \ \ \ -# 增加软件包特有源,并使用系统包管理方式安装软件 +# 包管理方式安装: 增加软件包特有源,并使用系统包管理方式安装软件; 安装后需要确认 ${APP_DEF_DIR} 目录中存在原始配置文件 echo "deb http://apt.postgresql.org/pub/repos/apt/ buster-pgdg main ${APP_VERSION}" >> /etc/apt/sources.list; \ echo "deb-src http://apt.postgresql.org/pub/repos/apt/ buster-pgdg main ${APP_VERSION}" >> /etc/apt/sources.list; \ apt-get update; \ @@ -108,12 +104,8 @@ RUN set -eux; \ \ \ \ -# 检测是否存在对应版本的 overrides 脚本文件;如果存在,执行 - { [ ! -e "/usr/local/overrides/overrides-${APP_VERSION}.sh" ] || /bin/bash "/usr/local/overrides/overrides-${APP_VERSION}.sh"; }; \ - \ -# 设置应用关联目录的权限信息,设置为'777'是为了保证后续使用`--user`或`gosu`时,可以更改目录对应的用户属性信息;运行时会被更改为'700'或'755' - chown -Rf ${APP_USER}:${APP_GROUP} ${APP_DIRS}; \ - chmod 777 ${APP_DIRS}; \ +# 设置应用关联目录的权限信息 + chown -Rf ${APP_USER}:${APP_USER} ${APP_DIRS}; \ \ # 查找新安装的应用及应用依赖软件包,并标识为'manual',防止后续自动清理时被删除 apt-mark auto '.*' > /dev/null; \ @@ -130,11 +122,24 @@ RUN set -eux; \ apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false ${fetchDeps}; \ apt-get autoclean -y; \ rm -rf /var/lib/apt/lists/*; \ + :; + +# 拷贝应用专用 Shell 脚本至容器相关目录中 +COPY customer / + +RUN set -eux; \ +# 设置容器入口脚本的可执行权限 + chmod +x /usr/local/bin/entrypoint.sh; \ + \ +# 检测是否存在对应版本的 overrides 脚本文件;如果存在,执行 + { [ ! -e "/usr/local/overrides/overrides-${app_ver}.sh" ] || /bin/bash "/usr/local/overrides/overrides-${app_ver}.sh"; }; \ \ # 验证安装的软件是否可以正常运行,常规情况下放置在命令行的最后 - gosu ${APP_USER} ${APP_EXEC} --version ; + gosu ${APP_USER} ${APP_EXEC} --version ; \ + :; -VOLUME ["/srv/conf", "/srv/data", "/var/log", "/var/run"] +# 默认提供的数据卷 +VOLUME ["/srv/conf", "/srv/data", "/srv/cert", "/srv/datalog", "/var/log"] # 默认使用gosu切换为新建用户启动,必须保证端口在1024之上 EXPOSE 5432 @@ -142,5 +147,7 @@ EXPOSE 5432 # 容器初始化命令,默认存放在:/usr/local/bin/entrypoint.sh ENTRYPOINT ["entrypoint.sh"] +WORKDIR ${APP_DATA_DIR} + # 应用程序的服务命令,必须使用非守护进程方式运行。如果使用变量,则该变量必须在运行环境中存在(ENV可以获取) CMD ["${APP_EXEC}", "--config-file=${PG_CONF_FILE}"] diff --git a/LICENSE b/LICENSE index b1886f9..80e3bb7 100644 --- a/LICENSE +++ b/LICENSE @@ -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 diff --git a/Makefile b/Makefile index d9d4aae..00e815c 100644 --- a/Makefile +++ b/Makefile @@ -2,14 +2,16 @@ # # 当前 Docker 镜像的编译脚本 +app_name := postgres current_branch := $(shell git rev-parse --abbrev-ref HEAD) # Sources List: default / tencent / ustc / aliyun / huawei build-arg := --build-arg apt_source=tencent # 设置本地下载服务器路径,加速调试时的本地编译速度 -build-arg += --build-arg local_url=http://192.168.48.132/dist-files/ +local_ip=`ifconfig -a|grep inet|grep -v 127.0.0.1|grep -v inet6|awk '{print $$2}'|tr -d "addr:"` +build-arg += --build-arg local_url=http://$(local_ip)/dist-files/ build: - docker rmi postgres:$(current_branch) || true - docker build --force-rm $(build-arg) -t postgres:$(current_branch) . + docker rmi $(app_name):$(current_branch) || true + docker build --force-rm $(build-arg) -t $(app_name):$(if $(current_branch),$(current_branch),latest) . diff --git a/README.md b/README.md index 9a6ca24..da165cb 100644 --- a/README.md +++ b/README.md @@ -1,27 +1,90 @@ # 简介 -基于的Ubuntu系统的 PostgreSQL Docker镜像。 +针对 [PostgreSQL](https://www.postgresql.org) 应用的 Docker 镜像,用于提供 PostgreSQL 服务。 + +详细信息可参照:[官方说明](https://www.postgresql.org/docs/) + +postgresql-logo **版本信息:** - +- 11、11.8、latest +- 10、10.13 **镜像信息:** * 镜像地址:colovu/postgres:latest - * 依赖镜像:colovu/ubuntu:latest -## 数据卷 +## TL;DR + +Docker 快速启动命令: ```shell - /srv/data:数据存储目录 - /srv/conf:配置文件及初始化文件存储目录 - /var/run:运行时文件存储目录 - /var/log:日志文件存储目录 +$ docker run -d --name postgres -e ALLOW_EMPTY_PASSWORD=yes colovu/postgres:latest ``` +Docker-Compose 快速启动命令: + +```shell +$ curl -sSL https://raw.githubusercontent.com/colovu/docker-postgres/master/docker-compose.yml > docker-compose.yml + +$ docker-compose up -d +``` + + + +**** + + + +## 默认对外声明 + +### 端口 + +- 5432:PostgreSQL 业务客户端访问端口 + +### 数据卷 + +镜像默认提供以下数据卷定义: + +```shell +/var/log # 日志输出,应用日志输出,非数据日志输出 +/srv/conf # 配置文件 +/srv/data # 数据文件 +/srv/datalog # 数据操作日志文件 +``` + +如果需要持久化存储相应数据,需要在宿主机建立本地目录,并在使用镜像初始化容器时进行数据卷映射。 + +举例: + +- 使用宿主机`/host/dir/to/conf`存储配置文件 +- 使用宿主机`/host/dir/to/data`存储数据文件 +- 使用宿主机`/host/dir/to/log`存储日志文件 + +创建以上相应的宿主机目录后,容器启动命令中对应的数据卷映射参数类似如下: + +```shell +-v /host/dir/to/conf:/srv/conf -v /host/dir/to/data:/srv/data -v /host/dir/to/log:/var/log +``` + +使用 Docker Compose 时配置文件类似如下: + +```yaml +services: + postgresql: + ... + volumes: + - /host/dir/to/conf:/srv/conf + - /host/dir/to/data:/srv/data + - /host/dir/to/log:/var/log + ... +``` + +> 注意:应用需要使用的子目录会自动创建。 + ## 使用说明 @@ -325,10 +388,51 @@ initdb: could not look up effective user ID 1000: user does not exist +## 安全 + +### 用户及密码 + +PostgreSQL 镜像默认禁用了无密码访问功能,在实际生产环境中建议使用用户名及密码控制访问;如果为了测试需要,可以使用以下环境变量启用无密码访问功能: + +```shell +ALLOW_EMPTY_PASSWORD=yes +``` + +通过配置环境变量`PG_PASSWORD`,可以启用基于密码的用户认证功能。命令行使用参考: + +```shell +$ docker run -d -e PG_USERNAME=postgres -e PG_PASSWORD=colovu colovu/postgres:latest +``` + +使用 Docker-Compose 时,`docker-compose.yml`应包含类似如下配置: + +```yaml +services: + postgres: + ... + environment: + - PG_USERNAME=postgres + - PG_PASSWORD=colovu + ... +``` + +### 容器安全 + +本容器默认使用应用对应的运行时用户及用户组运行应用,以加强容器的安全性。在使用非`root`用户运行容器时,相关的资源访问会受限;应用仅能操作镜像创建时指定的路径及数据。使用`Non-root`方式的容器,更适合在生产环境中使用。 + + + +## 注意事项 + +- 容器中 PostgreSQL 启动参数不能配置为后台运行,只能使用前台运行方式 + + + ## 参考 - [官方Docker](https://hub.docker.com/_/postgres?tab=description) - [官方介绍](http://www.postgresql.org/docs/9.5/interactive/app-initdb.html) +- [官方中文手册](http://www.postgres.cn/v2/document) ---- diff --git a/prebuilds/usr/local/bin/appcommon.sh b/customer/usr/local/bin/appcommon.sh similarity index 99% rename from prebuilds/usr/local/bin/appcommon.sh rename to customer/usr/local/bin/appcommon.sh index 032fd79..5d49348 100644 --- a/prebuilds/usr/local/bin/appcommon.sh +++ b/customer/usr/local/bin/appcommon.sh @@ -4,13 +4,13 @@ # 应用通用业务处理函数 # 加载依赖脚本 -#. /usr/local/scripts/liblog.sh # 日志输出函数库 . /usr/local/scripts/libcommon.sh # 通用函数库 . /usr/local/scripts/libfile.sh . /usr/local/scripts/libfs.sh . /usr/local/scripts/libos.sh . /usr/local/scripts/libservice.sh . /usr/local/scripts/libvalidations.sh +. /usr/local/scripts/libnet.sh # 函数列表 @@ -40,8 +40,6 @@ export PG_PID_FILE="${APP_RUN_DIR}/postgresql.pid" export PG_LOG_FILE="${APP_LOG_DIR}/postgresql.log" # Users -export APP_USER="${PG_DAEMON_USER:-${APP_USER}}" -export APP_GROUP="${PG_DAEMON_GROUP:-${APP_GROUP}}" # Cluster configuration export PG_CLUSTER_APP_NAME=${PG_CLUSTER_APP_NAME:-cvreceiver} diff --git a/prebuilds/usr/local/bin/entrypoint.sh b/customer/usr/local/bin/entrypoint.sh similarity index 86% rename from prebuilds/usr/local/bin/entrypoint.sh rename to customer/usr/local/bin/entrypoint.sh index d738b10..88be582 100644 --- a/prebuilds/usr/local/bin/entrypoint.sh +++ b/customer/usr/local/bin/entrypoint.sh @@ -17,13 +17,13 @@ set -o pipefail #. /usr/local/scripts/libcommon.sh # 通用函数库 . /usr/local/bin/appcommon.sh # 应用专用函数库 -LOG_D "Run entrypoint.sh for container init..." +LOG_D "Process entrypoint.sh..." # 初始化环境变量。 docker_app_env()函数在文件 appcommon.sh 中定义 eval "$(docker_app_env)" # 定义容器中使用的默认目录(未定义时设置默认值为空"") -APP_DIRS="${APP_DEF_DIR:-} ${APP_HOME_DIR:-} ${APP_CONF_DIR:-} ${APP_DATA_DIR:-} ${APP_CACHE_DIR:-} ${APP_RUN_DIR:-} ${APP_LOG_DIR:-} ${APP_CERT_DIR:-} ${APP_WWW_DIR:-} ${APP_DATA_LOG_DIR:-}" +APP_DIRS="${APP_CONF_DIR:-} ${APP_DATA_DIR:-} ${APP_LOG_DIR:-} ${APP_CERT_DIR:-} ${APP_DATA_LOG_DIR:-}" APP_DIRS="${APP_DIRS} ${PG_DATA_DIR}" @@ -32,7 +32,7 @@ docker_print_welcome #postgresql_enable_nss_wrapper -# 检测数据卷,创建默认的关联目录,并拷贝所必须的默认配置文件及初始化文件 +# 检测数据卷中相关目录,创建默认的关联目录,并拷贝所必须的默认配置文件及初始化文件 # 全局变量: # APP_* docker_ensure_dir_and_configs() { @@ -40,9 +40,9 @@ docker_ensure_dir_and_configs() { local user_id; user_id="$(id -u)" - LOG_D "Directories: ${APP_DIRS}" + LOG_D "Check directories..." for dir in ${APP_DIRS}; do - LOG_D "Check directory $dir" + LOG_D " Check $dir" ensure_dir_exists "$dir" done @@ -76,9 +76,9 @@ _main() { # 以root用户启动时,修改相应目录的所属用户信息为 APP_USER ,确保切换用户时,权限正常 for dir in ${APP_DIRS}; do - LOG_D "Change ownership and permissions of $dir" chmod 755 ${dir} - configure_permissions_ownership "$dir" -u "${APP_USER}" -g "${APP_GROUP}" + configure_permissions_ownership "$dir" -u "${APP_USER}" -g "${APP_USER}" + : done # 解决 PostgreSQL 目录权限过于开放,无法初始化问题:FATAL: data directory "/srv/data/postgresql" has group or world access @@ -96,7 +96,7 @@ _main() { exec gosu "${APP_USER}" "$0" "$@" fi - # 执行预初始化操作 + # 执行应用预初始化操作 docker_custom_preinit # 执行应用初始化操作 diff --git a/prebuilds/usr/local/overrides/overrides-11.sh b/customer/usr/local/overrides/overrides-11.sh similarity index 100% rename from prebuilds/usr/local/overrides/overrides-11.sh rename to customer/usr/local/overrides/overrides-11.sh diff --git a/docker-compose.yml b/docker-compose.yml index ba92a6b..3a8be07 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -4,14 +4,10 @@ version: '3.6' # 更多配置参数请参考镜像 README.md 文档中说明 services: postgres: - # 10 - image: 'colovu/postgres:10' + image: 'colovu/postgres:latest' ports: - '5432:5432' - container_name: postgres restart: always - networks: - - back-tier volumes: - $PWD/conf:/srv/conf - $PWD/log:/var/log @@ -21,16 +17,3 @@ services: - PG_USERNAME=postgres - PG_PASSWORD=colovu - PG_DATABASE=postgres - - ENV_DEBUG=yes - -volumes: - zookeeper_data: - driver: local - kafka_data: - driver: local - -networks: - back-tier: - driver: bridge - front-tier: - driver: bridge \ No newline at end of file diff --git a/img/postgresql-logo.png b/img/postgresql-logo.png new file mode 100644 index 0000000..d765318 Binary files /dev/null and b/img/postgresql-logo.png differ