feat: Small core version of supabase postgres #1
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Release Minimal Alpine Images on Dockerhub | ||
|
Check failure on line 1 in .github/workflows/dockerhub-release-minimal.yml
|
||
| # This workflow builds and publishes minimal Alpine-based Supabase Postgres images | ||
| # with configurable extension profiles. It runs separately from the main release | ||
| # workflow to avoid conflicts with the full Ubuntu-based images. | ||
| on: | ||
| push: | ||
| branches: | ||
| - develop | ||
| - release/* | ||
| paths: | ||
| - ".github/workflows/dockerhub-release-minimal.yml" | ||
| - "Dockerfile-alpine-minimal" | ||
| - "extensions-config.json" | ||
| - "nix/packages/postgres-configurable.nix" | ||
| workflow_dispatch: | ||
| inputs: | ||
| extension_profile: | ||
| description: 'Extension profile to build' | ||
| type: choice | ||
| options: | ||
| - core | ||
| - standard | ||
| - full | ||
| - all | ||
| default: standard | ||
| custom_extensions: | ||
| description: 'Custom comma-separated extension list (overrides profile)' | ||
| required: false | ||
| default: '' | ||
| postgres_version: | ||
| description: 'PostgreSQL version to build' | ||
| type: choice | ||
| options: | ||
| - '17' | ||
| - '15' | ||
| - 'all' | ||
| default: '17' | ||
| permissions: | ||
| contents: read | ||
| id-token: write | ||
| jobs: | ||
| # Prepare build matrix based on inputs | ||
| prepare: | ||
| runs-on: blacksmith-4vcpu-ubuntu-2404 | ||
| outputs: | ||
| matrix_config: ${{ steps.set-matrix.outputs.matrix_config }} | ||
| steps: | ||
| - name: Checkout Repo | ||
| uses: supabase/postgres/.github/actions/shared-checkout@HEAD | ||
| - uses: ./.github/actions/nix-install-ephemeral | ||
| - name: Generate build matrix | ||
| id: set-matrix | ||
| run: | | ||
| nix run nixpkgs#nushell -- -c ' | ||
| let input_profile = "${{ github.event.inputs.extension_profile || '\''standard'\'' }}" | ||
| let input_pg_version = "${{ github.event.inputs.postgres_version || '\''17'\'' }}" | ||
| let custom_extensions = "${{ github.event.inputs.custom_extensions || '\'''\'' }}" | ||
| # Determine profiles to build | ||
| let profiles = if $custom_extensions != "" { | ||
| ["custom"] | ||
| } else if $input_profile == "all" { | ||
| ["core", "standard", "full"] | ||
| } else { | ||
| [$input_profile] | ||
| } | ||
| # Determine PostgreSQL versions to build | ||
| let pg_versions = if $input_pg_version == "all" { | ||
| ["15", "17"] | ||
| } else { | ||
| [$input_pg_version] | ||
| } | ||
| # Generate matrix combinations | ||
| let matrix = ($profiles | each { |profile| | ||
| $pg_versions | each { |pg_ver| | ||
| { | ||
| profile: $profile, | ||
| pg_version: $pg_ver, | ||
| custom_extensions: (if $profile == "custom" { $custom_extensions } else { "" }) | ||
| } | ||
| } | ||
| } | flatten) | ||
| let matrix_config = { | ||
| include: $matrix | ||
| } | ||
| $"matrix_config=($matrix_config | to json -r)" | save --append $env.GITHUB_OUTPUT | ||
| ' | ||
| # Get build arguments from ansible/vars.yml | ||
| build_args: | ||
| runs-on: blacksmith-4vcpu-ubuntu-2404 | ||
| outputs: | ||
| build_args: ${{ steps.args.outputs.result }} | ||
| steps: | ||
| - name: Checkout Repo | ||
| uses: supabase/postgres/.github/actions/shared-checkout@HEAD | ||
| - uses: ./.github/actions/nix-install-ephemeral | ||
| - id: args | ||
| run: | | ||
| nix run nixpkgs#nushell -- -c ' | ||
| open ansible/vars.yml | ||
| | items { |key value| {name: $key, item: $value} } | ||
| | where { |it| ($it.item | describe) == "string" } | ||
| | each { |it| $"($it.name)=($it.item)" } | ||
| | str join "\n" | ||
| | save --append $env.GITHUB_OUTPUT | ||
| ' | ||
| # Build images for each profile/version/arch combination | ||
| build_release_image: | ||
| needs: [prepare, build_args] | ||
| strategy: | ||
| matrix: ${{ fromJson(needs.prepare.outputs.matrix_config) }} | ||
| fail-fast: false | ||
| runs-on: ${{ matrix.arch == 'arm64' && 'large-linux-arm' || 'large-linux-x86' }} | ||
| timeout-minutes: 180 | ||
| steps: | ||
| - name: Checkout Repo | ||
| uses: supabase/postgres/.github/actions/shared-checkout@HEAD | ||
| - uses: ./.github/actions/nix-install-ephemeral | ||
| - 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 }} | ||
| - name: Get image tag | ||
| id: image | ||
| run: | | ||
| nix run nixpkgs#nushell -- -c ' | ||
| let pg_version = "${{ matrix.pg_version }}" | ||
| let profile = "${{ matrix.profile }}" | ||
| let custom_ext = "${{ matrix.custom_extensions }}" | ||
| # Get the release version from vars.yml | ||
| let release_key = $"postgres($pg_version)" | ||
| let pg_release = (open ansible/vars.yml | get postgres_release | get $release_key | str trim) | ||
| # Build tag based on profile | ||
| let tag_suffix = if $custom_ext != "" { | ||
| "alpine-custom" | ||
| } else { | ||
| $"alpine-($profile)" | ||
| } | ||
| let tag = $"supabase/postgres:($pg_release)-($tag_suffix)" | ||
| $"tag=($tag)" | save --append $env.GITHUB_OUTPUT | ||
| ' | ||
| - name: Build and push image (amd64) | ||
| if: matrix.arch != 'arm64' | ||
| uses: docker/build-push-action@v5 | ||
| with: | ||
| push: true | ||
| build-args: | | ||
| POSTGRES_VERSION=${{ matrix.pg_version }} | ||
| EXTENSION_PROFILE=${{ matrix.profile }} | ||
| CUSTOM_EXTENSIONS=${{ matrix.custom_extensions }} | ||
| target: production | ||
| tags: ${{ steps.image.outputs.tag }}_amd64 | ||
| platforms: linux/amd64 | ||
| cache-from: type=gha,scope=${{ github.ref_name }}-minimal-${{ matrix.profile }}-${{ matrix.pg_version }}-amd64 | ||
| cache-to: type=gha,mode=max,scope=${{ github.ref_name }}-minimal-${{ matrix.profile }}-${{ matrix.pg_version }}-amd64 | ||
| file: Dockerfile-alpine-minimal | ||
| - name: Build and push image (arm64) | ||
| if: matrix.arch == 'arm64' | ||
| uses: docker/build-push-action@v5 | ||
| with: | ||
| push: true | ||
| build-args: | | ||
| POSTGRES_VERSION=${{ matrix.pg_version }} | ||
| EXTENSION_PROFILE=${{ matrix.profile }} | ||
| CUSTOM_EXTENSIONS=${{ matrix.custom_extensions }} | ||
| target: production | ||
| tags: ${{ steps.image.outputs.tag }}_arm64 | ||
| platforms: linux/arm64 | ||
| cache-from: type=gha,scope=${{ github.ref_name }}-minimal-${{ matrix.profile }}-${{ matrix.pg_version }}-arm64 | ||
| cache-to: type=gha,mode=max,scope=${{ github.ref_name }}-minimal-${{ matrix.profile }}-${{ matrix.pg_version }}-arm64 | ||
| file: Dockerfile-alpine-minimal | ||
| # Build for both architectures in parallel | ||
| build_multiarch: | ||
| needs: [prepare, build_args] | ||
| strategy: | ||
| matrix: | ||
| include: ${{ fromJson(needs.prepare.outputs.matrix_config).include }} | ||
| arch: [amd64, arm64] | ||
| fail-fast: false | ||
| runs-on: ${{ matrix.arch == 'arm64' && 'large-linux-arm' || 'large-linux-x86' }} | ||
| timeout-minutes: 180 | ||
| steps: | ||
| - name: Checkout Repo | ||
| uses: supabase/postgres/.github/actions/shared-checkout@HEAD | ||
| - uses: ./.github/actions/nix-install-ephemeral | ||
| - 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 }} | ||
| - name: Get image tag | ||
| id: image | ||
| run: | | ||
| nix run nixpkgs#nushell -- -c ' | ||
| let pg_version = "${{ matrix.pg_version }}" | ||
| let profile = "${{ matrix.profile }}" | ||
| let custom_ext = "${{ matrix.custom_extensions }}" | ||
| # Get the release version from vars.yml | ||
| let release_key = $"postgres($pg_version)" | ||
| let pg_release = (open ansible/vars.yml | get postgres_release | get $release_key | str trim) | ||
| # Build tag based on profile | ||
| let tag_suffix = if $custom_ext != "" { | ||
| "alpine-custom" | ||
| } else { | ||
| $"alpine-($profile)" | ||
| } | ||
| let tag = $"supabase/postgres:($pg_release)-($tag_suffix)" | ||
| $"tag=($tag)" | save --append $env.GITHUB_OUTPUT | ||
| ' | ||
| - name: Build and push image | ||
| uses: docker/build-push-action@v5 | ||
| with: | ||
| push: true | ||
| build-args: | | ||
| POSTGRES_VERSION=${{ matrix.pg_version }} | ||
| EXTENSION_PROFILE=${{ matrix.profile }} | ||
| CUSTOM_EXTENSIONS=${{ matrix.custom_extensions }} | ||
| target: production | ||
| tags: ${{ steps.image.outputs.tag }}_${{ matrix.arch }} | ||
| platforms: linux/${{ matrix.arch }} | ||
| cache-from: type=gha,scope=${{ github.ref_name }}-minimal-${{ matrix.profile }}-${{ matrix.pg_version }}-${{ matrix.arch }} | ||
| cache-to: type=gha,mode=max,scope=${{ github.ref_name }}-minimal-${{ matrix.profile }}-${{ matrix.pg_version }}-${{ matrix.arch }} | ||
| file: Dockerfile-alpine-minimal | ||
| # Merge multi-arch manifests | ||
| merge_manifest: | ||
| needs: [prepare, build_multiarch] | ||
| strategy: | ||
| matrix: | ||
| include: ${{ fromJson(needs.prepare.outputs.matrix_config).include }} | ||
| runs-on: large-linux-x86 | ||
| steps: | ||
| - name: Checkout Repo | ||
| uses: supabase/postgres/.github/actions/shared-checkout@HEAD | ||
| - uses: ./.github/actions/nix-install-ephemeral | ||
| - uses: docker/setup-buildx-action@v3 | ||
| - uses: docker/login-action@v2 | ||
| with: | ||
| username: ${{ secrets.DOCKER_USERNAME }} | ||
| password: ${{ secrets.DOCKER_PASSWORD }} | ||
| - name: Get image tag | ||
| id: get_tag | ||
| run: | | ||
| nix run nixpkgs#nushell -- -c ' | ||
| let pg_version = "${{ matrix.pg_version }}" | ||
| let profile = "${{ matrix.profile }}" | ||
| let custom_ext = "${{ matrix.custom_extensions }}" | ||
| let release_key = $"postgres($pg_version)" | ||
| let pg_release = (open ansible/vars.yml | get postgres_release | get $release_key | str trim) | ||
| let tag_suffix = if $custom_ext != "" { | ||
| "alpine-custom" | ||
| } else { | ||
| $"alpine-($profile)" | ||
| } | ||
| let tag = $"supabase/postgres:($pg_release)-($tag_suffix)" | ||
| $"tag=($tag)" | save --append $env.GITHUB_OUTPUT | ||
| ' | ||
| - name: Merge multi-arch manifests | ||
| run: | | ||
| docker buildx imagetools create -t ${{ steps.get_tag.outputs.tag }} \ | ||
| ${{ steps.get_tag.outputs.tag }}_amd64 \ | ||
| ${{ steps.get_tag.outputs.tag }}_arm64 | ||
| - name: Create alpine alias for standard profile | ||
| if: matrix.profile == 'standard' | ||
| run: | | ||
| nix run nixpkgs#nushell -- -c ' | ||
| let pg_version = "${{ matrix.pg_version }}" | ||
| let release_key = $"postgres($pg_version)" | ||
| let pg_release = (open ansible/vars.yml | get postgres_release | get $release_key | str trim) | ||
| # Create an alias without the profile suffix for standard | ||
| let alias_tag = $"supabase/postgres:($pg_release)-alpine" | ||
| let source_tag = "${{ steps.get_tag.outputs.tag }}" | ||
| $"alias_tag=($alias_tag)" | save --append $env.GITHUB_OUTPUT | ||
| ' | ||
| docker buildx imagetools create -t ${{ env.alias_tag }} \ | ||
| ${{ steps.get_tag.outputs.tag }}_amd64 \ | ||
| ${{ steps.get_tag.outputs.tag }}_arm64 | ||
| - name: Upload tag artifact | ||
| uses: actions/upload-artifact@v4 | ||
| with: | ||
| name: minimal-image-tag-${{ matrix.profile }}-${{ matrix.pg_version }} | ||
| path: | | ||
| echo "${{ steps.get_tag.outputs.tag }}" > tag.txt | ||
| if-no-files-found: warn | ||
| # Summary job | ||
| summary: | ||
| needs: [prepare, merge_manifest] | ||
| runs-on: ubuntu-latest | ||
| if: always() | ||
| steps: | ||
| - name: Summary | ||
| run: | | ||
| echo "## Minimal Alpine Image Build Summary" >> $GITHUB_STEP_SUMMARY | ||
| echo "" >> $GITHUB_STEP_SUMMARY | ||
| echo "### Build Configuration" >> $GITHUB_STEP_SUMMARY | ||
| echo "- **Trigger**: ${{ github.event_name }}" >> $GITHUB_STEP_SUMMARY | ||
| echo "- **Profile**: ${{ github.event.inputs.extension_profile || 'standard' }}" >> $GITHUB_STEP_SUMMARY | ||
| echo "- **PostgreSQL Version**: ${{ github.event.inputs.postgres_version || '17' }}" >> $GITHUB_STEP_SUMMARY | ||
| if [ -n "${{ github.event.inputs.custom_extensions }}" ]; then | ||
| echo "- **Custom Extensions**: ${{ github.event.inputs.custom_extensions }}" >> $GITHUB_STEP_SUMMARY | ||
| fi | ||
| echo "" >> $GITHUB_STEP_SUMMARY | ||
| echo "### Built Images" >> $GITHUB_STEP_SUMMARY | ||
| echo "Images have been published to Docker Hub with the following naming convention:" >> $GITHUB_STEP_SUMMARY | ||
| echo "\`supabase/postgres:<version>-alpine-<profile>\`" >> $GITHUB_STEP_SUMMARY | ||
| echo "" >> $GITHUB_STEP_SUMMARY | ||
| echo "### Profiles" >> $GITHUB_STEP_SUMMARY | ||
| echo "| Profile | Description | Est. Size |" >> $GITHUB_STEP_SUMMARY | ||
| echo "|---------|-------------|-----------|" >> $GITHUB_STEP_SUMMARY | ||
| echo "| core | Minimal extensions | ~200MB |" >> $GITHUB_STEP_SUMMARY | ||
| echo "| standard | Common extensions | ~400MB |" >> $GITHUB_STEP_SUMMARY | ||
| echo "| full | All extensions | ~1.5GB |" >> $GITHUB_STEP_SUMMARY | ||