Skip to content

Commit

Permalink
Build, test and deploy from GitHub Actions (#26)
Browse files Browse the repository at this point in the history
* Build, test and deploy from GitHub Actions

* Run action every week

* Re-apply Postgres updates

* Build cache images only on main branch

* Replace `make install` with `make install-world`
  • Loading branch information
andyundso authored Apr 29, 2024
1 parent 0d00eb8 commit 809077f
Show file tree
Hide file tree
Showing 4 changed files with 271 additions and 145 deletions.
125 changes: 125 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
name: Build and push

on:
push:
pull_request:
schedule:
- cron: "0 0 * * 0"

jobs:
base-images:
# for security reason, we only build these images in our repository and on the main branch
if: github.repository == 'pgautoupgrade/docker-pgautoupgrade' && github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
strategy:
matrix:
pg_version:
- "9.5"
- "9.6"
- "10"
- "11"
- "12"
- "13"
- "14"
- "15"
- "16"

steps:
- name: Set up QEMU
uses: docker/setup-qemu-action@v3

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ vars.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_PASSWORD }}

- name: Build and push image
uses: docker/build-push-action@v5
with:
push: true
platforms: linux/amd64,linux/arm64
build-args: |
"PGTARGET=16"
target: "build-${{ matrix.pg_version }}"
tags: "pgautoupgrade/pgautoupgrade:build-${{ matrix.pg_version }}"
cache-to: type=inline
cache-from: type=registry,ref=pgautoupgrade/pgautoupgrade:build-${{ matrix.pg_version }}

target-images:
runs-on: ubuntu-latest
needs: base-images
# otherwise, it would skip the build entirely (because the base step does not run)
if: always()
env:
# but still use our public caches in any case
# they might be outdated, in which case a full rebuild will be triggered
TARGET_TAG: ${{ github.ref == 'refs/heads/main' && 'alpine3.19' || 'dev-alpine3.19' }}
CACHE_FROM: |
type=registry,ref=pgautoupgrade/pgautoupgrade:build-9.5
type=registry,ref=pgautoupgrade/pgautoupgrade:build-9.6
type=registry,ref=pgautoupgrade/pgautoupgrade:build-10
type=registry,ref=pgautoupgrade/pgautoupgrade:build-11
type=registry,ref=pgautoupgrade/pgautoupgrade:build-12
type=registry,ref=pgautoupgrade/pgautoupgrade:build-13
type=registry,ref=pgautoupgrade/pgautoupgrade:build-14
type=registry,ref=pgautoupgrade/pgautoupgrade:build-15
type=registry,ref=pgautoupgrade/pgautoupgrade:build-16
type=registry,ref=pgautoupgrade/pgautoupgrade:${{ matrix.pg_target }}-alpine3.19
# we cannot access TARGET_TAG from env
# https://docs.github.com/en/actions/learn-github-actions/contexts#context-availability

strategy:
matrix:
pg_target:
- "12"
- "13"
- "14"
- "15"
- "16"

steps:
- name: Set up QEMU
uses: docker/setup-qemu-action@v3

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Login to Docker Hub
if: github.repository == 'pgautoupgrade/docker-pgautoupgrade'
uses: docker/login-action@v3
with:
username: ${{ vars.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_PASSWORD }}

- name: Build image
uses: docker/build-push-action@v5
with:
load: true
tags: "pgautoupgrade/pgautoupgrade:${{ matrix.pg_target }}-alpine3.19"
build-args: |
"PGTARGET=${{ matrix.pg_target }}"
cache-to: type=inline
cache-from: "${{ env.CACHE_FROM }}"

- name: Checkout code
uses: actions/checkout@v4

- name: Test image
run: |
make test
env:
PGTARGET: ${{ matrix.pg_target }}

