Skip to content

Commit

Permalink
feat: docker base psql15.6 img and release (#1072)
Browse files Browse the repository at this point in the history
* feat: docker base psql15.6 img and release
on merge to develop. nix creates a base version of the image
which will be pushed to docker.io on each PR push, ovewriting
the same tag. Dockerfile-156 will then use that tag as it's base
to build the finale base supabase/postgres image for 15.6
(built from nix)

* feat: our nix set up uses skopeo under the hood
so we'll try to feed skopeo what it needs to push to docekr hub

* chore: update paths

* chore: propagate vars in Dockerfile used by gha

* chore: use conventional env var

* chore: better handling for arm64 and amd64

* chore: fix sha, rules about when wf runs

* chore: a different approach to trigger on success

* chore: cleaning up to test triggering

* test: run in this PR context on any success

* chore: just combine docker operations

* chore: remove completion rule

* chore: account for both scripts

* chore: yml formatting

* chore: reformat and cleaning up

* fix: typo on filename

* chore: need some way to run this on push to PR for now

* chore: adjusting tmp rules

* chore: naild down var names

* fix: no need for s3 access here

* chore: reorder

* chore: not all systems for flake check

* chore: use tmp img tag for now

* chore: bring in values for base image

* fix: version

* chore: prefix already passed in

* chore: isolate cache to this commit

* chore: dockerfile should be file

* chore: use root at this layer

* chore: rm base image from workflow

* chore: db dir

* chore: make sure dirs and perms exist

* chore: include timezonesets

* chore: create symlink

* chore: create more missing dirs

* chore: more symlinks for the psql package

* test: try removing caching of docker image in ci

* test: force different tag each time

* chore: rm git sha from docker image tag

* chore: cleanup for merge

* chore: re-intro docker caching

---------

Co-authored-by: Sam Rose <[email protected]>
  • Loading branch information
samrose and samrose authored Jul 30, 2024
1 parent 40b884c commit 92ddd74
Show file tree
Hide file tree
Showing 6 changed files with 381 additions and 20 deletions.
102 changes: 102 additions & 0 deletions .github/workflows/dockerhub-release-15-6.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
name: Release 15.6 on Dockerhub

on:
push:
branches:
- develop
paths:
- ".github/workflows/dockerhub-release-15-6.yml"
- "common-nix.vars*"

jobs:
settings:
runs-on: ubuntu-latest
outputs:
docker_version: ${{ steps.settings.outputs.postgres-version }}
image_tag: supabase/postgres:${{ steps.settings.outputs.postgres-version }}
build_args: ${{ steps.args.outputs.result }}
steps:
- uses: actions/checkout@v3
- id: settings
# Remove spaces and quotes to get the raw version string
run: sed -r 's/(\s|\")+//g' common-nix.vars.pkr.hcl >> $GITHUB_OUTPUT
- id: args
uses: mikefarah/yq@master
with:
cmd: yq 'to_entries | map(select(.value|type == "!!str")) | map(.key + "=" + .value) | join("\n")' 'ansible/vars.yml'

build_release_image:
needs: [settings]
strategy:
matrix:
include:
- runner: [self-hosted, X64]
arch: amd64
- runner: arm-runner
arch: arm64
runs-on: ${{ matrix.runner }}
timeout-minutes: 180
outputs:
image_digest: ${{ steps.build.outputs.digest }}
steps:
- run: docker context create builders
- uses: docker/setup-buildx-action@v3
with:
endpoint: builders
- uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- id: build
uses: docker/build-push-action@v5
with:
push: true
build-args: |
${{ needs.settings.outputs.build_args }}
target: production
tags: ${{ needs.settings.outputs.image_tag }}_${{ matrix.arch }}
platforms: linux/${{ matrix.arch }}
cache-from: type=gha,scope=${{ github.ref_name }}-latest-${{ matrix.arch }}
cache-to: type=gha,mode=max,scope=${{ github.ref_name }}-latest-${{ matrix.arch }}
file: "Dockerfile-156"
- name: Slack Notification
if: ${{ failure() }}
uses: rtCamp/action-slack-notify@v2
env:
SLACK_WEBHOOK: ${{ secrets.SLACK_NOTIFICATIONS_WEBHOOK }}
SLACK_USERNAME: "gha-failures-notifier"
SLACK_COLOR: "danger"
SLACK_MESSAGE: "Building Postgres ${{ matrix.arch }} image failed"
SLACK_FOOTER: ""

merge_manifest:
needs: [settings, build_release_image]
runs-on: ubuntu-latest
steps:
- uses: docker/setup-buildx-action@v3
- uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Merge multi-arch manifests
run: |
docker buildx imagetools create -t ${{ needs.settings.outputs.image_tag }} \
${{ needs.settings.outputs.image_tag }}_amd64 \
${{ needs.settings.outputs.image_tag }}_arm64
- name: Slack Notification
if: ${{ failure() }}
uses: rtCamp/action-slack-notify@v2
env:
SLACK_WEBHOOK: ${{ secrets.SLACK_NOTIFICATIONS_WEBHOOK }}
SLACK_USERNAME: "gha-failures-notifier"
SLACK_COLOR: "danger"
SLACK_MESSAGE: "Building Postgres image failed"
SLACK_FOOTER: ""

publish:
needs: [settings, merge_manifest]
# Call workflow explicitly because events from actions cannot trigger more actions
uses: ./.github/workflows/mirror.yml
with:
version: ${{ needs.settings.outputs.docker_version }}
secrets: inherit
15 changes: 12 additions & 3 deletions .github/workflows/nix-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,18 @@ jobs:
python -c "import os; file = open('nix-secret-key', 'w'); file.write(os.environ['NIX_SIGN_SECRET_KEY']); file.close()"
env:
NIX_SIGN_SECRET_KEY: ${{ secrets.NIX_SIGN_SECRET_KEY }}

- name: Build docker images
- name: Log in to Docker Hub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Build psql bundle with nix
run: docker build -t base_nix -f docker/nix/Dockerfile .
- name: Run build psql bundle
run: docker run -e AWS_ACCESS_KEY_ID=${{ env.AWS_ACCESS_KEY_ID }} -e AWS_SECRET_ACCESS_KEY=${{ env.AWS_SECRET_ACCESS_KEY }} -e AWS_SESSION_TOKEN=${{ env.AWS_SESSION_TOKEN }} base_nix bash -c "./workspace/docker/nix/build.sh"
run: |
docker run -e AWS_ACCESS_KEY_ID=${{ env.AWS_ACCESS_KEY_ID }} \
-e AWS_SECRET_ACCESS_KEY=${{ env.AWS_SECRET_ACCESS_KEY }} \
-e AWS_SESSION_TOKEN=${{ env.AWS_SESSION_TOKEN }} \
base_nix bash -c "./workspace/docker/nix/build_nix.sh"
name: build psql bundle on ${{ matrix.arch }}

222 changes: 222 additions & 0 deletions Dockerfile-156
Original file line number Diff line number Diff line change
@@ -0,0 +1,222 @@
# syntax=docker/dockerfile:1.6
ARG postgresql_major=15
ARG postgresql_release=${postgresql_major}.1

# Bump default build arg to build a package from source
# Bump vars.yml to specify runtime package version
ARG sfcgal_release=1.3.10
ARG postgis_release=3.3.2
ARG pgrouting_release=3.4.1
ARG pgtap_release=1.2.0
ARG pg_cron_release=1.6.2
ARG pgaudit_release=1.7.0
ARG pgjwt_release=9742dab1b2f297ad3811120db7b21451bca2d3c9
ARG pgsql_http_release=1.5.0
ARG plpgsql_check_release=2.2.5
ARG pg_safeupdate_release=1.4
ARG timescaledb_release=2.9.1
ARG wal2json_release=2_5
ARG pljava_release=1.6.4
ARG plv8_release=3.1.5
ARG pg_plan_filter_release=5081a7b5cb890876e67d8e7486b6a64c38c9a492
ARG pg_net_release=0.7.1
ARG rum_release=1.3.13
ARG pg_hashids_release=cd0e1b31d52b394a0df64079406a14a4f7387cd6
ARG libsodium_release=1.0.18
ARG pgsodium_release=3.1.6
ARG pg_graphql_release=1.5.1
ARG pg_stat_monitor_release=1.1.1
ARG pg_jsonschema_release=0.1.4
ARG pg_repack_release=1.4.8
ARG vault_release=0.2.8
ARG groonga_release=12.0.8
ARG pgroonga_release=2.4.0
ARG wrappers_release=0.3.0
ARG hypopg_release=1.3.1
ARG pgvector_release=0.4.0
ARG pg_tle_release=1.3.2
ARG index_advisor_release=0.2.0
ARG supautils_release=2.2.0
ARG wal_g_release=2.0.1

FROM ubuntu:focal as base

RUN apt update -y && apt install -y \
curl \
gnupg \
lsb-release \
software-properties-common \
wget \
sudo \
&& apt clean


RUN adduser --system --home /var/lib/postgresql --no-create-home --shell /bin/bash --group --gecos "PostgreSQL administrator" postgres
RUN adduser --system --no-create-home --shell /bin/bash --group wal-g
RUN curl --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix | sh -s -- install linux \
--init none \
--no-confirm \
--extra-conf "substituters = https://cache.nixos.org https://nix-postgres-artifacts.s3.amazonaws.com" \
--extra-conf "trusted-public-keys = nix-postgres-artifacts:dGZlQOvKcNEjvT7QEAJbcV6b6uk7VF/hWMjhYleiaLI=% cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY="

ENV PATH="${PATH}:/nix/var/nix/profiles/default/bin"

COPY . /nixpg

WORKDIR /nixpg

RUN nix profile install .#psql_15/bin



WORKDIR /


RUN mkdir -p /usr/lib/postgresql/bin \
/usr/lib/postgresql/share/postgresql \
/usr/share/postgresql \
# /usr/lib/postgresql/share/postgresql/contrib \
#/usr/lib/postgresql/share/postgresql/timezonesets \
#/usr/lib/postgresql/share/postgresql/tsearch_data \
# /usr/lib/postgresql/share/postgresql/extension \
&& chown -R postgres:postgres /usr/lib/postgresql \
&& chown -R postgres:postgres /usr/share/postgresql

# Create symbolic links
RUN ln -s /nix/var/nix/profiles/default/bin/* /usr/lib/postgresql/bin/ \
&& ln -s /nix/var/nix/profiles/default/bin/* /usr/bin/ \
&& chown -R postgres:postgres /usr/bin

# Create symbolic links for PostgreSQL shares
RUN ln -s /nix/var/nix/profiles/default/share/postgresql/* /usr/lib/postgresql/share/postgresql/
RUN ln -s /nix/var/nix/profiles/default/share/postgresql/* /usr/share/postgresql/
RUN chown -R postgres:postgres /usr/lib/postgresql/share/postgresql/
RUN chown -R postgres:postgres /usr/share/postgresql/
# Create symbolic links for contrib directory
RUN mkdir -p /usr/lib/postgresql/share/postgresql/contrib \
&& find /nix/var/nix/profiles/default/share/postgresql/contrib/ -mindepth 1 -type d -exec sh -c 'for dir do ln -s "$dir" "/usr/lib/postgresql/share/postgresql/contrib/$(basename "$dir")"; done' sh {} + \
&& chown -R postgres:postgres /usr/lib/postgresql/share/postgresql/contrib/

RUN chown -R postgres:postgres /usr/lib/postgresql

RUN ln -sf /usr/lib/postgresql/share/postgresql/timezonesets /usr/share/postgresql/timezonesets


RUN apt-get update && \
apt-get install -y --no-install-recommends tzdata

RUN ln -fs /usr/share/zoneinfo/Etc/UTC /etc/localtime && \
dpkg-reconfigure --frontend noninteractive tzdata

RUN apt-get update && \
apt-get install -y --no-install-recommends \
build-essential \
checkinstall \
cmake

ENV PGDATA=/var/lib/postgresql/data

####################
# setup-wal-g.yml
####################
FROM base as walg
ARG wal_g_release
# ADD "https://github.com/wal-g/wal-g/releases/download/v${wal_g_release}/wal-g-pg-ubuntu-20.04-${TARGETARCH}.tar.gz" /tmp/wal-g.tar.gz
RUN arch=$([ "$TARGETARCH" = "arm64" ] && echo "aarch64" || echo "$TARGETARCH") && \
apt-get update && apt-get install -y --no-install-recommends curl && \
curl -kL "https://github.com/wal-g/wal-g/releases/download/v${wal_g_release}/wal-g-pg-ubuntu-20.04-aarch64.tar.gz" -o /tmp/wal-g.tar.gz && \
tar -xvf /tmp/wal-g.tar.gz -C /tmp && \
rm -rf /tmp/wal-g.tar.gz && \
mv /tmp/wal-g-pg-ubuntu*20.04-aarch64 /tmp/wal-g

# ####################
# # Download gosu for easy step-down from root
# ####################
FROM base as gosu
ARG TARGETARCH
# Install dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \
gnupg \
ca-certificates \
&& rm -rf /var/lib/apt/lists/*
# Download binary
ARG GOSU_VERSION=1.16
ARG GOSU_GPG_KEY=B42F6819007F00F88E364FD4036A9C25BF357DD4
ADD https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$TARGETARCH \
/usr/local/bin/gosu
ADD https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$TARGETARCH.asc \
/usr/local/bin/gosu.asc
# Verify checksum
RUN gpg --batch --keyserver hkps://keys.openpgp.org --recv-keys $GOSU_GPG_KEY && \
gpg --batch --verify /usr/local/bin/gosu.asc /usr/local/bin/gosu && \
gpgconf --kill all && \
chmod +x /usr/local/bin/gosu

# ####################
# # Build final image
# ####################
FROM gosu as production
RUN id postgres || (echo "postgres user does not exist" && exit 1)
# # Setup extensions
COPY --from=walg /tmp/wal-g /usr/local/bin/

# # Initialise configs
COPY --chown=postgres:postgres ansible/files/postgresql_config/postgresql.conf.j2 /etc/postgresql/postgresql.conf
COPY --chown=postgres:postgres ansible/files/postgresql_config/pg_hba.conf.j2 /etc/postgresql/pg_hba.conf
COPY --chown=postgres:postgres ansible/files/postgresql_config/pg_ident.conf.j2 /etc/postgresql/pg_ident.conf
COPY --chown=postgres:postgres ansible/files/postgresql_config/postgresql-stdout-log.conf /etc/postgresql/logging.conf
COPY --chown=postgres:postgres ansible/files/postgresql_config/supautils.conf.j2 /etc/postgresql-custom/supautils.conf
COPY --chown=postgres:postgres ansible/files/postgresql_extension_custom_scripts /etc/postgresql-custom/extension-custom-scripts
COPY --chown=postgres:postgres ansible/files/pgsodium_getkey_urandom.sh.j2 /usr/lib/postgresql/bin/pgsodium_getkey.sh
COPY --chown=postgres:postgres ansible/files/postgresql_config/custom_read_replica.conf.j2 /etc/postgresql-custom/read-replica.conf
COPY --chown=postgres:postgres ansible/files/postgresql_config/custom_walg.conf.j2 /etc/postgresql-custom/wal-g.conf
COPY --chown=postgres:postgres ansible/files/walg_helper_scripts/wal_fetch.sh /home/postgres/wal_fetch.sh
COPY ansible/files/walg_helper_scripts/wal_change_ownership.sh /root/wal_change_ownership.sh

RUN sed -i \
-e "s|#unix_socket_directories = '/tmp'|unix_socket_directories = '/var/run/postgresql'|g" \
-e "s|#session_preload_libraries = ''|session_preload_libraries = 'supautils'|g" \
-e "s|#include = '/etc/postgresql-custom/supautils.conf'|include = '/etc/postgresql-custom/supautils.conf'|g" \
-e "s|#include = '/etc/postgresql-custom/wal-g.conf'|include = '/etc/postgresql-custom/wal-g.conf'|g" /etc/postgresql/postgresql.conf && \
echo "cron.database_name = 'postgres'" >> /etc/postgresql/postgresql.conf && \
#echo "pljava.libjvm_location = '/usr/lib/jvm/java-11-openjdk-${TARGETARCH}/lib/server/libjvm.so'" >> /etc/postgresql/postgresql.conf && \
echo "pgsodium.getkey_script= '/usr/lib/postgresql/bin/pgsodium_getkey.sh'" >> /etc/postgresql/postgresql.conf && \
echo 'auto_explain.log_min_duration = 10s' >> /etc/postgresql/postgresql.conf && \
usermod -aG postgres wal-g && \
mkdir -p /etc/postgresql-custom && \
chown postgres:postgres /etc/postgresql-custom

# # Include schema migrations
COPY migrations/db /docker-entrypoint-initdb.d/
COPY ansible/files/pgbouncer_config/pgbouncer_auth_schema.sql /docker-entrypoint-initdb.d/init-scripts/00-schema.sql
COPY ansible/files/stat_extension.sql /docker-entrypoint-initdb.d/migrations/00-extension.sql

# # Add upstream entrypoint script
COPY --from=gosu /usr/local/bin/gosu /usr/local/bin/gosu
ADD --chmod=0755 \
https://github.com/docker-library/postgres/raw/master/15/bullseye/docker-entrypoint.sh \
/usr/local/bin/

RUN mkdir -p /var/run/postgresql && chown postgres:postgres /var/run/postgresql

ENTRYPOINT ["docker-entrypoint.sh"]

HEALTHCHECK --interval=2s --timeout=2s --retries=10 CMD pg_isready -U postgres -h localhost
STOPSIGNAL SIGINT
EXPOSE 5432

ENV POSTGRES_HOST=/var/run/postgresql
RUN 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 \
&& localedef -i C -c -f UTF-8 -A /usr/share/locale/locale.alias C.UTF-8
RUN echo "C.UTF-8 UTF-8" > /etc/locale.gen && echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen && locale-gen
ENV LANG en_US.UTF-8
ENV LANGUAGE en_US:en
ENV LC_ALL en_US.UTF-8
ENV LC_CTYPE=C.UTF-8
ENV LC_COLLATE=C.UTF-8
ENV LOCALE_ARCHIVE /usr/lib/locale/locale-archive
CMD ["postgres", "-D", "/etc/postgresql"]

6 changes: 2 additions & 4 deletions docker/nix/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@ RUN mkdir -p /workspace

COPY ./ /workspace

RUN chmod +x /workspace/docker/nix/build.sh

RUN chown -R $USER:$USER /workspace

RUN chmod +x /workspace/docker/nix/build_nix.sh

RUN chown -R $USER:$USER /workspace
4 changes: 1 addition & 3 deletions docker/nix/build.sh → docker/nix/build_nix.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,5 @@ nix --version
cd /workspace
nix build .#psql_15/bin -o psql_15
nix build .#psql_15/docker
nix flake check -L --all-systems
nix flake check -L
nix copy --to s3://nix-postgres-artifacts?secret-key=nix-secret-key ./psql_15

#a future step nix run .#psql_15/docker.copyToRegistry
Loading

0 comments on commit 92ddd74

Please sign in to comment.