# centos7下使用docker安装postgresql服务(带plpython3u扩展) ## 安装docker (使用root用户) 1. 更新yum yum update 2. 安装必要的依赖 yum install -y yum-utils device-mapper-persistent-data lvm2 3. 设置yum源(二选一) yum-config-manager --add-repo http://download.docker.com/linux/centos/docker-ce.repo(中央仓库) yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo(阿里仓库) 4. 查看仓库中docker版本 yum list docker-ce --showduplicates | sort -r 5. 安装docker yum install docker-ce-版本号 (例如: yum install docker-ce-18.03.1.ce) 6. 启动docker并将docker加入开机启动 1). systemctl start docker 2). systemctl enable docker 7. docker帮助 docker --help docker 命令 --help ## 创建镜像 1. 创建临时工作目录 cd ~ && mkdir dockerTemp && cd dockerTemp 2. 拷贝docker-entrypoint.sh 和 Dockerfile进临时工作目录 (文件名大小写敏感, docker-entrypoint.sh 需要有可执行权限, chmod 777 docker-entrypoint.sh) ![pg001](./img/pgdocker_001.jpg)
docker-entrypoint.sh 内容 #!/usr/bin/env bash set -Eeo pipefail # TODO swap to -Eeuo pipefail above (after handling all potentially-unset variables) # usage: file_env VAR [DEFAULT] # ie: file_env 'XYZ_DB_PASSWORD' 'example' # (will allow for "$XYZ_DB_PASSWORD_FILE" to fill in the value of # "$XYZ_DB_PASSWORD" from a file, especially for Docker's secrets feature) file_env() { local var="$1" local fileVar="${var}_FILE" local def="${2:-}" if [ "${!var:-}" ] && [ "${!fileVar:-}" ]; then echo >&2 "error: both $var and $fileVar are set (but are exclusive)" exit 1 fi local val="$def" if [ "${!var:-}" ]; then val="${!var}" elif [ "${!fileVar:-}" ]; then val="$(< "${!fileVar}")" fi export "$var"="$val" unset "$fileVar" } # check to see if this file is being run or sourced from another script _is_sourced() { # https://unix.stackexchange.com/a/215279 [ "${#FUNCNAME[@]}" -ge 2 ] \ && [ "${FUNCNAME[0]}" = '_is_sourced' ] \ && [ "${FUNCNAME[1]}" = 'source' ] } # used to create initial postgres directories and if run as root, ensure ownership to the "postgres" user docker_create_db_directories() { local user; user="$(id -u)" mkdir -p "$PGDATA" chmod 700 "$PGDATA" # ignore failure since it will be fine when using the image provided directory; see also https://github.com/docker-library/postgres/pull/289 mkdir -p /var/run/postgresql || : chmod 775 /var/run/postgresql || : # Create the transaction log directory before initdb is run so the directory is owned by the correct user if [ -n "$POSTGRES_INITDB_WALDIR" ]; then mkdir -p "$POSTGRES_INITDB_WALDIR" if [ "$user" = '0' ]; then find "$POSTGRES_INITDB_WALDIR" \! -user postgres -exec chown postgres '{}' + fi chmod 700 "$POSTGRES_INITDB_WALDIR" fi # allow the container to be started with `--user` if [ "$user" = '0' ]; then find "$PGDATA" \! -user postgres -exec chown postgres '{}' + find /var/run/postgresql \! -user postgres -exec chown postgres '{}' + fi } # initialize empty PGDATA directory with new database via 'initdb' # arguments to `initdb` can be passed via POSTGRES_INITDB_ARGS or as arguments to this function # `initdb` automatically creates the "postgres", "template0", and "template1" dbnames # this is also where the database user is created, specified by `POSTGRES_USER` env docker_init_database_dir() { # "initdb" is particular about the current user existing in "/etc/passwd", so we use "nss_wrapper" to fake that if necessary # see https://github.com/docker-library/postgres/pull/253, https://github.com/docker-library/postgres/issues/359, https://cwrap.org/nss_wrapper.html if ! getent passwd "$(id -u)" &> /dev/null && [ -e /usr/lib/libnss_wrapper.so ]; then export LD_PRELOAD='/usr/lib/libnss_wrapper.so' export NSS_WRAPPER_PASSWD="$(mktemp)" export NSS_WRAPPER_GROUP="$(mktemp)" echo "postgres:x:$(id -u):$(id -g):PostgreSQL:$PGDATA:/bin/false" > "$NSS_WRAPPER_PASSWD" echo "postgres:x:$(id -g):" > "$NSS_WRAPPER_GROUP" fi if [ -n "$POSTGRES_INITDB_WALDIR" ]; then set -- --waldir "$POSTGRES_INITDB_WALDIR" "$@" fi eval 'initdb --username="$POSTGRES_USER" --pwfile=<(echo "$POSTGRES_PASSWORD") '"$POSTGRES_INITDB_ARGS"' "$@"' # unset/cleanup "nss_wrapper" bits if [ "${LD_PRELOAD:-}" = '/usr/lib/libnss_wrapper.so' ]; then rm -f "$NSS_WRAPPER_PASSWD" "$NSS_WRAPPER_GROUP" unset LD_PRELOAD NSS_WRAPPER_PASSWD NSS_WRAPPER_GROUP fi } # print large warning if POSTGRES_PASSWORD is long # error if both POSTGRES_PASSWORD is empty and POSTGRES_HOST_AUTH_METHOD is not 'trust' # print large warning if POSTGRES_HOST_AUTH_METHOD is set to 'trust' # assumes database is not set up, ie: [ -z "$DATABASE_ALREADY_EXISTS" ] docker_verify_minimum_env() { # check password first so we can output the warning before postgres # messes it up if [ "${#POSTGRES_PASSWORD}" -ge 100 ]; then cat >&2 <<-'EOWARN' WARNING: The supplied POSTGRES_PASSWORD is 100+ characters. This will not work if used via PGPASSWORD with "psql". https://www.postgresql.org/message-id/flat/E1Rqxp2-0004Qt-PL%40wrigleys.postgresql.org (BUG #6412) https://github.com/docker-library/postgres/issues/507 EOWARN fi if [ -z "$POSTGRES_PASSWORD" ] && [ 'trust' != "$POSTGRES_HOST_AUTH_METHOD" ]; then # The - option suppresses leading tabs but *not* spaces. :) cat >&2 <<-'EOE' Error: Database is uninitialized and superuser password is not specified. You must specify POSTGRES_PASSWORD to a non-empty value for the superuser. For example, "-e POSTGRES_PASSWORD=password" on "docker run". You may also use "POSTGRES_HOST_AUTH_METHOD=trust" to allow all connections without a password. This is *not* recommended. See PostgreSQL documentation about "trust": https://www.postgresql.org/docs/current/auth-trust.html EOE exit 1 fi if [ 'trust' = "$POSTGRES_HOST_AUTH_METHOD" ]; then cat >&2 <<-'EOWARN' ******************************************************************************** WARNING: POSTGRES_HOST_AUTH_METHOD has been set to "trust". This will allow anyone with access to the Postgres port to access your database without a password, even if POSTGRES_PASSWORD is set. See PostgreSQL documentation about "trust": https://www.postgresql.org/docs/current/auth-trust.html In Docker's default configuration, this is effectively any other container on the same system. It is not recommended to use POSTGRES_HOST_AUTH_METHOD=trust. Replace it with "-e POSTGRES_PASSWORD=password" instead to set a password in "docker run". ******************************************************************************** EOWARN fi } # usage: docker_process_init_files [file [file [...]]] # ie: docker_process_init_files /always-initdb.d/* # process initializer files, based on file extensions and permissions docker_process_init_files() { # psql here for backwards compatiblilty "${psql[@]}" psql=( docker_process_sql ) echo local f for f; do case "$f" in *.sh) # https://github.com/docker-library/postgres/issues/450#issuecomment-393167936 # https://github.com/docker-library/postgres/pull/452 if [ -x "$f" ]; then echo "$0: running $f" "$f" else echo "$0: sourcing $f" . "$f" fi ;; *.sql) echo "$0: running $f"; docker_process_sql -f "$f"; echo ;; *.sql.gz) echo "$0: running $f"; gunzip -c "$f" | docker_process_sql; echo ;; *.sql.xz) echo "$0: running $f"; xzcat "$f" | docker_process_sql; echo ;; *) echo "$0: ignoring $f" ;; esac echo done } # Execute sql script, passed via stdin (or -f flag of pqsl) # usage: docker_process_sql [psql-cli-args] # ie: docker_process_sql --dbname=mydb <<<'INSERT ...' # ie: docker_process_sql -f my-file.sql # ie: docker_process_sql > "$PGDATA/pg_hba.conf" } # start socket-only postgresql server for setting up or running scripts # all arguments will be passed along as arguments to `postgres` (via pg_ctl) docker_temp_server_start() { if [ "$1" = 'postgres' ]; then shift fi # internal start of server in order to allow setup using psql client # does not listen on external TCP/IP and waits until start finishes set -- "$@" -c listen_addresses='' -p "${PGPORT:-5432}" PGUSER="${PGUSER:-$POSTGRES_USER}" \ pg_ctl -D "$PGDATA" \ -o "$(printf '%q ' "$@")" \ -w start } # stop postgresql server after done setting up user and running scripts docker_temp_server_stop() { PGUSER="${PGUSER:-postgres}" \ pg_ctl -D "$PGDATA" -m fast -w stop } # check arguments for an option that would cause postgres to stop # return true if there is one _pg_want_help() { local arg for arg; do case "$arg" in # postgres --help | grep 'then exit' # leaving out -C on purpose since it always fails and is unhelpful: # postgres: could not access the server configuration file "/var/lib/postgresql/data/postgresql.conf": No such file or directory -'?'|--help|--describe-config|-V|--version) return 0 ;; esac done return 1 } _main() { # if first arg looks like a flag, assume we want to run postgres server if [ "${1:0:1}" = '-' ]; then set -- postgres "$@" fi if [ "$1" = 'postgres' ] && ! _pg_want_help "$@"; then docker_setup_env # setup data directories and permissions (when run as root) docker_create_db_directories if [ "$(id -u)" = '0' ]; then # then restart script as postgres user exec gosu postgres "$BASH_SOURCE" "$@" fi # only run initialization on an empty data directory if [ -z "$DATABASE_ALREADY_EXISTS" ]; then docker_verify_minimum_env # check dir permissions to reduce likelihood of half-initialized database ls /docker-entrypoint-initdb.d/ > /dev/null docker_init_database_dir pg_setup_hba_conf # PGPASSWORD is required for psql when authentication is required for 'local' connections via pg_hba.conf and is otherwise harmless # e.g. when '--auth=md5' or '--auth-local=md5' is used in POSTGRES_INITDB_ARGS export PGPASSWORD="${PGPASSWORD:-$POSTGRES_PASSWORD}" docker_temp_server_start "$@" docker_setup_db docker_process_init_files /docker-entrypoint-initdb.d/* docker_temp_server_stop unset PGPASSWORD echo echo 'PostgreSQL init process complete; ready for start up.' echo else echo echo 'PostgreSQL Database directory appears to contain a database; Skipping initialization' echo fi fi exec "$@" } if ! _is_sourced; then _main "$@" fi
Dockerfile 内容 # FROM debian:buster-slim AS BASE1 FROM buildpack-deps:buster # ensure local python is preferred over distribution python ENV PATH /usr/local/bin:$PATH # http://bugs.python.org/issue19846 # > At the moment, setting "LANG=C" on a Linux system *fundamentally breaks Python 3*, and that's not OK. ENV LANG C.UTF-8 # extra dependencies (over what buildpack-deps already includes) RUN apt-get update && apt-get install -y --no-install-recommends \ libbluetooth-dev \ tk-dev \ uuid-dev \ && rm -rf /var/lib/apt/lists/* ENV GPG_KEY 0D96DF4D4110E5C43FBFB17F2D347EA6AA65421D ENV PYTHON_VERSION 3.7.7 RUN set -ex \ \ && wget -O python.tar.xz "https://www.python.org/ftp/python/${PYTHON_VERSION%%[a-z]*}/Python-$PYTHON_VERSION.tar.xz" \ && wget -O python.tar.xz.asc "https://www.python.org/ftp/python/${PYTHON_VERSION%%[a-z]*}/Python-$PYTHON_VERSION.tar.xz.asc" \ && export GNUPGHOME="$(mktemp -d)" \ && gpg --batch --keyserver ha.pool.sks-keyservers.net --recv-keys "$GPG_KEY" \ && gpg --batch --verify python.tar.xz.asc python.tar.xz \ && { command -v gpgconf > /dev/null && gpgconf --kill all || :; } \ && rm -rf "$GNUPGHOME" python.tar.xz.asc \ && mkdir -p /usr/src/python \ && tar -xJC /usr/src/python --strip-components=1 -f python.tar.xz \ && rm python.tar.xz \ \ && cd /usr/src/python \ && gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)" \ && ./configure \ --build="$gnuArch" \ --enable-loadable-sqlite-extensions \ --enable-optimizations \ --enable-option-checking=fatal \ --enable-shared \ --with-system-expat \ --with-system-ffi \ --without-ensurepip \ && make -j "$(nproc)" \ # setting PROFILE_TASK makes "--enable-optimizations" reasonable: https://bugs.python.org/issue36044 / https://github.com/docker-library/python/issues/160#issuecomment-509426916 PROFILE_TASK='-m test.regrtest --pgo \ test_array \ test_base64 \ test_binascii \ test_binhex \ test_binop \ test_bytes \ test_c_locale_coercion \ test_class \ test_cmath \ test_codecs \ test_compile \ test_complex \ test_csv \ test_decimal \ test_dict \ test_float \ test_fstring \ test_hashlib \ test_io \ test_iter \ test_json \ test_long \ test_math \ test_memoryview \ test_pickle \ test_re \ test_set \ test_slice \ test_struct \ test_threading \ test_time \ test_traceback \ test_unicode \ ' \ && make install \ && ldconfig \ \ && find /usr/local -depth \ \( \ \( -type d -a \( -name test -o -name tests -o -name idle_test \) \) \ -o \ \( -type f -a \( -name '*.pyc' -o -name '*.pyo' \) \) \ \) -exec rm -rf '{}' + \ && rm -rf /usr/src/python \ \ && python3 --version # make some useful symlinks that are expected to exist RUN cd /usr/local/bin \ && ln -s idle3 idle \ && ln -s pydoc3 pydoc \ && ln -s python3 python \ && ln -s python3-config python-config # if this is called "PIP_VERSION", pip explodes with "ValueError: invalid truth value ''" ENV PYTHON_PIP_VERSION 20.1.1 # https://github.com/pypa/get-pip ENV PYTHON_GET_PIP_URL https://github.com/pypa/get-pip/raw/eff16c878c7fd6b688b9b4c4267695cf1a0bf01b/get-pip.py ENV PYTHON_GET_PIP_SHA256 b3153ec0cf7b7bbf9556932aa37e4981c35dc2a2c501d70d91d2795aa532be79 RUN set -ex; \ \ wget -O get-pip.py "$PYTHON_GET_PIP_URL"; \ echo "$PYTHON_GET_PIP_SHA256 *get-pip.py" | sha256sum --check --strict -; \ \ python get-pip.py \ --disable-pip-version-check \ --no-cache-dir \ "pip==$PYTHON_PIP_VERSION" \ ; \ pip --version; \ \ find /usr/local -depth \ \( \ \( -type d -a \( -name test -o -name tests -o -name idle_test \) \) \ -o \ \( -type f -a \( -name '*.pyc' -o -name '*.pyo' \) \) \ \) -exec rm -rf '{}' +; \ rm -f get-pip.py RUN pip3 install shapely -i https://pypi.tuna.tsinghua.edu.cn/simple \ && pip3 install matplotlib -i https://pypi.tuna.tsinghua.edu.cn/simple \ && pip3 install short-text-sim -i http://dev.dp.sagacloud.cn:8082/repository/saga-pypi-group/simple --trusted-host dev.dp.sagacloud.cn \ && pip3 install numpy -i https://pypi.tuna.tsinghua.edu.cn/simple \ && pip3 install vg -i https://pypi.tuna.tsinghua.edu.cn/simple \ && pip3 install networkx -i https://pypi.tuna.tsinghua.edu.cn/simple \ && pip3 install jieba -i https://pypi.tuna.tsinghua.edu.cn/simple \ && cd /usr/local/lib/python3.7/site-packages \ && git clone http://39.106.8.246:3003/chenhaiyang/relations.git # CMD ["python3"] # FROM debian:buster-slim RUN set -ex; \ if ! command -v gpg > /dev/null; then \ apt-get update; \ apt-get install -y --no-install-recommends \ gnupg \ dirmngr \ ; \ rm -rf /var/lib/apt/lists/*; \ fi # explicitly set user/group IDs RUN set -eux; \ groupadd -r postgres --gid=999; \ # https://salsa.debian.org/postgresql/postgresql-common/blob/997d842ee744687d99a2b2d95c1083a2615c79e8/debian/postgresql-common.postinst#L32-35 useradd -r -g postgres --uid=999 --home-dir=/var/lib/postgresql --shell=/bin/bash postgres; \ # also create the postgres user's home directory with appropriate permissions # see https://github.com/docker-library/postgres/issues/274 mkdir -p /var/lib/postgresql; \ chown -R postgres:postgres /var/lib/postgresql # grab gosu for easy step-down from root # https://github.com/tianon/gosu/releases ENV GOSU_VERSION 1.12 RUN set -eux; \ savedAptMark="$(apt-mark showmanual)"; \ apt-get update; \ apt-get install -y --no-install-recommends ca-certificates wget; \ rm -rf /var/lib/apt/lists/*; \ dpkgArch="$(dpkg --print-architecture | awk -F- '{ print $NF }')"; \ wget -O /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$dpkgArch"; \ wget -O /usr/local/bin/gosu.asc "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$dpkgArch.asc"; \ export GNUPGHOME="$(mktemp -d)"; \ gpg --batch --keyserver hkps://keys.openpgp.org --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4; \ gpg --batch --verify /usr/local/bin/gosu.asc /usr/local/bin/gosu; \ gpgconf --kill all; \ rm -rf "$GNUPGHOME" /usr/local/bin/gosu.asc; \ apt-mark auto '.*' > /dev/null; \ [ -z "$savedAptMark" ] || apt-mark manual $savedAptMark > /dev/null; \ apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \ chmod +x /usr/local/bin/gosu; \ gosu --version; \ gosu nobody true # make the "en_US.UTF-8" locale so postgres will be utf-8 enabled by default RUN set -eux; \ if [ -f /etc/dpkg/dpkg.cfg.d/docker ]; then \ # if this file exists, we're likely in "debian:xxx-slim", and locales are thus being excluded so we need to remove that exclusion (since we need locales) grep -q '/usr/share/locale' /etc/dpkg/dpkg.cfg.d/docker; \ sed -ri '/\/usr\/share\/locale/d' /etc/dpkg/dpkg.cfg.d/docker; \ ! grep -q '/usr/share/locale' /etc/dpkg/dpkg.cfg.d/docker; \ fi; \ apt-get update; apt-get install -y --no-install-recommends locales; rm -rf /var/lib/apt/lists/*; \ localedef -i en_US -c -f UTF-8 -A /usr/share/locale/locale.alias en_US.UTF-8 ENV LANG en_US.utf8 RUN set -eux; \ apt-get update; \ apt-get install -y --no-install-recommends \ # install "nss_wrapper" in case we need to fake "/etc/passwd" and "/etc/group" (especially for OpenShift) # https://github.com/docker-library/postgres/issues/359 # https://cwrap.org/nss_wrapper.html libnss-wrapper \ # install "xz-utils" for .sql.xz docker-entrypoint-initdb.d files xz-utils \ ; \ rm -rf /var/lib/apt/lists/* RUN mkdir /docker-entrypoint-initdb.d RUN set -ex; \ # pub 4096R/ACCC4CF8 2011-10-13 [expires: 2019-07-02] # Key fingerprint = B97B 0AFC AA1A 47F0 44F2 44A0 7FCC 7D46 ACCC 4CF8 # uid PostgreSQL Debian Repository key='B97B0AFCAA1A47F044F244A07FCC7D46ACCC4CF8'; \ export GNUPGHOME="$(mktemp -d)"; \ gpg --batch --keyserver ha.pool.sks-keyservers.net --recv-keys "$key"; \ gpg --batch --export "$key" > /etc/apt/trusted.gpg.d/postgres.gpg; \ command -v gpgconf > /dev/null && gpgconf --kill all; \ rm -rf "$GNUPGHOME"; \ apt-key list ENV PG_MAJOR 12 ENV PG_VERSION 12.3-1.pgdg100+1 RUN set -ex; \ \ # see note below about "*.pyc" files export PYTHONDONTWRITEBYTECODE=1; \ \ dpkgArch="$(dpkg --print-architecture)"; \ case "$dpkgArch" in \ amd64 | arm64 | i386 | ppc64el) \ # arches officialy built by upstream echo "deb http://apt.postgresql.org/pub/repos/apt/ buster-pgdg main $PG_MAJOR" > /etc/apt/sources.list.d/pgdg.list; \ apt-get update; \ ;; \ *) \ # we're on an architecture upstream doesn't officially build for # let's build binaries from their published source packages echo "deb-src http://apt.postgresql.org/pub/repos/apt/ buster-pgdg main $PG_MAJOR" > /etc/apt/sources.list.d/pgdg.list; \ \ case "$PG_MAJOR" in \ 9.* | 10 ) ;; \ *) \ # https://github.com/docker-library/postgres/issues/484 (clang-6.0 required, only available in stretch-backports) # TODO remove this once we hit buster+ echo 'deb http://deb.debian.org/debian buster-backports main' >> /etc/apt/sources.list.d/pgdg.list; \ ;; \ esac; \ \ tempDir="$(mktemp -d)"; \ cd "$tempDir"; \ \ savedAptMark="$(apt-mark showmanual)"; \ \ # build .deb files from upstream's source packages (which are verified by apt-get) apt-get update; \ apt-get build-dep -y \ postgresql-common pgdg-keyring \ "postgresql-$PG_MAJOR=$PG_VERSION" \ ; \ DEB_BUILD_OPTIONS="nocheck parallel=$(nproc)" \ apt-get source --compile \ postgresql-common pgdg-keyring \ "postgresql-$PG_MAJOR=$PG_VERSION" \ ; \ # we don't remove APT lists here because they get re-downloaded and removed later \ # reset apt-mark's "manual" list so that "purge --auto-remove" will remove all build dependencies # (which is done after we install the built packages so we don't have to redownload any overlapping dependencies) apt-mark showmanual | xargs apt-mark auto > /dev/null; \ apt-mark manual $savedAptMark; \ \ # create a temporary local APT repo to install from (so that dependency resolution can be handled by APT, as it should be) ls -lAFh; \ dpkg-scanpackages . > Packages; \ grep '^Package: ' Packages; \ echo "deb [ trusted=yes ] file://$tempDir ./" > /etc/apt/sources.list.d/temp.list; \ # work around the following APT issue by using "Acquire::GzipIndexes=false" (overriding "/etc/apt/apt.conf.d/docker-gzip-indexes") # Could not open file /var/lib/apt/lists/partial/_tmp_tmp.ODWljpQfkE_._Packages - open (13: Permission denied) # ... # E: Failed to fetch store:/var/lib/apt/lists/partial/_tmp_tmp.ODWljpQfkE_._Packages Could not open file /var/lib/apt/lists/partial/_tmp_tmp.ODWljpQfkE_._Packages - open (13: Permission denied) apt-get -o Acquire::GzipIndexes=false update; \ ;; \ esac; \ \ apt-get install -y --no-install-recommends postgresql-common; \ sed -ri 's/#(create_main_cluster) .*$/\1 = false/' /etc/postgresql-common/createcluster.conf; \ apt-get install -y --no-install-recommends \ "postgresql-$PG_MAJOR=$PG_VERSION" \ ; \ \ rm -rf /var/lib/apt/lists/*; \ \ if [ -n "$tempDir" ]; then \ # if we have leftovers from building, let's purge them (including extra, unnecessary build deps) apt-get purge -y --auto-remove; \ rm -rf "$tempDir" /etc/apt/sources.list.d/temp.list; \ fi; \ \ # some of the steps above generate a lot of "*.pyc" files (and setting "PYTHONDONTWRITEBYTECODE" beforehand doesn't propagate properly for some reason), so we clean them up manually (as long as they aren't owned by a package) find /usr -name '*.pyc' -type f -exec bash -c 'for pyc; do dpkg -S "$pyc" &> /dev/null || rm -vf "$pyc"; done' -- '{}' + # make the sample config easier to munge (and "correct by default") RUN set -eux; \ dpkg-divert --add --rename --divert "/usr/share/postgresql/postgresql.conf.sample.dpkg" "/usr/share/postgresql/$PG_MAJOR/postgresql.conf.sample"; \ cp -v /usr/share/postgresql/postgresql.conf.sample.dpkg /usr/share/postgresql/postgresql.conf.sample; \ ln -sv ../postgresql.conf.sample "/usr/share/postgresql/$PG_MAJOR/"; \ sed -ri "s!^#?(listen_addresses)\s*=\s*\S+.*!\1 = '*'!" /usr/share/postgresql/postgresql.conf.sample; \ grep -F "listen_addresses = '*'" /usr/share/postgresql/postgresql.conf.sample RUN mkdir -p /var/run/postgresql && chown -R postgres:postgres /var/run/postgresql && chmod 2777 /var/run/postgresql ENV PATH $PATH:/usr/lib/postgresql/$PG_MAJOR/bin ENV PGDATA /var/lib/postgresql/data # this 777 will be replaced by 700 at runtime (allows semi-arbitrary "--user" values) RUN mkdir -p "$PGDATA" && chown -R postgres:postgres "$PGDATA" && chmod 777 "$PGDATA" VOLUME /var/lib/postgresql/data COPY docker-entrypoint.sh /usr/local/bin/ RUN ln -s usr/local/bin/docker-entrypoint.sh / # backwards compat ENTRYPOINT ["docker-entrypoint.sh"] RUN apt-get update && apt-get install -y "postgresql-plpython3-12" # RUN echo 'CREATE EXTENSION plpythonu;' > /docker-entrypoint-initdb.d/plpythonu.sql EXPOSE 5432 CMD ["postgres"]
3. 文件内容说明 1). docker-entrypoint.sh 是postgresql数据库的配置文件, 会拷贝到镜像内部使用 2). Dockerfile是docker用来构建镜像的文件, 分为以下几个部分 1. 安装python3 2. 安装python模块 vg, matplotlib, shapely, jieba, short-text-sim, networkx, numpy, git.sagacloud.cn上的算法包 3. 安装postgresql数据库 4. 安装plpython3插件 以上是镜像文件构建的准备工作 ## 构建镜像 1. 在dockerTemp临时工作目录内构建镜像 docker build -t mypg:1 . 其中-t是给镜像起个名字, mypg是名字, 2是版本号, 最后还有一个.表示基于当前目录进行构建镜像, 如果初次执行, 该命令耗时较长 ## 运行镜像, 开启服务 1. 查看镜像 docker images ![pg002](./img/pgdocker_002.png) 2. 运行 mkdir -p /var/lib/postgresql/data docker run -d -e POSTGRES_PASSWORD=123456 --restart=on-failure:5 --name pg12 -v /var/lib/postgresql/data:/var/lib/postgresql/data -p 5432:5432 mypg:1 postgres -d表示后台执行 (容器有个特性, 如果你run容器时执行的命令结束的话, 容器则自动结束) -e表示设置环境变量(此处为pg数据库密码) --restart=always 表示自动重启策略 (策略类型有 no, on-failure, unless-stopped, always) --name是给容器起一个名字pg12 -p 表示端口映射(本机端口:容器端口) -v 表示文件夹映射(本机目录:容器目录) 此处表示postgresql的数据文件存放目录放在本机中, 即便换了容器, 数据也是不变 postgres 表示开启容器后执行的命令(postgres表示开启postgresql数据库) 3. 检测 docker ps (查看当前运行中的容器 -a是查看所有) 如下图所示, 服务已经开启, 可以测试连接数据库 ![pg003](./img/pgdocker_003.jpg) ## 查看pg数据库数据文件的映射(volumes 映射) volumes文件映射的功能是让容器和本机的文件夹数据共享的机制 docker inspect pg12 | grep Mounts -A 20 ![pg004](./img/pgdocker_004.jpg) ## 其他常用命令 1. 查看所有容器 docker ps -a 2. 查看所有镜像 docker images 3. 关闭容器, 开启容器 docker start pg12 docker stop pg12 4. 删除容器 docker rm pg12 (需要先关闭容器) docker rm -f pg12 (强制删除) 5. 删除镜像 docker rmi [镜像id] 6. 进入容器 docker exec -it pg12 /bin/bash (帮助: docker exec --help) 7. 退出容器 exit/quit ctrl + P + Q (不关闭当前进程) 8. 修改容器配置 docker update --restart=always pg12 (设置容器的重启规则) --restart=on-failure:5 9. Dockerfile 给镜像内文件增加文本 sed -i '$a# comment' /etc/apt/sources.list 给/etc/apt/sources.list文件末尾追加 # comment ## 导出和载入镜像 镜像的导入和导出是方便镜像的分享和迁移, 如果服务器网路不好或者pull不下来镜像,只能在其它网路比较好的机器上pull下来 镜像,导出成一个文件,再下载上传到网路不好的机器上,然后再从文件中导出来,这样在网络不好的机器上也能使用docker镜像 1. 使用 docker images 找到需要导出的镜像 2. 导出镜像, 将镜像保存为文件 docker save 镜像id > /root/myimage.tar 3. 将镜像保存到另一台不能联网的服务器(需要安装过docker)上, 加载镜像 docker load < /root/myimage.tar 4. (选作) 有可能在新服务器上不能识别镜像的tag(名称:版本), 需要执行 docker tag 镜像id 名称:版本 (例如: docker tag eb40dcf64078 nginx:latest)