- name: Push image
if: github.repository == 'pgautoupgrade/docker-pgautoupgrade' && github.ref == 'refs/heads/main'
uses: docker/build-push-action@v5
with:
platforms: linux/amd64,linux/arm64
tags: "pgautoupgrade/pgautoupgrade:${{ matrix.pg_target }}-${{ env.TARGET_TAG }}"
push: true
cache-to: type=inline
cache-from: "${{ env.CACHE_FROM }}"
204 changes: 121 additions & 83 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,13 +1,7 @@
# The version of PostgreSQL this container migrates data to
ARG PGTARGET=16

# We use Alpine as a base image to compile older
# PostgreSQL versions in, then copy the binaries
# into the official PG Alpine image
FROM alpine:3.19 AS build

# We need to define this here, to make the above PGTARGET available after the FROM
ARG PGTARGET
### Things we need in all build containers
FROM alpine:3.19 as base-build

# Where we'll do all our compiling and similar
ENV BUILD_ROOT /buildroot
Expand All @@ -16,76 +10,118 @@ ENV BUILD_ROOT /buildroot
RUN mkdir ${BUILD_ROOT}
WORKDIR ${BUILD_ROOT}

# Download the source code for previous PG releases
RUN wget https://ftp.postgresql.org/pub/source/v9.5.25/postgresql-9.5.25.tar.bz2 && \
wget https://ftp.postgresql.org/pub/source/v9.6.24/postgresql-9.6.24.tar.bz2 && \
wget https://ftp.postgresql.org/pub/source/v10.23/postgresql-10.23.tar.bz2 && \
wget https://ftp.postgresql.org/pub/source/v11.22/postgresql-11.22.tar.bz2
RUN if [ "${PGTARGET}" -gt 12 ]; then wget https://ftp.postgresql.org/pub/source/v12.18/postgresql-12.18.tar.bz2; fi
RUN if [ "${PGTARGET}" -gt 13 ]; then wget https://ftp.postgresql.org/pub/source/v13.14/postgresql-13.14.tar.bz2; fi
RUN if [ "${PGTARGET}" -gt 14 ]; then wget https://ftp.postgresql.org/pub/source/v14.11/postgresql-14.11.tar.bz2; fi
RUN if [ "${PGTARGET}" -gt 15 ]; then wget https://ftp.postgresql.org/pub/source/v15.6/postgresql-15.6.tar.bz2; fi

# Extract the source code
RUN tar -xf postgresql-9.5*.tar.bz2 && \
tar -xf postgresql-9.6*.tar.bz2 && \
tar -xf postgresql-10*.tar.bz2 && \
tar -xf postgresql-11*.tar.bz2
RUN if [ "${PGTARGET}" -gt 12 ]; then tar -xf postgresql-12*.tar.bz2; fi
RUN if [ "${PGTARGET}" -gt 13 ]; then tar -xf postgresql-13*.tar.bz2; fi
RUN if [ "${PGTARGET}" -gt 14 ]; then tar -xf postgresql-14*.tar.bz2; fi
RUN if [ "${PGTARGET}" -gt 15 ]; then tar -xf postgresql-15*.tar.bz2; fi

# Install things needed for development
# We might want to install "alpine-sdk" instead of "build-base", if build-base
# doesn't have everything we need
RUN apk update && \
apk upgrade && \
apk add --update build-base icu-data-full icu-dev linux-headers lz4-dev musl musl-locales musl-utils tzdata zlib-dev zstd-dev && \
apk cache clean
apk upgrade && \
apk add --update build-base icu-data-full icu-dev linux-headers lz4-dev musl musl-locales musl-utils tzdata zlib-dev zstd-dev && \
apk cache clean

### PostgreSQL 9.5
FROM base-build as build-9.5

RUN wget https://ftp.postgresql.org/pub/source/v9.5.25/postgresql-9.5.25.tar.bz2 && \
tar -xf postgresql-9.5*.tar.bz2

