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
28 changes: 14 additions & 14 deletions Data/Data.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,23 @@
<UserSecretsId>e9f8dafb-10db-45a2-b53a-f8cdf43eab5e</UserSecretsId>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="10.0.8" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="10.0.8">
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="10.0.10" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="10.0.10">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="10.0.8" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="10.0.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="10.0.10" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="10.0.3" />
<PackageReference Include="EFCore.NamingConventions" Version="10.0.1" />
<PackageReference Include="NodaTime.Serialization.SystemTextJson" Version="1.3.1" />
<PackageReference Include="NodaTime" Version="3.3.2" />
<PackageReference Include="Npgsql" Version="10.0.2" />
<PackageReference Include="Npgsql.NodaTime" Version="10.0.2" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL.NodaTime" Version="10.0.1" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="10.0.8" />
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="10.0.8" />
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="10.0.8" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="10.0.8" />
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="10.0.8" />
<PackageReference Include="NodaTime.Serialization.SystemTextJson" Version="1.4.0" />
<PackageReference Include="NodaTime" Version="3.3.3" />
<PackageReference Include="Npgsql" Version="10.0.3" />
<PackageReference Include="Npgsql.NodaTime" Version="10.0.3" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL.NodaTime" Version="10.0.3" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="10.0.10" />
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="10.0.10" />
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="10.0.10" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="10.0.10" />
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="10.0.10" />
</ItemGroup>
</Project>
4 changes: 2 additions & 2 deletions Data/erm.sql
Original file line number Diff line number Diff line change
Expand Up @@ -567,7 +567,7 @@ DO $EF$
BEGIN
IF NOT EXISTS(SELECT 1 FROM "__EFMigrationsHistory" WHERE "migration_id" = '20250425070016_CreateInitial') THEN
INSERT INTO "__EFMigrationsHistory" (migration_id, product_version)
VALUES ('20250425070016_CreateInitial', '10.0.8');
VALUES ('20250425070016_CreateInitial', '10.0.10');
END IF;
END $EF$;
COMMIT;
Expand Down Expand Up @@ -661,7 +661,7 @@ DO $EF$
BEGIN
IF NOT EXISTS(SELECT 1 FROM "__EFMigrationsHistory" WHERE "migration_id" = '20260622060127_BlobItem') THEN
INSERT INTO "__EFMigrationsHistory" (migration_id, product_version)
VALUES ('20260622060127_BlobItem', '10.0.8');
VALUES ('20260622060127_BlobItem', '10.0.10');
END IF;
END $EF$;
COMMIT;
Expand Down
33 changes: 33 additions & 0 deletions Doc/INSTALL.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
# Install Calendare Server <!-- omit in toc -->

