Skip to content

Commit 9d31257

Browse files
authored
feat: self hosted supabase and postgres docs + release builds (#35)
* docs: add quickstarts for postgres and supabase * feat(postgresql): add multi-version PG builds and Docker Hub publishing Build PostgreSQL extension packages for both PG 17 and PG 15 in CI. Add Dockerfile.release and Dockerfile.supabase.release for end-users to create Docker images from pre-built GitHub release binaries without cloning the repo. Add docker-publish CI job to push multi-arch images to Docker Hub (sqlitecloud/sqlite-sync-postgres and sqlitecloud/sqlite-sync-supabase) on release. * chore: organize docs folder
1 parent 0848b05 commit 9d31257

File tree

22 files changed

+2654
-110
lines changed

22 files changed

+2654
-110
lines changed

.github/workflows/main.yml

Lines changed: 114 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,7 @@ jobs:
277277
278278
postgres-build:
279279
runs-on: ${{ matrix.os }}
280-
name: postgresql-${{ matrix.name }}-${{ matrix.arch }} build
280+
name: postgresql${{ matrix.postgres_version }}-${{ matrix.name }}-${{ matrix.arch }} build
281281
timeout-minutes: 15
282282
strategy:
283283
fail-fast: false
@@ -286,15 +286,35 @@ jobs:
286286
- os: ubuntu-22.04
287287
arch: x86_64
288288
name: linux
289+
postgres_version: '17'
290+
- os: ubuntu-22.04
291+
arch: x86_64
292+
name: linux
293+
postgres_version: '15'
294+
- os: ubuntu-22.04-arm
295+
arch: arm64
296+
name: linux
297+
postgres_version: '17'
289298
- os: ubuntu-22.04-arm
290299
arch: arm64
291300
name: linux
301+
postgres_version: '15'
292302
- os: macos-15
293303
arch: arm64
294304
name: macos
305+
postgres_version: '17'
306+
- os: macos-15
307+
arch: arm64
308+
name: macos
309+
postgres_version: '15'
295310
- os: macos-15
296311
arch: x86_64
297312
name: macos
313+
postgres_version: '17'
314+
- os: macos-15
315+
arch: x86_64
316+
name: macos
317+
postgres_version: '15'
298318
steps:
299319

300320
- uses: actions/checkout@v4.2.2
@@ -307,23 +327,23 @@ jobs:
307327
sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list'
308328
curl -fsSL https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/postgresql.gpg
309329
sudo apt-get update
310-
sudo apt-get install -y postgresql-server-dev-17
330+
sudo apt-get install -y postgresql-server-dev-${{ matrix.postgres_version }}
311331
312332
- name: macos install postgresql
313333
if: matrix.name == 'macos'
314-
run: brew install postgresql@17 gettext
334+
run: brew install postgresql@${{ matrix.postgres_version }} gettext
315335

316336
- name: build and package postgresql extension (linux)
317337
if: matrix.name == 'linux'
318-
run: make postgres-package
338+
run: make postgres-package PG_CONFIG=/usr/lib/postgresql/${{ matrix.postgres_version }}/bin/pg_config
319339

320340
- name: build and package postgresql extension (macos)
321341
if: matrix.name == 'macos'
322-
run: make postgres-package PG_CONFIG=$(brew --prefix postgresql@17)/bin/pg_config PG_EXTRA_CFLAGS="-I$(brew --prefix gettext)/include ${{ matrix.arch == 'x86_64' && '-arch x86_64' || '' }}"
342+
run: make postgres-package PG_CONFIG=$(brew --prefix postgresql@${{ matrix.postgres_version }})/bin/pg_config PG_EXTRA_CFLAGS="-I$(brew --prefix gettext)/include ${{ matrix.arch == 'x86_64' && '-arch x86_64' || '' }}"
323343

324344
- uses: actions/upload-artifact@v4.6.2
325345
with:
326-
name: cloudsync-postgresql-${{ matrix.name }}-${{ matrix.arch }}
346+
name: cloudsync-postgresql${{ matrix.postgres_version }}-${{ matrix.name }}-${{ matrix.arch }}
327347
path: dist/postgresql/
328348
if-no-files-found: error
329349

@@ -546,6 +566,8 @@ jobs:
546566
[**Expo**](https://www.npmjs.com/package/@sqliteai/sqlite-sync-expo): `npm install @sqliteai/sqlite-sync-expo`
547567
[**Android**](https://central.sonatype.com/artifact/ai.sqlite/sync): `ai.sqlite:sync:${{ steps.tag.outputs.version }}`
548568
[**Swift**](https://github.com/sqliteai/sqlite-sync#swift-package): [Installation Guide](https://github.com/sqliteai/sqlite-sync#swift-package)
569+
[**Docker (PostgreSQL)**](https://hub.docker.com/r/sqlitecloud/sqlite-sync-postgres): `docker pull sqlitecloud/sqlite-sync-postgres:17` or `:15`
570+
[**Docker (Supabase)**](https://hub.docker.com/r/sqlitecloud/sqlite-sync-supabase): `docker pull sqlitecloud/sqlite-sync-supabase:17` or `:15`
549571
550572
---
551573
@@ -555,3 +577,89 @@ jobs:
555577
cloudsync-*-${{ steps.tag.outputs.version }}.*
556578
CloudSync-*-${{ steps.tag.outputs.version }}.*
557579
make_latest: true
580+
581+
docker-publish:
582+
runs-on: ubuntu-22.04
583+
name: docker ${{ matrix.image }} pg${{ matrix.pg_major }}
584+
needs: [release]
585+
if: github.ref == 'refs/heads/main'
586+
587+
env:
588+
DOCKERHUB_ORG: sqlitecloud
589+
590+
strategy:
591+
fail-fast: false
592+
matrix:
593+
include:
594+
- image: sqlite-sync-postgres
595+
pg_major: '17'
596+
dockerfile: docker/postgresql/Dockerfile.release
597+
- image: sqlite-sync-postgres
598+
pg_major: '15'
599+
dockerfile: docker/postgresql/Dockerfile.release
600+
- image: sqlite-sync-supabase
601+
pg_major: '17'
602+
dockerfile: docker/postgresql/Dockerfile.supabase.release
603+
supabase_tag: '17.6.1.071'
604+
- image: sqlite-sync-supabase
605+
pg_major: '15'
606+
dockerfile: docker/postgresql/Dockerfile.supabase.release
607+
supabase_tag: '15.8.1.085'
608+
609+
steps:
610+
611+
- uses: actions/checkout@v4.2.2
612+
with:
613+
submodules: true
614+
615+
- name: get cloudsync version
616+
id: version
617+
run: echo "version=$(make version)" >> $GITHUB_OUTPUT
618+
619+
- uses: docker/setup-qemu-action@v3
620+
621+
- uses: docker/setup-buildx-action@v3
622+
623+
- uses: docker/login-action@v3
624+
with:
625+
username: ${{ secrets.DOCKERHUB_USERNAME }}
626+
password: ${{ secrets.DOCKERHUB_TOKEN }}
627+
628+
- name: set docker tags and build args (standalone)
629+
if: matrix.image == 'sqlite-sync-postgres'
630+
id: standalone
631+
run: |
632+
VERSION=${{ steps.version.outputs.version }}
633+
PG=${{ matrix.pg_major }}
634+
IMAGE=${{ env.DOCKERHUB_ORG }}/${{ matrix.image }}
635+
{
636+
echo "tags=${IMAGE}:${PG},${IMAGE}:${PG}-${VERSION}"
637+
echo "build_args<<EOF"
638+
echo "POSTGRES_TAG=${PG}"
639+
echo "CLOUDSYNC_VERSION=${VERSION}"
640+
echo "EOF"
641+
} >> $GITHUB_OUTPUT
642+
643+
- name: set docker tags and build args (supabase)
644+
if: matrix.image == 'sqlite-sync-supabase'
645+
id: supabase
646+
run: |
647+
VERSION=${{ steps.version.outputs.version }}
648+
IMAGE=${{ env.DOCKERHUB_ORG }}/${{ matrix.image }}
649+
SUPABASE_TAG=${{ matrix.supabase_tag }}
650+
{
651+
echo "tags=${IMAGE}:${{ matrix.pg_major }},${IMAGE}:${{ matrix.pg_major }}-${VERSION},${IMAGE}:${SUPABASE_TAG}"
652+
echo "build_args<<EOF"
653+
echo "SUPABASE_POSTGRES_TAG=${SUPABASE_TAG}"
654+
echo "CLOUDSYNC_VERSION=${VERSION}"
655+
echo "EOF"
656+
} >> $GITHUB_OUTPUT
657+
658+
- uses: docker/build-push-action@v6
659+
with:
660+
context: .
661+
file: ${{ matrix.dockerfile }}
662+
platforms: linux/amd64,linux/arm64
663+
push: true
664+
tags: ${{ matrix.image == 'sqlite-sync-postgres' && steps.standalone.outputs.tags || steps.supabase.outputs.tags }}
665+
build-args: ${{ matrix.image == 'sqlite-sync-postgres' && steps.standalone.outputs.build_args || steps.supabase.outputs.build_args }}

API.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ When designing your database schema for SQLite Sync, follow these essential requ
5757
- **Foreign Key Compatibility**: Be aware of potential conflicts during CRDT merge operations and RLS policy interactions.
5858
- **Trigger Compatibility**: Triggers may cause duplicate operations or be called multiple times due to column-by-column processing.
5959

60-
For comprehensive guidelines, see the [Database Schema Recommendations](docs/SCHEMA.md).
60+
For comprehensive guidelines, see the [Database Schema Recommendations](docs/schema.md).
6161

6262
The function supports three overloads:
6363
- `cloudsync_init(table_name)`: Uses the default 'cls' CRDT algorithm.

README.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ Built on **CRDT** (Conflict-free Replicated Data Types), it guarantees:
5353

5454
### 1. Install
5555

56-
Download a pre-built binary from the [Releases](https://github.com/sqliteai/sqlite-sync/releases) page, or install a platform package (see [full installation guide](./docs/INSTALLATION.md) for platform-specific code examples):
56+
Download a pre-built binary from the [Releases](https://github.com/sqliteai/sqlite-sync/releases) page, or install a platform package (see [full installation guide](./docs/installation.md) for platform-specific code examples):
5757

5858
| Platform | Install |
5959
|----------|---------|
@@ -165,7 +165,7 @@ SELECT cloudsync_init('notes');
165165
SELECT cloudsync_set_column('notes', 'body', 'algo', 'block');
166166
```
167167

168-
Now two agents (or devices) can edit different lines of the same note, and both edits are preserved after sync. See the full guide: **[Block-Level LWW Documentation](./docs/BLOCK-LWW.md)**.
168+
Now two agents (or devices) can edit different lines of the same note, and both edits are preserved after sync. See the full guide: **[Block-Level LWW Documentation](./docs/block-lww.md)**.
169169

170170
## Row-Level Security
171171

@@ -174,16 +174,16 @@ With SQLite Cloud's RLS, a single shared cloud database serves all users while e
174174
- One database, multiple tenants, no per-user database provisioning.
175175
- Each client syncs only authorized rows, minimal bandwidth and storage.
176176

177-
See the full guide: **[Row-Level Security Documentation](./docs/ROW-LEVEL-SECURITY.md)**.
177+
See the full guide: **[Row-Level Security Documentation](./docs/row-level-security.md)**.
178178

179179
## Documentation
180180

181181
- **[API Reference](./API.md)**: all functions, parameters, and examples
182-
- **[Installation Guide](./docs/INSTALLATION.md)**: platform-specific setup (Swift, Android, Expo, React Native, Flutter, WASM)
183-
- **[Block-Level LWW Guide](./docs/BLOCK-LWW.md)**: line-level text merge for markdown and documents
184-
- **[Row-Level Security Guide](./docs/ROW-LEVEL-SECURITY.md)**: multi-tenant access control with server-enforced policies
185-
- **[Database Schema Recommendations](./docs/SCHEMA.md)**: primary keys, constraints, foreign keys, triggers
186-
- **[Custom Network Layer](./docs/Network.md)**: replace the built-in libcurl networking
182+
- **[Installation Guide](./docs/installation.md)**: platform-specific setup (Swift, Android, Expo, React Native, Flutter, WASM)
183+
- **[Block-Level LWW Guide](./docs/block-lww.md)**: line-level text merge for markdown and documents
184+
- **[Row-Level Security Guide](./docs/row-level-security.md)**: multi-tenant access control with server-enforced policies
185+
- **[Database Schema Recommendations](./docs/schema.md)**: primary keys, constraints, foreign keys, triggers
186+
- **[Custom Network Layer](./docs/internal/network.md)**: replace the built-in libcurl networking
187187
- **[Examples](./examples/)**: complete walkthroughs (todo app, sport tracker, Swift multiplatform)
188188

189189
## SQLite Cloud Setup
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# PostgreSQL with pre-compiled CloudSync (sqlite-sync) extension
2+
#
3+
# Usage:
4+
# docker build \
5+
# --build-arg POSTGRES_TAG=17 \
6+
# --build-arg CLOUDSYNC_VERSION=1.0.1 \
7+
# -t sqlite-sync-postgres:17 \
8+
# -f docker/postgresql/Dockerfile.release .
9+
#
10+
# Or pull the pre-built image from Docker Hub:
11+
# docker pull sqlitecloud/sqlite-sync-postgres:17
12+
#
13+
14+
ARG POSTGRES_TAG=17
15+
FROM postgres:${POSTGRES_TAG}
16+
17+
ARG CLOUDSYNC_VERSION
18+
ARG TARGETARCH
19+
20+
# Map Docker platform arch to artifact arch
21+
RUN case "${TARGETARCH}" in \
22+
amd64) ARCH="x86_64" ;; \
23+
arm64) ARCH="arm64" ;; \
24+
*) echo "Unsupported architecture: ${TARGETARCH}" && exit 1 ;; \
25+
esac && \
26+
apt-get update && apt-get install -y --no-install-recommends curl ca-certificates && \
27+
ASSET="cloudsync-postgresql${PG_MAJOR}-linux-${ARCH}-${CLOUDSYNC_VERSION}.tar.gz" && \
28+
URL="https://github.com/sqliteai/sqlite-sync/releases/download/${CLOUDSYNC_VERSION}/${ASSET}" && \
29+
echo "Downloading ${URL}" && \
30+
curl -fSL "${URL}" -o /tmp/cloudsync.tar.gz && \
31+
mkdir -p /tmp/cloudsync && \
32+
tar -xzf /tmp/cloudsync.tar.gz -C /tmp/cloudsync && \
33+
install -m 755 /tmp/cloudsync/cloudsync.so "$(pg_config --pkglibdir)/" && \
34+
install -m 644 /tmp/cloudsync/cloudsync--1.0.sql "$(pg_config --sharedir)/extension/" && \
35+
install -m 644 /tmp/cloudsync/cloudsync.control "$(pg_config --sharedir)/extension/" && \
36+
rm -rf /tmp/cloudsync /tmp/cloudsync.tar.gz && \
37+
apt-get purge -y curl && apt-get autoremove -y && rm -rf /var/lib/apt/lists/*
38+
39+
# Verify installation
40+
RUN ls -la "$(pg_config --pkglibdir)/cloudsync.so" && \
41+
ls -la "$(pg_config --sharedir)/extension/cloudsync"* && \
42+
echo "CloudSync extension installed successfully"
43+
44+
# Copy initialization script (auto-creates the extension on first start)
45+
COPY docker/postgresql/init.sql /docker-entrypoint-initdb.d/
46+
47+
EXPOSE 5432
48+
49+
LABEL org.sqliteai.cloudsync.description="PostgreSQL with CloudSync CRDT extension" \
50+
org.opencontainers.image.source="https://github.com/sqliteai/sqlite-sync"
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
# Supabase PostgreSQL with pre-compiled CloudSync (sqlite-sync) extension
2+
#
3+
# Usage:
4+
# docker build \
5+
# --build-arg SUPABASE_POSTGRES_TAG=15.8.1.085 \
6+
# --build-arg CLOUDSYNC_VERSION=1.0.1 \
7+
# -f docker/postgresql/Dockerfile.supabase.release \
8+
# -t my-cloudsync-supabase-postgres .
9+
#
10+
# Or pull the pre-built image from Docker Hub:
11+
# docker pull sqlitecloud/sqlite-sync-supabase:15
12+
#
13+
14+
ARG SUPABASE_POSTGRES_TAG=17.6.1.071
15+
FROM public.ecr.aws/supabase/postgres:${SUPABASE_POSTGRES_TAG}
16+
17+
ARG CLOUDSYNC_VERSION
18+
ARG TARGETARCH
19+
20+
ENV CLOUDSYNC_PG_CONFIG=/root/.nix-profile/bin/pg_config
21+
22+
# Download pre-compiled extension and install into Supabase's Nix layout
23+
RUN case "${TARGETARCH}" in \
24+
amd64) ARCH="x86_64" ;; \
25+
arm64) ARCH="arm64" ;; \
26+
*) echo "Unsupported architecture: ${TARGETARCH}" && exit 1 ;; \
27+
esac && \
28+
# Derive PG major version from pg_config
29+
PG_MAJOR=$(${CLOUDSYNC_PG_CONFIG} --version | sed 's/[^0-9]*//' | cut -d. -f1) && \
30+
apt-get update && apt-get install -y --no-install-recommends curl ca-certificates && \
31+
ASSET="cloudsync-postgresql${PG_MAJOR}-linux-${ARCH}-${CLOUDSYNC_VERSION}.tar.gz" && \
32+
URL="https://github.com/sqliteai/sqlite-sync/releases/download/${CLOUDSYNC_VERSION}/${ASSET}" && \
33+
echo "Downloading ${URL}" && \
34+
curl -fSL "${URL}" -o /tmp/cloudsync.tar.gz && \
35+
mkdir -p /tmp/cloudsync && \
36+
tar -xzf /tmp/cloudsync.tar.gz -C /tmp/cloudsync && \
37+
# Resolve Supabase's Nix library path
38+
PKGLIBDIR="$(${CLOUDSYNC_PG_CONFIG} --pkglibdir)" && \
39+
NIX_PGLIBDIR="$(grep -E '^export NIX_PGLIBDIR' /usr/bin/postgres | sed -E "s/.*'([^']+)'.*/\1/" || true)" && \
40+
if [ -n "$NIX_PGLIBDIR" ]; then PKGLIBDIR="$NIX_PGLIBDIR"; fi && \
41+
SHAREDIR_PGCONFIG="$(${CLOUDSYNC_PG_CONFIG} --sharedir)" && \
42+
SHAREDIR_STD="/usr/share/postgresql" && \
43+
install -d "$PKGLIBDIR" "$SHAREDIR_PGCONFIG/extension" && \
44+
install -m 755 /tmp/cloudsync/cloudsync.so "$PKGLIBDIR/" && \
45+
install -m 644 /tmp/cloudsync/cloudsync--1.0.sql /tmp/cloudsync/cloudsync.control "$SHAREDIR_PGCONFIG/extension/" && \
46+
if [ "$SHAREDIR_STD" != "$SHAREDIR_PGCONFIG" ]; then \
47+
install -d "$SHAREDIR_STD/extension" && \
48+
install -m 644 /tmp/cloudsync/cloudsync--1.0.sql /tmp/cloudsync/cloudsync.control "$SHAREDIR_STD/extension/"; \
49+
fi && \
50+
rm -rf /tmp/cloudsync /tmp/cloudsync.tar.gz && \
51+
apt-get purge -y curl && apt-get autoremove -y && rm -rf /var/lib/apt/lists/*
52+
53+
# Verify installation
54+
RUN NIX_PGLIBDIR="$(grep -E '^export NIX_PGLIBDIR' /usr/bin/postgres | sed -E "s/.*'([^']+)'.*/\1/" || true)" && \
55+
echo "Verifying CloudSync extension installation..." && \
56+
if [ -n "$NIX_PGLIBDIR" ]; then \
57+
ls -la "$NIX_PGLIBDIR/cloudsync.so"; \
58+
else \
59+
ls -la "$(${CLOUDSYNC_PG_CONFIG} --pkglibdir)/cloudsync.so"; \
60+
fi && \
61+
ls -la "$(${CLOUDSYNC_PG_CONFIG} --sharedir)/extension/cloudsync"* && \
62+
if [ -d "/usr/share/postgresql/extension" ]; then \
63+
ls -la /usr/share/postgresql/extension/cloudsync*; \
64+
fi && \
65+
echo "CloudSync extension installed successfully"
66+
67+
EXPOSE 5432
68+
69+
WORKDIR /
70+
71+
LABEL org.sqliteai.cloudsync.description="Supabase PostgreSQL with CloudSync CRDT extension" \
72+
org.opencontainers.image.source="https://github.com/sqliteai/sqlite-sync"

docs/ROW-LEVEL-SECURITY.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,6 @@ CREATE TABLE users (
4444
);
4545
```
4646

47-
For more schema guidelines, see [Database Schema Recommendations](./SCHEMA.md).
47+
For more schema guidelines, see [Database Schema Recommendations](./schema.md).
4848

4949
For full RLS documentation, see the [SQLite Cloud RLS documentation](https://docs.sqlitecloud.io/docs/rls).
File renamed without changes.
File renamed without changes.
File renamed without changes.

0 commit comments

Comments
 (0)