# Compile PG releases with fairly minimal options
# Note that given some time, we could likely remove the pieces of the older PG installs which aren't needed by pg_upgrade
RUN cd postgresql-9.5.* && \
./configure --prefix=/usr/local-pg9.5 --with-openssl=no --without-readline --with-system-tzdata=/usr/share/zoneinfo --enable-debug=no CFLAGS="-Os" && \
make -j $(nproc) && \
make install-world && \
rm -rf /usr/local-pg9.5/include
./configure --prefix=/usr/local-pg9.5 --with-openssl=no --without-readline --with-system-tzdata=/usr/share/zoneinfo --enable-debug=no CFLAGS="-Os" && \
make -j $(nproc) && \
make install-world && \
rm -rf /usr/local-pg9.5/include

### PostgreSQL 9.6
FROM base-build as build-9.6

RUN wget https://ftp.postgresql.org/pub/source/v9.6.24/postgresql-9.6.24.tar.bz2 && \
tar -xf postgresql-9.6*.tar.bz2

RUN cd postgresql-9.6.* && \
./configure --prefix=/usr/local-pg9.6 --with-openssl=no --without-readline --with-system-tzdata=/usr/share/zoneinfo --enable-debug=no CFLAGS="-Os" && \
make -j $(nproc) && \
make install-world && \
rm -rf /usr/local-pg9.6/include
./configure --prefix=/usr/local-pg9.6 --with-openssl=no --without-readline --with-system-tzdata=/usr/share/zoneinfo --enable-debug=no CFLAGS="-Os" && \
make -j $(nproc) && \
make install-world && \
rm -rf /usr/local-pg9.6/include

### PostgreSQL 10
FROM base-build as build-10
RUN wget https://ftp.postgresql.org/pub/source/v10.23/postgresql-10.23.tar.bz2 && \
tar -xf postgresql-10*.tar.bz2

RUN cd postgresql-10.* && \
./configure --prefix=/usr/local-pg10 --with-openssl=no --without-readline --with-system-tzdata=/usr/share/zoneinfo --with-icu --enable-debug=no CFLAGS="-Os" && \
make -j $(nproc) && \
make install-world && \
rm -rf /usr/local-pg10/include
./configure --prefix=/usr/local-pg10 --with-openssl=no --without-readline --with-icu --with-system-tzdata=/usr/share/zoneinfo --enable-debug=no CFLAGS="-Os" && \
make -j $(nproc) && \
make install-world && \
rm -rf /usr/local-pg10/include

### PostgreSQL 11
FROM base-build as build-11
RUN wget https://ftp.postgresql.org/pub/source/v11.22/postgresql-11.22.tar.bz2 && \
tar -xf postgresql-11*.tar.bz2

RUN cd postgresql-11.* && \
./configure --prefix=/usr/local-pg11 --with-openssl=no --without-readline --with-system-tzdata=/usr/share/zoneinfo --with-icu --enable-debug=no CFLAGS="-Os" && \
make -j $(nproc) && \
make install-world && \
rm -rf /usr/local-pg11/include
RUN if [ "${PGTARGET}" -gt 12 ]; then cd postgresql-12.* && \
./configure --prefix=/usr/local-pg12 --with-openssl=no --without-readline --with-system-tzdata=/usr/share/zoneinfo --with-icu --enable-debug=no CFLAGS="-Os" && \
make -j $(nproc) && \
make install-world && \
rm -rf /usr/local-pg12/include; else mkdir /usr/local-pg12; fi
RUN if [ "${PGTARGET}" -gt 13 ]; then cd postgresql-13.* && \
./configure --prefix=/usr/local-pg13 --with-openssl=no --without-readline --with-system-tzdata=/usr/share/zoneinfo --with-icu --enable-debug=no CFLAGS="-Os" && \
make -j $(nproc) && \
make install-world && \
rm -rf /usr/local-pg13/include; else mkdir /usr/local-pg13; fi
RUN if [ "${PGTARGET}" -gt 14 ]; then cd postgresql-14.* && \
./configure --prefix=/usr/local-pg14 --with-openssl=no --without-readline --with-system-tzdata=/usr/share/zoneinfo --with-icu --with-lz4 --enable-debug=no CFLAGS="-Os" && \
make -j $(nproc) && \
make install-world && \
rm -rf /usr/local-pg14/include; else mkdir /usr/local-pg14; fi
RUN if [ "${PGTARGET}" -gt 15 ]; then cd postgresql-15.* && \
./configure --prefix=/usr/local-pg15 --with-openssl=no --without-readline --with-system-tzdata=/usr/share/zoneinfo --with-icu --with-lz4 --with-zstd --enable-debug=no CFLAGS="-Os" && \
make -j $(nproc) && \
make install-world && \
rm -rf /usr/local-pg15/include; else mkdir /usr/local-pg15; fi
./configure --prefix=/usr/local-pg11 --with-openssl=no --without-readline --with-icu --with-system-tzdata=/usr/share/zoneinfo --enable-debug=no CFLAGS="-Os" && \
make -j $(nproc) && \
make install-world && \
rm -rf /usr/local-pg11/include