- [Infrastructure requirements](#infrastructure-requirements)
- [Database](#database)
- [File storage](#file-storage)
- [S3 Storage Provider](#s3-storage-provider)
- [Local storage](#local-storage)
- [DNS](#dns)
- [Domain and subdomain](#domain-and-subdomain)
- [Base Path Configuration](#base-path-configuration)
Expand All @@ -18,8 +22,34 @@

The Calendare Server requires specific infrastructure to operate.

## Database

It uses a **PostgreSQL database** for data persistence and relies on an **OIDC provider** for user authentication. These components must be managed independently and are not covered in the following server installation guide.

The database contains user data and administrative data. The only exception relates to the WebDAV feature (file storage). The file contents are stored externally.

## File storage

File storage is only needed if the WebDAV feature is enabled (**not** for calendar or contact information). The default installation doesn't enable WebDAV.

### S3 Storage Provider

The **preferred** option is to use an external S3 provider (`provider: S3`). A dedicated bucket needs to be configured.

> [!WARNING]
> The Calendare Server requires a dedicated bucket. It will regulary **delete** all content which is not managed by the server.

### Local storage

The local storage (`provider: Filesystem`) requires a base path to the local file system. Using Kubernetes this means that you need to define `PersistentVolumes` and `VolumeMounts`.

While local storage is supported, it is primarily intended for development and testing. For production deployments, using an **S3-compatible provider** is highly recommended.

> [!NOTE]
> Furthermore, if you run a multi-instance (highly available) setup, you must ensure your storage backend is distributed (supporting `ReadWriteMany` access).
>
> In contrast, the **S3 provider option** is much easier to configure, scales seamlessly across multiple instances out-of-the-box, and eliminates the need to manage complex storage volumes in your cluster.

## DNS

### Domain and subdomain
Expand Down Expand Up @@ -99,6 +129,7 @@ Similarly, ensure that your environment does not filter or block the specific MI
#### Request Body Size Limits

Ensure that your ingress controller, proxy, or web server is configured to allow larger HTTP request bodies. Providing a universal "one-size-fits-all" limit is difficult, as CalDAV and CardDAV payloads can be quite large.
The server has for CalDAV and CardDAV requests an internal limit of 30'000'000 bytes (~ 28.6 MB). Currently this limit is fixed and not configurable.

Individual calendar events with long descriptions or attachments or contact cards containing high-resolution profile photos (vCards) can significantly increase the request size. We recommend starting with a limit of at least 10MB to 20MB and adjusting based on your specific use case.

Expand All @@ -110,6 +141,8 @@ ingress:
nginx.ingress.kubernetes.io/proxy-body-size: "10m"
```

If you enable WebDAV take care to revisit the body size limit. The server removes for WebDAV requests any internal body size limit.

## Others / Manual

The Calendar Server is built with **.NET 10** and is compatible with various platforms. Although native installation is possible, the only officially supported environment is the provided **Alpine-based OCI container**.
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ The **Calendare Server** is built on open standards to ensure seamless compatibi
- **Availability Management**: Includes "Free/Busy" support, helping you manage your schedule and share your availability with others.
- **Efficient Synchronization**: High-performance syncing that only downloads changes since your last update, saving battery life and data.
- **Real-Time Push Notifications**: Support for modern Web Push standards (including encrypted notifications and VAPID keys), so your devices stay updated instantly without constant polling.

- **Basic WebDAV Storage:** Lightweight file hosting support, allowing you to store personal files backed by either local storage or an external S3-compatible provider (preferred).
-
For the full list of supported RFC's and other specification see the [implemented scope](./Doc/SCOPE.md).

## Designed for Collaboration & Scalability
Expand Down
2 changes: 1 addition & 1 deletion Server.Tests/Server.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.7.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.8.1" />
<PackageReference Include="xunit.v3" Version="3.2.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="3.1.5">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
Expand Down
24 changes: 24 additions & 0 deletions deploy/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,18 @@ Or include the VAPID keys directly in `values.yaml` with:

These defaults are only used if no value is supplied by the user during account creation. The user can change these values later.

## Calendare User Constraints

| Key | Type | Default | Description |
| ------------------------------------- | ------ | --------------- | ---------------------------------------- |
| calendare.userConstraints | object | `{}` | ... |
| calendare.userConstraints.ApplicationKeySecret | string | undefined | A secret (e.g. 'd9HbXPCSU...Aq5nRk` |

A missing `ApplicationKeySecret` doesn't allow the use of the recommended client application secrets.

Changing the secret invalidates all application keys the users have created.


## Calendar Clients Feature Configuration

| Key | Type | Default | Description |
Expand Down Expand Up @@ -153,6 +165,18 @@ Disabled features have a higher priority than enabled features.

If a client is not configured in `calendare.features` the in-built settings are applied, which are taken from the `appsettings.json` file of the server.

## WebDAV file storage

| Key | Type | Default | Description |
| ----------------------------------- | ------ | ---------------------- | ------------------------------ |
| webdav.enabled | bool | false | Enable/Disable WebDAV storage |
| webdav.provider | string | `None' | Define S3 or Filestorage |

The `webdav.s3` supports `Bucket`, `Host`, `AccessKey`, `SecretKey`, `Region` and `PathStyle` (true|false).

The `webdav.filestorage` supports `PathBase`.


## Testing and Debugging Configuration

| Key | Type | Default | Description |
Expand Down
24 changes: 24 additions & 0 deletions deploy/README.md.gotmpl
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,18 @@ Or include the VAPID keys directly in `values.yaml` with:

These defaults are only used if no value is supplied by the user during account creation. The user can change these values later.

## Calendare User Constraints

| Key | Type | Default | Description |
| ------------------------------------- | ------ | --------------- | ---------------------------------------- |
| calendare.userConstraints | object | `{}` | ... |
| calendare.userConstraints.ApplicationKeySecret | string | undefined | A secret (e.g. 'd9HbXPCSU...Aq5nRk` |

A missing `ApplicationKeySecret` doesn't allow the use of the recommended client application secrets.

Changing the secret invalidates all application keys the users have created.


## Calendar Clients Feature Configuration

| Key | Type | Default | Description |
Expand Down Expand Up @@ -153,6 +165,18 @@ Disabled features have a higher priority than enabled features.

If a client is not configured in `calendare.features` the in-built settings are applied, which are taken from the `appsettings.json` file of the server.

## WebDAV file storage

| Key | Type | Default | Description |
| ----------------------------------- | ------ | ---------------------- | ------------------------------ |
| webdav.enabled | bool | false | Enable/Disable WebDAV storage |
| webdav.provider | string | `None' | Define S3 or Filestorage |

The `webdav.s3` supports `Bucket`, `Host`, `AccessKey`, `SecretKey`, `Region` and `PathStyle` (true|false).

The `webdav.filestorage` supports `PathBase`.


## Testing and Debugging Configuration

| Key | Type | Default | Description |
Expand Down
2 changes: 1 addition & 1 deletion openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"name": "MIT",
"url": "https://mit-license.org/"
},
"version": "0.0.1"
"version": "0.8.0"
},
"paths": {
"/api/version": {
Expand Down