Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Latest stable changes from develop with support for PostgreSQL 12.2 #1

Merged
merged 7 commits into from
Apr 27, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 3 additions & 23 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,23 +1,3 @@
# Compiled class file
*.class

# Log file
*.log

# BlueJ files
*.ctxt

# Mobile Tools for Java (J2ME)
.mtj.tmp/

# Package Files #
*.jar
*.war
*.nar
*.ear
*.zip
*.tar.gz
*.rar

# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
.idea/
target/
*.iml
62 changes: 60 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,60 @@
# postgresql
Containerised PostgreSQL database with flyway baked-in
# PostgreSQL database with embedded schema migrator

Docker image containing a PostgreSQL database and a schema migrator to simplify database schema upgrades.

## Building the Docker image

### Using the Maven command line:

```shell script
mvn clean install
```

### Using the Docker command line:
From the top-level directory, run the following command to copy the build assets to the target directory:

```shell script
mvn compile
```

Then go to the target directory and invoke Docker build as shown here:

```shell script
pushd target/docker
docker build . --tag localhost.localdomain/postgresql-container:latest --no-cache
popd
```

## Running the database

Use the following command to the start the Database in a background docker container:

```shell script
docker run -p 5432:5432 --name postgres -d localhost.localdomain/postgresql-container:latest
```

## Connecting to the database

Use the following JDBC URL to connect to the database:

```text
jdbc:postgresql://localhost:5432/postgres
```
## Extending the database schema

To extend the schema definition with the tables, data, etc, simply add new idempotent SQL scripts to the
`src/main/resources/db/migration/` folder.

The SQL script file names must follow the pattern
`SPRINT<zero padded three digit sprint number>_<zero padded two digit script order number>__<description>.sql`
as shown in this example: `SPRINT001_01__Initial_database_revision.sql`.

## Resources