### PostgreSQL 12
FROM base-build as build-12
RUN wget https://ftp.postgresql.org/pub/source/v12.18/postgresql-12.18.tar.bz2 && \
tar -xf postgresql-12*.tar.bz2

RUN cd postgresql-12.* && \
./configure --prefix=/usr/local-pg12 --with-openssl=no --without-readline --with-icu --with-system-tzdata=/usr/share/zoneinfo --enable-debug=no CFLAGS="-Os" && \
make -j $(nproc) && \
make install-world && \
rm -rf /usr/local-pg12/include

### PostgreSQL 13
FROM base-build as build-13

RUN wget https://ftp.postgresql.org/pub/source/v13.14/postgresql-13.14.tar.bz2 && \
tar -xf postgresql-13*.tar.bz2

RUN cd postgresql-13.* && \
./configure --prefix=/usr/local-pg13 --with-openssl=no --without-readline --with-icu --with-system-tzdata=/usr/share/zoneinfo --enable-debug=no CFLAGS="-Os" && \
make -j $(nproc) && \
make install-world && \
rm -rf /usr/local-pg13/include

### PostgreSQL 14
FROM base-build as build-14

RUN wget https://ftp.postgresql.org/pub/source/v14.11/postgresql-14.11.tar.bz2 && \
tar -xf postgresql-14*.tar.bz2

RUN cd postgresql-14.* && \
./configure --prefix=/usr/local-pg14 --with-openssl=no --without-readline --with-icu --with-lz4 --with-system-tzdata=/usr/share/zoneinfo --enable-debug=no CFLAGS="-Os" && \
make -j $(nproc) && \
make install-world && \
rm -rf /usr/local-pg14/include

### PostgreSQL 15
FROM base-build as build-15

RUN wget https://ftp.postgresql.org/pub/source/v15.6/postgresql-15.6.tar.bz2 && \
tar -xf postgresql-15*.tar.bz2

RUN cd postgresql-15.* && \
./configure --prefix=/usr/local-pg15 --with-openssl=no --without-readline --with-icu --with-lz4 --with-system-tzdata=/usr/share/zoneinfo --enable-debug=no CFLAGS="-Os" && \
make -j $(nproc) && \
make install-world && \
rm -rf /usr/local-pg15/include

### PostgreSQL 16
FROM base-build as build-16

RUN wget https://ftp.postgresql.org/pub/source/v16.2/postgresql-16.2.tar.gz && \
tar -xf postgresql-16*.tar.gz

RUN cd postgresql-16.* && \
./configure --prefix=/usr/local-pg16 --with-openssl=no --without-readline --with-icu --with-lz4 --with-system-tzdata=/usr/share/zoneinfo --enable-debug=no CFLAGS="-Os" && \
make -j $(nproc) && \
make install-world && \
rm -rf /usr/local-pg16/include

