Compare commits
164 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 617236558e | |||
| f29b570b82 | |||
| 3b7a853c71 | |||
| 42c4c1f38f | |||
| 1c37a2b930 | |||
| 632dea4517 | |||
| 8f3a34a277 | |||
| fc9abad56b | |||
| 6cf536bc67 | |||
| 55808e9afa | |||
| fe7bc72131 | |||
| 953ee82a97 | |||
| c9e554c9a8 | |||
| 0652dde795 | |||
| 5549f03f6e | |||
| 98b26537a1 | |||
| a2810a720f | |||
| 66c3625633 | |||
| 18d14d09df | |||
| f62914d566 | |||
| 1bf9fc6a9c | |||
| 2b13ee7163 | |||
| f28b82db3f | |||
| 9d4849ee38 | |||
| 3e23a8b9d6 | |||
| 626a5b5031 | |||
| f0c225961a | |||
| 212da52a7a | |||
| 50cc98abb2 | |||
| 82ab3c25e9 | |||
| f20a55768b | |||
| aaee86823e | |||
| 6d3aaf7277 | |||
| 98c8185655 | |||
| 00d7269e00 | |||
| 801ae12029 | |||
| 2ccc6bd65c | |||
| 5d2e5919b1 | |||
| 1d16c17c35 | |||
| 760a4ba44a | |||
| 5d62c2de4f | |||
| 65717243a5 | |||
| 8f94e35bf5 | |||
| 3785b3b4d1 | |||
| 7b1c28a8c9 | |||
| 762d594e80 | |||
| 0f80f13d50 | |||
| e60248cf80 | |||
| bc5013f160 | |||
| c688f894d8 | |||
| 1df089cd21 | |||
| c4c674b4d0 | |||
| 1e2cc6c64a | |||
| 94dac7a7b3 | |||
| 4af60e1c64 | |||
| 9f89dd330f | |||
| 89fd59f6a3 | |||
| 435a0568b4 | |||
| b849e1d41a | |||
| 7986a0a58b | |||
| 5abfa15d93 | |||
| af89daf278 | |||
| f2116a5dbf | |||
| fbfcb82f2c | |||
| c5f631043b | |||
| f267b44f63 | |||
| ec0950463b | |||
| 321556f611 | |||
| 58a6d329be | |||
| 8fe05f6c47 | |||
| 20fe2bc96f | |||
| 415be71ecf | |||
| 593048373f | |||
| 2ffd41cbad | |||
| 2d79243bb7 | |||
| cdd6860521 | |||
| 263498c66d | |||
| 049ed4aa49 | |||
| e50a34747e | |||
| 6596c652de | |||
| a94cd3de7f | |||
| 14842b8f4f | |||
| 70f0d8e419 | |||
| 6c2646d093 | |||
| 9aa4b171c2 | |||
| cad15b753c | |||
| bbeb030fb1 | |||
| 7453fe8e30 | |||
| 2d7fe935b5 | |||
| db4950a316 | |||
| 25371bcf8c | |||
| 589b93fda9 | |||
| 24051834f9 | |||
| a1eacc6800 | |||
| 53430140ca | |||
| 5ec5895638 | |||
| 91a066a900 | |||
| 6e4346f2c1 | |||
| edf2e457ea | |||
| 142b9927c0 | |||
| 9230cb7e8a | |||
| 7a03dcdbdd | |||
| 517ef4c0c6 | |||
| 1150801603 | |||
| 14778231b1 | |||
| a3c5d7b411 | |||
| 71bf88f49a | |||
| 0be5e84dc7 | |||
| 924ce9ced3 | |||
| ee51507d2a | |||
| 5307db4fa7 | |||
| baca33c565 | |||
| bf1ef9a8be | |||
| 4cb24ede92 | |||
| 70ace7fc9a | |||
| da8afdd97a | |||
| 121d10d6ce | |||
| a3a81a4439 | |||
| 6313f6528e | |||
| cb85f771ac | |||
| 6716db77fe | |||
| 7e8e6796bb | |||
| e3740e4c9e | |||
| 736b1c5d75 | |||
| 42c045aad3 | |||
| 38ff54a341 | |||
| 035828dd1f | |||
| 1907354bf8 | |||
| 29cda3bc2d | |||
| e300261f4f | |||
| 62a0edfca3 | |||
| 1648886ba2 | |||
| 64459a39e4 | |||
| d777a26ab7 | |||
| 4ad63bb672 | |||
| 79e6b88e5f | |||
| 8f54d8aeb2 | |||
| 3cebe5d5df | |||
| b902505524 | |||
| bccf900ccb | |||
| f784e5fd86 | |||
| ebbf090373 | |||
| 0925d79852 | |||
| c40522d218 | |||
| d1b8fe0559 | |||
| 399e7e3b6b | |||
| e9dfaecd72 | |||
| e6a75435a4 | |||
| ea12f23cfb | |||
| 5337d19d1b | |||
| ed70c9010f | |||
| 3458f63aa2 | |||
| d2a19463b2 | |||
| df6aa7cdc4 | |||
| 29acbdb9c8 | |||
| b492849666 | |||
| 58dbd39bb7 | |||
| 37c3f602b6 | |||
| 87ce90b9e7 | |||
| e535432e94 | |||
| 435e3af06a | |||
| ac2da2db19 | |||
| 1d01c51099 | |||
| a8858657dc |
+28
-104
@@ -1,110 +1,34 @@
|
||||
# Ente Cloudron App Build and Installation Instructions
|
||||
# Ente Cloudron – Quick Guide
|
||||
|
||||
This document provides detailed instructions for building and installing the Ente Cloudron app, an open-source, end-to-end encrypted photo storage and authentication solution.
|
||||
## Build
|
||||
```bash
|
||||
git clone https://github.com/andreasdueren/ente-cloudron.git
|
||||
cd ente-cloudron
|
||||
|
||||
## Prerequisites
|
||||
cloudron build \
|
||||
--set-build-service builder.docker.due.ren \
|
||||
--build-service-token e3265de06b1d0e7bb38400539012a8433a74c2c96a17955e \
|
||||
--set-repository andreasdueren/ente-cloudron \
|
||||
--tag 0.5.3
|
||||
```
|
||||
|
||||
- **Cloudron CLI**: Ensure the Cloudron CLI is installed and configured on your system. Refer to [Cloudron CLI Documentation](https://docs.cloudron.io/packaging/cli/) for setup instructions.
|
||||
- **Docker**: Required for local testing or custom builds if needed.
|
||||
- **Git**: To clone or manage the repository.
|
||||
- **Repository Access**: Ensure you have access to the Ente Cloudron repository at `andreasdueren/ente-cloudron`.
|
||||
- **Build Service Token**: A token for the Cloudron build service is required (provided in the command below).
|
||||
## Install
|
||||
```bash
|
||||
cloudron install \
|
||||
--location ente.due.ren \
|
||||
--image andreasdueren/ente-cloudron:0.5.3
|
||||
```
|
||||
|
||||
## Build Commands
|
||||
## After Install
|
||||
1. **S3** – In Cloudron File Manager open `/app/data/config/s3.env`, fill in your endpoint/region/bucket/access/secret, then restart the app from the dashboard. Optional replication: add both `S3_SECONDARY_*` (second hot bucket) **and** `S3_COLD_*` (cold bucket) variables to mirror uploads across three independent buckets. Replication is only enabled when all three buckets are present. See Ente’s [object storage guide](https://ente.io/help/self-hosting/administration/object-storage) for example configs.
|
||||
2. **Secondary hostnames** – During installation Cloudron now prompts for hostnames for the Accounts/Auth/Cast/Albums/Family web apps (powered by `httpPorts`). Ensure matching DNS records exist that point to the primary app domain. If you use Cloudron-managed DNS, those records are created automatically; otherwise create CNAME/A records such as `accounts.<app-domain> → <app-domain>`.
|
||||
|
||||
1. **Clone the Repository** (if not already done):
|
||||
```bash
|
||||
git clone https://github.com/andreasdueren/ente-cloudron.git
|
||||
cd ente-cloudron
|
||||
```
|
||||
Once DNS propagates, use the dedicated hosts (defaults shown below — substitute the names you selected during install):
|
||||
- `https://<app-host>` (the hostname you chose during install, main UI & uploads)
|
||||
- `https://accounts.<app-domain>`
|
||||
- `https://auth.<app-domain>`
|
||||
- `https://cast.<app-domain>`
|
||||
- `https://albums.<app-domain>`
|
||||
- `https://family.<app-domain>`
|
||||
|
||||
2. **Build the App Using Cloudron Build Service**:
|
||||
Use the provided build service and token to build the app. Replace `<version>` with the desired version tag (e.g., `0.1.0` or as per `CloudronManifest.json`).
|
||||
```bash
|
||||
cloudron build --set-build-service builder.docker.due.ren --build-service-token e3265de06b1d0e7bb38400539012a8433a74c2c96a17955e --set-repository andreasdueren/ente-cloudron --tag 1.0.1
|
||||
```
|
||||
**Note**: The build process should complete within a reasonable time. Monitor the output for any errors.
|
||||
|
||||
## Installation Commands
|
||||
|
||||
1. **Install the App on Cloudron**:
|
||||
After a successful build, install the app on your Cloudron instance at the desired location (e.g., `ente.due.ren`).
|
||||
```bash
|
||||
cloudron install --location ente.due.ren --image andreasdueren/ente-cloudron:1.0.1
|
||||
```
|
||||
**Important**: Do not wait more than 30 seconds for feedback after running the install command. If there's an error, the process may hang, and you should terminate it to troubleshoot.
|
||||
**Note**: Always uninstall and reinstall during development rather than updating an existing app to ensure a clean setup.
|
||||
|
||||
## Testing Procedures
|
||||
|
||||
1. **Verify Installation**:
|
||||
- Access the app at `https://ente.due.ren` (or your configured domain).
|
||||
- Ensure the Ente web interfaces (Photos, Accounts, Auth, Cast) load correctly.
|
||||
|
||||
2. **Check S3 Configuration**:
|
||||
- Confirm that S3 environment variables are set in Cloudron app settings under the 'Environment Variables' section.
|
||||
- Variables to check: `APP_S3_ENABLED`, `APP_S3_ENDPOINT`, `APP_S3_ACCESS_KEY_ID`, `APP_S3_SECRET_ACCESS_KEY`, `APP_S3_BUCKET`.
|
||||
|
||||
3. **Monitor Logs for Errors**:
|
||||
- Use the Cloudron CLI to view logs:
|
||||
```bash
|
||||
cloudron logs --app ente.due.ren -f
|
||||
```
|
||||
- Alternatively, shell into the app for detailed log inspection:
|
||||
```bash
|
||||
cloudron exec --app ente.due.ren
|
||||
tail -f /app/data/logs/*
|
||||
```
|
||||
- Look for S3 connection errors or other issues.
|
||||
|
||||
## Deployment Steps
|
||||
|
||||
1. **Post-Installation Configuration**:
|
||||
- If S3 is not working, update the environment variables in Cloudron app settings and restart the app:
|
||||
```bash
|
||||
cloudron restart --app ente.due.ren
|
||||
```
|
||||
|
||||
2. **User Authentication**:
|
||||
- Ente uses its own authentication system. Ensure user registration and login work as expected.
|
||||
- If OIDC integration is desired in the future, it can be configured using Cloudron's OIDC variables (`CLOUDRON_OIDC_IDENTIFIER`, `CLOUDRON_OIDC_CLIENT_ID`, `CLOUDRON_OIDC_CLIENT_SECRET`).
|
||||
|
||||
## Troubleshooting Common Issues
|
||||
|
||||
- **S3 Configuration Errors**:
|
||||
- **Symptom**: App falls back to local storage or logs show S3 connection failures.
|
||||
- **Solution**: Verify S3 environment variables in Cloudron settings. Test connectivity manually using AWS CLI (`aws s3 ls s3://<bucket> --endpoint-url <endpoint>`).
|
||||
|
||||
- **Build Failures**:
|
||||
- **Symptom**: Build command errors out or hangs.
|
||||
- **Solution**: Check network connectivity to the build service, ensure the token is correct, and review build logs for specific errors.
|
||||
|
||||
- **Installation Hangs**:
|
||||
- **Symptom**: Install command does not complete within 30 seconds.
|
||||
- **Solution**: Terminate the command and check Cloudron logs for errors (`cloudron logs --app ente.due.ren`). Reinstall if necessary.
|
||||
|
||||
- **App Not Starting**:
|
||||
- **Symptom**: App shows as 'Stopped' or inaccessible after install.
|
||||
- **Solution**: Check logs for startup errors (`cloudron logs --app ente.due.ren`). Ensure database connectivity and correct configuration.
|
||||
|
||||
## Configuration Examples
|
||||
|
||||
- **S3 Environment Variables** in Cloudron settings:
|
||||
```
|
||||
APP_S3_ENABLED=true
|
||||
APP_S3_ENDPOINT=s3.amazonaws.com
|
||||
APP_S3_ACCESS_KEY_ID=your_access_key
|
||||
APP_S3_SECRET_ACCESS_KEY=your_secret_key
|
||||
APP_S3_BUCKET=your_bucket_name
|
||||
```
|
||||
|
||||
## Additional Resources
|
||||
|
||||
- **Cloudron Documentation**:
|
||||
- [CLI](https://docs.cloudron.io/packaging/cli/)
|
||||
- [Packaging Tutorial](https://docs.cloudron.io/packaging/tutorial/)
|
||||
- [Manifest Reference](https://docs.cloudron.io/packaging/manifest/)
|
||||
- [Addons Guide](https://docs.cloudron.io/packaging/addons/)
|
||||
- [Cheat Sheet](https://docs.cloudron.io/packaging/cheat-sheet/)
|
||||
|
||||
For further assistance, contact the Ente team at `contact@ente.io` or refer to the GitHub repository at [https://github.com/ente-io/ente](https://github.com/ente-io/ente).
|
||||
Check `cloudron logs --app ente.due.ren -f` or `/app/data/logs/startup.log` if anything looks off.
|
||||
|
||||
+106
@@ -1,5 +1,111 @@
|
||||
# Changelog
|
||||
|
||||
## 0.5.10 (2025-11-20)
|
||||
|
||||
* Bundle the Ente Families web app so `family.<domain>` serves the correct invite/management UI instead of the placeholder photos build.
|
||||
* Ship built-in billing plan JSON so Museum can resolve subscriptions (`family/add-member`, invite acceptance) on self-hosted installs without manual DB edits.
|
||||
|
||||
## 0.5.7 (2025-11-18)
|
||||
|
||||
* Inject the API origin into all served HTML so the Next.js bundles (including `accounts/passkeys`) read the self-hosted endpoint instead of defaulting to `https://api.ente.io`
|
||||
* Document the working Backblaze B2 CORS JSON that whitelists the wildcard origin + upload operations for desktop casts
|
||||
|
||||
## 0.5.6 (2025-11-18)
|
||||
|
||||
* Allow the accounts frontend origin in Museum’s `webauthn.rporigins` when subdomain routing is enabled so passkey enrollment via the desktop flow succeeds
|
||||
* Document the Ente desktop scheme (`ente://app`) in the recommended S3 CORS rules to keep signed URL fetches working for the desktop client
|
||||
|
||||
## 0.5.5 (2025-11-18)
|
||||
|
||||
* Validate S3 data-center identifiers so replication only uses the canonical `b2-eu-cen`/`wasabi-eu-central-2-v3`/`scw-eu-fr-v3` keys and update the docs to reflect the upstream requirements
|
||||
|
||||
## 0.5.4 (2025-11-18)
|
||||
|
||||
* Respect user-defined S3 data-center identifiers so replication targets use the intended buckets
|
||||
|
||||
## 0.5.1 (2025-11-05)
|
||||
|
||||
* Fix `httpPorts` host detection so accounts/cast/family/albums subdomains serve their static frontends again
|
||||
|
||||
## 0.5.2 (2025-11-05)
|
||||
|
||||
* Allow httpPort hostnames like `cast.ente`/`accounts.ente` so Cloudron can append the primary domain (`.due.ren`) automatically
|
||||
|
||||
## 0.5.3 (2025-11-05)
|
||||
|
||||
* Fix regression that could produce duplicated suffixes (e.g. `cast.due.due.ren`) when httpPort hostnames already included the full domain
|
||||
|
||||
## 0.5.0 (2025-11-04)
|
||||
|
||||
* Proxy Museum GET/HEAD routes (e.g. `/collections`, `/files`, `/remote-store`) so clients that talk to the primary host without `/api` still hit the backend
|
||||
|
||||
## 0.4.13 (2025-11-04)
|
||||
|
||||
* Forward all non-GET requests to the Museum backend so uploads and other write operations reach the API
|
||||
|
||||
## 0.4.12 (2025-11-04)
|
||||
|
||||
* Ensure dedicated hosts serve static `.html` exports and SPA fallbacks (`/gallery`, etc.) without 404s
|
||||
|
||||
## 0.4.11 (2025-11-04)
|
||||
|
||||
* Serve static `.html` exports for all dedicated hosts so routes like `/gallery` refresh and upload flows work again
|
||||
|
||||
## 0.4.10 (2025-11-04)
|
||||
|
||||
* Fix SPA fallbacks on dedicated hosts so `/gallery` and other client routes refresh correctly
|
||||
|
||||
## 0.4.9 (2025-11-04)
|
||||
|
||||
* Raise default memory allocation to 3 GiB for smoother media processing workloads
|
||||
|
||||
## 0.4.8 (2025-11-04)
|
||||
|
||||
* Allow persistent Museum overrides via `/app/data/config/museum.override.yaml` while keeping generated defaults intact
|
||||
|
||||
## 0.4.7 (2025-11-04)
|
||||
|
||||
* Proxy `/users` API endpoints through Caddy so mobile SRP/OTT flows reach the backend
|
||||
|
||||
## 0.4.6 (2025-11-04)
|
||||
|
||||
* Switch to Cloudron `httpPorts` so secondary web apps get provisioned domains automatically
|
||||
* Teach the startup script to honour Cloudron-provided secondary domain variables (no manual aliasing required)
|
||||
* Refresh post-install docs and build instructions to reflect the new installation flow
|
||||
|
||||
## 0.4.5 (2025-10-30)
|
||||
|
||||
* Serve photos UI on the primary hostname and mount other apps on `accounts/auth/cast/albums/family.<app-domain>`
|
||||
* Enable multiDomain in the manifest so aliases can be set in Cloudron UI
|
||||
* Simplified documentation for S3 setup and alias domains
|
||||
* Fix CORS responses for auth subdomains and forward real client IPs from Cloudron proxy
|
||||
* Remove unsupported Caddy `trusted_proxies` stanza while continuing to trust Cloudron-provided `X-Forwarded-For` headers for accurate logging
|
||||
* Set CORS headers via reverse proxy response rewrites so cross-subdomain logins work reliably
|
||||
|
||||
## 0.4.4 (2025-10-30)
|
||||
|
||||
* Restore Cloudflare R2 path-style URLs and simplify to a single hot-storage data center
|
||||
* Serve the frontend apps on dedicated subdomains (photos/accounts/auth/cast/albums/family)
|
||||
* Startup script now regenerates Caddy and Museum configs for the new host layout
|
||||
* Added post-install checklist entries and updated docs for required DNS records
|
||||
|
||||
## 0.4.3 (2025-10-29)
|
||||
|
||||
* Always regenerate Museum configuration on startup to pick up S3 credential changes
|
||||
* Enables seamless workflow: add S3 credentials to /app/data/config/s3.env and restart
|
||||
* Fixes issue where S3 configuration changes required manual intervention
|
||||
|
||||
## 0.4.2 (2025-10-29)
|
||||
|
||||
* Use SMTPS (port 2465) with TLS encryption for email delivery
|
||||
* Fixes email sending with requiresValidCertificate flag on Cloudron 9
|
||||
|
||||
## 0.4.1 (2025-10-23)
|
||||
|
||||
* Fix email sending for user registration by enabling TLS certificate validation in sendmail addon
|
||||
* Add requiresValidCertificate flag to sendmail configuration to ensure proper SMTP authentication with Go applications
|
||||
* Note: Requires Cloudron 9 or later for requiresValidCertificate support
|
||||
|
||||
## 1.0.0 (2024-06-01)
|
||||
|
||||
* Initial release of Ente for Cloudron
|
||||
|
||||
+53
-16
@@ -1,38 +1,75 @@
|
||||
{
|
||||
"id": "io.ente.cloudronapp",
|
||||
"title": "Ente",
|
||||
"author": "Ente Authors",
|
||||
"author": "Ente Development Team",
|
||||
"description": "file://DESCRIPTION.md",
|
||||
"changelog": "file://CHANGELOG.md",
|
||||
"contactEmail": "contact@ente.io",
|
||||
"tagline": "Open Source End-to-End Encrypted Photos & Authentication",
|
||||
"upstreamVersion": "1.0.0",
|
||||
"version": "0.1.128",
|
||||
"healthCheckPath": "/ping",
|
||||
"website": "https://ente.io",
|
||||
"tagline": "Open source, end-to-end encrypted photo backup",
|
||||
"version": "0.5.10",
|
||||
"upstreamVersion": "git-main",
|
||||
"healthCheckPath": "/health",
|
||||
"httpPort": 3080,
|
||||
"memoryLimit": 1073741824,
|
||||
"httpPorts": {
|
||||
"ACCOUNTS_DOMAIN": {
|
||||
"title": "Accounts hostname",
|
||||
"description": "Hostname for the Ente accounts web app (e.g. accounts)",
|
||||
"containerPort": 3080,
|
||||
"defaultValue": "accounts",
|
||||
"aliasableDomain": true
|
||||
},
|
||||
"AUTH_DOMAIN": {
|
||||
"title": "Auth hostname",
|
||||
"description": "Hostname for the Ente authentication frontend (e.g. auth)",
|
||||
"containerPort": 3080,
|
||||
"defaultValue": "auth",
|
||||
"aliasableDomain": true
|
||||
},
|
||||
"CAST_DOMAIN": {
|
||||
"title": "Cast hostname",
|
||||
"description": "Hostname for the Ente casting web app (e.g. cast)",
|
||||
"containerPort": 3080,
|
||||
"defaultValue": "cast",
|
||||
"aliasableDomain": true
|
||||
},
|
||||
"ALBUMS_DOMAIN": {
|
||||
"title": "Public albums hostname",
|
||||
"description": "Hostname for the Ente public albums frontend (e.g. albums)",
|
||||
"containerPort": 3080,
|
||||
"defaultValue": "albums",
|
||||
"aliasableDomain": true
|
||||
},
|
||||
"FAMILY_DOMAIN": {
|
||||
"title": "Family hostname",
|
||||
"description": "Hostname for the Ente family web app (e.g. family)",
|
||||
"containerPort": 3080,
|
||||
"defaultValue": "family",
|
||||
"aliasableDomain": true
|
||||
}
|
||||
},
|
||||
"memoryLimit": 3221225472,
|
||||
"postInstallMessage": "file://POSTINSTALL.md",
|
||||
"addons": {
|
||||
"localstorage": {},
|
||||
"postgresql": {},
|
||||
"email": {},
|
||||
"sendmail": {
|
||||
"supportsDisplayName": true
|
||||
"supportsDisplayName": true,
|
||||
"requiresValidCertificate": true
|
||||
}
|
||||
},
|
||||
"checklist": {
|
||||
"create-permanent-admin": {
|
||||
"message": "Required: S3 Storage Configuration!"
|
||||
"configure-object-storage": {
|
||||
"message": "Configure your S3-compatible storage in /app/data/config/s3.env before first use."
|
||||
}
|
||||
},
|
||||
|
||||
"icon": "file://logo.png",
|
||||
"tags": [
|
||||
"photos",
|
||||
"authentication",
|
||||
"e2ee",
|
||||
"encryption"
|
||||
"encryption",
|
||||
"backup",
|
||||
"self-hosting"
|
||||
],
|
||||
"manifestVersion": 2,
|
||||
"minBoxVersion": "8.1.0",
|
||||
"website": "https://ente.io"
|
||||
"minBoxVersion": "8.1.0"
|
||||
}
|
||||
|
||||
+126
-166
@@ -1,188 +1,148 @@
|
||||
# Build Museum server from source
|
||||
# syntax=docker/dockerfile:1
|
||||
|
||||
ARG ENTE_GIT_REF=main
|
||||
ARG FAMILIES_GIT_REF=main
|
||||
|
||||
FROM debian:bookworm AS ente-source
|
||||
ARG ENTE_GIT_REF
|
||||
COPY patches /patches
|
||||
RUN set -e; \
|
||||
apt-get update && \
|
||||
apt-get install -y --no-install-recommends ca-certificates git patch && \
|
||||
git clone --depth=1 --branch "${ENTE_GIT_REF}" https://github.com/ente-io/ente.git /src && \
|
||||
if [ -d /patches ]; then \
|
||||
for patch_file in /patches/*.patch; do \
|
||||
[ -f "$patch_file" ] || continue; \
|
||||
(cd /src && patch -p1 < "$patch_file"); \
|
||||
done; \
|
||||
fi && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
FROM debian:bookworm AS families-source
|
||||
ARG FAMILIES_GIT_REF
|
||||
RUN apt-get update && \
|
||||
apt-get install -y --no-install-recommends ca-certificates git && \
|
||||
git clone --depth=1 --branch "${FAMILIES_GIT_REF}" https://github.com/ente-io/families.git /families && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
FROM golang:1.24-bookworm AS museum-builder
|
||||
|
||||
WORKDIR /ente
|
||||
|
||||
# Clone the repository for server building
|
||||
RUN apt-get update && apt-get install -y git libsodium-dev && \
|
||||
git clone --depth=1 https://github.com/ente-io/ente.git . && \
|
||||
apt-get clean && apt-get autoremove && \
|
||||
rm -rf /var/cache/apt /var/lib/apt/lists
|
||||
|
||||
# Build the Museum server
|
||||
COPY --from=ente-source /src /ente
|
||||
WORKDIR /ente/server
|
||||
RUN go mod download && \
|
||||
CGO_ENABLED=1 GOOS=linux go build -a -o museum ./cmd/museum
|
||||
|
||||
FROM node:20-bookworm-slim as web-builder
|
||||
|
||||
WORKDIR /ente
|
||||
|
||||
# Clone the repository for web app building
|
||||
RUN apt-get update && apt-get install -y git && \
|
||||
git clone --depth=1 https://github.com/ente-io/ente.git . && \
|
||||
apt-get clean && apt-get autoremove && \
|
||||
rm -rf /var/cache/apt /var/lib/apt/lists
|
||||
|
||||
# Will help default to yarn version 1.22.22
|
||||
RUN corepack enable
|
||||
|
||||
# Set environment variables for web app build - use relative endpoint
|
||||
ENV NEXT_PUBLIC_ENTE_ENDPOINT="/api"
|
||||
RUN echo "Building with relative NEXT_PUBLIC_ENTE_ENDPOINT=/api for self-hosted deployment"
|
||||
|
||||
# Debugging the repository structure
|
||||
RUN find . -type d -maxdepth 3 | sort
|
||||
|
||||
# Check if web directory exists with apps subdirectory
|
||||
RUN mkdir -p /build/web/photos /build/web/accounts /build/web/auth /build/web/cast && \
|
||||
if [ -d "web" ] && [ -d "web/apps" ]; then \
|
||||
echo "Found web/apps directory, building web apps"; \
|
||||
cd web && \
|
||||
yarn cache clean && \
|
||||
yarn install --network-timeout 1000000000 && \
|
||||
yarn build:photos && \
|
||||
yarn build:accounts && \
|
||||
yarn build:auth && \
|
||||
yarn build:cast && \
|
||||
if [ -d "apps/photos/out" ]; then \
|
||||
cp -r apps/photos/out/* /build/web/photos/; \
|
||||
fi && \
|
||||
if [ -d "apps/accounts/out" ]; then \
|
||||
cp -r apps/accounts/out/* /build/web/accounts/; \
|
||||
fi && \
|
||||
if [ -d "apps/auth/out" ]; then \
|
||||
cp -r apps/auth/out/* /build/web/auth/; \
|
||||
fi && \
|
||||
if [ -d "apps/cast/out" ]; then \
|
||||
cp -r apps/cast/out/* /build/web/cast/; \
|
||||
fi; \
|
||||
elif [ -d "web" ]; then \
|
||||
echo "Found web directory, looking for alternative structure"; \
|
||||
find web -type d | grep -v node_modules | sort; \
|
||||
if [ -d "web/photos" ]; then \
|
||||
echo "Building photos app"; \
|
||||
cd web/photos && yarn install && yarn build && \
|
||||
if [ -d "out" ]; then cp -r out/* /build/web/photos/; fi; \
|
||||
fi; \
|
||||
if [ -d "web/accounts" ]; then \
|
||||
echo "Building accounts app"; \
|
||||
cd web/accounts && yarn install && yarn build && \
|
||||
if [ -d "out" ]; then cp -r out/* /build/web/accounts/; fi; \
|
||||
fi; \
|
||||
if [ -d "web/auth" ]; then \
|
||||
echo "Building auth app"; \
|
||||
cd web/auth && yarn install && yarn build && \
|
||||
if [ -d "out" ]; then cp -r out/* /build/web/auth/; fi; \
|
||||
fi; \
|
||||
if [ -d "web/cast" ]; then \
|
||||
echo "Building cast app"; \
|
||||
cd web/cast && yarn install && yarn build && \
|
||||
if [ -d "out" ]; then cp -r out/* /build/web/cast/; fi; \
|
||||
fi; \
|
||||
RUN apt-get update && \
|
||||
apt-get install -y --no-install-recommends build-essential pkg-config libsodium-dev && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
RUN mkdir -p /build/museum && \
|
||||
CGO_ENABLED=1 GOOS=linux go build -o /build/museum/museum ./cmd/museum && \
|
||||
for dir in migrations web-templates mail-templates assets; do \
|
||||
rm -rf "/build/museum/$dir"; \
|
||||
if [ -d "$dir" ]; then \
|
||||
cp -r "$dir" "/build/museum/$dir"; \
|
||||
else \
|
||||
echo "Web directory not found, creating placeholder web pages"; \
|
||||
# Create placeholder HTML files for each app \
|
||||
mkdir -p /build/web/photos /build/web/accounts /build/web/auth /build/web/cast; \
|
||||
echo "<html><body><h1>Ente Photos</h1><p>Web app not available. Please check the build logs.</p></body></html>" > /build/web/photos/index.html; \
|
||||
echo "<html><body><h1>Ente Accounts</h1><p>Web app not available. Please check the build logs.</p></body></html>" > /build/web/accounts/index.html; \
|
||||
echo "<html><body><h1>Ente Auth</h1><p>Web app not available. Please check the build logs.</p></body></html>" > /build/web/auth/index.html; \
|
||||
echo "<html><body><h1>Ente Cast</h1><p>Web app not available. Please check the build logs.</p></body></html>" > /build/web/cast/index.html; \
|
||||
fi
|
||||
mkdir -p "/build/museum/$dir"; \
|
||||
fi; \
|
||||
done
|
||||
|
||||
FROM golang:1.24-bookworm AS cli-builder
|
||||
COPY --from=ente-source /src /ente
|
||||
WORKDIR /ente/cli
|
||||
RUN go build -o /build/ente .
|
||||
|
||||
FROM node:20-bookworm-slim AS web-builder
|
||||
ENV NEXT_PUBLIC_ENTE_ENDPOINT=ENTE_API_ORIGIN_PLACEHOLDER
|
||||
ENV NEXT_PUBLIC_ENTE_ALBUMS_ENDPOINT=https://albums.localhost.invalid
|
||||
COPY --from=ente-source /src /ente
|
||||
WORKDIR /ente/web
|
||||
RUN apt-get update && \
|
||||
apt-get install -y --no-install-recommends build-essential python3 && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
RUN corepack enable
|
||||
RUN yarn install --network-timeout 1000000
|
||||
RUN mkdir -p /build/web/photos /build/web/accounts /build/web/auth /build/web/cast /build/web/albums /build/web/family
|
||||
RUN set -e; \
|
||||
yarn build:photos; \
|
||||
yarn build:accounts; \
|
||||
yarn build:auth; \
|
||||
yarn build:cast
|
||||
RUN if [ -d "apps" ]; then \
|
||||
for app in photos accounts auth cast; do \
|
||||
if [ -d "apps/${app}/out" ]; then \
|
||||
rm -rf "/build/web/${app}"; \
|
||||
mkdir -p "/build/web/${app}"; \
|
||||
cp -r "apps/${app}/out/." "/build/web/${app}/"; \
|
||||
else \
|
||||
printf 'Missing build output for %s\n' "${app}"; \
|
||||
printf '<html><body><h1>Ente %s</h1><p>Build output missing.</p></body></html>\n' "${app}" > "/build/web/${app}/index.html"; \
|
||||
fi; \
|
||||
done; \
|
||||
else \
|
||||
for app in photos accounts auth cast; do \
|
||||
printf '<html><body><h1>Ente %s</h1><p>Build output missing.</p></body></html>\n' "${app}" > "/build/web/${app}/index.html"; \
|
||||
done; \
|
||||
fi && \
|
||||
rm -rf /build/web/albums && \
|
||||
cp -r /build/web/photos /build/web/albums
|
||||
|
||||
FROM node:20-bookworm-slim AS families-builder
|
||||
ENV NEXT_PUBLIC_ENTE_ENDPOINT=ENTE_API_ORIGIN_PLACEHOLDER \
|
||||
NEXT_WEB_ENTE_ENDPOINT=ENTE_WEB_ENDPOINT_PLACEHOLDER \
|
||||
NEXT_PUBLIC_IS_SENTRY_ENABLED=no \
|
||||
NEXT_PUBLIC_SENTRY_ENV=local \
|
||||
NEXT_PUBLIC_SENTRY_DSN= \
|
||||
NEXT_TELEMETRY_DISABLED=1
|
||||
COPY --from=families-source /families /families
|
||||
WORKDIR /families
|
||||
RUN apt-get update && \
|
||||
apt-get install -y --no-install-recommends build-essential python3 && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
RUN corepack enable
|
||||
RUN yarn install --network-timeout 1000000
|
||||
RUN mkdir -p /build/family && \
|
||||
yarn build && \
|
||||
./node_modules/.bin/next export -o /build/family
|
||||
|
||||
FROM cloudron/base:5.0.0@sha256:04fd70dbd8ad6149c19de39e35718e024417c3e01dc9c6637eaf4a41ec4e596c
|
||||
|
||||
# Install necessary packages and Caddy webserver
|
||||
ENV APP_DIR=/app/code \
|
||||
DATA_DIR=/app/data \
|
||||
HOME=/app/data/home
|
||||
|
||||
RUN apt-get update && \
|
||||
apt-get install -y curl git nodejs npm libsodium23 libsodium-dev pkg-config postgresql-client && \
|
||||
npm install -g yarn serve && \
|
||||
# Install Caddy for web server
|
||||
apt-get install -y debian-keyring debian-archive-keyring apt-transport-https && \
|
||||
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg && \
|
||||
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | tee /etc/apt/sources.list.d/caddy-stable.list && \
|
||||
apt-get update && \
|
||||
apt-get install -y caddy && \
|
||||
apt-get clean && apt-get autoremove && \
|
||||
rm -rf /var/cache/apt /var/lib/apt/lists
|
||||
apt-get install -y --no-install-recommends ca-certificates curl jq libsodium23 pkg-config postgresql-client caddy openssl && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Install Go 1.24.1
|
||||
RUN curl -L https://go.dev/dl/go1.24.1.linux-amd64.tar.gz -o go.tar.gz && \
|
||||
rm -rf /usr/local/go && \
|
||||
tar -C /usr/local -xzf go.tar.gz && \
|
||||
rm go.tar.gz && \
|
||||
ln -sf /usr/local/go/bin/go /usr/local/bin/go && \
|
||||
ln -sf /usr/local/go/bin/gofmt /usr/local/bin/gofmt
|
||||
RUN mkdir -p /app/pkg /app/web "$HOME" && chown -R cloudron:cloudron /app /app/web "$HOME"
|
||||
|
||||
# Set up directory structure
|
||||
RUN mkdir -p /app/code /app/data/config /app/data/caddy /app/web
|
||||
COPY --from=ente-source /src ${APP_DIR}
|
||||
COPY data ${APP_DIR}/data
|
||||
RUN rm -rf ${APP_DIR}/.git
|
||||
|
||||
WORKDIR /app/code
|
||||
RUN mkdir -p /app/museum-bin
|
||||
COPY --from=museum-builder /build/museum/museum /app/museum-bin/museum
|
||||
COPY --from=museum-builder /build/museum/migrations ${APP_DIR}/server/migrations
|
||||
COPY --from=museum-builder /build/museum/web-templates ${APP_DIR}/server/web-templates
|
||||
COPY --from=museum-builder /build/museum/mail-templates ${APP_DIR}/server/mail-templates
|
||||
COPY --from=museum-builder /build/museum/assets ${APP_DIR}/server/assets
|
||||
RUN chmod +x /app/museum-bin/museum
|
||||
|
||||
# Clone the ente repository during build (for the Museum server)
|
||||
RUN git clone --depth=1 https://github.com/ente-io/ente.git . && \
|
||||
sed -i 's/go 1.23/go 1.24/' server/go.mod && \
|
||||
mkdir -p /app/data/go && \
|
||||
cp -r server/go.mod server/go.sum /app/data/go/ && \
|
||||
chmod 777 /app/data/go/go.mod /app/data/go/go.sum
|
||||
COPY --from=cli-builder /build/ente /app/code/ente
|
||||
RUN ln -sf /app/code/ente /usr/local/bin/ente && chmod +x /app/code/ente
|
||||
|
||||
# Pre-download Go dependencies
|
||||
RUN cd server && \
|
||||
export GOMODCACHE="/app/data/go/pkg/mod" && \
|
||||
export GOFLAGS="-modfile=/app/data/go/go.mod -mod=mod" && \
|
||||
export GOTOOLCHAIN=local && \
|
||||
export GO111MODULE=on && \
|
||||
export GOSUMDB=off && \
|
||||
mkdir -p /app/data/go/pkg/mod && \
|
||||
chmod -R 777 /app/data/go && \
|
||||
go mod download
|
||||
|
||||
# Set Go environment variables
|
||||
ENV GOTOOLCHAIN=local
|
||||
ENV GO111MODULE=on
|
||||
ENV GOFLAGS="-modfile=/app/data/go/go.mod -mod=mod"
|
||||
ENV PATH="/usr/local/go/bin:${PATH}"
|
||||
ENV GOSUMDB=off
|
||||
ENV GOMODCACHE="/app/data/go/pkg/mod"
|
||||
ENV HOME=/app/data/home
|
||||
|
||||
# Copy the web app built files from the first stage
|
||||
COPY --from=web-builder /build/web/photos /app/web/photos
|
||||
COPY --from=web-builder /build/web/accounts /app/web/accounts
|
||||
COPY --from=web-builder /build/web/auth /app/web/auth
|
||||
COPY --from=web-builder /build/web/cast /app/web/cast
|
||||
COPY --from=web-builder /build/web/albums /app/web/albums
|
||||
COPY --from=families-builder /build/family /app/web/family
|
||||
|
||||
# Build Ente CLI and place binary in /app/code
|
||||
WORKDIR /app/code/cli
|
||||
RUN env GOFLAGS= GOMODCACHE=/tmp/cli-go-cache GO111MODULE=on go build -o /app/code/ente . && chmod +x /app/code/ente
|
||||
COPY start.sh /app/pkg/start.sh
|
||||
COPY admin-helper.sh /app/pkg/admin-helper.sh
|
||||
COPY admin-helper-direct.sh /app/pkg/admin-helper-direct.sh
|
||||
|
||||
WORKDIR /app/code
|
||||
|
||||
# Symlink CLI into PATH for convenience
|
||||
RUN ln -sf /app/code/ente /usr/local/bin/ente
|
||||
|
||||
# Prepare CLI data directory symlink to persistent storage
|
||||
RUN mkdir -p /app/data/cli-data && ln -s /app/data/cli-data /cli-data
|
||||
|
||||
# Copy Museum server binary from builder stage to app directory (not data volume)
|
||||
RUN mkdir -p /app/museum-bin
|
||||
COPY --from=museum-builder /ente/server/museum /app/museum-bin/museum
|
||||
RUN chmod +x /app/museum-bin/museum
|
||||
|
||||
# Copy configuration and startup scripts
|
||||
ADD start.sh /app/pkg/
|
||||
ADD config.template.yaml /app/pkg/
|
||||
ADD otp-email-monitor.js /app/pkg/
|
||||
ADD package.json /app/pkg/
|
||||
ADD admin-helper.sh /app/pkg/
|
||||
ADD admin-helper-direct.sh /app/pkg/
|
||||
|
||||
# Set proper permissions
|
||||
RUN chmod +x /app/pkg/start.sh /app/pkg/admin-helper.sh /app/pkg/admin-helper-direct.sh
|
||||
RUN ln -s /app/data/cli-data /cli-data && \
|
||||
rm -rf /home/cloudron && \
|
||||
ln -s /app/data/home /home/cloudron
|
||||
|
||||
# Expose the web port (Cloudron expects port 3080)
|
||||
EXPOSE 3080
|
||||
# Also expose API port
|
||||
EXPOSE 8080
|
||||
EXPOSE 3080 8080
|
||||
|
||||
# Start the application
|
||||
CMD ["/app/pkg/start.sh"]
|
||||
|
||||
+82
-25
@@ -1,33 +1,90 @@
|
||||
Your Ente installation is almost ready!
|
||||
|
||||
## Required: S3 Storage Configuration
|
||||
## Required: External Object Storage
|
||||
|
||||
Before you can use Ente, you need to configure an S3-compatible storage service:
|
||||
Before using Ente, configure an S3-compatible object storage provider:
|
||||
|
||||
1. Go to your Cloudron dashboard
|
||||
2. Click on your Ente app
|
||||
3. Click on "Terminal"
|
||||
4. Edit the S3 configuration file:
|
||||
1. Open the Cloudron dashboard and select your Ente app.
|
||||
2. Launch the file explorer.
|
||||
3. Open `/app/data/config/s3.env` and provide values for **all** required keys.
|
||||
4. Save the file and restart the app from the Cloudron dashboard.
|
||||
5. (Required for cast/slideshow) Configure your S3 bucket’s CORS policy to allow the Ente domains you serve from Cloudron (e.g. `https://ente.due.ren`, `https://accounts.due.ren`, `https://cast.due.ren`, etc.). Without CORS, browsers will block the signed URLs that power the cast slideshow.
|
||||
- **Backblaze B2 tip:** B2 ships with “native” CORS rules that block S3-style updates. Install the Backblaze CLI `pip install 'b2<4'`, then:
|
||||
```bash
|
||||
# Authorise once (replace with your key ID/secret)
|
||||
b2 authorize-account <KEY_ID> <APP_KEY>
|
||||
|
||||
# Inspect the current bucket type (usually allPrivate) and capture it
|
||||
BUCKET_TYPE=$(b2 get-bucket ente-due-ren | awk -F'"' '/bucketType/ {print $4}')
|
||||
|
||||
# Clear any native rules without changing visibility
|
||||
b2 update-bucket ente-due-ren "$BUCKET_TYPE" --cors-rules '[]'
|
||||
|
||||
# Apply the S3-compatible rule (adjust origins as needed)
|
||||
cat >cors.json <<'EOF'
|
||||
[
|
||||
{
|
||||
"corsRuleName": "entephotos",
|
||||
"allowedOrigins": ["*"],
|
||||
"allowedHeaders": ["*"],
|
||||
"allowedOperations": [
|
||||
"b2_download_file_by_id",
|
||||
"b2_download_file_by_name",
|
||||
"b2_upload_file",
|
||||
"b2_upload_part",
|
||||
"s3_get",
|
||||
"s3_post",
|
||||
"s3_put",
|
||||
"s3_head"
|
||||
],
|
||||
"exposeHeaders": ["X-Amz-Request-Id","X-Amz-Id-2","ETag"],
|
||||
"maxAgeSeconds": 3600
|
||||
}
|
||||
]
|
||||
EOF
|
||||
b2 update-bucket ente-due-ren "$BUCKET_TYPE" --cors-rules "$(<cors.json)"
|
||||
```
|
||||
nano /app/data/config/s3.env
|
||||
Verify with `curl -I -H 'Origin: https://ente.due.ren' <signed-url>`; you should see `Access-Control-Allow-Origin`.
|
||||
|
||||
Supported variables (these map directly to the fields described in the upstream “Configuring Object Storage” documentation):
|
||||
- `S3_ENDPOINT` (e.g. `https://<account>.r2.cloudflarestorage.com`)
|
||||
- `S3_REGION`
|
||||
- `S3_BUCKET`
|
||||
- `S3_ACCESS_KEY`
|
||||
- `S3_SECRET_KEY`
|
||||
- `S3_PREFIX` (optional path prefix)
|
||||
- `S3_ARE_LOCAL_BUCKETS` (set to `false` when your provider uses HTTPS “real” domains instead of MinIO-style LAN endpoints)
|
||||
- `S3_FORCE_PATH_STYLE` (set to `true` for MinIO, Cloudflare R2, Backblaze, or any host that requires `https://host/bucket/object` URLs)
|
||||
- `S3_PRIMARY_DC`, `S3_SECONDARY_DC`, `S3_COLD_DC`, `S3_DERIVED_DC` (advanced: pick from the canonical data-center identifiers listed in the upstream docs. The names are hard-coded in Museum; leave them at `b2-eu-cen`, `wasabi-eu-central-2-v3`, `scw-eu-fr-v3` unless you know you need one of the legacy aliases such as `scw-eu-fr`.)
|
||||
- Optional replication: define **both** `S3_SECONDARY_*` and `S3_COLD_*` (endpoints, keys, secrets, optional prefixes, DC names) to mirror uploads to a second hot bucket and a third cold bucket. Replication is only enabled when all three buckets are configured; otherwise the app stays in single-bucket mode. See [Ente’s object storage guide](https://ente.io/help/self-hosting/administration/object-storage) for sample layouts and discussion of reliability.
|
||||
|
||||
You should never edit the generated `/app/data/museum/configurations/local.yaml` directly. If you need to append extra settings (for example, defining `internal.super-admins`), create `/app/data/config/museum.override.yaml` and add only the keys you want to override. Copying the entire sample `s3:` block from the docs into that file will erase the credentials that the package renders from `s3.env` and break replication.
|
||||
|
||||
## Required: Secondary Hostnames
|
||||
|
||||
The installer now asks for dedicated hostnames for the Auth/Accounts/Cast/Albums/Family web apps (via Cloudron `httpPorts`). If you manage DNS outside of Cloudron, create CNAME/A records such as `accounts.<app-domain>`, `auth.<app-domain>`, etc., pointing at the primary app domain. With Cloudron-managed DNS the records are created automatically.
|
||||
|
||||
## Administration
|
||||
|
||||
- **Grant yourself admin privileges**
|
||||
1. Open the Cloudron dashboard → your Ente app → **File Manager**.
|
||||
2. Navigate to `/app/data/config/` and open (or create) `museum.override.yaml`.
|
||||
3. Add your email to the super-admin list:
|
||||
```yaml
|
||||
internal:
|
||||
super-admins:
|
||||
- you@example.com
|
||||
```
|
||||
5. Uncomment the variables you need and fill in your S3 credentials (AWS S3, Cloudflare R2, MinIO, etc.). The file includes commented examples for the previous Wasabi defaults and a generic Cloudflare R2 setup.
|
||||
6. Save the file and restart your Ente app from the Cloudron dashboard
|
||||
4. Save the file and restart the app. The override is appended to Museum’s configuration on every start.
|
||||
|
||||
## Next Steps
|
||||
- **Sign in to the bundled CLI**
|
||||
*The package now preconfigures the CLI (config: `/app/data/cli-data/config.yaml`, exports: `/app/data/cli-data/export`).*
|
||||
From the Cloudron **Terminal** run:
|
||||
```bash
|
||||
# authenticate once (enter the OTP you receive by email)
|
||||
sudo -u cloudron ente account add
|
||||
|
||||
1. Once S3 is configured, visit your app URL to create an admin account
|
||||
2. Configure your mobile apps to use your custom self-hosted server (Settings → Advanced → Custom Server)
|
||||
3. Enjoy your private, end-to-end encrypted photo storage!
|
||||
|
||||
## Ente CLI
|
||||
|
||||
- The Ente CLI binary is pre-built at `/app/code/ente` inside the app container.
|
||||
- Open the Cloudron web terminal (working directory `/app/code`) and run commands with `./ente ...` or add `/app/code` to your `PATH`.
|
||||
- A writable CLI config template lives at `/app/data/home/.ente/config.yaml` for pointing the CLI to your instance.
|
||||
|
||||
## Museum Server Configuration
|
||||
|
||||
- The active configuration lives at `/app/data/ente/server/configurations/local.yaml` and is created the first time the app starts.
|
||||
- Subsequent restarts leave this file untouched, so you can whitelist admin accounts or adjust other settings as documented by Ente.
|
||||
- Delete the file to regenerate the default template (environment values such as database and S3 credentials are rendered during creation).
|
||||
# inspect available commands
|
||||
sudo -u cloudron ente --help
|
||||
```
|
||||
After you’re signed in you can follow the upstream docs for tasks like increasing storage: see [user administration](https://ente.io/help/self-hosting/administration/users) and the [CLI reference](https://ente.io/help/self-hosting/administration/cli). The [object storage guide](https://ente.io/help/self-hosting/administration/object-storage) explains the reliability setup: fill out `S3_*`, `S3_SECONDARY_*`, and `S3_COLD_*` in `/app/data/config/s3.env`, and the package will automatically enable three-bucket replication when you restart (no extra toggle needed).
|
||||
|
||||
@@ -9,28 +9,6 @@ This repository contains the Cloudron packaging for [Ente](https://ente.io), an
|
||||
- Configured to use Cloudron's mail service for sending emails
|
||||
- Easy to deploy and manage through the Cloudron interface
|
||||
|
||||
## Requirements
|
||||
|
||||
### Browser Compatibility
|
||||
|
||||
Ente uses modern web technologies for its end-to-end encryption:
|
||||
|
||||
- **WebAssembly**: Required for cryptographic operations
|
||||
- **IndexedDB**: Required for client-side data storage
|
||||
|
||||
Most modern browsers support these features, but they may be blocked by:
|
||||
- Browser privacy settings
|
||||
- Content Security Policies
|
||||
- Certain browser extensions
|
||||
|
||||
This package includes custom Caddy configuration with appropriate security headers to ensure these features work correctly.
|
||||
|
||||
### S3-Compatible Storage
|
||||
|
||||
Ente requires an S3-compatible object storage service. You can use:
|
||||
- Cloudron's built-in object storage
|
||||
- External services like AWS S3, Wasabi, or MinIO
|
||||
|
||||
## Building and Installing
|
||||
|
||||
### Option 1: Build and Install Manually
|
||||
@@ -73,23 +51,95 @@ The app is configured automatically using Cloudron's environment variables for:
|
||||
- SMTP mail service
|
||||
- App origin URL
|
||||
|
||||
### Additional Configuration
|
||||
### Cloudron Admin Notes
|
||||
|
||||
The package includes several enhancements to ensure proper functionality:
|
||||
After installing on Cloudron remember to:
|
||||
|
||||
1. **Security Headers**: Custom Content-Security-Policy headers that allow WebAssembly and IndexedDB
|
||||
2. **API Configuration**: Dynamic runtime configuration to ensure the frontend connects to the correct API endpoint
|
||||
3. **CORS Headers**: Proper CORS configuration for API access
|
||||
1. Open the File Manager for the app, edit `/app/data/config/s3.env`, and set the S3-compatible credentials that belong in `museum.yaml`. The upstream documentation expects the canonical keys `b2-eu-cen` (primary), `wasabi-eu-central-2-v3` (secondary) and `scw-eu-fr-v3` (cold); this package renders those blocks automatically from the environment variables below so you don’t have to touch the generated config. At minimum set `S3_ENDPOINT`, `S3_REGION`, `S3_BUCKET`, `S3_ACCESS_KEY`, `S3_SECRET_KEY`, plus the optional `S3_PREFIX`. To enable replication you must also define **both** `S3_SECONDARY_*` and `S3_COLD_*` (endpoint, region, bucket, key, secret, optional prefix/DC overrides); after a restart the package will flip `replication.enabled` on your behalf when all three buckets are present. Advanced knobs from the documentation map to the following variables:
|
||||
- `S3_ARE_LOCAL_BUCKETS=false` toggles SSL/subdomain-style URLs (`are_local_buckets` in `museum.yaml`); leave it at `true` for MinIO-style setups.
|
||||
- `S3_FORCE_PATH_STYLE=true` translates to `use_path_style_urls=true` (required for R2/MinIO and most LAN storage).
|
||||
- The data-center identifiers (`b2-eu-cen`, `wasabi-eu-central-2-v3`, `scw-eu-fr-v3`, etc.) are **hard-coded upstream**. Keep the defaults unless you know you are targeting one of the legacy names (as listed in the Ente docs). The start script will ignore unknown values to prevent replication from breaking with empty bucket names.
|
||||
- Leave the generated `museum/configurations/local.yaml` alone—if you need to append extra settings, do so via `/app/data/config/museum.override.yaml` and only add the keys you actually want to change. Copy‑pasting the full sample `s3:` block from the docs will overwrite the generated credentials with blanks.
|
||||
- If you are using Cloudflare R2 or another hosted S3 provider, configure your bucket’s CORS policy to allow the Ente frontends (e.g. `https://ente.due.ren`, `https://accounts.due.ren`, `https://cast.due.ren`, **and** the desktop scheme `ente://app`) so that cast/slideshow playback and the desktop client can fetch signed URLs directly from storage. Backblaze B2 also requires clearing its “native” CORS rules; see the script in `POSTINSTALL.md`. When using the Backblaze CLI remember to preserve your bucket visibility (`allPrivate` for most installs): run `b2 get-bucket <bucket>` to confirm the current type, then invoke `b2 update-bucket <bucket> <bucketType> --cors-rules "$(<cors.json)"` so you only touch the CORS block. A minimal rule that works with Ente’s signed URLs looks like:
|
||||
```bash
|
||||
cat <<'EOF' >cors.json
|
||||
[
|
||||
{
|
||||
"corsRuleName": "entephotos",
|
||||
"allowedOrigins": ["*"],
|
||||
"allowedHeaders": ["*"],
|
||||
"allowedOperations": [
|
||||
"b2_download_file_by_id",
|
||||
"b2_download_file_by_name",
|
||||
"b2_upload_file",
|
||||
"b2_upload_part",
|
||||
"s3_get",
|
||||
"s3_post",
|
||||
"s3_put",
|
||||
"s3_head"
|
||||
],
|
||||
"exposeHeaders": ["X-Amz-Request-Id","X-Amz-Id-2","ETag"],
|
||||
"maxAgeSeconds": 3600
|
||||
}
|
||||
]
|
||||
EOF
|
||||
b2 update-bucket ente-due-ren allPrivate --cors-rules "$(<cors.json)"
|
||||
```
|
||||
Adjust the hostnames and bucket type as needed; afterwards verify with `curl -I -H 'Origin: https://cast.example.com' '<signed-url>'` and ensure `Access-Control-Allow-Origin` is present.
|
||||
2. When prompted during installation, pick hostnames for the Accounts/Auth/Cast/Albums/Family web apps (they are exposed via Cloudron `httpPorts`). Ensure matching DNS records exist; Cloudron-managed DNS creates them automatically, otherwise point CNAME/A records such as `accounts.<app-domain>` at the primary hostname.
|
||||
3. To persist tweaks to Museum (for example, seeding super-admin or whitelist entries), create `/app/data/config/museum.override.yaml`. Its contents are appended to the generated `museum/configurations/local.yaml` on every start, so you only need to declare the keys you want to override.
|
||||
```yaml
|
||||
# /app/data/config/museum.override.yaml
|
||||
internal:
|
||||
super-admins:
|
||||
- admin@example.com
|
||||
```
|
||||
4. Use the bundled Ente CLI for admin tasks via `cloudron exec --app <location> -- sudo -u cloudron ente --help`. On a fresh install run the following once (initialises the CLI config, whitelists your admin, and clears the CLI DB):
|
||||
```bash
|
||||
cloudron exec --app ente.cloudron.io -- bash -lc \
|
||||
'cat <<EOF >/cli-data/config.yaml
|
||||
endpoint:
|
||||
api: https://ente.cloudron.io/api
|
||||
log:
|
||||
http: false
|
||||
EOF
|
||||
mkdir -p /cli-data/export
|
||||
chown cloudron:cloudron /cli-data /cli-data/config.yaml /cli-data/export
|
||||
cat <<EOF >/app/data/config/museum.override.yaml
|
||||
internal:
|
||||
super-admins:
|
||||
- admin@example.com
|
||||
EOF
|
||||
rm -f /cli-data/ente-cli.db
|
||||
chown cloudron:cloudron /app/data/config/museum.override.yaml'
|
||||
|
||||
You need to manually set up and configure:
|
||||
cloudron restart --app ente.cloudron.io
|
||||
|
||||
- S3-compatible object storage
|
||||
# add your account (respond to prompts with the OTP sent to your email)
|
||||
cloudron exec --app ente.cloudron.io -- sudo -u cloudron ente account add
|
||||
```
|
||||
Afterwards the usual admin commands work as documented. Example:
|
||||
```bash
|
||||
cloudron exec --app ente.cloudron.io -- sudo -u cloudron ente admin list-users --admin-user admin@example.com
|
||||
```
|
||||
|
||||
The main photos UI continues to live on the hostname you selected during installation.
|
||||
|
||||
### Object storage quick reference
|
||||
|
||||
The upstream documentation at [ente.io/help/self-hosting/administration/object-storage](https://ente.io/help/self-hosting/administration/object-storage) is written for bare-metal installs where you edit `museum.yaml` by hand. The Cloudron package wraps those steps so you only maintain `/app/data/config/s3.env`, but the same concepts apply:
|
||||
|
||||
- **Canonical bucket names.** Museum’s schema ships with `b2-eu-cen`, `wasabi-eu-central-2-v3`, and `scw-eu-fr-v3`. You can point those identifiers at any S3-compatible provider, but you cannot rename them—replication logic only understands the upstream keys (or their documented legacy aliases). Leave the defaults in `s3.env` and only change the credentials/endpoints under each key.
|
||||
- **Three buckets for replication.** Replication only works when two “hot” buckets and one “cold” bucket are configured. Populate `S3_*`, `S3_SECONDARY_*`, and `S3_COLD_*`; once all three have endpoints/keys/secrets the package automatically writes the `replication.enabled: true` stanza.
|
||||
- **Transport settings.** Set `S3_ARE_LOCAL_BUCKETS=true`/`false` and `S3_FORCE_PATH_STYLE=true` to mirror the documentation’s `are_local_buckets`/`use_path_style_urls` toggles when talking to MinIO, Cloudflare R2, or other providers that require path-style URLs over HTTPS.
|
||||
- **CORS.** If browsers cannot upload/download because of CORS, apply the recommended JSON from the docs (or the Backblaze helper script in `POSTINSTALL.md`). Ensure `Content-MD5` is listed in `AllowedHeaders` for providers with allow-lists.
|
||||
- **Do not overwrite the generated config.** Keep `/app/data/config/museum.override.yaml` minimal (only the keys you need). Dropping the example `s3:` block from the docs into that file will clear the generated credentials and replication will fail with “PutObjectInput.Bucket” errors.
|
||||
|
||||
## Usage
|
||||
|
||||
### Web Client
|
||||
|
||||
After installation, you can access the Ente web client at your app's URL. Create an admin account on first use.
|
||||
After installation, you can access the Ente web client at your app's URL. Create the first user and promote them to an administrator using the override file or upstream admin tooling as documented by Ente.
|
||||
|
||||
### Mobile Apps
|
||||
|
||||
@@ -107,18 +157,6 @@ To update to a newer version:
|
||||
cloudron update --app ente.yourdomain.com
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Common Issues
|
||||
|
||||
1. **"Failed to fetch" errors**: Check if your browser is blocking API requests to your domain
|
||||
2. **WebAssembly errors**: Ensure your browser supports and allows WebAssembly (try using Chrome or Firefox)
|
||||
3. **IndexedDB errors**: Make sure your browser allows IndexedDB (not in private/incognito mode)
|
||||
|
||||
For issues specific to the Cloudron packaging, please open an issue in this repository.
|
||||
|
||||
For issues with Ente itself, please refer to the [main Ente repository](https://github.com/ente-io/ente).
|
||||
|
||||
## License
|
||||
|
||||
This Cloudron package is licensed under the same license as Ente (Apache 2.0).
|
||||
+4
-4
@@ -2,7 +2,7 @@
|
||||
# Ente Admin Helper Script for Cloudron
|
||||
# This script simplifies admin operations in the Cloudron terminal
|
||||
|
||||
MUSEUM_BIN="/app/data/ente/server/museum"
|
||||
MUSEUM_BIN="/app/museum-bin/museum"
|
||||
|
||||
# Check if museum binary exists
|
||||
if [ ! -f "$MUSEUM_BIN" ]; then
|
||||
@@ -26,7 +26,7 @@ update_subscription() {
|
||||
echo "Storage: ${storage_gb}GB"
|
||||
echo "Valid for: ${valid_days} days"
|
||||
|
||||
cd /app/data/ente/server
|
||||
cd /app/data/museum
|
||||
|
||||
# Use environment variables for database connection
|
||||
export DB_HOST="$CLOUDRON_POSTGRESQL_HOST"
|
||||
@@ -48,14 +48,14 @@ get_user_details() {
|
||||
return 1
|
||||
fi
|
||||
|
||||
cd /app/data/ente/server
|
||||
cd /app/data/museum
|
||||
|
||||
"$MUSEUM_BIN" admin get-user-details --user "$user_email"
|
||||
}
|
||||
|
||||
# Function to list all users
|
||||
list_users() {
|
||||
cd /app/data/ente/server
|
||||
cd /app/data/museum
|
||||
|
||||
# Connect to PostgreSQL and list users
|
||||
PGPASSWORD="$CLOUDRON_POSTGRESQL_PASSWORD" psql \
|
||||
|
||||
+11
-7
@@ -18,16 +18,20 @@ database:
|
||||
maxIdleConns: 25
|
||||
connMaxLifetime: "1h"
|
||||
|
||||
storage:
|
||||
type: "s3"
|
||||
s3:
|
||||
s3:
|
||||
are_local_buckets: false
|
||||
use_path_style_urls: true
|
||||
hot_storage:
|
||||
primary: b2-eu-cen
|
||||
secondary: b2-eu-cen
|
||||
derived-storage: b2-eu-cen
|
||||
b2-eu-cen:
|
||||
endpoint: "%%S3_ENDPOINT%%"
|
||||
region: "%%S3_REGION%%"
|
||||
bucket: "%%S3_BUCKET%%"
|
||||
accessKey: "%%S3_ACCESS_KEY%%"
|
||||
secretKey: "%%S3_SECRET_KEY%%"
|
||||
prefix: "%%S3_PREFIX%%"
|
||||
forcePathStyle: true
|
||||
key: "%%S3_ACCESS_KEY%%"
|
||||
secret: "%%S3_SECRET_KEY%%"
|
||||
path_prefix: "%%S3_PREFIX%%"
|
||||
|
||||
email:
|
||||
smtp:
|
||||
|
||||
@@ -0,0 +1,186 @@
|
||||
{
|
||||
"IN": [
|
||||
{
|
||||
"id": "50gb_monthly_v4",
|
||||
"androidID": "50gb_monthly_v4",
|
||||
"iosID": "50gb_monthly_v4",
|
||||
"stripeID": "50gb_monthly_v4",
|
||||
"storage": 53687091200,
|
||||
"price": "₹0",
|
||||
"period": "month"
|
||||
},
|
||||
{
|
||||
"id": "200gb_monthly_v4",
|
||||
"androidID": "200gb_monthly_v4",
|
||||
"iosID": "200gb_monthly_v4",
|
||||
"stripeID": "200gb_monthly_v4",
|
||||
"storage": 214748364800,
|
||||
"price": "₹0",
|
||||
"period": "month"
|
||||
},
|
||||
{
|
||||
"id": "1000gb_monthly_v4",
|
||||
"androidID": "1000gb_monthly_v4",
|
||||
"iosID": "1000gb_monthly_v4",
|
||||
"stripeID": "1000gb_monthly_v4",
|
||||
"storage": 1073741824000,
|
||||
"price": "₹0",
|
||||
"period": "month"
|
||||
},
|
||||
{
|
||||
"id": "2000gb_monthly_v4",
|
||||
"androidID": "2000gb_monthly_v4",
|
||||
"iosID": "2000gb_monthly_v4",
|
||||
"stripeID": "2000gb_monthly_v4",
|
||||
"storage": 2147483648000,
|
||||
"price": "₹0",
|
||||
"period": "month"
|
||||
},
|
||||
{
|
||||
"id": "50gb_yearly_v4",
|
||||
"androidID": "50gb_yearly_v4",
|
||||
"iosID": "50gb_yearly_v4",
|
||||
"stripeID": "50gb_yearly_v4",
|
||||
"storage": 53687091200,
|
||||
"price": "₹0",
|
||||
"period": "year"
|
||||
},
|
||||
{
|
||||
"id": "200gb_yearly_v4",
|
||||
"androidID": "200gb_yearly_v4",
|
||||
"iosID": "200gb_yearly_v4",
|
||||
"stripeID": "200gb_yearly_v4",
|
||||
"storage": 214748364800,
|
||||
"price": "₹0",
|
||||
"period": "year"
|
||||
},
|
||||
{
|
||||
"id": "1000gb_yearly_v4",
|
||||
"androidID": "1000gb_yearly_v4",
|
||||
"iosID": "1000gb_yearly_v4",
|
||||
"stripeID": "1000gb_yearly_v4",
|
||||
"storage": 1073741824000,
|
||||
"price": "₹0",
|
||||
"period": "year"
|
||||
},
|
||||
{
|
||||
"id": "2000gb_yearly_v4",
|
||||
"androidID": "2000gb_yearly_v4",
|
||||
"iosID": "2000gb_yearly_v4",
|
||||
"stripeID": "2000gb_yearly_v4",
|
||||
"storage": 2147483648000,
|
||||
"price": "₹0",
|
||||
"period": "year"
|
||||
},
|
||||
{
|
||||
"id": "family",
|
||||
"androidID": "family",
|
||||
"iosID": "family",
|
||||
"stripeID": "family",
|
||||
"storage": 2147483648000,
|
||||
"price": "₹0",
|
||||
"period": "year"
|
||||
},
|
||||
{
|
||||
"id": "free",
|
||||
"androidID": "free",
|
||||
"iosID": "free",
|
||||
"stripeID": "free",
|
||||
"storage": 10737418240,
|
||||
"price": "₹0",
|
||||
"period": "year"
|
||||
}
|
||||
],
|
||||
"US": [
|
||||
{
|
||||
"id": "50gb_monthly_v4",
|
||||
"androidID": "50gb_monthly_v4",
|
||||
"iosID": "50gb_monthly_v4",
|
||||
"stripeID": "50gb_monthly_v4",
|
||||
"storage": 53687091200,
|
||||
"price": "$0",
|
||||
"period": "month"
|
||||
},
|
||||
{
|
||||
"id": "200gb_monthly_v4",
|
||||
"androidID": "200gb_monthly_v4",
|
||||
"iosID": "200gb_monthly_v4",
|
||||
"stripeID": "200gb_monthly_v4",
|
||||
"storage": 214748364800,
|
||||
"price": "$0",
|
||||
"period": "month"
|
||||
},
|
||||
{
|
||||
"id": "1000gb_monthly_v4",
|
||||
"androidID": "1000gb_monthly_v4",
|
||||
"iosID": "1000gb_monthly_v4",
|
||||
"stripeID": "1000gb_monthly_v4",
|
||||
"storage": 1073741824000,
|
||||
"price": "$0",
|
||||
"period": "month"
|
||||
},
|
||||
{
|
||||
"id": "2000gb_monthly_v4",
|
||||
"androidID": "2000gb_monthly_v4",
|
||||
"iosID": "2000gb_monthly_v4",
|
||||
"stripeID": "2000gb_monthly_v4",
|
||||
"storage": 2147483648000,
|
||||
"price": "$0",
|
||||
"period": "month"
|
||||
},
|
||||
{
|
||||
"id": "50gb_yearly_v4",
|
||||
"androidID": "50gb_yearly_v4",
|
||||
"iosID": "50gb_yearly_v4",
|
||||
"stripeID": "50gb_yearly_v4",
|
||||
"storage": 53687091200,
|
||||
"price": "$0",
|
||||
"period": "year"
|
||||
},
|
||||
{
|
||||
"id": "200gb_yearly_v4",
|
||||
"androidID": "200gb_yearly_v4",
|
||||
"iosID": "200gb_yearly_v4",
|
||||
"stripeID": "200gb_yearly_v4",
|
||||
"storage": 214748364800,
|
||||
"price": "$0",
|
||||
"period": "year"
|
||||
},
|
||||
{
|
||||
"id": "1000gb_yearly_v4",
|
||||
"androidID": "1000gb_yearly_v4",
|
||||
"iosID": "1000gb_yearly_v4",
|
||||
"stripeID": "1000gb_yearly_v4",
|
||||
"storage": 1073741824000,
|
||||
"price": "$0",
|
||||
"period": "year"
|
||||
},
|
||||
{
|
||||
"id": "2000gb_yearly_v4",
|
||||
"androidID": "2000gb_yearly_v4",
|
||||
"iosID": "2000gb_yearly_v4",
|
||||
"stripeID": "2000gb_yearly_v4",
|
||||
"storage": 2147483648000,
|
||||
"price": "$0",
|
||||
"period": "year"
|
||||
},
|
||||
{
|
||||
"id": "family",
|
||||
"androidID": "family",
|
||||
"iosID": "family",
|
||||
"stripeID": "family",
|
||||
"storage": 2147483648000,
|
||||
"price": "$0",
|
||||
"period": "year"
|
||||
},
|
||||
{
|
||||
"id": "free",
|
||||
"androidID": "free",
|
||||
"iosID": "free",
|
||||
"stripeID": "free",
|
||||
"storage": 10737418240,
|
||||
"price": "$0",
|
||||
"period": "year"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,186 @@
|
||||
{
|
||||
"US": [
|
||||
{
|
||||
"id": "50gb_monthly_v4",
|
||||
"androidID": "50gb_monthly_v4",
|
||||
"iosID": "50gb_monthly_v4",
|
||||
"stripeID": "50gb_monthly_v4",
|
||||
"storage": 53687091200,
|
||||
"price": "$0",
|
||||
"period": "month"
|
||||
},
|
||||
{
|
||||
"id": "200gb_monthly_v4",
|
||||
"androidID": "200gb_monthly_v4",
|
||||
"iosID": "200gb_monthly_v4",
|
||||
"stripeID": "200gb_monthly_v4",
|
||||
"storage": 214748364800,
|
||||
"price": "$0",
|
||||
"period": "month"
|
||||
},
|
||||
{
|
||||
"id": "1000gb_monthly_v4",
|
||||
"androidID": "1000gb_monthly_v4",
|
||||
"iosID": "1000gb_monthly_v4",
|
||||
"stripeID": "1000gb_monthly_v4",
|
||||
"storage": 1073741824000,
|
||||
"price": "$0",
|
||||
"period": "month"
|
||||
},
|
||||
{
|
||||
"id": "2000gb_monthly_v4",
|
||||
"androidID": "2000gb_monthly_v4",
|
||||
"iosID": "2000gb_monthly_v4",
|
||||
"stripeID": "2000gb_monthly_v4",
|
||||
"storage": 2147483648000,
|
||||
"price": "$0",
|
||||
"period": "month"
|
||||
},
|
||||
{
|
||||
"id": "50gb_yearly_v4",
|
||||
"androidID": "50gb_yearly_v4",
|
||||
"iosID": "50gb_yearly_v4",
|
||||
"stripeID": "50gb_yearly_v4",
|
||||
"storage": 53687091200,
|
||||
"price": "$0",
|
||||
"period": "year"
|
||||
},
|
||||
{
|
||||
"id": "200gb_yearly_v4",
|
||||
"androidID": "200gb_yearly_v4",
|
||||
"iosID": "200gb_yearly_v4",
|
||||
"stripeID": "200gb_yearly_v4",
|
||||
"storage": 214748364800,
|
||||
"price": "$0",
|
||||
"period": "year"
|
||||
},
|
||||
{
|
||||
"id": "1000gb_yearly_v4",
|
||||
"androidID": "1000gb_yearly_v4",
|
||||
"iosID": "1000gb_yearly_v4",
|
||||
"stripeID": "1000gb_yearly_v4",
|
||||
"storage": 1073741824000,
|
||||
"price": "$0",
|
||||
"period": "year"
|
||||
},
|
||||
{
|
||||
"id": "2000gb_yearly_v4",
|
||||
"androidID": "2000gb_yearly_v4",
|
||||
"iosID": "2000gb_yearly_v4",
|
||||
"stripeID": "2000gb_yearly_v4",
|
||||
"storage": 2147483648000,
|
||||
"price": "$0",
|
||||
"period": "year"
|
||||
},
|
||||
{
|
||||
"id": "family",
|
||||
"androidID": "family",
|
||||
"iosID": "family",
|
||||
"stripeID": "family",
|
||||
"storage": 2147483648000,
|
||||
"price": "$0",
|
||||
"period": "year"
|
||||
},
|
||||
{
|
||||
"id": "free",
|
||||
"androidID": "free",
|
||||
"iosID": "free",
|
||||
"stripeID": "free",
|
||||
"storage": 10737418240,
|
||||
"price": "$0",
|
||||
"period": "year"
|
||||
}
|
||||
],
|
||||
"EU": [
|
||||
{
|
||||
"id": "50gb_monthly_v4",
|
||||
"androidID": "50gb_monthly_v4",
|
||||
"iosID": "50gb_monthly_v4",
|
||||
"stripeID": "50gb_monthly_v4",
|
||||
"storage": 53687091200,
|
||||
"price": "€0",
|
||||
"period": "month"
|
||||
},
|
||||
{
|
||||
"id": "200gb_monthly_v4",
|
||||
"androidID": "200gb_monthly_v4",
|
||||
"iosID": "200gb_monthly_v4",
|
||||
"stripeID": "200gb_monthly_v4",
|
||||
"storage": 214748364800,
|
||||
"price": "€0",
|
||||
"period": "month"
|
||||
},
|
||||
{
|
||||
"id": "1000gb_monthly_v4",
|
||||
"androidID": "1000gb_monthly_v4",
|
||||
"iosID": "1000gb_monthly_v4",
|
||||
"stripeID": "1000gb_monthly_v4",
|
||||
"storage": 1073741824000,
|
||||
"price": "€0",
|
||||
"period": "month"
|
||||
},
|
||||
{
|
||||
"id": "2000gb_monthly_v4",
|
||||
"androidID": "2000gb_monthly_v4",
|
||||
"iosID": "2000gb_monthly_v4",
|
||||
"stripeID": "2000gb_monthly_v4",
|
||||
"storage": 2147483648000,
|
||||
"price": "€0",
|
||||
"period": "month"
|
||||
},
|
||||
{
|
||||
"id": "50gb_yearly_v4",
|
||||
"androidID": "50gb_yearly_v4",
|
||||
"iosID": "50gb_yearly_v4",
|
||||
"stripeID": "50gb_yearly_v4",
|
||||
"storage": 53687091200,
|
||||
"price": "€0",
|
||||
"period": "year"
|
||||
},
|
||||
{
|
||||
"id": "200gb_yearly_v4",
|
||||
"androidID": "200gb_yearly_v4",
|
||||
"iosID": "200gb_yearly_v4",
|
||||
"stripeID": "200gb_yearly_v4",
|
||||
"storage": 214748364800,
|
||||
"price": "€0",
|
||||
"period": "year"
|
||||
},
|
||||
{
|
||||
"id": "1000gb_yearly_v4",
|
||||
"androidID": "1000gb_yearly_v4",
|
||||
"iosID": "1000gb_yearly_v4",
|
||||
"stripeID": "1000gb_yearly_v4",
|
||||
"storage": 1073741824000,
|
||||
"price": "€0",
|
||||
"period": "year"
|
||||
},
|
||||
{
|
||||
"id": "2000gb_yearly_v4",
|
||||
"androidID": "2000gb_yearly_v4",
|
||||
"iosID": "2000gb_yearly_v4",
|
||||
"stripeID": "2000gb_yearly_v4",
|
||||
"storage": 2147483648000,
|
||||
"price": "€0",
|
||||
"period": "year"
|
||||
},
|
||||
{
|
||||
"id": "family",
|
||||
"androidID": "family",
|
||||
"iosID": "family",
|
||||
"stripeID": "family",
|
||||
"storage": 2147483648000,
|
||||
"price": "€0",
|
||||
"period": "year"
|
||||
},
|
||||
{
|
||||
"id": "free",
|
||||
"androidID": "free",
|
||||
"iosID": "free",
|
||||
"stripeID": "free",
|
||||
"storage": 10737418240,
|
||||
"price": "€0",
|
||||
"period": "year"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
diff --git a/server/pkg/controller/family/admin.go b/server/pkg/controller/family/admin.go
|
||||
index 1b58f6b8..8fd74a99 100644
|
||||
--- a/server/pkg/controller/family/admin.go
|
||||
+++ b/server/pkg/controller/family/admin.go
|
||||
@@
|
||||
- "github.com/ente-io/museum/pkg/utils/auth"
|
||||
- "github.com/ente-io/museum/pkg/utils/billing"
|
||||
+ "github.com/ente-io/museum/pkg/utils/auth"
|
||||
+ "github.com/ente-io/museum/pkg/utils/billing"
|
||||
emailUtil "github.com/ente-io/museum/pkg/utils/email"
|
||||
"github.com/ente-io/stacktrace"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/google/uuid"
|
||||
"github.com/sirupsen/logrus"
|
||||
+ "github.com/spf13/viper"
|
||||
)
|
||||
@@
|
||||
- FamilyPlainHost = "https://family.ente.io"
|
||||
+ defaultFamilyHost = "https://family.ente.io"
|
||||
)
|
||||
+
|
||||
+func familyInviteHost() string {
|
||||
+ host := viper.GetString("apps.family")
|
||||
+ if host != "" {
|
||||
+ return host
|
||||
+ }
|
||||
+ return defaultFamilyHost
|
||||
+}
|
||||
@@
|
||||
- templateData["FamilyInviteLink"] = fmt.Sprintf("%s?inviteToken=%s", FamilyPlainHost, *inviteToken)
|
||||
+ templateData["FamilyInviteLink"] = fmt.Sprintf("%s?inviteToken=%s", familyInviteHost(), *inviteToken)
|
||||
Reference in New Issue
Block a user