- [PostgreSQL](https://www.postgresql.org)
- [Flyway](https://flywaydb.org)
- [postgres - Docker Official Images](https://hub.docker.com/_/postgres)
- [Docker Library PostgreSQL on GitHub](https://github.com/docker-library/postgres)
- ["exec: \"docker-entrypoint.sh\": executable file not found in $PATH". #296](https://github.com/docker-library/postgres/issues/296)
- [Sending RUN ["docker-entrypoint.sh", "postgres", "--version"] output to the console during the build #718](https://github.com/docker-library/postgres/issues/718)
- [Functionalize the entrypoint to allow outside sourcing for extreme customizing of startup #496](https://github.com/docker-library/postgres/pull/496)
167 changes: 167 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.doraemoncito</groupId>
<artifactId>postgresql-container</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>pom</packaging>
<name>PostgreSQL container</name>
<description>PostgreSQL database bound with flyway and encapsulated in a docker container</description>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>

<java.version>11</java.version>
<maven.version>3.6.0</maven.version>

<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>

<docker.registry.url>localhost.localdomain</docker.registry.url>
<docker.image.name>${docker.registry.url}/${project.artifactId}</docker.image.name>
<docker.pull.on.build>true</docker.pull.on.build>

<dockerfile-maven-plugin.version>1.4.13</dockerfile-maven-plugin.version>
<maven-dependency-plugin.version>3.1.2</maven-dependency-plugin.version>
<maven-resources-plugin.version>3.1.0</maven-resources-plugin.version>

<flyway-commandline.version>6.3.3</flyway-commandline.version>
</properties>
<dependencies>
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-commandline</artifactId>
<version>${flyway-commandline.version}</version>
<classifier>linux-x64</classifier>
<type>tar.gz</type>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>${maven-dependency-plugin.version}</version>
<executions>
<execution>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-commandline</artifactId>
<version>${flyway-commandline.version}</version>
<classifier>linux-x64</classifier>
<type>tar.gz</type>
<outputDirectory>${project.build.directory}/docker</outputDirectory>
<overWrite>false</overWrite>
</artifactItem>
</artifactItems>
<stripClassifier>true</stripClassifier>
<stripVersion>true</stripVersion>
<overWriteIfNewer>true</overWriteIfNewer>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>${maven-resources-plugin.version}</version>
<executions>
<execution>
<id>copy-scripts</id>
<phase>generate-resources</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/docker</outputDirectory>
<overwrite>true</overwrite>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>db/**</include>
</includes>
</resource>
</resources>
</configuration>
</execution>
<execution>
<id>copy-docker</id>
<phase>generate-resources</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/docker</outputDirectory>
<overwrite>true</overwrite>
<resources>
<resource>
<directory>${project.basedir}/src/main/docker</directory>
<includes>
<include>**</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.spotify</groupId>
<artifactId>dockerfile-maven-plugin</artifactId>
<version>${dockerfile-maven-plugin.version}</version>
<configuration>
<repository>${docker.image.name}</repository>
<dockerfile>${project.build.directory}/docker/Dockerfile</dockerfile>
<contextDirectory>${project.build.directory}/docker</contextDirectory>
<tag>${project.version}</tag>
<!-- NOTE: dockerfile-maven-plugin does not appear to be able to tag the same image with multiple labels-->
<!-- <tag>latest</tag>-->
<!-- skip writing the test metadata to ${project.build.directory}/docker or copy the resources to -->
<!-- a directory other than ${project.build.directory}/docker because the dockerfile-maven-plugin -->
<!-- itself uses that directory to write metadata that that conflicts with the build. -->
<!-- See https://github.com/spotify/dockerfile-maven/issues/75 for more details. -->
<writeTestMetadata>false</writeTestMetadata>
</configuration>
<executions>
<!-- Build the docker image using the Maven project version as the tag -->
<execution>
<id>build</id>
<phase>package</phase>
<goals>
<goal>build</goal>
</goals>
</execution>
<!-- Tag the newly built docker image using the 'latest' tag -->
<execution>
<id>tag-latest</id>
<goals>
<goal>tag</goal>
</goals>
<configuration>
<tag>latest</tag>
</configuration>
</execution>
<execution>
<id>deploy</id>
<phase>deploy</phase>
<goals>
<goal>push</goal>
</goals>
<configuration>
<tag>${project.version}</tag>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
30 changes: 30 additions & 0 deletions src/main/docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
FROM postgres:12-alpine
LABEL maintainer="jose.hernandez@bristolalumni.org.uk"
LABEL name="PostgreSQL 12 Database" vendor="Jose Hernandez"
EXPOSE 5432

RUN apk --no-cache update upgrade && apk add --no-cache openjdk11 su-exec
COPY db/ /db/
COPY entrypoint.sh /entrypoint.sh
COPY flyway-commandline.tar.gz /flyway-commandline.tar.gz

# Install the flyway schema migrator
RUN tar -pxzf flyway-commandline.tar.gz \
&& rm flyway-commandline.tar.gz \
&& mv /flyway-* /flyway \
&& rm -fr /flyway/jre \
&& chmod 777 -R /flyway /db /entrypoint.sh

# Variables required for the schema migration (i.e. flyway)
ENV PGDATA=/var/lib/postgresql-static/data \
POSTGRES_DB=postgres \
POSTGRES_USER=postgres \
POSTGRES_PASSWORD=password \
PGPORT=5432 \
# Uncomment this line to use password authentication, instead of trust, inside the container.
# Please note that using trust authentication generates the following warning in the logs:
# initdb: warning: enabling "trust" authentication for local connections
# POSTGRES_INITDB_ARGS="-A password" \
JAVA_HOME=/usr/lib/jvm/java-11-openjdk

RUN ["/entrypoint.sh", "postgres"]
66 changes: 66 additions & 0 deletions src/main/docker/entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#!/bin/bash

#!/usr/bin/env bash
set -Eeo pipefail

# Example using the functions of the postgres entry point to customize startup to always run files in /always-initdb.d/

source "$(which docker-entrypoint.sh)"

docker_setup_env
docker_create_db_directories
# assumption: we are already running as the owner of PGDATA

# This is needed if the container is started as `root`
if [ "$1" = 'postgres' ] && [ "$(id -u)" = '0' ]; then
exec su-exec postgres "$BASH_SOURCE" "$@"
fi

echo "Running flyway to update the PostgreSQL database"
PATH=$PATH:/flyway

echo "============================================================"
echo " PATH: ${PATH}"
echo " PGDATA: ${PGDATA}"
echo " POSTGRES_DB: ${POSTGRES_DB}"
echo " POSTGRES_USER: ${POSTGRES_USER}"
echo " PGPORT: ${PGPORT}"
echo "POSTGRES_INITDB_ARGS: ${POSTGRES_INITDB_ARGS}"
echo "============================================================"

if [ -z "$DATABASE_ALREADY_EXISTS" ]; then
docker_verify_minimum_env
docker_init_database_dir
pg_setup_hba_conf

# only required for '--auth[-local]=md5' on POSTGRES_INITDB_ARGS
export PGPASSWORD="${PGPASSWORD:-$POSTGRES_PASSWORD}"

docker_temp_server_start "$@" -c max_locks_per_transaction=256
docker_setup_db

# Ensure that PostgreSQL is restarted after the authentication is set to trust instead of ident so that flyway can
# connect to the database to perform migration. For more details please visit the PostgreSQL documentation page at
# https://www.postgresql.org/docs/11/client-authentication.html
pg_ctl --options "-c listen_addresses='localhost'" --wait restart

/flyway/flyway -user="$POSTGRES_USER" -password="$POSTGRES_PASSWORD" -configFiles=/db/configuration/postgres/flyway.properties -url="jdbc:postgresql://localhost:$PGPORT/$POSTGRES_DB?user=$POSTGRES_USER" -locations="filesystem:/db/migration" info migrate info || exit 1

docker_process_init_files /docker-entrypoint-initdb.d/*

docker_temp_server_stop
else
docker_temp_server_start "$@"

# Ensure that PostgreSQL is restarted after the authentication is set to trust instead of ident so that flyway can
# connect to the database to perform migration. For more details please visit the PostgreSQL documentation page at
# https://www.postgresql.org/docs/11/client-authentication.html
pg_ctl --options "-c listen_addresses='localhost'" --wait restart

/flyway/flyway -user="$POSTGRES_USER" -password="$POSTGRES_PASSWORD" -configFiles=/db/configuration/postgres/flyway.properties -url="jdbc:postgresql://localhost:$PGPORT/$POSTGRES_DB?user=$POSTGRES_USER" -locations="filesystem:/db/migration" info migrate info || exit 1

docker_process_init_files /always-initdb.d/*
docker_temp_server_stop
fi

echo "entrypoint.sh Completed"
Loading