Giter VIP home page Giter VIP logo

dockerfile-postgres's Introduction

  • Based on Debian
  • Includes postgres-contrib, enables the extensions pg_stat_statements by default
  • Includes wal-g for WAL archiving and shipping
  • Includes pg_auto_failover for automatic failover
  • Runs as postgres user with uid (1000), gid (1000)
  • Does not try to fix permissions during boot to support a fast startup
  • Does not have Dockerfile VOLUME declarations and therefore no issues with pg_upgrade --link
  • Simplifies streaming replication setups by providing some simple commands

Create a container and give it a name

# Secured with a password, by default the image is secure
docker run -d  --name postgres -p 5432:5432 -v postgres:/var/lib/postgresql -e POSTGRES_PASSWORD=somepassword livingdocs/postgres:16.2

Upgrade an existing postgres container

# Let's assume you've created a container previously
docker run -d --name postgres -p 5432:5432 -v postgres:/var/lib/postgresql livingdocs/postgres:14.5

# First stop it, then run the upgrade image
docker stop postgres
docker run --rm -v postgres:/var/lib/postgresql livingdocs/postgres:16.2-upgrade

# After it succeeds, you can run the new image and mount the existing volume
docker run -d --name postgres -p 5432:5432 -v postgres:/var/lib/postgresql livingdocs/postgres:16.2

To build this image manually

docker build -t livingdocs/postgres:16.2 .

With buildx on docker

# To build and push the multi-arch manifest to docker hub
docker buildx build --platform linux/amd64,linux/arm64 -t livingdocs/postgres:16.2 --push .

docker buildx build --platform linux/amd64,linux/arm64 -t livingdocs/postgres:16.2-upgrade --push  -f Dockerfile.upgrade .

With nerdctl on lima/containerd

nerdctl build --platform=amd64,arm64 -t livingdocs/postgres:16.2 .
nerdctl build --platform=amd64,arm64 -t livingdocs/postgres:16.2-upgrade -f Dockerfile.upgrade .

lima nerdctl push --all-platforms livingdocs/postgres:16.2
lima nerdctl push --all-platforms livingdocs/postgres:16.2-upgrade

Set up streaming replication

Simple setup

# Create the containers
docker run -d -p 5433:5432 --name postgres-1 livingdocs/postgres:16.2
docker run -d -p 5434:5432 --name postgres-2 livingdocs/postgres:16.2 standby -d "host=host.docker.internal port=5433 user=postgres target_session_attrs=read-write"

# Test the replication
docker exec postgres-1 psql -c "CREATE TABLE hello (value text); INSERT INTO hello(value) VALUES('world');"
docker exec postgres-2 psql -c "SELECT * FROM hello;"
# Output:
#   value
#  -------
#  world
#  (1 row)

Advanced setup using passwords

# Create a docker network to emulate dns resolution in a production system
docker network create local

# First create the database primary
docker run -d -p 5433:5432 --name postgres-1 --network=local --network-alias=postgres -e POSTGRES_HOST_AUTH_METHOD=md5 livingdocs/postgres:16.2

# Create the users on database intialization
# You could also mount an sql or script into /var/lib/postgresql/initdb.d during cluster startup to execute the script automatically.
docker exec postgres-1 psql -c "ALTER ROLE postgres ENCRYPTED PASSWORD 'some-postgres-password';"
docker exec postgres-1 psql -c "CREATE USER replication REPLICATION LOGIN ENCRYPTED PASSWORD 'some-replication-password';"

# The launch the replicas
export DB_URL="host=postgres port=5432 user=replication password=some-replication-password target_session_attrs=read-write"
docker run -d -p 5434:5432 --name postgres-2 --network=local --network-alias=postgres livingdocs/postgres:16.2 standby -d $DB_URL
docker run -d -p 5435:5432 --name postgres-3 --network=local --network-alias=postgres livingdocs/postgres:16.2 standby -d $DB_URL

# Test the replication
docker exec postgres-1 psql -c "CREATE TABLE hello (value text); INSERT INTO hello(value) VALUES('hello');"
docker exec postgres-2 psql -c "SELECT * FROM hello;"
docker exec postgres-3 psql -c "SELECT * FROM hello;"
# Output for both instances:
#  value
# -------
# hello
# (1 row)


#
# Test a replica promotion (manually)
#
docker rm -f postgres-1

# Inserts will still fail into slaves: ERROR:  cannot execute INSERT in a read-only transaction
docker exec postgres-2 psql -c "INSERT INTO hello(value) VALUES('world');"

# Promote a slave
docker exec postgres-2 touch /var/lib/postgresql/data/promote.signal

# And test it
docker exec postgres-2 psql -c "INSERT INTO hello(value) VALUES('world');"
docker exec postgres-3 psql -c "SELECT * FROM hello;"
# Output for both instances:
#  value
# -------
#  hello
#  world
# (2 rows)

To promote a replica to a primary

Please make sure that first the old master doesn't accept any writes anymore. Either stop it or reject writes:

ALTER SYSTEM SET default_transaction_read_only TO 'on';
SELECT pg_terminate_backend(pg_stat_activity.pid) FROM pg_stat_activity WHERE pid <> pg_backend_pid();

Then promote the replica. There are two options:

  • Create the promote.signal in the data directory touch /var/lib/postgresql/data/promote.signal on the replica. If you've changed your configuration, make sure promote_trigger_file declares that path.
  • Execute gosu postgres pg_ctl promote in the container.

dockerfile-postgres's People

Contributors

marcbachmann avatar masone avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.