mirror of
https://github.com/wassname/docker-postgresql.git
synced 2026-06-28 23:40:33 +08:00
Compare commits
147 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 197d53e0a1 | |||
| 88208071b0 | |||
| 38dc995884 | |||
| 116b158c1a | |||
| 60a249dd7d | |||
| 490f33c05c | |||
| c1cce0328c | |||
| ba9d02ecb3 | |||
| ee497d68d0 | |||
| 8572e6bc77 | |||
| cdad6abd5a | |||
| d0904a4ca1 | |||
| 3a838eaa69 | |||
| ce64f22779 | |||
| d92102d951 | |||
| a1ca18b780 | |||
| 22c969c88c | |||
| 8458c2a3ca | |||
| e6dff6ef93 | |||
| edee0f1ce7 | |||
| 1f87e4aa1b | |||
| a6a2a78585 | |||
| 2668b06886 | |||
| 27ffe14e79 | |||
| 6c7706c8f1 | |||
| 710299161a | |||
| 22dba65610 | |||
| 73be444cea | |||
| c7bae0d677 | |||
| c5522c9fda | |||
| ce2caf3937 | |||
| 5e09110558 | |||
| afe467bec7 | |||
| 7f1e051f1a | |||
| 978c70a78a | |||
| faaa87cc64 | |||
| 6418c9e044 | |||
| 5f6024062f | |||
| 7eeda81f1e | |||
| 761ec9645c | |||
| b6f0cba6a7 | |||
| de5295ffa7 | |||
| c8e9dec549 | |||
| a68b58aefe | |||
| f3b18c1f1b | |||
| b4a5810e13 | |||
| ca479d90cf | |||
| 8aa5c9b64f | |||
| 728f606b4d | |||
| b5dd975ad1 | |||
| 693995dd2b | |||
| 7601996544 | |||
| 4d92cfc63e | |||
| 6d98301424 | |||
| 4fa09528b6 | |||
| a443dfb2d9 | |||
| b75f1ea632 | |||
| a934d8131c | |||
| 8f331ff0b3 | |||
| d933707cad | |||
| f5f7c094a1 | |||
| ba8244feea | |||
| fae08e9091 | |||
| eedfc6a1c9 | |||
| 57f7f6597c | |||
| fbc06c1604 | |||
| 47f6fd61a7 | |||
| b3d5862cd1 | |||
| 7da82b6646 | |||
| 9ca966eb1f | |||
| da0fb3dc36 | |||
| 306f915aaf | |||
| fd3794fa03 | |||
| 3c5e076101 | |||
| 17c826882a | |||
| c37ff75c41 | |||
| 2c1b7a1519 | |||
| 7bb94d25f9 | |||
| 28316a48f4 | |||
| 58e1b2da94 | |||
| 2a86901c5f | |||
| 24a109da76 | |||
| 691ca31510 | |||
| dfe862ad7e | |||
| dea4219815 | |||
| ededd9a1fc | |||
| 7348f88758 | |||
| 2b6d6604a9 | |||
| 8627633263 | |||
| c065419269 | |||
| 8d4025257f | |||
| 87857b903f | |||
| a22c6032ec | |||
| 6237bf1164 | |||
| b0102f69e7 | |||
| f0c4e38261 | |||
| 3fe050caf2 | |||
| 43b64e09e5 | |||
| 02927cdae7 | |||
| 77bc912ed1 | |||
| 8de5ac9829 | |||
| a9e44ea16d | |||
| 5105cd9b70 | |||
| 3d90afa4c6 | |||
| cd6fef8397 | |||
| f229f9d3b1 | |||
| a4802bce49 | |||
| 09a6cad414 | |||
| 9dd5b55b3a | |||
| b56a5fd91e | |||
| 209a5f095a | |||
| 353b4b1bc7 | |||
| ed45b2b3f1 | |||
| 2c282c41af | |||
| 69f62d13fb | |||
| 328e31bdcd | |||
| df2a0478d0 | |||
| 18c17a1a52 | |||
| ca237ff80c | |||
| a0579ee8a1 | |||
| 83733cc469 | |||
| 71d9e80152 | |||
| c777d2abe6 | |||
| 6608fd24bc | |||
| ebb171489a | |||
| 788be37f87 | |||
| a0e0231358 | |||
| eb5e3600d1 | |||
| 678031d48d | |||
| a79e655a39 | |||
| defe9ff649 | |||
| f88ada5af0 | |||
| 9cca232ba0 | |||
| 638dd689bd | |||
| 1184d9e566 | |||
| fec631fe5a | |||
| a1486868fa | |||
| c5a9e8cdb2 | |||
| 5d4cff076a | |||
| 8ed8d2e0f5 | |||
| d01ae5e1d7 | |||
| 1873e0d389 | |||
| eaa8ee9bce | |||
| 25350fb87e | |||
| cf166ff153 | |||
| 3230aafc6c | |||
| afdf196abc |
@@ -1,4 +1,7 @@
|
||||
.git
|
||||
circle.yml
|
||||
LICENSE
|
||||
VERSION
|
||||
README.md
|
||||
Changelog.md
|
||||
Makefile
|
||||
|
||||
@@ -1,5 +1,32 @@
|
||||
# Changelog
|
||||
|
||||
**9.4-11**
|
||||
- added `PG_PASSWORD` variable to specify password for `postgres` user
|
||||
|
||||
**9.4-9**
|
||||
- complete rewrite
|
||||
- `PSQL_TRUST_LOCALNET` config parameter renamed to `PG_TRUST_LOCALNET`
|
||||
- `PSQL_MODE` config parameter renamed to `REPLICATION_MODE`
|
||||
- `PSQL_SSLMODE` config parameter renamed to `REPLICATION_SSLMODE`
|
||||
- defined `/etc/postgresql/certs` as the mountpoint to install SSL key and certificate
|
||||
- added `PG_SSL` parameter to enable/disable SSL support
|
||||
- `DB_LOCALE` config parameter renamed to `PG_LOCALE`
|
||||
- complete rewrite of the README
|
||||
- add support for creating backups using `pg_basebackup`
|
||||
- removed `PG_LOCALE` option (doesn't work!)
|
||||
- added `DEBUG` option to enable bash debugging
|
||||
|
||||
**9.4-2**
|
||||
- added replication options
|
||||
|
||||
**9.4-1**
|
||||
- start: removed `pwfile` logic
|
||||
- init: added `USERMAP_*` configuration options
|
||||
- base image update to fix SSL vulnerability
|
||||
|
||||
**9.4**
|
||||
- postgresql: upgrade to 9.4
|
||||
|
||||
**9.1-2**
|
||||
- use the official postgresql apt repo
|
||||
- feature: automatic data migration on upgrade
|
||||
|
||||
+25
-13
@@ -1,20 +1,32 @@
|
||||
FROM sameersbn/ubuntu:14.04.20150120
|
||||
FROM sameersbn/ubuntu:14.04.20151213
|
||||
MAINTAINER sameer@damagehead.com
|
||||
|
||||
ENV PG_VERSION 9.1
|
||||
ENV PG_APP_HOME="/etc/docker-postgresql"\
|
||||
PG_VERSION=9.4 \
|
||||
PG_USER=postgres \
|
||||
PG_HOME=/var/lib/postgresql \
|
||||
PG_RUNDIR=/run/postgresql \
|
||||
PG_LOGDIR=/var/log/postgresql \
|
||||
PG_CERTDIR=/etc/postgresql/certs
|
||||
|
||||
ENV PG_BINDIR=/usr/lib/postgresql/${PG_VERSION}/bin \
|
||||
PG_DATADIR=${PG_HOME}/${PG_VERSION}/main
|
||||
|
||||
RUN wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add - \
|
||||
&& echo 'deb http://apt.postgresql.org/pub/repos/apt/ trusty-pgdg main' > /etc/apt/sources.list.d/pgdg.list \
|
||||
&& apt-get update \
|
||||
&& apt-get install -y postgresql-${PG_VERSION} postgresql-client-${PG_VERSION} pwgen \
|
||||
&& rm -rf /var/lib/postgresql \
|
||||
&& rm -rf /var/lib/apt/lists/* # 20141001
|
||||
&& DEBIAN_FRONTEND=noninteractive apt-get install -y postgresql-${PG_VERSION} postgresql-client-${PG_VERSION} postgresql-contrib-${PG_VERSION} \
|
||||
&& ln -sf ${PG_DATADIR}/postgresql.conf /etc/postgresql/${PG_VERSION}/main/postgresql.conf \
|
||||
&& ln -sf ${PG_DATADIR}/pg_hba.conf /etc/postgresql/${PG_VERSION}/main/pg_hba.conf \
|
||||
&& ln -sf ${PG_DATADIR}/pg_ident.conf /etc/postgresql/${PG_VERSION}/main/pg_ident.conf \
|
||||
&& rm -rf ${PG_HOME} \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
ADD start /start
|
||||
RUN chmod 755 /start
|
||||
COPY runtime/ ${PG_APP_HOME}/
|
||||
COPY entrypoint.sh /sbin/entrypoint.sh
|
||||
RUN chmod 755 /sbin/entrypoint.sh
|
||||
|
||||
EXPOSE 5432
|
||||
|
||||
VOLUME ["/var/lib/postgresql"]
|
||||
VOLUME ["/run/postgresql"]
|
||||
|
||||
CMD ["/start"]
|
||||
EXPOSE 5432/tcp
|
||||
VOLUME ["${PG_HOME}", "${PG_RUNDIR}"]
|
||||
WORKDIR ${PG_HOME}
|
||||
ENTRYPOINT ["/sbin/entrypoint.sh"]
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
all: build
|
||||
|
||||
build:
|
||||
@docker build --tag=${USER}/postgresql .
|
||||
@docker build --tag=sameersbn/postgresql .
|
||||
|
||||
release: build
|
||||
@docker build --tag=sameersbn/postgresql:$(shell cat VERSION) .
|
||||
|
||||
@@ -1,239 +1,382 @@
|
||||
# Table of Contents
|
||||
[](https://circleci.com/gh/sameersbn/docker-postgresql) [](https://quay.io/repository/sameersbn/postgresql) [](https://imagelayers.io/?images=sameersbn/postgresql:latest 'Get your own badge on imagelayers.io')
|
||||
|
||||
# sameersbn/postgresql:9.4-11
|
||||
|
||||
- [Introduction](#introduction)
|
||||
- [Changelog](Changelog.md)
|
||||
- [Contributing](#contributing)
|
||||
- [Reporting Issues](#reporting-issues)
|
||||
- [Installation](#installation)
|
||||
- [Quick Start](#quick-start)
|
||||
- [Creating User and Database at Launch](creating-user-and-database-at-launch)
|
||||
- [Configuration](#configuration)
|
||||
- [Data Store](#data-store)
|
||||
- [Securing the server](#securing-the-server)
|
||||
- [Shell Access](#shell-access)
|
||||
- [Upgrading](#upgrading)
|
||||
- [Contributing](#contributing)
|
||||
- [Issues](#issues)
|
||||
- [Getting started](#getting-started)
|
||||
- [Installation](#installation)
|
||||
- [Quickstart](#quickstart)
|
||||
- [Persistence](#persistence)
|
||||
- [Trusting local connections](#trusting-local-connections)
|
||||
- [Setting `postgres` user password](#setting-postgres-user-password)
|
||||
- [Creating database user](#creating-database-user)
|
||||
- [Creating databases](#creating-databases)
|
||||
- [Enabling unaccent extension](#enabling-unaccent-extension)
|
||||
- [Granting user access to a database](#granting-user-access-to-a-database)
|
||||
- [Creating replication user](#creating-replication-user)
|
||||
- [Setting up a replication cluster](#setting-up-a-replication-cluster)
|
||||
- [Creating a snapshot](#creating-a-snapshot)
|
||||
- [Creating a backup](#creating-a-backup)
|
||||
- [Command-line arguments](#command-line-arguments)
|
||||
- [Logs](#logs)
|
||||
- [UID/GID mapping](#uid-gid-mapping)
|
||||
- [Maintenance](#maintenance)
|
||||
- [Upgrading](#upgrading)
|
||||
- [Shell Access](#shell-access)
|
||||
|
||||
# Introduction
|
||||
|
||||
Dockerfile to build a PostgreSQL container image which can be linked to other containers.
|
||||
`Dockerfile` to create a [Docker](https://www.docker.com/) container image for [PostgreSQL](http://postgresql.org/).
|
||||
|
||||
# Contributing
|
||||
PostgreSQL is an object-relational database management system (ORDBMS) with an emphasis on extensibility and standards-compliance [[source](https://en.wikipedia.org/wiki/PostgreSQL)].
|
||||
|
||||
## Contributing
|
||||
|
||||
If you find this image useful here's how you can help:
|
||||
|
||||
- Send a Pull Request with your awesome new features and bug fixes
|
||||
- Help new users with [Issues](https://github.com/sameersbn/docker-postgresql/issues) they may encounter
|
||||
- Send me a tip via [Bitcoin](https://www.coinbase.com/sameersbn) or using [Gratipay](https://gratipay.com/sameersbn/)
|
||||
- Send a pull request with your awesome features and bug fixes
|
||||
- Help users resolve their [issues](../../issues?q=is%3Aopen+is%3Aissue).
|
||||
- Support the development of this image with a [donation](http://www.damagehead.com/donate/)
|
||||
|
||||
# Reporting Issues
|
||||
## Issues
|
||||
|
||||
Docker is a relatively new project and is active being developed and tested by a thriving community of developers and testers and every release of docker features many enhancements and bugfixes.
|
||||
Before reporting your issue please try updating Docker to the latest version and check if it resolves the issue. Refer to the Docker [installation guide](https://docs.docker.com/installation) for instructions.
|
||||
|
||||
Given the nature of the development and release cycle it is very important that you have the latest version of docker installed because any issue that you encounter might have already been fixed with a newer docker release.
|
||||
SELinux users should try disabling SELinux using the command `setenforce 0` to see if it resolves the issue.
|
||||
|
||||
For ubuntu users I suggest [installing docker](https://docs.docker.com/installation/ubuntulinux/) using docker's own package repository since the version of docker packaged in the ubuntu repositories are a little dated.
|
||||
If the above recommendations do not help then [report your issue](../../issues/new) along with the following information:
|
||||
|
||||
Here is the shortform of the installation of an updated version of docker on ubuntu.
|
||||
- Output of the `docker version` and `docker info` commands
|
||||
- The `docker run` command or `docker-compose.yml` used to start the image. Mask out the sensitive bits.
|
||||
- Please state if you are using [Boot2Docker](http://www.boot2docker.io), [VirtualBox](https://www.virtualbox.org), etc.
|
||||
|
||||
# Getting started
|
||||
|
||||
## Installation
|
||||
|
||||
Automated builds of the image are available on [Dockerhub](https://hub.docker.com/r/sameersbn/postgresql) and is the recommended method of installation.
|
||||
|
||||
> **Note**: Builds are also available on [Quay.io](https://quay.io/repository/sameersbn/postgresql)
|
||||
|
||||
```bash
|
||||
sudo apt-get purge docker.io
|
||||
curl -s https://get.docker.io/ubuntu/ | sudo sh
|
||||
sudo apt-get update
|
||||
sudo apt-get install lxc-docker
|
||||
docker pull sameersbn/postgresql:9.4-11
|
||||
```
|
||||
|
||||
Fedora and RHEL/CentOS users should try disabling selinux with `setenforce 0` and check if resolves the issue. If it does than there is not much that I can help you with. You can either stick with selinux disabled (not recommended by redhat) or switch to using ubuntu.
|
||||
|
||||
If using the latest docker version and/or disabling selinux does not fix the issue then please file a issue request on the [issues](https://github.com/sameersbn/docker-postgresql/issues) page.
|
||||
|
||||
In your issue report please make sure you provide the following information:
|
||||
|
||||
- The host ditribution and release version.
|
||||
- Output of the `docker version` command
|
||||
- Output of the `docker info` command
|
||||
- The `docker run` command you used to run the image (mask out the sensitive bits).
|
||||
|
||||
# Installation
|
||||
|
||||
Pull the latest version of the image from the docker index. This is the recommended method of installation as it is easier to update image in the future. These builds are performed by the **Docker Trusted Build** service.
|
||||
Alternatively you can build the image yourself.
|
||||
|
||||
```bash
|
||||
docker pull sameersbn/postgresql:9.1-2
|
||||
docker build -t sameersbn/postgresql github.com/sameersbn/docker-postgresql
|
||||
```
|
||||
|
||||
Alternately you can build the image yourself.
|
||||
## Quickstart
|
||||
|
||||
Start PostgreSQL using:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/sameersbn/docker-postgresql.git
|
||||
cd docker-postgresql
|
||||
docker build -t="$USER/postgresql" .
|
||||
docker run --name postgresql -itd --restart always \
|
||||
--publish 5432:5432 \
|
||||
--volume /srv/docker/postgresql:/var/lib/postgresql \
|
||||
sameersbn/postgresql:9.4-11
|
||||
```
|
||||
|
||||
# Quick Start
|
||||
|
||||
Run the postgresql image
|
||||
Login to the PostgreSQL server using:
|
||||
|
||||
```bash
|
||||
docker run --name postgresql -d sameersbn/postgresql:9.1-2
|
||||
docker exec -it postgresql sudo -u postgres psql
|
||||
```
|
||||
|
||||
The simplest way to login to the postgresql container as the administrative `postgres` user is to use the `--volumes-from` docker option to connect to the postgresql server over the unix socket.
|
||||
*Alternatively, you can use the sample [docker-compose.yml](docker-compose.yml) file to start the container using [Docker Compose](https://docs.docker.com/compose/)*
|
||||
|
||||
## Persistence
|
||||
|
||||
For PostgreSQL to preserve its state across container shutdown and startup you should mount a volume at `/var/lib/postgresql`.
|
||||
|
||||
> *The [Quickstart](#quickstart) command already mounts a volume for persistence.*
|
||||
|
||||
SELinux users should update the security context of the host mountpoint so that it plays nicely with Docker:
|
||||
|
||||
```bash
|
||||
docker run -it --rm --volumes-from=postgresql \
|
||||
sameersbn/postgresql:9.1-2 sudo -u postgres -H psql
|
||||
mkdir -p /srv/docker/postgresql
|
||||
chcon -Rt svirt_sandbox_file_t /srv/docker/postgresql
|
||||
```
|
||||
|
||||
Alternately you can fetch the password set for the `postgres` user from the container logs.
|
||||
## Trusting local connections
|
||||
|
||||
By default connections to the PostgreSQL server need to authenticated using a password. If desired you can trust connections from the local network using the `PG_TRUST_LOCALNET` variable.
|
||||
|
||||
```bash
|
||||
docker logs postgresql
|
||||
docker run --name postgresql -itd --restart always \
|
||||
--env 'PG_TRUST_LOCALNET=true' \
|
||||
sameersbn/postgresql:9.4-11
|
||||
```
|
||||
|
||||
In the output you will notice the following lines with the password:
|
||||
> **Note**
|
||||
>
|
||||
> The local network here is network to which the container is attached. This has different meanings depending on the `--net` parameter specified while starting the container. In the default configuration, this parameter would trust connections from other containers on the `docker0` bridge.
|
||||
|
||||
## Setting `postgres` user password
|
||||
|
||||
By default the `postgres` user is not assigned a password and as a result you can only login to the PostgreSQL server locally. If you wish to login remotely to the PostgreSQL server as the `postgres` user, you will need to assign a password for the user using the `PG_PASSWORD` variable.
|
||||
|
||||
```bash
|
||||
|------------------------------------------------------------------|
|
||||
| PostgreSQL User: postgres, Password: xxxxxxxxxxxxxx |
|
||||
| |
|
||||
| To remove the PostgreSQL login credentials from the logs, please |
|
||||
| make a note of password and then delete the file pwfile |
|
||||
| from the data store. |
|
||||
|------------------------------------------------------------------|
|
||||
docker run --name postgresql -itd --restart always \
|
||||
--env 'PG_PASSWORD=passw0rd' \
|
||||
sameersbn/postgresql:9.4-11
|
||||
```
|
||||
|
||||
To test if the postgresql server is working properly, try connecting to the server.
|
||||
|
||||
> **Note**
|
||||
>
|
||||
> - When [persistence](#persistence) is in use, `PG_PASSWORD` is effective on the first run.
|
||||
> - This feature is only available in the `latest` and versions > `9.4-10`
|
||||
|
||||
## Creating database user
|
||||
|
||||
A new PostgreSQL database user can be created by specifying the `DB_USER` and `DB_PASS` variables while starting the container.
|
||||
|
||||
```bash
|
||||
psql -U postgres -h $(docker inspect --format {{.NetworkSettings.IPAddress}} postgresql)
|
||||
docker run --name postgresql -itd --restart always \
|
||||
--env 'DB_USER=dbuser' --env 'DB_PASS=dbuserpass' \
|
||||
sameersbn/postgresql:9.4-11
|
||||
```
|
||||
|
||||
# Creating User and Database at Launch
|
||||
> **Notes**
|
||||
>
|
||||
> - The created user can login remotely
|
||||
> - The container will error out if a password is not specified for the user
|
||||
> - No changes will be made if the user already exists
|
||||
> - Only a single user can be created at each launch
|
||||
|
||||
The image allows you to create a user and database at launch time.
|
||||
## Creating databases
|
||||
|
||||
To create a new user you should specify the `DB_USER` and `DB_PASS` variables. The following command will create a new user *dbuser* with the password *dbpass*.
|
||||
A new PostgreSQL database can be created by specifying the `DB_NAME` variable while starting the container.
|
||||
|
||||
```bash
|
||||
docker run --name postgresql -d \
|
||||
-e 'DB_USER=dbuser' -e 'DB_PASS=dbpass' \
|
||||
sameersbn/postgresql:9.1-2
|
||||
docker run --name postgresql -itd --restart always \
|
||||
--env 'DB_NAME=dbname' \
|
||||
sameersbn/postgresql:9.4-11
|
||||
```
|
||||
|
||||
**NOTE**
|
||||
- If the password is not specified the user will not be created
|
||||
- If the user user already exists no changes will be made
|
||||
Additionally, more than one database can be created by specifying a comma separated list of database names in `DB_NAME`. For example, the following command creates two new databases named `dbname1` and `dbname2`.
|
||||
|
||||
Similarly, you can also create a new database by specifying the database name in the `DB_NAME` variable.
|
||||
*This feature is only available in releases greater than `9.1-1`*
|
||||
|
||||
```bash
|
||||
docker run --name postgresql -d \
|
||||
-e 'DB_NAME=dbname' sameersbn/postgresql:9.1-2
|
||||
docker run --name postgresql -itd --restart always \
|
||||
--env 'DB_NAME=dbname1,dbname2' \
|
||||
sameersbn/postgresql:9.4-11
|
||||
```
|
||||
|
||||
You may also specify a comma separated list of database names in the `DB_NAME` variable. The following command creates two new databases named *dbname1* and *dbname2 (p.s. this feature is only available in releases greater than 9.1-2)*
|
||||
# Enabling unaccent extension
|
||||
|
||||
Unaccent is a text search dictionary that removes accents (diacritic signs) from lexemes. It's a filtering dictionary, which means its output is always passed to the next dictionary (if any), unlike the normal behavior of dictionaries. This allows accent-insensitive processing for full text search [[source](http://www.postgresql.org/docs/9.4/static/unaccent.html)].
|
||||
|
||||
You can enable the unaccent extension on database(s) by specifying `DB_UNACCENT=true`. For example, the following command enables the unaccent extension for the `dbname` database.
|
||||
|
||||
```bash
|
||||
docker run --name postgresql -d \
|
||||
-e 'DB_NAME=dbname1,dbname2' sameersbn/postgresql:latest
|
||||
docker run --name postgresql -itd \
|
||||
--env 'DB_NAME=dbname' --env 'DB_UNACCENT=true' \
|
||||
sameersbn/postgresql:9.4-11
|
||||
```
|
||||
|
||||
If the `DB_USER` and `DB_PASS` variables are also specified while creating the database, then the user is granted access to the database(s).
|
||||
*By default the unaccent extension is disabled*
|
||||
|
||||
For example,
|
||||
## Granting user access to a database
|
||||
|
||||
If the `DB_USER` and `DB_PASS` variables are specified along with the `DB_NAME` variable, then the user specified in `DB_USER` will be granted access to all the databases listed in `DB_NAME`. Note that if the user and/or databases do not exist, they will be created.
|
||||
|
||||
```bash
|
||||
docker run --name postgresql -d \
|
||||
-e 'DB_USER=dbuser' -e 'DB_PASS=dbpass' -e 'DB_NAME=dbname' \
|
||||
sameersbn/postgresql:9.1-2
|
||||
docker run --name postgresql -itd --restart always \
|
||||
--env 'DB_USER=dbuser' --env 'DB_PASS=dbuserpass' \
|
||||
--env 'DB_NAME=dbname1,dbname2' \
|
||||
sameersbn/postgresql:9.4-11
|
||||
```
|
||||
|
||||
, will create a user *dbuser* with the password *dbpass*. It will also create a database named *dbname* and the *dbuser* user will have full access to the *dbname* database.
|
||||
In the above example `dbuser` with be granted access to both the `dbname1` and `dbname2` databases.
|
||||
|
||||
# Configuration
|
||||
## Creating replication user
|
||||
|
||||
## Data Store
|
||||
|
||||
For data persistence a volume should be mounted at `/var/lib/postgresql`.
|
||||
|
||||
SELinux users are also required to change the security context of the mount point so that it plays nicely with selinux.
|
||||
Similar to the creation of a database user, a new PostgreSQL replication user can be created by specifying the `REPLICATION_USER` and `REPLICATION_PASS` variables while starting the container.
|
||||
|
||||
```bash
|
||||
mkdir -p /opt/postgresql/data
|
||||
sudo chcon -Rt svirt_sandbox_file_t /opt/postgresql/data
|
||||
docker run --name postgresql -itd --restart always \
|
||||
--env 'REPLICATION_USER=repluser' --env 'REPLICATION_PASS=repluserpass' \
|
||||
sameersbn/postgresql:9.4-11
|
||||
```
|
||||
|
||||
The updated run command looks like this.
|
||||
> **Notes**
|
||||
>
|
||||
> - The created user can login remotely
|
||||
> - The container will error out if a password is not specified for the user
|
||||
> - No changes will be made if the user already exists
|
||||
> - Only a single user can be created at each launch
|
||||
|
||||
*It is a good idea to create a replication user even if you are not going to use it as it will allow you to setup slave nodes and/or generate snapshots and backups when the need arises.*
|
||||
|
||||
## Setting up a replication cluster
|
||||
|
||||
When the container is started, it is by default configured to act as a master node in a replication cluster. This means that you can scale your PostgreSQL database backend when the need arises without incurring any downtime. However do note that a replication user must exist on the master node for this to work.
|
||||
|
||||
Begin by creating the master node of our cluster:
|
||||
|
||||
```bash
|
||||
docker run --name postgresql -d \
|
||||
-v /opt/postgresql/data:/var/lib/postgresql sameersbn/postgresql:9.1-2
|
||||
docker run --name postgresql-master -itd --restart always \
|
||||
--env 'DB_USER=dbuser' --env 'DB_PASS=dbuserpass' --env 'DB_NAME=dbname' \
|
||||
--env 'REPLICATION_USER=repluser' --env 'REPLICATION_PASS=repluserpass' \
|
||||
sameersbn/postgresql:9.4-11
|
||||
```
|
||||
|
||||
This will make sure that the data stored in the database is not lost when the image is stopped and started again.
|
||||
Notice that no additional arguments are specified while starting the master node of the cluster.
|
||||
|
||||
## Securing the server
|
||||
To create a replication slave the `REPLICATION_MODE` variable should be set to `slave` and additionally the `REPLICATION_HOST`, `REPLICATION_PORT`, `REPLICATION_SSLMODE`, `REPLICATION_USER` and `REPLICATION_PASS` variables should be specified.
|
||||
|
||||
By default a randomly generated password is assigned for the postgres user. The password is stored in a file named `pwfile` in the data store and is printed in the logs.
|
||||
|
||||
If you dont want this password to be displayed in the logs, then please note down the password listed in `/opt/postgresql/data/pwfile` and then delete the file.
|
||||
Create a slave node:
|
||||
|
||||
```bash
|
||||
cat /opt/postgresql/data/pwfile
|
||||
rm /opt/postgresql/data/pwfile
|
||||
docker run --name postgresql-slave01 -itd --restart always \
|
||||
--link postgresql-master:master \
|
||||
--env 'REPLICATION_MODE=slave' --env 'REPLICATION_SSLMODE=prefer' \
|
||||
--env 'REPLICATION_HOST=master' --env 'REPLICATION_PORT=5432' \
|
||||
--env 'REPLICATION_USER=repluser' --env 'REPLICATION_PASS=repluserpass' \
|
||||
sameersbn/postgresql:9.4-11
|
||||
```
|
||||
|
||||
Alternately, you can change the password of the postgres user
|
||||
*In the above command, we used docker links so that we can address the master node using the `master` alias in `REPLICATION_HOST`.*
|
||||
|
||||
> **Note**
|
||||
>
|
||||
> - The default value of `REPLICATION_PORT` is `5432`
|
||||
> - The default value of `REPLICATION_SSLMODE` is `prefer`
|
||||
> - The value of `REPLICATION_USER` and `REPLICATION_PASS` should be the same as the ones specified on the master node.
|
||||
> - With [persistence](#persistence) in use, if the container is stopped and started, for the container continue to function as a slave you need to ensure that `REPLICATION_MODE=slave` is defined in the containers environment. In the absense of which the slave configuration will be turned off and the node will allow writing to it while having the last synced data from the master.
|
||||
|
||||
And just like that with minimal effort you have a PostgreSQL replication cluster setup. You can create additional slaves to scale the cluster horizontally.
|
||||
|
||||
Here are some important notes about a PostgreSQL replication cluster:
|
||||
|
||||
- Writes can only occur on the master
|
||||
- Slaves are read-only
|
||||
- For best performance, limit the reads to the slave nodes
|
||||
|
||||
## Creating a snapshot
|
||||
|
||||
Similar to a creating replication slave node, you can create a snapshot of the master by specifying `REPLICATION_MODE=snapshot`.
|
||||
|
||||
Once the master node is created as specified in [Setting up a replication cluster](#setting-up-a-replication-cluster), you can create a snapshot using:
|
||||
|
||||
```bash
|
||||
psql -U postgres -h $(docker inspect --format {{.NetworkSettings.IPAddress}} postgresql)
|
||||
\password postgres
|
||||
docker run --name postgresql-snapshot -itd --restart always \
|
||||
--link postgresql-master:master \
|
||||
--env 'REPLICATION_MODE=snapshot' --env 'REPLICATION_SSLMODE=prefer' \
|
||||
--env 'REPLICATION_HOST=master' --env 'REPLICATION_PORT=5432' \
|
||||
--env 'REPLICATION_USER=repluser' --env 'REPLICATION_PASS=repluserpass' \
|
||||
sameersbn/postgresql:9.4-11
|
||||
```
|
||||
|
||||
# Shell Access
|
||||
The difference between a slave and a snapshot is that a slave is read-only and updated whenever the master data is updated (streaming replication), while a snapshot is read-write and is not updated after the initial snapshot of the data from the master.
|
||||
|
||||
For debugging and maintenance purposes you may want access the containers shell. If you are using docker version `1.3.0` or higher you can access a running containers shell using `docker exec` command.
|
||||
This is useful for developers to quickly snapshot the current state of a live database and use it for development/debugging purposes without altering the database on the live instance.
|
||||
|
||||
## Creating a backup
|
||||
|
||||
Just as the case of setting up a slave node or generating a snapshot, you can also create a backup of the data on the master by specifying `REPLICATION_MODE=backup`.
|
||||
|
||||
> The backups are generated with [pg_basebackup](http://www.postgresql.org/docs/9.4/static/app-pgbasebackup.html) using the replication protocol.
|
||||
|
||||
Once the master node is created as specified in [Setting up a replication cluster](#setting-up-a-replication-cluster), you can create a point-in-time backup using:
|
||||
|
||||
```bash
|
||||
docker run --name postgresql-backup -it --rm \
|
||||
--link postgresql-master:master \
|
||||
--env 'REPLICATION_MODE=backup' --env 'REPLICATION_SSLMODE=prefer' \
|
||||
--env 'REPLICATION_HOST=master' --env 'REPLICATION_PORT=5432' \
|
||||
--env 'REPLICATION_USER=repluser' --env 'REPLICATION_PASS=repluserpass' \
|
||||
--volume /srv/docker/backups/postgresql.$(date +%Y%m%d%H$M%S):/var/lib/postgresql \
|
||||
sameersbn/postgresql:9.4-11
|
||||
```
|
||||
|
||||
Once the backup is generated, the container will exit and the backup of the master data will be available at `/srv/docker/backups/postgresql.XXXXXXXXXXXX/`. Restoring the backup involves starting a container with the data in `/srv/docker/backups/postgresql.XXXXXXXXXXXX`.
|
||||
|
||||
## Command-line arguments
|
||||
|
||||
You can customize the launch command of PostgreSQL server by specifying arguments for `postgres` on the `docker run` command. For example the following command enables connection logging:
|
||||
|
||||
```bash
|
||||
docker run --name postgresql -itd --restart always \
|
||||
sameersbn/postgresql:9.4-11 -c log_connections=on
|
||||
```
|
||||
|
||||
Please refer to the documentation of [postgres](http://www.postgresql.org/docs/9.4/static/app-postgres.html) for the complete list of available options.
|
||||
|
||||
## Logs
|
||||
|
||||
By default the PostgreSQL server logs are sent to the standard output. Using the [Command-line arguments](#command-line-arguments) feature you can configure the PostgreSQL server to send the log output to a file using the `-c logging_collector=on` argument:
|
||||
|
||||
```bash
|
||||
docker run --name postgresql -itd --restart always \
|
||||
sameersbn/postgresql:9.4-11 -c logging_collector=on
|
||||
```
|
||||
|
||||
To access the PostgreSQL logs you can use `docker exec`. For example:
|
||||
|
||||
```bash
|
||||
docker exec -it postgresql tail -f /var/log/postgresql/postgresql-9.4-main.log
|
||||
```
|
||||
|
||||
# UID/GID mapping
|
||||
|
||||
The files and processes created by the container are owned by the `postgres` user that is internal to the container. In the absense of user namespace in docker the UID and GID of the containers `postgres` user may have different meaning on the host.
|
||||
|
||||
For example, a user on the host with the same UID and/or GID as the `postgres` user of the container will be able to access the data in the persistent volumes mounted from the host as well as be able to KILL the `postgres` server process started by the container.
|
||||
|
||||
To circumvent this issue you can specify the UID and GID for the `postgres` user of the container using the `USERMAP_UID` and `USERMAP_GID` variables respectively.
|
||||
|
||||
For example, if you want to assign the `postgres` user of the container the UID and GID `999`:
|
||||
|
||||
```bash
|
||||
docker run --name postgresql -itd --restart always \
|
||||
--env 'USERMAP_UID=999' --env 'USERMAP_GID=999' \
|
||||
sameersbn/postgresql:9.4-11
|
||||
```
|
||||
|
||||
# Maintenance
|
||||
|
||||
## Upgrading
|
||||
|
||||
To upgrade to newer releases:
|
||||
|
||||
1. Download the updated Docker image:
|
||||
|
||||
```bash
|
||||
docker pull sameersbn/postgresql:9.4-11
|
||||
```
|
||||
|
||||
2. Stop the currently running image:
|
||||
|
||||
```bash
|
||||
docker stop postgresql
|
||||
```
|
||||
|
||||
3. Remove the stopped container
|
||||
|
||||
```bash
|
||||
docker rm -v postgresql
|
||||
```
|
||||
|
||||
4. Start the updated image
|
||||
|
||||
```bash
|
||||
docker run --name postgresql -itd \
|
||||
[OPTIONS] \
|
||||
sameersbn/postgresql:9.4-11
|
||||
```
|
||||
|
||||
## Shell Access
|
||||
|
||||
For debugging and maintenance purposes you may want access the containers shell. If you are using Docker version `1.3.0` or higher you can access a running containers shell by starting `bash` using `docker exec`:
|
||||
|
||||
```bash
|
||||
docker exec -it postgresql bash
|
||||
```
|
||||
|
||||
If you are using an older version of docker, you can use the [nsenter](http://man7.org/linux/man-pages/man1/nsenter.1.html) linux tool (part of the util-linux package) to access the container shell.
|
||||
|
||||
Some linux distros (e.g. ubuntu) use older versions of the util-linux which do not include the `nsenter` tool. To get around this @jpetazzo has created a nice docker image that allows you to install the `nsenter` utility and a helper script named `docker-enter` on these distros.
|
||||
|
||||
To install `nsenter` execute the following command on your host,
|
||||
|
||||
```bash
|
||||
docker run --rm -v /usr/local/bin:/target jpetazzo/nsenter
|
||||
```
|
||||
|
||||
Now you can access the container shell using the command
|
||||
|
||||
```bash
|
||||
sudo docker-enter postgresql
|
||||
```
|
||||
|
||||
For more information refer https://github.com/jpetazzo/nsenter
|
||||
|
||||
# Upgrading
|
||||
|
||||
To upgrade to newer releases, simply follow this 3 step upgrade procedure.
|
||||
|
||||
- **Step 1**: Stop the currently running image
|
||||
|
||||
```bash
|
||||
docker stop postgresql
|
||||
```
|
||||
|
||||
- **Step 2**: Update the docker image.
|
||||
|
||||
```bash
|
||||
docker pull sameersbn/postgresql:9.1-2
|
||||
```
|
||||
|
||||
- **Step 3**: Start the image
|
||||
|
||||
```bash
|
||||
docker run --name postgresql -d [OPTIONS] sameersbn/postgresql:9.1-2
|
||||
```
|
||||
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
machine:
|
||||
services:
|
||||
- docker
|
||||
dependencies:
|
||||
cache_directories:
|
||||
- "~/docker-postgresql"
|
||||
override:
|
||||
- docker info
|
||||
- if [[ -e ~/docker-postgresql/image.tar ]]; then docker load --input ~/docker-postgresql/image.tar; fi
|
||||
- docker build -t sameersbn/postgresql .
|
||||
- mkdir -p ~/docker-postgresql; docker save --output ~/docker-postgresql/image.tar sameersbn/postgresql
|
||||
test:
|
||||
override:
|
||||
- docker run -d --name=postgresql sameersbn/postgresql; sleep 10
|
||||
- docker run -it --volumes-from=postgresql sameersbn/postgresql sudo -u postgres -H psql -c "\conninfo"
|
||||
@@ -0,0 +1,16 @@
|
||||
PostgreSQL:
|
||||
restart: always
|
||||
image: sameersbn/postgresql:9.4-11
|
||||
ports:
|
||||
- "5432:5432"
|
||||
environment:
|
||||
- DEBUG=false
|
||||
- DB_USER=
|
||||
- DB_PASS=
|
||||
- DB_NAME=
|
||||
- REPLICATION_MODE=
|
||||
- REPLICATION_USER=
|
||||
- REPLICATION_PASS=
|
||||
- REPLICATION_SSLMODE=
|
||||
volumes:
|
||||
- /srv/docker/postgresql:/var/lib/postgresql
|
||||
Executable
+40
@@ -0,0 +1,40 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
source ${PG_APP_HOME}/functions
|
||||
|
||||
[[ ${DEBUG} == true ]] && set -x
|
||||
|
||||
# allow arguments to be passed to postgres
|
||||
if [[ ${1:0:1} = '-' ]]; then
|
||||
EXTRA_ARGS="$@"
|
||||
set --
|
||||
elif [[ ${1} == postgres || ${1} == $(which postgres) ]]; then
|
||||
EXTRA_ARGS="${@:2}"
|
||||
set --
|
||||
fi
|
||||
|
||||
# default behaviour is to launch postgres
|
||||
if [[ -z ${1} ]]; then
|
||||
map_uidgid
|
||||
|
||||
create_datadir
|
||||
create_certdir
|
||||
create_logdir
|
||||
create_rundir
|
||||
|
||||
initialize_database
|
||||
configure_recovery
|
||||
configure_ssl
|
||||
trust_localnet
|
||||
|
||||
create_user
|
||||
create_database
|
||||
create_replication_user
|
||||
|
||||
echo "Starting PostgreSQL ${PG_VERSION}..."
|
||||
exec start-stop-daemon --start --chuid ${PG_USER}:${PG_USER} \
|
||||
--exec ${PG_BINDIR}/postgres -- -D ${PG_DATADIR} ${EXTRA_ARGS}
|
||||
else
|
||||
exec "$@"
|
||||
fi
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
#!/bin/bash
|
||||
|
||||
PG_SSL=${PG_SSL:-}
|
||||
|
||||
PG_TRUST_LOCALNET=${PG_TRUST_LOCALNET:-$PSQL_TRUST_LOCALNET} # backward compatibility
|
||||
PG_TRUST_LOCALNET=${PG_TRUST_LOCALNET:-false}
|
||||
|
||||
REPLICATION_MODE=${REPLICATION_MODE:-$PSQL_MODE} # backward compatibility
|
||||
REPLICATION_MODE=${REPLICATION_MODE:-}
|
||||
REPLICATION_USER=${REPLICATION_USER:-}
|
||||
REPLICATION_PASS=${REPLICATION_PASS:-}
|
||||
REPLICATION_HOST=${REPLICATION_HOST:-}
|
||||
REPLICATION_PORT=${REPLICATION_PORT:-5432}
|
||||
REPLICATION_SSLMODE=${REPLICATION_SSLMODE:-prefer}
|
||||
|
||||
DB_NAME=${DB_NAME:-}
|
||||
DB_USER=${DB_USER:-}
|
||||
DB_PASS=${DB_PASS:-}
|
||||
|
||||
DB_UNACCENT=${DB_UNACCENT:-false}
|
||||
Executable
+348
@@ -0,0 +1,348 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
source ${PG_APP_HOME}/env-defaults
|
||||
|
||||
PG_CONF=${PG_DATADIR}/postgresql.conf
|
||||
PG_HBA_CONF=${PG_DATADIR}/pg_hba.conf
|
||||
PG_IDENT_CONF=${PG_DATADIR}/pg_ident.conf
|
||||
PG_RECOVERY_CONF=${PG_DATADIR}/recovery.conf
|
||||
|
||||
## Execute command as PG_USER
|
||||
exec_as_postgres() {
|
||||
sudo -HEu ${PG_USER} "$@"
|
||||
}
|
||||
|
||||
map_uidgid() {
|
||||
USERMAP_ORIG_UID=$(id -u ${PG_USER})
|
||||
USERMAP_ORIG_GID=$(id -g ${PG_USER})
|
||||
USERMAP_GID=${USERMAP_GID:-${USERMAP_UID:-$USERMAP_ORIG_GID}}
|
||||
USERMAP_UID=${USERMAP_UID:-$USERMAP_ORIG_UID}
|
||||
if [[ ${USERMAP_UID} != ${USERMAP_ORIG_UID} ]] || [[ ${USERMAP_GID} != ${USERMAP_ORIG_GID} ]]; then
|
||||
echo "Adapting uid and gid for ${PG_USER}:${PG_USER} to $USERMAP_UID:$USERMAP_GID"
|
||||
groupmod -g ${USERMAP_GID} ${PG_USER}
|
||||
sed -i -e "s|:${USERMAP_ORIG_UID}:${USERMAP_GID}:|:${USERMAP_UID}:${USERMAP_GID}:|" /etc/passwd
|
||||
fi
|
||||
}
|
||||
|
||||
create_datadir() {
|
||||
echo "Initializing datadir..."
|
||||
mkdir -p ${PG_HOME}
|
||||
if [[ -d ${PG_DATADIR} ]]; then
|
||||
find ${PG_DATADIR} -type f -exec chmod 0600 {} \;
|
||||
find ${PG_DATADIR} -type d -exec chmod 0700 {} \;
|
||||
fi
|
||||
chown -R ${PG_USER}:${PG_USER} ${PG_HOME}
|
||||
}
|
||||
|
||||
create_certdir() {
|
||||
echo "Initializing certdir..."
|
||||
mkdir -p ${PG_CERTDIR}
|
||||
[[ -f ${PG_CERTDIR}/server.crt ]] && chmod 0644 ${PG_CERTDIR}/server.crt
|
||||
[[ -f ${PG_CERTDIR}/server.key ]] && chmod 0640 ${PG_CERTDIR}/server.key
|
||||
chmod 0755 ${PG_CERTDIR}
|
||||
chown -R root:${PG_USER} ${PG_CERTDIR}
|
||||
}
|
||||
|
||||
create_logdir() {
|
||||
echo "Initializing logdir..."
|
||||
mkdir -p ${PG_LOGDIR}
|
||||
chmod -R 1775 ${PG_LOGDIR}
|
||||
chown -R root:${PG_USER} ${PG_LOGDIR}
|
||||
}
|
||||
|
||||
create_rundir() {
|
||||
echo "Initializing rundir..."
|
||||
mkdir -p ${PG_RUNDIR} ${PG_RUNDIR}/${PG_VERSION}-main.pg_stat_tmp
|
||||
chmod -R 0755 ${PG_RUNDIR}
|
||||
chmod g+s ${PG_RUNDIR}
|
||||
chown -R ${PG_USER}:${PG_USER} ${PG_RUNDIR}
|
||||
}
|
||||
|
||||
set_postgresql_param() {
|
||||
local key=${1}
|
||||
local value=${2}
|
||||
if [[ -n ${value} ]]; then
|
||||
local current=$(exec_as_postgres sed -n -e "s/^\("${key}" = '\)\([^ ']*\)\(.*\)$/\2/p" ${PG_CONF})
|
||||
if [[ "${current}" != "${value}" ]]; then
|
||||
echo "‣ Setting postgresql.conf parameter: ${key} = '${value}'"
|
||||
value="$(echo "${value}" | sed 's|[&]|\\&|g')"
|
||||
exec_as_postgres sed -i "s|^[#]*[ ]*${key} = .*|${key} = '${value}'|" ${PG_CONF}
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
set_recovery_param() {
|
||||
local key=${1}
|
||||
local value=${2}
|
||||
local hide=${3}
|
||||
if [[ -n ${value} ]]; then
|
||||
local current=$(exec_as_postgres sed -n -e "s/^\(.*\)\("${key}"=\)\([^ ']*\)\(.*\)$/\3/p" ${PG_RECOVERY_CONF})
|
||||
if [[ "${current}" != "${value}" ]]; then
|
||||
case ${hide} in
|
||||
true) echo "‣ Setting primary_conninfo parameter: ${key}" ;;
|
||||
*) echo "‣ Setting primary_conninfo parameter: ${key} = '${value}'" ;;
|
||||
esac
|
||||
exec_as_postgres sed -i "s|${key}=[^ ']*|${key}=${value}|" ${PG_RECOVERY_CONF}
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
set_hba_param() {
|
||||
local value=${1}
|
||||
if ! grep -q "$(sed "s| | \\\+|g" <<< ${value})" ${PG_HBA_CONF}; then
|
||||
echo "${value}" >> ${PG_HBA_CONF}
|
||||
fi
|
||||
}
|
||||
|
||||
configure_ssl() {
|
||||
## NOT SURE IF THIS IS A GOOD ALTERNATIVE TO ENABLE SSL SUPPORT BY DEFAULT ##
|
||||
## BECAUSE USERS WHO PULL A PREBUILT IMAGE WILL HAVE THE SAME CERTIFICATES ##
|
||||
# if [[ ! -f ${PG_CERTDIR}/server.crt && ! -f ${PG_CERTDIR}/server.key ]]; then
|
||||
# if [[ -f /etc/ssl/certs/ssl-cert-snakeoil.pem && -f /etc/ssl/private/ssl-cert-snakeoil.key ]]; then
|
||||
# ln -sf /etc/ssl/certs/ssl-cert-snakeoil.pem ${PG_CERTDIR}/server.crt
|
||||
# ln -sf /etc/ssl/private/ssl-cert-snakeoil.key ${PG_CERTDIR}/server.key
|
||||
# fi
|
||||
# fi
|
||||
|
||||
if [[ -f ${PG_CERTDIR}/server.crt && -f ${PG_CERTDIR}/server.key ]]; then
|
||||
PG_SSL=${PG_SSL:-on}
|
||||
set_postgresql_param "ssl_cert_file" "${PG_CERTDIR}/server.crt"
|
||||
set_postgresql_param "ssl_key_file" "${PG_CERTDIR}/server.key"
|
||||
fi
|
||||
PG_SSL=${PG_SSL:-off}
|
||||
set_postgresql_param "ssl" "${PG_SSL}"
|
||||
}
|
||||
|
||||
configure_hot_standby() {
|
||||
case ${REPLICATION_MODE} in
|
||||
slave|snapshot|backup) ;;
|
||||
*)
|
||||
echo "Configuring hot standby..."
|
||||
set_postgresql_param "wal_level" "hot_standby"
|
||||
set_postgresql_param "max_wal_senders" "16"
|
||||
set_postgresql_param "checkpoint_segments" "8"
|
||||
set_postgresql_param "wal_keep_segments" "32"
|
||||
set_postgresql_param "hot_standby" "on"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
initialize_database() {
|
||||
if [[ ! -f ${PG_DATADIR}/PG_VERSION ]]; then
|
||||
case ${REPLICATION_MODE} in
|
||||
slave|snapshot|backup)
|
||||
if [[ -z $REPLICATION_HOST ]]; then
|
||||
echo "ERROR! Cannot continue without the REPLICATION_HOST. Exiting..."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ -z $REPLICATION_USER ]]; then
|
||||
echo "ERROR! Cannot continue without the REPLICATION_USER. Exiting..."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ -z $REPLICATION_PASS ]]; then
|
||||
echo "ERROR! Cannot continue without the REPLICATION_PASS. Exiting..."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo -n "Waiting for $REPLICATION_HOST to accept connections (60s timeout)"
|
||||
timeout=60
|
||||
while ! ${PG_BINDIR}/pg_isready -h $REPLICATION_HOST -p $REPLICATION_PORT -t 1 >/dev/null 2>&1
|
||||
do
|
||||
timeout=$(expr $timeout - 1)
|
||||
if [[ $timeout -eq 0 ]]; then
|
||||
echo "Timeout! Exiting..."
|
||||
exit 1
|
||||
fi
|
||||
echo -n "."
|
||||
sleep 1
|
||||
done
|
||||
echo
|
||||
|
||||
case ${REPLICATION_MODE} in
|
||||
slave)
|
||||
echo "Replicating initial data from $REPLICATION_HOST..."
|
||||
exec_as_postgres PGPASSWORD=$REPLICATION_PASS ${PG_BINDIR}/pg_basebackup -D ${PG_DATADIR} \
|
||||
-h ${REPLICATION_HOST} -p ${REPLICATION_PORT} -U ${REPLICATION_USER} -X stream -w >/dev/null
|
||||
;;
|
||||
snapshot)
|
||||
echo "Generating a snapshot data on $REPLICATION_HOST..."
|
||||
exec_as_postgres PGPASSWORD=$REPLICATION_PASS ${PG_BINDIR}/pg_basebackup -D ${PG_DATADIR} \
|
||||
-h ${REPLICATION_HOST} -p ${REPLICATION_PORT} -U ${REPLICATION_USER} -X fetch -w >/dev/null
|
||||
;;
|
||||
backup)
|
||||
echo "Backing up data on $REPLICATION_HOST..."
|
||||
exec_as_postgres PGPASSWORD=$REPLICATION_PASS ${PG_BINDIR}/pg_basebackup -D ${PG_DATADIR} \
|
||||
-h ${REPLICATION_HOST} -p ${REPLICATION_PORT} -U ${REPLICATION_USER} -X fetch -w >/dev/null
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
*)
|
||||
echo "Initializing database..."
|
||||
PG_OLD_VERSION=$(find ${PG_HOME}/[0-9].[0-9]/main -maxdepth 1 -name PG_VERSION 2>/dev/null | grep -v $PG_VERSION | sort -r | head -n1 | cut -d'/' -f5)
|
||||
if [[ -n ${PG_OLD_VERSION} ]]; then
|
||||
echo "‣ Migrating PostgreSQL ${PG_OLD_VERSION} data to ${PG_VERSION}..."
|
||||
|
||||
# protect the existing data from being altered by apt-get
|
||||
mv ${PG_HOME}/${PG_OLD_VERSION} ${PG_HOME}/${PG_OLD_VERSION}.migrating
|
||||
|
||||
echo "‣ Installing PostgreSQL ${PG_OLD_VERSION}..."
|
||||
if ! ( apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y postgresql-${PG_OLD_VERSION} postgresql-client-${PG_OLD_VERSION} ) >/dev/null; then
|
||||
echo "ERROR! Failed to install PostgreSQL ${PG_OLD_VERSION}. Exiting..."
|
||||
# first move the old data back
|
||||
rm -rf ${PG_HOME}/${PG_OLD_VERSION}
|
||||
mv ${PG_HOME}/${PG_OLD_VERSION}.migrating ${PG_HOME}/${PG_OLD_VERSION}
|
||||
exit 1
|
||||
fi
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# we're ready to migrate, move back the old data and remove the trap
|
||||
rm -rf ${PG_HOME}/${PG_OLD_VERSION}
|
||||
mv ${PG_HOME}/${PG_OLD_VERSION}.migrating ${PG_HOME}/${PG_OLD_VERSION}
|
||||
fi
|
||||
|
||||
if [[ -n $PG_PASSWORD ]]; then
|
||||
echo "${PG_PASSWORD}" > /tmp/pwfile
|
||||
fi
|
||||
|
||||
exec_as_postgres ${PG_BINDIR}/initdb --pgdata=${PG_DATADIR} \
|
||||
--username=${PG_USER} --encoding=unicode --auth=trust ${PG_PASSWORD:+--pwfile=/tmp/pwfile} >/dev/null
|
||||
|
||||
if [[ -n ${PG_OLD_VERSION} ]]; then
|
||||
PG_OLD_BINDIR=/usr/lib/postgresql/${PG_OLD_VERSION}/bin
|
||||
PG_OLD_DATADIR=${PG_HOME}/${PG_OLD_VERSION}/main
|
||||
PG_OLD_CONF=${PG_OLD_DATADIR}/postgresql.conf
|
||||
PG_OLD_HBA_CONF=${PG_OLD_DATADIR}/pg_hba.conf
|
||||
PG_OLD_IDENT_CONF=${PG_OLD_DATADIR}/pg_ident.conf
|
||||
|
||||
echo -n "‣ Migration in progress. Please be patient..."
|
||||
exec_as_postgres ${PG_BINDIR}/pg_upgrade \
|
||||
-b ${PG_OLD_BINDIR} -B ${PG_BINDIR} \
|
||||
-d ${PG_OLD_DATADIR} -D ${PG_DATADIR} \
|
||||
-o "-c config_file=${PG_OLD_CONF} --hba_file=${PG_OLD_HBA_CONF} --ident_file=${PG_OLD_IDENT_CONF}" \
|
||||
-O "-c config_file=${PG_CONF} --hba_file=${PG_HBA_CONF} --ident_file=${PG_IDENT_CONF}" >/dev/null
|
||||
echo
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
configure_hot_standby
|
||||
|
||||
# Change DSM from `posix' to `sysv' if we are inside an lx-brand container
|
||||
if [[ $(uname -v) == "BrandZ virtual linux" ]]; then
|
||||
set_postgresql_param "dynamic_shared_memory_type" "sysv"
|
||||
fi
|
||||
fi
|
||||
|
||||
# configure path to data_directory
|
||||
set_postgresql_param "data_directory" "${PG_DATADIR}"
|
||||
|
||||
# configure logging
|
||||
set_postgresql_param "log_directory" "${PG_LOGDIR}"
|
||||
set_postgresql_param "log_filename" "postgresql-${PG_VERSION}-main.log"
|
||||
|
||||
# listen on all interfaces
|
||||
set_postgresql_param "listen_addresses" "*"
|
||||
|
||||
# allow remote connections to postgresql database
|
||||
set_hba_param "host all all 0.0.0.0/0 md5"
|
||||
}
|
||||
|
||||
trust_localnet() {
|
||||
if [[ ${PG_TRUST_LOCALNET} == true ]]; then
|
||||
echo "Trusting connections from the local network..."
|
||||
set_hba_param "host all all samenet trust"
|
||||
fi
|
||||
}
|
||||
|
||||
configure_recovery() {
|
||||
if [[ ${REPLICATION_MODE} == slave ]]; then
|
||||
echo "Configuring recovery..."
|
||||
if [[ ! -f ${PG_RECOVERY_CONF} ]]; then
|
||||
# initialize recovery.conf on the firstrun (slave only)
|
||||
exec_as_postgres touch ${PG_RECOVERY_CONF}
|
||||
( echo "standby_mode = 'on'";
|
||||
echo "primary_conninfo = 'host=${REPLICATION_HOST} port=${REPLICATION_PORT} user=${REPLICATION_USER} password=${REPLICATION_PASS} sslmode=${REPLICATION_SSLMODE}'";
|
||||
) > ${PG_RECOVERY_CONF}
|
||||
else
|
||||
set_recovery_param "host" "${REPLICATION_HOST}"
|
||||
set_recovery_param "port" "${REPLICATION_PORT}"
|
||||
set_recovery_param "user" "${REPLICATION_USER}"
|
||||
set_recovery_param "password" "${REPLICATION_PASS}" "true"
|
||||
set_recovery_param "sslmode" "${REPLICATION_SSLMODE}"
|
||||
fi
|
||||
else
|
||||
# recovery.conf can only exist on a slave node, its existence otherwise causes problems
|
||||
rm -rf ${PG_RECOVERY_CONF}
|
||||
fi
|
||||
}
|
||||
|
||||
create_user() {
|
||||
if [[ -n ${DB_USER} ]]; then
|
||||
case $REPLICATION_MODE in
|
||||
slave|snapshot|backup)
|
||||
echo "INFO! Database user cannot be created on a $REPLICATION_MODE node. Skipping..."
|
||||
;;
|
||||
*)
|
||||
if [[ -z ${DB_PASS} ]]; then
|
||||
echo "ERROR! Please specify a password for DB_USER in DB_PASS. Exiting..."
|
||||
exit 1
|
||||
fi
|
||||
echo "Creating database user: ${DB_USER}"
|
||||
echo "CREATE ROLE \"${DB_USER}\" with LOGIN CREATEDB PASSWORD '${DB_PASS}';" | \
|
||||
exec_as_postgres ${PG_BINDIR}/postgres --single -D ${PG_DATADIR} >/dev/null 2>&1
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
}
|
||||
|
||||
create_database() {
|
||||
if [[ -n ${DB_NAME} ]]; then
|
||||
case $REPLICATION_MODE in
|
||||
slave|snapshot|backup)
|
||||
echo "INFO! Database cannot be created on a $REPLICATION_MODE node. Skipping..."
|
||||
;;
|
||||
*)
|
||||
echo -n "Creating database(s): "
|
||||
for database in $(awk -F',' '{for (i = 1 ; i <= NF ; i++) print $i}' <<< "${DB_NAME}"); do
|
||||
echo -n "${database} "
|
||||
echo "CREATE DATABASE \"${database}\";" | \
|
||||
exec_as_postgres ${PG_BINDIR}/postgres --single -D ${PG_DATADIR} >/dev/null 2>&1
|
||||
|
||||
if [[ ${DB_UNACCENT} == true ]]; then
|
||||
echo "CREATE EXTENSION IF NOT EXISTS unaccent;" | \
|
||||
exec_as_postgres ${PG_BINDIR}/postgres --single ${database} -D ${PG_DATADIR} >/dev/null 2>&1
|
||||
fi
|
||||
|
||||
if [[ -n ${DB_USER} ]]; then
|
||||
echo "GRANT ALL PRIVILEGES ON DATABASE \"${database}\" to \"${DB_USER}\";" | \
|
||||
exec_as_postgres ${PG_BINDIR}/postgres --single -D ${PG_DATADIR} >/dev/null 2>&1
|
||||
fi
|
||||
done
|
||||
echo
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
}
|
||||
|
||||
create_replication_user() {
|
||||
if [[ -n ${REPLICATION_USER} ]]; then
|
||||
case $REPLICATION_MODE in
|
||||
slave|snapshot|backup) ;; # replication user can only be created on the master
|
||||
*)
|
||||
if [[ -z ${REPLICATION_PASS} ]]; then
|
||||
echo "ERROR! Please specify a password for REPLICATION_USER in REPLICATION_PASS. Exiting..."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Creating replication user: ${REPLICATION_USER}"
|
||||
echo "CREATE ROLE \"${REPLICATION_USER}\" WITH REPLICATION LOGIN ENCRYPTED PASSWORD '${REPLICATION_PASS}';" | \
|
||||
exec_as_postgres ${PG_BINDIR}/postgres --single -D ${PG_DATADIR} >/dev/null 2>&1
|
||||
|
||||
set_hba_param "host replication ${REPLICATION_USER} 0.0.0.0/0 md5"
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
}
|
||||
@@ -1,122 +0,0 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
PG_HOME="/var/lib/postgresql"
|
||||
PG_CONFDIR="/etc/postgresql/${PG_VERSION}/main"
|
||||
PG_BINDIR="/usr/lib/postgresql/${PG_VERSION}/bin"
|
||||
PG_DATADIR="${PG_HOME}/${PG_VERSION}/main"
|
||||
|
||||
DB_NAME=${DB_NAME:-}
|
||||
DB_USER=${DB_USER:-}
|
||||
DB_PASS=${DB_PASS:-}
|
||||
|
||||
# fix permissions and ownership of ${PG_HOME}
|
||||
mkdir -p -m 0700 ${PG_HOME}
|
||||
chown -R postgres:postgres ${PG_HOME}
|
||||
|
||||
# fix permissions and ownership of /run/postgresql
|
||||
mkdir -p -m 0755 /run/postgresql /run/postgresql/${PG_VERSION}-main.pg_stat_tmp
|
||||
chown -R postgres:postgres /run/postgresql
|
||||
chmod g+s /run/postgresql
|
||||
|
||||
# disable ssl
|
||||
sed 's/ssl = true/#ssl = true/' -i ${PG_CONFDIR}/postgresql.conf
|
||||
|
||||
# listen on all interfaces
|
||||
cat >> ${PG_CONFDIR}/postgresql.conf <<EOF
|
||||
listen_addresses = '*'
|
||||
EOF
|
||||
|
||||
# allow remote connections to postgresql database
|
||||
cat >> ${PG_CONFDIR}/pg_hba.conf <<EOF
|
||||
host all all 0.0.0.0/0 md5
|
||||
EOF
|
||||
|
||||
cd ${PG_HOME}
|
||||
|
||||
# initialize PostgreSQL data directory
|
||||
if [ ! -d ${PG_DATADIR} ]; then
|
||||
# check if we need to perform data migration
|
||||
PG_OLD_VERSION=$(find ${PG_HOME}/[0-9].[0-9]/main -maxdepth 1 -name PG_VERSION | sort -r | head -n1 | cut -d'/' -f5)
|
||||
|
||||
if [ ! -f "${PG_HOME}/pwfile" ]; then
|
||||
PG_PASSWORD=$(pwgen -c -n -1 14)
|
||||
echo "${PG_PASSWORD}" > ${PG_HOME}/pwfile
|
||||
fi
|
||||
|
||||
echo "Initializing database..."
|
||||
sudo -u postgres -H "${PG_BINDIR}/initdb" \
|
||||
--pgdata="${PG_DATADIR}" --pwfile=${PG_HOME}/pwfile \
|
||||
--username=postgres --encoding=unicode --auth=trust >/dev/null
|
||||
fi
|
||||
|
||||
if [ -n "${PG_OLD_VERSION}" ]; then
|
||||
echo "Migrating postgresql ${PG_OLD_VERSION} data..."
|
||||
PG_OLD_CONFDIR="/etc/postgresql/${PG_OLD_VERSION}/main"
|
||||
PG_OLD_BINDIR="/usr/lib/postgresql/${PG_OLD_VERSION}/bin"
|
||||
PG_OLD_DATADIR="${PG_HOME}/${PG_OLD_VERSION}/main"
|
||||
|
||||
# backup ${PG_OLD_DATADIR} to avoid data loss
|
||||
PG_BKP_SUFFIX=$(date +%Y%m%d%H%M%S)
|
||||
echo "Backing up ${PG_OLD_DATADIR} to ${PG_OLD_DATADIR}.${PG_BKP_SUFFIX}..."
|
||||
cp -a ${PG_OLD_DATADIR} ${PG_OLD_DATADIR}.${PG_BKP_SUFFIX}
|
||||
|
||||
echo "Installing postgresql-${PG_OLD_VERSION}..."
|
||||
apt-get update
|
||||
apt-get install postgresql-${PG_OLD_VERSION} postgresql-client-${PG_OLD_VERSION}
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# migrate ${PG_OLD_VERSION} data
|
||||
echo "Migration in progress. This could take a while, please be patient..."
|
||||
sudo -u postgres -H ${PG_BINDIR}/pg_upgrade \
|
||||
-b ${PG_OLD_BINDIR} -B ${PG_BINDIR} \
|
||||
-d ${PG_OLD_DATADIR} -D ${PG_DATADIR} \
|
||||
-o "-c config_file=${PG_OLD_CONFDIR}/postgresql.conf" \
|
||||
-O "-c config_file=${PG_CONFDIR}/postgresql.conf" >/dev/null
|
||||
fi
|
||||
|
||||
if [ -f ${PG_HOME}/pwfile ]; then
|
||||
PG_PASSWORD=$(cat ${PG_HOME}/pwfile)
|
||||
echo "|------------------------------------------------------------------|"
|
||||
echo "| PostgreSQL User: postgres, Password: ${PG_PASSWORD} |"
|
||||
echo "| |"
|
||||
echo "| To remove the PostgreSQL login credentials from the logs, please |"
|
||||
echo "| make a note of password and then delete the file pwfile |"
|
||||
echo "| from the data store. |"
|
||||
echo "|------------------------------------------------------------------|"
|
||||
fi
|
||||
|
||||
if [ -n "${DB_USER}" ]; then
|
||||
if [ -z "${DB_PASS}" ]; then
|
||||
echo ""
|
||||
echo "WARNING: "
|
||||
echo " Please specify a password for \"${DB_USER}\". Skipping user creation..."
|
||||
echo ""
|
||||
DB_USER=
|
||||
else
|
||||
echo "Creating user \"${DB_USER}\"..."
|
||||
echo "CREATE ROLE ${DB_USER} with LOGIN CREATEDB PASSWORD '${DB_PASS}';" |
|
||||
sudo -u postgres -H ${PG_BINDIR}/postgres --single \
|
||||
-D ${PG_DATADIR} -c config_file=${PG_CONFDIR}/postgresql.conf >/dev/null 2>&1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -n "${DB_NAME}" ]; then
|
||||
for db in $(awk -F',' '{for (i = 1 ; i <= NF ; i++) print $i}' <<< "${DB_NAME}"); do
|
||||
echo "Creating database \"${db}\"..."
|
||||
echo "CREATE DATABASE ${db};" | \
|
||||
sudo -u postgres -H ${PG_BINDIR}/postgres --single \
|
||||
-D ${PG_DATADIR} -c config_file=${PG_CONFDIR}/postgresql.conf >/dev/null 2>&1
|
||||
|
||||
if [ -n "${DB_USER}" ]; then
|
||||
echo "Granting access to database \"${db}\" for user \"${DB_USER}\"..."
|
||||
echo "GRANT ALL PRIVILEGES ON DATABASE ${db} to ${DB_USER};" |
|
||||
sudo -u postgres -H ${PG_BINDIR}/postgres --single \
|
||||
-D ${PG_DATADIR} -c config_file=${PG_CONFDIR}/postgresql.conf >/dev/null 2>&1
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
echo "Starting PostgreSQL server..."
|
||||
exec sudo -u postgres -H ${PG_BINDIR}/postgres \
|
||||
-D ${PG_DATADIR} -c config_file=${PG_CONFDIR}/postgresql.conf
|
||||
Reference in New Issue
Block a user