7 Commits

Author SHA1 Message Date
Your Name
b7fcf5c01d Add comprehensive API documentation to Cloudron setup instructions
- Added detailed API endpoint information in SETUP-INSTRUCTIONS.md
- Documented API usage with Ente CLI
- Enhanced routing configuration for auth/cast/accounts apps
- Updated to version 0.1.64
2025-07-25 11:02:06 -06:00
Your Name
da50bf4773 Add OTP email monitor to handle Museum skipped emails
- Implement comprehensive OTP email monitoring service
- Monitor Museum logs for "Skipping sending email" pattern
- Send verification emails using Cloudron email addon
- Add specific regex pattern for Museum's skip email format
- Version bump to 0.1.62

The monitor captures OTP codes from logs when Museum skips sending
emails and sends them via Cloudron's email system. This ensures
users receive their verification codes even when Museum's email
configuration is not sending directly.
2025-07-22 12:27:44 -06:00
Your Name
4290a33ba9 Fix JavaScript URL construction error for API endpoint
- Change NEXT_PUBLIC_ENTE_ENDPOINT from "/api" to "https://example.com/api" during build to satisfy URL constructor requirements
- Add runtime replacement in start.sh to replace placeholder with actual domain endpoint
- This resolves the "TypeError: Failed to construct 'URL': Invalid URL" error in the frontend

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-22 08:58:53 -06:00
Your Name
62b6f7f9ac Fix S3 configuration - set are_local_buckets to true
- Changed are_local_buckets from false to true (required for external S3)
- Simplified S3 configuration to only use b2-eu-cen bucket
- Removed unnecessary replication buckets for single bucket setup

This aligns with Ente's documentation where are_local_buckets=true
is used for external S3 services like Wasabi.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-21 20:44:19 -06:00
Your Name
e3eb1b0491 Hardcode Wasabi S3 configuration with proper Ente format
- Remove dynamic S3 configuration loading
- Hardcode Wasabi credentials as requested
- Use proper Ente S3 configuration format with datacenter names
- Configure all three storage buckets (b2-eu-cen, wasabi-eu-central-2-v3, scw-eu-fr-v3)
- Set are_local_buckets to false for external S3
- Add compliance flag for Wasabi bucket

This should fix the MissingRegion error by properly configuring S3 storage
according to Ente's expected format.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-21 20:41:58 -06:00
Your Name
fc82e988e9 Update CloudronManifest version to 1.0.1
Increment version after multiple iterations of S3 configuration fixes and port conflict resolution.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-21 20:37:07 -06:00
Your Name
5068e12025 Fix port conflict between Museum server and Caddy
- Changed Museum server to run on port 8080 instead of 3080
- Updated all health check URLs to use port 8080
- Updated Caddy reverse proxy to forward API requests to port 8080
- Added clarifying comment about port usage

This resolves the circular reference where both Caddy and Museum were trying to use port 3080.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-21 17:18:51 -06:00
11 changed files with 1208 additions and 1291 deletions

View File

@@ -1,34 +1,110 @@
# Ente Cloudron Quick Guide # Ente Cloudron App Build and Installation Instructions
## Build 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.
```bash
git clone https://github.com/andreasdueren/ente-cloudron.git
cd ente-cloudron
cloudron build \ ## Prerequisites
--set-build-service builder.docker.due.ren \
--build-service-token e3265de06b1d0e7bb38400539012a8433a74c2c96a17955e \
--set-repository andreasdueren/ente-cloudron \
--tag 0.4.5
```
## Install - **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.
```bash - **Docker**: Required for local testing or custom builds if needed.
cloudron install \ - **Git**: To clone or manage the repository.
--location ente.due.ren \ - **Repository Access**: Ensure you have access to the Ente Cloudron repository at `andreasdueren/ente-cloudron`.
--image andreasdueren/ente-cloudron:0.4.5 - **Build Service Token**: A token for the Cloudron build service is required (provided in the command below).
```
## After Install ## Build Commands
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.
2. **Subdomains** In the Cloudron *Domains* tab add aliases for `auth.<app-domain>`, `accounts.<app-domain>`, `cast.<app-domain>`, `albums.<app-domain>` and `family.<app-domain>`. Create matching DNS records pointing at the primary domain (for example, if the app is `ente.cloudron.io`, add `auth.ente.cloudron.io`, `accounts.ente.cloudron.io`, etc. → `ente.cloudron.io`).
Once DNS propagates, use the dedicated hosts: 1. **Clone the Repository** (if not already done):
- `https://<app-host>` (the hostname you chose during install, main UI & uploads) ```bash
- `https://accounts.<app-domain>` git clone https://github.com/andreasdueren/ente-cloudron.git
- `https://auth.<app-domain>` cd ente-cloudron
- `https://cast.<app-domain>` ```
- `https://albums.<app-domain>`
- `https://family.<app-domain>`
Check `cloudron logs --app ente.due.ren -f` or `/app/data/logs/startup.log` if anything looks off. 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).

