Skip to content
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
13 changes: 12 additions & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ jobs:
target: aarch64-apple-darwin
artifact_name: database-replicator
asset_name: database-replicator-macos-arm64-binary
- os: windows-latest
target: x86_64-pc-windows-msvc
artifact_name: database-replicator.exe
asset_name: database-replicator-windows-x64.exe
steps:
- name: Checkout code
uses: actions/checkout@v4
Expand All @@ -51,11 +55,18 @@ jobs:
if: matrix.os == 'macos-latest'
run: strip target/${{ matrix.target }}/release/${{ matrix.artifact_name }}

- name: Rename binary
- name: Rename binary (Unix)
if: matrix.os != 'windows-latest'
run: |
cp target/${{ matrix.target }}/release/${{ matrix.artifact_name }} ${{ matrix.asset_name }}
chmod +x ${{ matrix.asset_name }}

- name: Rename binary (Windows)
if: matrix.os == 'windows-latest'
run: |
copy target\${{ matrix.target }}\release\${{ matrix.artifact_name }} ${{ matrix.asset_name }}
shell: cmd

- name: Upload artifact
uses: actions/upload-artifact@v4
with:
Expand Down
28 changes: 15 additions & 13 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,30 +1,32 @@
# syntax=docker/dockerfile:1

FROM rust:1.82-slim AS builder
WORKDIR /app
FROM debian:bookworm-slim AS downloader
ARG VERSION=latest
ENV BINARY_NAME=database-replicator-linux-x64-binary
ENV RELEASE_ROOT=https://github.com/serenorg/database-replicator/releases

# Install build dependencies for OpenSSL / libpq bindings
RUN apt-get update && \
apt-get install -y --no-install-recommends pkg-config libssl-dev libpq-dev && \
rm -rf /var/lib/apt/lists/*
RUN apt-get update && apt-get install -y --no-install-recommends curl ca-certificates && rm -rf /var/lib/apt/lists/*

# Cache dependencies
COPY Cargo.toml Cargo.lock ./
COPY src ./src
COPY README.md .
RUN cargo build --release --bin database-replicator
RUN set -eux; \
if [ "$VERSION" = "latest" ]; then \
URL="$RELEASE_ROOT/latest/download/$BINARY_NAME"; \
else \
URL="$RELEASE_ROOT/download/$VERSION/$BINARY_NAME"; \
fi; \
curl -fL "$URL" -o /tmp/database-replicator && \
chmod +x /tmp/database-replicator

FROM debian:bookworm-slim
LABEL org.opencontainers.image.title="database-replicator" \
org.opencontainers.image.description="Seren database replicator CLI" \
org.opencontainers.image.source="https://github.com/serenorg/database-replicator"

RUN apt-get update && \
apt-get install -y --no-install-recommends ca-certificates libssl3 libpq5 && \
apt-get install -y --no-install-recommends ca-certificates libssl3 libpq5 postgresql-client && \
rm -rf /var/lib/apt/lists/* && \
useradd -m replicator

COPY --from=builder /app/target/release/database-replicator /usr/local/bin/database-replicator
COPY --from=downloader /tmp/database-replicator /usr/local/bin/database-replicator
USER replicator
ENTRYPOINT ["database-replicator"]
CMD ["--help"]
29 changes: 20 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ Replicate any database to PostgreSQL with zero downtime. Supports PostgreSQL, SQ
SerenAI provides managed PostgreSQL databases optimized for AI workloads. When replicating to SerenDB targets, this tool can run your replication jobs on SerenAI's cloud infrastructure - no local resources required.

**Benefits of SerenAI Cloud Execution:**

- No local compute resources needed
- Automatic retry and error handling
- Job monitoring and logging
Expand All @@ -32,8 +33,7 @@ With just your API key set, the tool will interactively guide you through select
export SEREN_API_KEY="your-api-key" # Get from console.serendb.com

database-replicator init \
--source "postgresql://user:pass@source:5432/db" \
--local
--source "postgresql://user:pass@source:5432/db"
```

The tool will:
Expand All @@ -54,7 +54,7 @@ database-replicator init \
--target "postgresql://user:pass@your-db.serendb.com:5432/db"
```

For local execution (non-SerenDB targets), use the `--local` flag. See [Remote Execution](#remote-execution-serendb-only) for details.
For local execution (non-SerenDB targets), use the `--local` flag. See [Remote Execution](#remote-execution-aws) for details.

---

Expand Down Expand Up @@ -205,14 +205,21 @@ Download the latest release for your platform from [GitHub Releases](https://git
- **Linux (x64)**: `database-replicator-linux-x64-binary`
- **macOS (Intel)**: `database-replicator-macos-x64-binary`
- **macOS (Apple Silicon)**: `database-replicator-macos-arm64-binary`
- **Windows (x64)**: `database-replicator-windows-x64.exe`

Make the binary executable:
Make the binary executable (Linux/macOS):

```bash
chmod +x database-replicator-*-binary
./database-replicator-*-binary --help
```

On Windows, run directly:

```cmd
database-replicator-windows-x64.exe --help
```

### Install from crates.io

```bash
Expand All @@ -233,18 +240,22 @@ The binary will be available at `target/release/database-replicator`.

### Docker Image

Build a container image with the latest source:
Build an image from the latest GitHub release (default) or a specific tag:

```bash
# latest release asset
docker build -t serenorg/database-replicator:latest .

# specific version
docker build --build-arg VERSION=v5.3.20 -t serenorg/database-replicator:v5.3.20 .
```

Run the CLI inside the container (pass connection strings via arguments or environment variables):

```bash
docker run --rm -it \
serenorg/database-replicator:latest \
validate --source "postgresql://user:pass@source/db" --target "postgresql://user:pass@target/db"
docker run --rm -it serenorg/database-replicator:latest \
validate --source "postgresql://user:pass@source/db" \
--target "postgresql://user:pass@target/db"
```

Mount local config files if needed:
Expand All @@ -253,7 +264,7 @@ Mount local config files if needed:
docker run --rm -it \
-v "$PWD:/work" \
serenorg/database-replicator:latest \
init --source @/work/source.txt --target @/work/target.txt
init --source "$(cat /work/source.txt)" --target "$(cat /work/target.txt)"
```

### Prerequisites
Expand Down
11 changes: 8 additions & 3 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -268,18 +268,23 @@ async fn main() -> anyhow::Result<()> {
let mut state = database_replicator::state::load()?;
let mut target = target.or(state.target_url);

// If no target and not forcing local execution, trigger interactive project selection
// This is the default behavior - remote execution with SerenDB target picker
if target.is_none() && !local {
target = Some(database_replicator::interactive::select_seren_database().await?);
}

// If --seren flag explicitly set, validate target is SerenDB
if seren {
if let Some(t) = &target {
if !database_replicator::utils::is_serendb_target(t) {
anyhow::bail!("--seren flag is only compatible with SerenDB targets.");
}
} else {
target = Some(database_replicator::interactive::select_seren_database().await?);
}
}

let target = target.ok_or_else(|| {
anyhow::anyhow!("Target database URL not provided and not set in state. Use `--target` or `database-replicator target set`.")
anyhow::anyhow!("Target database URL not provided. Use `--target` to specify a target database, or remove `--local` to use interactive SerenDB project selection.")
})?;

// Check if CLI filter flags were provided (skip interactive if so)
Expand Down
Loading