# Use the PostgreSQL Alpine image as our output image base
FROM postgres:${PGTARGET}-alpine3.19
Expand All @@ -94,25 +130,27 @@ FROM postgres:${PGTARGET}-alpine3.19
ARG PGTARGET

# Copy across our compiled files
COPY --from=build /usr/local-pg9.5 /usr/local-pg9.5
COPY --from=build /usr/local-pg9.6 /usr/local-pg9.6
COPY --from=build /usr/local-pg10 /usr/local-pg10
COPY --from=build /usr/local-pg11 /usr/local-pg11
COPY --from=build /usr/local-pg12 /usr/local-pg12
COPY --from=build /usr/local-pg13 /usr/local-pg13
COPY --from=build /usr/local-pg14 /usr/local-pg14
COPY --from=build /usr/local-pg15 /usr/local-pg15
COPY --from=build-9.5 /usr/local-pg9.5 /usr/local-pg9.5
COPY --from=build-9.6 /usr/local-pg9.6 /usr/local-pg9.6
COPY --from=build-10 /usr/local-pg10 /usr/local-pg10
COPY --from=build-11 /usr/local-pg11 /usr/local-pg11
COPY --from=build-12 /usr/local-pg12 /usr/local-pg12
COPY --from=build-13 /usr/local-pg13 /usr/local-pg13
COPY --from=build-14 /usr/local-pg14 /usr/local-pg14
COPY --from=build-15 /usr/local-pg15 /usr/local-pg15
COPY --from=build-16 /usr/local-pg16 /usr/local-pg16

# Remove any left over PG directory stubs. Doesn't help with image size, just with clarity on what's in the image.
RUN if [ "${PGTARGET}" -eq 12 ]; then rmdir /usr/local-pg12 /usr/local-pg13 /usr/local-pg14 /usr/local-pg15; fi
RUN if [ "${PGTARGET}" -eq 13 ]; then rmdir /usr/local-pg13 /usr/local-pg14 /usr/local-pg15; fi
RUN if [ "${PGTARGET}" -eq 14 ]; then rmdir /usr/local-pg14 /usr/local-pg15; fi
RUN if [ "${PGTARGET}" -eq 15 ]; then rmdir /usr/local-pg15; fi
RUN if [ "${PGTARGET}" -eq 12 ]; then rm -rf /usr/local-pg12 /usr/local-pg13 /usr/local-pg14 /usr/local-pg15 /usr/local-pg16; fi
RUN if [ "${PGTARGET}" -eq 13 ]; then rm -rf /usr/local-pg13 /usr/local-pg14 /usr/local-pg15 /usr/local-pg16; fi
RUN if [ "${PGTARGET}" -eq 14 ]; then rm -rf /usr/local-pg14 /usr/local-pg15 /usr/local-pg16; fi
RUN if [ "${PGTARGET}" -eq 15 ]; then rm -rf /usr/local-pg15 /usr/local-pg16; fi
RUN if [ "${PGTARGET}" -eq 16 ]; then rm -rf /usr/local-pg16; fi

# Install locale
RUN apk update && \
apk add --update icu-data-full musl musl-utils musl-locales tzdata && \
apk cache clean
apk add --update icu-data-full musl musl-utils musl-locales tzdata && \
apk cache clean

## FIXME: Only useful while developing this Dockerfile
##RUN apk add man-db man-pages-posix
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ If you instead want to run a specific version of PostgreSQL
then pick a matching tag on our Docker Hub. For example, to
use PostgreSQL 15 you can use:

pgautoupgrade/pgautoupgrade:15-alpine3.8
pgautoupgrade/pgautoupgrade:15-alpine3.19

### "One shot" mode

Expand Down
Loading

0 comments on commit 809077f

Please sign in to comment.