View File

@@ -1,42 +1,9 @@
# Changelog # Changelog
## 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) ## 1.0.0 (2024-06-01)
* Initial release of Ente for Cloudron * Initial release of Ente for Cloudron
* Integrates with PostgreSQL database * Integrates with PostgreSQL database
* Integrates with S3-compatible object storage * Integrates with S3-compatible object storage
* Integrates with Cloudron mail system * Integrates with Cloudron mail system
* Provides web UI for photos and authentication * Provides web UI for photos and authentication

158
CLAUDE.md
View File

@@ -1,158 +0,0 @@
Cloudron Application Packaging System Prompt
You are a Cloudron packaging expert specializing in creating complete, production-ready Cloudron packages. When a user requests packaging an application, follow this comprehensive process:
Core Process
1. Application Research: Research the target application's architecture, dependencies, configuration requirements, and deployment patterns
2. Package Generation: Create all required Cloudron packaging files
3. Documentation: Provide build and deployment instructions
Required Files to Generate
CloudronManifest.json
- Use reverse-domain notation for app ID (e.g., io.example.appname)
- Configure memory limits based on application requirements (minimum 128MB)
- Set httpPort matching NGINX configuration
- Include necessary addons: postgresql, mysql, mongodb, redis, localstorage, sendmail
- Add complete metadata: title, description, author, website, contactEmail
- Configure authentication: oidc (preferred) or ldap
- Include postInstallMessage with login credentials if applicable
- Add health check endpoints
- Set proper minBoxVersion (typically "7.0.0")
Dockerfile
- Base image: FROM cloudron/base:5.0.0
- Cloudron filesystem structure:
- /app/code - application code (read-only)
- /app/data - persistent data (backed up)
- /tmp - temporary files
- /run - runtime files
- Install dependencies and application
- Copy initialization data to /tmp/data
- Set proper permissions and ownership
- Configure services to log to stdout/stderr
- Entry point: CMD ["/app/code/start.sh"]
start.sh
- Initialize /app/data from /tmp/data on first run
- Configure application using Cloudron environment variables
- Handle addon configurations (database connections, etc.)
- Generate secrets/API keys on first run
- Set proper file permissions (chown cloudron:cloudron)
- Run database migrations if needed
- Configure authentication providers
- Launch application with supervisor or directly
NGINX Configuration
- Listen on port specified in CloudronManifest.json
- Handle proxy headers properly:
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $host;
- Configure static file serving
- Set up authentication routes for OIDC callbacks
- Ensure logs go to stdout/stderr
Supervisor Configuration (if needed)
- Multiple process management
- Proper signal handling
- Run processes as cloudron user
- Configure log output to stdout/stderr
Authentication Integration
OIDC (Preferred)
- Environment variables: CLOUDRON_OIDC_IDENTIFIER, CLOUDRON_OIDC_CLIENT_ID, CLOUDRON_OIDC_CLIENT_SECRET
- Callback route: /api/v1/session/callback
- User provisioning and group mapping
- Session management compatible with Cloudron proxy
LDAP (Fallback)
- Environment variables: CLOUDRON_LDAP_SERVER, CLOUDRON_LDAP_PORT, CLOUDRON_LDAP_BIND_DN, CLOUDRON_LDAP_BIND_PASSWORD
- User search base and group mapping
- Proper LDAP query configuration
Cloudron Environment Variables
Always utilize these standard variables:
- CLOUDRON_APP_ORIGIN - Application URL
- CLOUDRON_MAIL_SMTP_* - Email configuration
- Database addon variables (e.g., CLOUDRON_POSTGRESQL_URL)
- CLOUDRON_LDAP_* - LDAP configuration
- CLOUDRON_OIDC_* - OIDC configuration
Best Practices
1. Security: Never expose secrets, use environment variables
2. Persistence: Store data in /app/data, initialize from /tmp/data
3. Updates: Handle schema migrations and configuration updates
4. Logging: All logs to stdout/stderr for Cloudron log aggregation
5. Health Checks: Implement endpoints for monitoring
6. Process Management: Use supervisor for multi-process applications
7. File Permissions: Ensure cloudron user can read/write necessary files
8. Building: use the cloudron build service under builder.docker.due.ren
9. Installation: always uninstall and install fresh, never update an app during development
Build Instructions Format
Create a markdown file with:
- Prerequisites and dependencies
- Build commands (cloudron build, cloudron install)
- Testing procedures
- Deployment steps
- Troubleshooting common issues
- Configuration examples
Documentation References
- Cloudron 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/
Viewing logs
To view the logs of an app, use the logs command:
```cloudron logs --app blog.example.com```
```cloudron logs --app 52aae895-5b7d-4625-8d4c-52980248ac21```
Pass the -f to follow the logs. Note that not all apps log to stdout/stderr. For this reason, you may need to look further in the file system for logs:
```cloudron exec --app blog.example.com # shell into the app's file system```
``# tail -f /run/wordpress/wp-debug.log # note that log file path and name is specific to the app```
When packaging an application, research thoroughly, create production-ready configurations, and provide comprehensive documentation for successful deployment.
Always Build with the build service (switch out name and version) build with cloudron build --set-build-service builder.docker.due.ren --build-service-token
e3265de06b1d0e7bb38400539012a8433a74c2c96a17955e --set-repository andreasdueren/ente-cloudron --tag 0.1.0
cloudron install --location ente.due.ren --image andreasdueren/ente-cloudron:0.1.0
After install and build, dont wait more than 30 seconds for feedback. When there is an error during install, this will not finish and you will wait forever.
Remember all of this crucial information throughout the packaging process. Create a file for persistency if necessary to poll from later. Fix this packaging of ente for cloudron:
https://github.com/ente-io/ente/tree/main
There is documentation about self-hosting here: https://github.com/ente-io/ente/tree/main/docs/docs/self-hosting and here https://github.com/ente-io/ente/tree/main/server
Use Caddy as a reverse proxy. More info on setting it up: https://help.ente.io/self-hosting/reverse-proxy
Set up all web-apps (public-albums, cast, accounts, family). Use a path (/albums, /cast…) and not sub domains.: https://help.ente.io/self-hosting/museum
Stick to the original maintainers setup as close as possible while adhering to cordons restricti0ns. Use cloudrons postgresql as a database and an external s3 instance for object storage. You can use the following credentials for development but never commit these to any repository:
primary-storage:
key: "bbdfcc78c3d8aa970498fc309f1e5876" # Your S3 access key
secret: "4969ba66f326b4b7af7ca69716ee4a16931725a351a93643efce6447f81c9d68" # Your S3 secret key
endpoint: "40db7844966a4e896ccfac20ac9e7fb5.r2.cloudflarestorage.com" # S3 endpoint URL
region: "wnam" # S3 region (e.g. us-east-1)
bucket: "ente-due-ren" # Your bucket name
Here are the instructions as to how to use an external s3: https://help.ente.io/self-hosting/guides/external-s3

