Feat/incremental sync #1
@@ -1,61 +1,75 @@
|
|||||||
# Baïkal Calendar Sync
|
# Baïkal Calendar Sync
|
||||||
|
|
||||||
A Dockerized Python service that periodically synchronizes an external Outlook ICS calendar to a local Baïkal CalDAV server.
|
An incremental CalDAV sync service that keeps your Baïkal calendar in sync with an Outlook ICS feed — with zero downtime and near-instant sync times.
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
- **Automatic Sync**: Runs periodically (default: every 5 minutes).
|
|
||||||
- **Environment Configurable**: All credentials and URLs are set via environment variables.
|
- **Incremental Delta Sync**: Only adds, updates, or deletes events that actually changed
|
||||||
- **Docker Ready**: Includes `Dockerfile` and `docker-compose.yml` for easy deployment.
|
- **Zero Downtime**: Adds/updates events before deleting removed ones — calendar never goes empty
|
||||||
|
- **Smart Change Detection**: ETag check first, SHA-256 fallback. Skips sync when nothing changed
|
||||||
|
- **Stable Event Hashing**: Ignores volatile fields (DTSTAMP, LAST-MODIFIED) to avoid false updates
|
||||||
|
- **Automatic Backoff**: Exponential retry on failures (1m, 2m, 4m... max 30m)
|
||||||
|
- **Health Endpoint**: Built-in `/health` and `/metrics` (Prometheus-compatible) on port 8081
|
||||||
|
- **Graceful Shutdown**: SIGTERM/SIGINT handlers finish current sync before exiting
|
||||||
|
- **Docker Ready**: Includes `Dockerfile`, `docker-compose.yml`, and HEALTHCHECK
|
||||||
|
|
||||||
## Prerequisites
|
## Prerequisites
|
||||||
- Docker & Docker Compose installed.
|
|
||||||
- An existing Baïkal instance.
|
- Docker & Docker Compose installed
|
||||||
- An Outlook ICS link.
|
- An existing Baïkal instance
|
||||||
|
- An Outlook ICS link
|
||||||
|
|
||||||
## Configuration (Environment Variables)
|
## Configuration (Environment Variables)
|
||||||
|
|
||||||
| Variable | Description | Default |
|
| Variable | Description | Default |
|
||||||
| :--- | :--- | :--- |
|
| :--- | :--- | :--- |
|
||||||
| `ICS_URL` | The public ICS URL of your Outlook calendar. | **Required** |
|
| `ICS_URL` | The public ICS URL of your Outlook calendar. | **Required** |
|
||||||
| `BAIKAL_URL` | The URL to your Baïkal calendar (e.g., `http://baikal/dav.php/calendars/user/id/`). | **Required** |
|
| `BAIKAL_URL` | The URL to your Baïkal calendar. | **Required** |
|
||||||
| `BAIKAL_USER` | Your Baïkal username. | **Required** |
|
| `BAIKAL_USER` | Your Baïkal username. | **Required** |
|
||||||
| `BAIKAL_PASS` | Your Baïkal password. | **Required** |
|
| `BAIKAL_PASS` | Your Baïkal password. | **Required** |
|
||||||
| `SYNC_FREQUENCY` | How often to sync **in minutes**. | `5` |
|
| `SYNC_FREQUENCY` | How often to sync **in minutes**. | `5` |
|
||||||
|
| `CALENDAR_ID` | Optional calendar ID to match against. | — |
|
||||||
|
|
||||||
## Quick Start with Docker Compose
|
## Quick Start
|
||||||
|
|
||||||
1. **Clone or download** this repository.
|
1. **Clone or download** this repository.
|
||||||
2. **Create a `.env` file** (optional but recommended) or export variables:
|
2. **Create a `.env` file** (optional but recommended):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
ICS_URL="https://outlook.office365.com/..."
|
ICS_URL="https://outlook.office365.com/owa/calendar/your-calendar.ics"
|
||||||
BAIKAL_URL="http://localhost:8080/dav.php/calendars/Lago/default/"
|
BAIKAL_URL="https://your-baikal.com/dav.php/calendars/user/calendar-id/"
|
||||||
BAIKAL_USER="Lago"
|
BAIKAL_USER="your-username"
|
||||||
BAIKAL_PASS="secret"
|
BAIKAL_PASS="your-password"
|
||||||
SYNC_FREQUENCY=5
|
SYNC_FREQUENCY=5
|
||||||
```
|
```
|
||||||
|
|
||||||
3. **Run with Docker Compose**:
|
3. **Run with Docker Compose**:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker compose up -d
|
docker compose up -d
|
||||||
```
|
```
|
||||||
*Note: This will verify the image usage. If you need to rebuild locally, run `docker compose up -d --build`.*
|
|
||||||
|
|
||||||
4. **Check Logs**:
|
4. **Check Logs**:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker compose logs -f baikal-sync
|
docker compose logs -f baikal-sync
|
||||||
```
|
```
|
||||||
|
|
||||||
## Building & Publishing the Image
|
5. **Check Health**:
|
||||||
|
|
||||||
1. **Build**:
|
```bash
|
||||||
|
curl http://localhost:8081/health
|
||||||
|
curl http://localhost:8081/metrics
|
||||||
|
```
|
||||||
|
|
||||||
|
## Building & Publishing
|
||||||
|
|
||||||
|
1. **Build**:
|
||||||
```bash
|
```bash
|
||||||
docker build -t lagortinez/baikal-sync:latest .
|
docker build -t lagortinez/baikal-sync:latest .
|
||||||
```
|
```
|
||||||
|
|
||||||
2. **Push** (requires `docker login`):
|
2. **Push**:
|
||||||
```bash
|
```bash
|
||||||
docker push lagortinez/baikal-sync:latest
|
docker push lagortinez/baikal-sync:latest
|
||||||
```
|
```
|
||||||
|
|||||||
Reference in New Issue
Block a user