View File

@@ -1,42 +1,38 @@
{ {
"id": "io.ente.cloudronapp", "id": "io.ente.cloudronapp",
"title": "Ente", "title": "Ente",
"author": "Ente Development Team", "author": "Ente Authors",
"description": "file://DESCRIPTION.md", "description": "file://DESCRIPTION.md",
"changelog": "file://CHANGELOG.md", "changelog": "file://CHANGELOG.md",
"contactEmail": "contact@ente.io", "contactEmail": "contact@ente.io",
"website": "https://ente.io", "tagline": "Open Source End-to-End Encrypted Photos & Authentication",
"tagline": "Open source, end-to-end encrypted photo backup", "upstreamVersion": "1.0.0",
"version": "0.4.5", "version": "0.1.64",
"upstreamVersion": "git-main", "healthCheckPath": "/ping",
"healthCheckPath": "/health",
"httpPort": 3080, "httpPort": 3080,
"memoryLimit": 1610612736, "memoryLimit": 1073741824,
"postInstallMessage": "file://POSTINSTALL.md",
"multiDomain": true,
"addons": { "addons": {
"localstorage": {}, "localstorage": {},
"postgresql": {}, "postgresql": {},
"email": {},
"sendmail": { "sendmail": {
"supportsDisplayName": true, "supportsDisplayName": true
"requiresValidCertificate": true
} }
}, },
"checklist": { "checklist": {
"configure-object-storage": { "create-permanent-admin": {
"message": "Configure your S3-compatible storage in /app/data/config/s3.env before first use." "message": "Required: S3 Storage Configuration!"
},
"configure-subdomains": {
"message": "Create DNS records and add Cloudron aliases for accounts., auth., cast., albums. and family. (using the base domain of this app)."
} }
}, },
"icon": "file://logo.png", "icon": "file://logo.png",
"tags": [ "tags": [
"photos", "photos",
"encryption", "authentication",
"backup", "e2ee",
"self-hosting" "encryption"
], ],
"manifestVersion": 2, "manifestVersion": 2,
"minBoxVersion": "8.1.0" "minBoxVersion": "8.1.0",
} "website": "https://ente.io"
}

View File

@@ -1,114 +1,177 @@
# syntax=docker/dockerfile:1 # Build Museum server from source
ARG ENTE_GIT_REF=main
FROM debian:bookworm AS ente-source
ARG ENTE_GIT_REF
RUN apt-get update && \
apt-get install -y --no-install-recommends ca-certificates git && \
git clone --depth=1 --branch "${ENTE_GIT_REF}" https://github.com/ente-io/ente.git /src && \
rm -rf /var/lib/apt/lists/*
FROM golang:1.24-bookworm AS museum-builder FROM golang:1.24-bookworm AS museum-builder
COPY --from=ente-source /src /ente
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
WORKDIR /ente/server WORKDIR /ente/server
RUN apt-get update && \ RUN go mod download && \
apt-get install -y --no-install-recommends build-essential pkg-config libsodium-dev && \ CGO_ENABLED=1 GOOS=linux go build -a -o museum ./cmd/museum
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 \
mkdir -p "/build/museum/$dir"; \
fi; \
done
FROM golang:1.24-bookworm AS cli-builder FROM node:20-bookworm-slim as web-builder
COPY --from=ente-source /src /ente
WORKDIR /ente/cli
RUN go build -o /build/ente .
FROM node:20-bookworm-slim AS web-builder WORKDIR /ente
ENV NEXT_PUBLIC_ENTE_ENDPOINT=ENTE_API_ORIGIN_PLACEHOLDER
ENV NEXT_PUBLIC_ENTE_ALBUMS_ENDPOINT=https://albums.localhost.invalid # Clone the repository for web app building
COPY --from=ente-source /src /ente RUN apt-get update && apt-get install -y git && \
WORKDIR /ente/web git clone --depth=1 https://github.com/ente-io/ente.git . && \
RUN apt-get update && \ apt-get clean && apt-get autoremove && \
apt-get install -y --no-install-recommends build-essential python3 && \ rm -rf /var/cache/apt /var/lib/apt/lists
rm -rf /var/lib/apt/lists/*
# Will help default to yarn version 1.22.22
RUN corepack enable 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 # Set environment variables for web app build
RUN set -e; \ # Set the API endpoint to use current origin - this will work at runtime
yarn build:photos; \ ENV NEXT_PUBLIC_ENTE_ENDPOINT="/api"
yarn build:accounts; \ # Use relative path so it works with any domain
yarn build:auth; \ RUN echo "Building with NEXT_PUBLIC_ENTE_ENDPOINT=/api, will work with any domain via Caddy proxy"
yarn build:cast
RUN if [ -d "apps" ]; then \ # Debugging the repository structure
for app in photos accounts auth cast; do \ RUN find . -type d -maxdepth 3 | sort
if [ -d "apps/${app}/out" ]; then \
rm -rf "/build/web/${app}"; \ # Check if web directory exists with apps subdirectory
mkdir -p "/build/web/${app}"; \ RUN mkdir -p /build/web/photos /build/web/accounts /build/web/auth /build/web/cast && \
cp -r "apps/${app}/out/." "/build/web/${app}/"; \ if [ -d "web" ] && [ -d "web/apps" ]; then \
else \ echo "Found web/apps directory, building web apps"; \
printf 'Missing build output for %s\n' "${app}"; \ cd web && \
printf '<html><body><h1>Ente %s</h1><p>Build output missing.</p></body></html>\n' "${app}" > "/build/web/${app}/index.html"; \ 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; \ fi; \
done; \
else \ else \
for app in photos accounts auth cast; do \ echo "Web directory not found, creating placeholder web pages"; \
printf '<html><body><h1>Ente %s</h1><p>Build output missing.</p></body></html>\n' "${app}" > "/build/web/${app}/index.html"; \ # Create placeholder HTML files for each app \
done; \ mkdir -p /build/web/photos /build/web/accounts /build/web/auth /build/web/cast; \
fi && \ 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; \
rm -rf /build/web/albums /build/web/family && \ 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; \
cp -r /build/web/photos /build/web/albums && \ 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; \
cp -r /build/web/photos /build/web/family 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
FROM cloudron/base:5.0.0@sha256:04fd70dbd8ad6149c19de39e35718e024417c3e01dc9c6637eaf4a41ec4e596c FROM cloudron/base:5.0.0@sha256:04fd70dbd8ad6149c19de39e35718e024417c3e01dc9c6637eaf4a41ec4e596c
ENV APP_DIR=/app/code \ # Install necessary packages and Caddy webserver
DATA_DIR=/app/data \
HOME=/app/data/home
RUN apt-get update && \ RUN apt-get update && \
apt-get install -y --no-install-recommends ca-certificates curl jq libsodium23 pkg-config postgresql-client caddy openssl && \ apt-get install -y curl git nodejs npm libsodium23 libsodium-dev pkg-config postgresql-client && \
rm -rf /var/lib/apt/lists/* 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
RUN mkdir -p /app/pkg /app/web "$HOME" && chown -R cloudron:cloudron /app /app/web "$HOME" # 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
COPY --from=ente-source /src ${APP_DIR} # Set up directory structure
RUN rm -rf ${APP_DIR}/.git RUN mkdir -p /app/code /app/data/config /app/data/caddy /app/web
RUN mkdir -p /app/museum-bin WORKDIR /app/code
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
COPY --from=cli-builder /build/ente /app/code/ente # Clone the ente repository during build (for the Museum server)
RUN ln -sf /app/code/ente /usr/local/bin/ente && chmod +x /app/code/ente RUN git clone --depth=1 https://github.com/ente-io/ente.git . && \
sed -i 's/go 1.23/go 1.24.1/' 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
# 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"
# 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/photos /app/web/photos
COPY --from=web-builder /build/web/accounts /app/web/accounts 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/auth /app/web/auth
COPY --from=web-builder /build/web/cast /app/web/cast COPY --from=web-builder /build/web/cast /app/web/cast
COPY --from=web-builder /build/web/albums /app/web/albums
COPY --from=web-builder /build/web/family /app/web/family
COPY start.sh /app/pkg/start.sh # Copy Museum server binary from builder stage to app directory (not data volume)
COPY admin-helper.sh /app/pkg/admin-helper.sh RUN mkdir -p /app/museum-bin
COPY admin-helper-direct.sh /app/pkg/admin-helper-direct.sh 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 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 3080 8080 # Expose the web port (Cloudron expects port 3080)
EXPOSE 3080
# Also expose API port
EXPOSE 8080
CMD ["/app/pkg/start.sh"] # Start the application
CMD ["/app/pkg/start.sh"]

View File

@@ -1,52 +1,25 @@
Your Ente installation is almost ready! Your Ente installation is almost ready!
## Required: External Object Storage ## Required: S3 Storage Configuration
Before using Ente, configure an S3-compatible object storage provider: Before you can use Ente, you need to configure an S3-compatible storage service:
1. Open the Cloudron dashboard and select your Ente app. 1. Go to your Cloudron dashboard
2. Launch the web terminal. 2. Click on your Ente app
3. Edit `/app/data/config/s3.env` and provide values for **all** required keys: 3. Click on "Terminal"
```bash 4. Edit the S3 configuration template:
nano /app/data/config/s3.env
``` ```
4. Save the file and restart the app from the Cloudron dashboard. nano /app/data/config/s3.env.template
```
5. Fill in your S3 credentials (AWS S3, MinIO, DigitalOcean Spaces, etc.)
6. Save the file and rename it:
```
mv /app/data/config/s3.env.template /app/data/config/s3.env
```
7. Restart your Ente app from the Cloudron dashboard
Supported variables: ## Next Steps
- `S3_ENDPOINT` (e.g. `https://<account>.r2.cloudflarestorage.com`)
- `S3_REGION`
- `S3_BUCKET`
- `S3_ACCESS_KEY`
- `S3_SECRET_KEY`
- `S3_PREFIX` (optional path prefix)
## Required: DNS Subdomains 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)
Ente now serves supporting apps on dedicated hosts. Create DNS records (CNAME or A) and add matching alias domains in Cloudron for: 3. Enjoy your private, end-to-end encrypted photo storage!
- `auth.<app-domain>`
- `accounts.<app-domain>`
- `cast.<app-domain>`
- `albums.<app-domain>`
- `family.<app-domain>`
For example, if you installed the app at `ente.cloudron.io`, create records for `auth.ente.cloudron.io`, `accounts.ente.cloudron.io`, etc., all pointing to `ente.cloudron.io`, then add each hostname as an alias in the Cloudron dashboard.
## Administration
- Use the bundled CLI from the Cloudron web terminal (CLI state lives in `/app/data/cli-data`):
```bash
cloudron exec --app ente.cloudron.io -- sudo -u cloudron ente --help
# Whitelist an administrator
cloudron exec --app ente.cloudron.io -- sudo -u cloudron ente admin user whitelist --email admin@example.com
# Increase a users storage allocation (in GB)
cloudron exec --app ente.cloudron.io -- sudo -u cloudron ente admin user quota set --email user@example.com --storage-gb 500
```
See the upstream admin guides for further context: [user administration](https://ente.io/help/self-hosting/administration/users) and [CLI reference](https://ente.io/help/self-hosting/administration/cli).
Logs are streamed to the Cloudron dashboard. For deeper inspection use:
```bash
cloudron logs --app <location> -f
```

View File

@@ -9,6 +9,28 @@ This repository contains the Cloudron packaging for [Ente](https://ente.io), an
- Configured to use Cloudron's mail service for sending emails - Configured to use Cloudron's mail service for sending emails
- Easy to deploy and manage through the Cloudron interface - 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 ## Building and Installing
### Option 1: Build and Install Manually ### Option 1: Build and Install Manually
@@ -51,28 +73,23 @@ The app is configured automatically using Cloudron's environment variables for:
- SMTP mail service - SMTP mail service
- App origin URL - App origin URL
### Cloudron Admin Notes ### Additional Configuration
After installing on Cloudron remember to: The package includes several enhancements to ensure proper functionality:
1. Open the File Manager for the app, edit `/app/data/config/s3.env` with your object storage endpoint/keys, and restart the app. 1. **Security Headers**: Custom Content-Security-Policy headers that allow WebAssembly and IndexedDB
2. Add alias domains for `auth.<app-domain>`, `accounts.<app-domain>`, `cast.<app-domain>`, `albums.<app-domain>` and `family.<app-domain>` in the Cloudron **Domains** tab. Create matching DNS records pointing to the primary hostname (for example, if you installed at `ente.cloudron.io`, add `auth.ente.cloudron.io`, `accounts.ente.cloudron.io`, etc.). 2. **API Configuration**: Dynamic runtime configuration to ensure the frontend connects to the correct API endpoint
3. Use the bundled Ente CLI for admin tasks via `cloudron exec --app <location> -- sudo -u cloudron ente --help`. The CLI stores its state in `/app/data/cli-data` (exposed inside the container at `/cli-data`) and already trusts your apps API endpoint. Typical workflows: 3. **CORS Headers**: Proper CORS configuration for API access
```bash
# Whitelist an administrator (see https://ente.io/help/self-hosting/administration/users )
cloudron exec --app ente.cloudron.io -- sudo -u cloudron ente admin user whitelist --email admin@example.com
# Increase a users storage quota (see https://ente.io/help/self-hosting/administration/cli ) You need to manually set up and configure:
cloudron exec --app ente.cloudron.io -- sudo -u cloudron ente admin user quota set --email user@example.com --storage-gb 500
```
The main photos UI continues to live on the hostname you selected during installation. - S3-compatible object storage
## Usage ## Usage
### Web Client ### Web Client
After installation, you can access the Ente web client at your app's URL. Create the first user and whitelist them as an administrator using the CLI if desired. After installation, you can access the Ente web client at your app's URL. Create an admin account on first use.
### Mobile Apps ### Mobile Apps
@@ -90,6 +107,18 @@ To update to a newer version:
cloudron update --app ente.yourdomain.com 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 ## License
This Cloudron package is licensed under the same license as Ente (Apache 2.0). This Cloudron package is licensed under the same license as Ente (Apache 2.0).

View File

@@ -2,7 +2,7 @@
# Ente Admin Helper Script for Cloudron # Ente Admin Helper Script for Cloudron
# This script simplifies admin operations in the Cloudron terminal # This script simplifies admin operations in the Cloudron terminal
MUSEUM_BIN="/app/museum-bin/museum" MUSEUM_BIN="/app/data/ente/server/museum"
# Check if museum binary exists # Check if museum binary exists
if [ ! -f "$MUSEUM_BIN" ]; then if [ ! -f "$MUSEUM_BIN" ]; then
@@ -26,15 +26,15 @@ update_subscription() {
echo "Storage: ${storage_gb}GB" echo "Storage: ${storage_gb}GB"
echo "Valid for: ${valid_days} days" echo "Valid for: ${valid_days} days"
cd /app/data/museum cd /app/data/ente/server
# Use environment variables for database connection # Use environment variables for database connection
export DB_HOST="$CLOUDRON_POSTGRESQL_HOST" export DB_HOST="$CLOUDRON_POSTGRESQL_HOST"
export DB_PORT="$CLOUDRON_POSTGRESQL_PORT" export DB_PORT="$CLOUDRON_POSTGRESQL_PORT"
export DB_NAME="$CLOUDRON_POSTGRESQL_DATABASE" export DB_NAME="$CLOUDRON_POSTGRESQL_DATABASE"
export DB_USERNAME="$CLOUDRON_POSTGRESQL_USERNAME" export DB_USERNAME="$CLOUDRON_POSTGRESQL_USERNAME"
export DB_PASSWORD="$CLOUDRON_POSTGRESQL_PASSWORD" export DB_PASSWORD="$CLOUDRON_POSTGRESQL_PASSWORD"
# Museum admin commands need specific syntax # Museum admin commands need specific syntax
"$MUSEUM_BIN" admin update-subscription "$user_email" "$storage_gb" "$valid_days" "$MUSEUM_BIN" admin update-subscription "$user_email" "$storage_gb" "$valid_days"
} }
@@ -48,15 +48,15 @@ get_user_details() {
return 1 return 1
fi fi
cd /app/data/museum cd /app/data/ente/server
"$MUSEUM_BIN" admin get-user-details --user "$user_email" "$MUSEUM_BIN" admin get-user-details --user "$user_email"
} }
# Function to list all users # Function to list all users
list_users() { list_users() {
cd /app/data/museum cd /app/data/ente/server
# Connect to PostgreSQL and list users # Connect to PostgreSQL and list users
PGPASSWORD="$CLOUDRON_POSTGRESQL_PASSWORD" psql \ PGPASSWORD="$CLOUDRON_POSTGRESQL_PASSWORD" psql \
-h "$CLOUDRON_POSTGRESQL_HOST" \ -h "$CLOUDRON_POSTGRESQL_HOST" \

View File

@@ -18,20 +18,16 @@ database:
maxIdleConns: 25 maxIdleConns: 25
connMaxLifetime: "1h" connMaxLifetime: "1h"
s3: storage:
are_local_buckets: false type: "s3"
use_path_style_urls: true s3:
hot_storage:
primary: b2-eu-cen
secondary: b2-eu-cen
derived-storage: b2-eu-cen
b2-eu-cen:
endpoint: "%%S3_ENDPOINT%%" endpoint: "%%S3_ENDPOINT%%"
region: "%%S3_REGION%%" region: "%%S3_REGION%%"
bucket: "%%S3_BUCKET%%" bucket: "%%S3_BUCKET%%"
key: "%%S3_ACCESS_KEY%%" accessKey: "%%S3_ACCESS_KEY%%"
secret: "%%S3_SECRET_KEY%%" secretKey: "%%S3_SECRET_KEY%%"
path_prefix: "%%S3_PREFIX%%" prefix: "%%S3_PREFIX%%"
forcePathStyle: true
email: email:
smtp: smtp:
@@ -52,19 +48,19 @@ auth:
logging: logging:
level: "info" level: "info"
format: "text" format: "text"
# Additional settings based on Museum requirements # Additional settings based on Museum requirements
keygen: keygen:
master: "%%MASTER_KEY%%" master: "%%MASTER_KEY%%"
payments: payments:
enabled: false enabled: false
metadata: metadata:
localPath: "/app/data/storage/metadata" localPath: "/app/data/storage/metadata"
tempDirectory: "/app/data/storage/temp" tempDirectory: "/app/data/storage/temp"
memoryCache: memoryCache:
enabled: true enabled: true
size: 100 size: 100

View File

@@ -1,38 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>Debug Ente Auth Network Calls</title>
</head>
<body>
<h1>Debug Ente Auth Network Calls</h1>
<div id="output"></div>
<script>
// Override fetch to log all network requests
const originalFetch = window.fetch;
window.fetch = function(...args) {
console.log('FETCH REQUEST:', args[0], args[1]);
const output = document.getElementById('output');
output.innerHTML += '<p>FETCH: ' + args[0] + '</p>';
return originalFetch.apply(this, args)
.then(response => {
console.log('FETCH RESPONSE:', response.status, response.url);
output.innerHTML += '<p>RESPONSE: ' + response.status + ' ' + response.url + '</p>';
return response;
})
.catch(error => {
console.log('FETCH ERROR:', error);
output.innerHTML += '<p>ERROR: ' + error.message + '</p>';
throw error;
});
};
// Load the Ente Auth app in an iframe to see what happens
const iframe = document.createElement('iframe');
iframe.src = 'https://ente.due.ren/auth/';
iframe.style.width = '100%';
iframe.style.height = '400px';
document.body.appendChild(iframe);
</script>
</body>
</html>

1695
start.sh Executable file → Normal file

File diff suppressed because it is too large Load Diff