Update Cloudron app configuration and setup
This commit is contained in:
parent
05a0b42b8e
commit
65e88f4408
@ -8,8 +8,8 @@
|
|||||||
"tagline": "Open Source End-to-End Encrypted Photos & Authentication",
|
"tagline": "Open Source End-to-End Encrypted Photos & Authentication",
|
||||||
"upstreamVersion": "1.0.0",
|
"upstreamVersion": "1.0.0",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"healthCheckPath": "/",
|
"healthCheckPath": "/healthcheck",
|
||||||
"httpPort": 8080,
|
"httpPort": 3080,
|
||||||
"memoryLimit": 1073741824,
|
"memoryLimit": 1073741824,
|
||||||
"addons": {
|
"addons": {
|
||||||
"localstorage": {},
|
"localstorage": {},
|
||||||
@ -18,6 +18,12 @@
|
|||||||
"supportsDisplayName": true
|
"supportsDisplayName": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"checklist": {
|
||||||
|
"create-permanent-admin": {
|
||||||
|
"message": "Required: S3 Storage Configuration!"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
"icon": "file://logo.png",
|
"icon": "file://logo.png",
|
||||||
"tags": [
|
"tags": [
|
||||||
"photos",
|
"photos",
|
||||||
|
29
Dockerfile
29
Dockerfile
@ -12,8 +12,10 @@ RUN apt-get update && apt-get install -y git && \
|
|||||||
RUN corepack enable
|
RUN corepack enable
|
||||||
|
|
||||||
# Set environment variables for web app build
|
# Set environment variables for web app build
|
||||||
# Will be overridden at runtime with the actual server endpoint
|
# Use "/api" as the endpoint which will be replaced at runtime with the full URL
|
||||||
ENV NEXT_PUBLIC_ENTE_ENDPOINT="https://localhost:8080"
|
ENV NEXT_PUBLIC_ENTE_ENDPOINT="/api"
|
||||||
|
# Add a note for clarity
|
||||||
|
RUN echo "Building with NEXT_PUBLIC_ENTE_ENDPOINT=/api, will be replaced at runtime with full URL"
|
||||||
|
|
||||||
# Debugging the repository structure
|
# Debugging the repository structure
|
||||||
RUN find . -type d -maxdepth 3 | sort
|
RUN find . -type d -maxdepth 3 | sort
|
||||||
@ -78,8 +80,14 @@ FROM cloudron/base:5.0.0@sha256:04fd70dbd8ad6149c19de39e35718e024417c3e01dc9c663
|
|||||||
|
|
||||||
# Install necessary packages (excluding golang as we'll install it manually)
|
# Install necessary packages (excluding golang as we'll install it manually)
|
||||||
RUN apt-get update && \
|
RUN apt-get update && \
|
||||||
apt-get install -y curl git nodejs npm libsodium23 libsodium-dev pkg-config nginx && \
|
apt-get install -y curl git nodejs npm libsodium23 libsodium-dev pkg-config postgresql-client && \
|
||||||
npm install -g yarn serve && \
|
npm install -g yarn serve && \
|
||||||
|
# Install Caddy instead of NGINX
|
||||||
|
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 && \
|
apt-get clean && apt-get autoremove && \
|
||||||
rm -rf /var/cache/apt /var/lib/apt/lists
|
rm -rf /var/cache/apt /var/lib/apt/lists
|
||||||
|
|
||||||
@ -103,6 +111,17 @@ RUN git clone --depth=1 https://github.com/ente-io/ente.git . && \
|
|||||||
cp -r server/go.mod server/go.sum /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
|
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
|
# Set Go environment variables
|
||||||
ENV GOTOOLCHAIN=local
|
ENV GOTOOLCHAIN=local
|
||||||
ENV GO111MODULE=on
|
ENV GO111MODULE=on
|
||||||
@ -127,8 +146,8 @@ RUN chmod +x /app/pkg/start.sh
|
|||||||
# Create NGINX directories
|
# Create NGINX directories
|
||||||
RUN mkdir -p /etc/nginx/sites-available /etc/nginx/sites-enabled
|
RUN mkdir -p /etc/nginx/sites-available /etc/nginx/sites-enabled
|
||||||
|
|
||||||
# Expose the web port (Cloudron expects port 8080)
|
# Expose the web port (Cloudron expects port 3080 now)
|
||||||
EXPOSE 8080
|
EXPOSE 3080
|
||||||
|
|
||||||
# Start the application
|
# Start the application
|
||||||
CMD ["/app/pkg/start.sh"]
|
CMD ["/app/pkg/start.sh"]
|
36
README.md
36
README.md
@ -10,6 +10,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
|
||||||
@ -53,6 +75,14 @@ The app is configured automatically using Cloudron's environment variables for:
|
|||||||
- SMTP mail service
|
- SMTP mail service
|
||||||
- App origin URL
|
- App origin URL
|
||||||
|
|
||||||
|
### Additional Configuration
|
||||||
|
|
||||||
|
The package includes several enhancements to ensure proper functionality:
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
### Web Client
|
### Web Client
|
||||||
@ -77,6 +107,12 @@ cloudron update --app ente.yourdomain.com
|
|||||||
|
|
||||||
## Troubleshooting
|
## 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 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).
|
For issues with Ente itself, please refer to the [main Ente repository](https://github.com/ente-io/ente).
|
||||||
|
373
start.sh
373
start.sh
@ -1,14 +1,14 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
# Better signal handling - forward signals to child processes
|
# Better signal handling - forward signals to child processes
|
||||||
trap 'kill -TERM $SERVER_PID; kill -TERM $NGINX_PID; exit' TERM INT
|
trap 'kill -TERM $SERVER_PID; kill -TERM $CADDY_PID; exit' TERM INT
|
||||||
|
|
||||||
set -eu
|
set -eu
|
||||||
|
|
||||||
echo "==> Starting Ente Cloudron app..."
|
echo "==> Starting Ente Cloudron app..."
|
||||||
|
|
||||||
# Create necessary directories
|
# Create necessary directories
|
||||||
mkdir -p /app/data/config /app/data/storage /app/data/nginx/tmp /app/data/go /app/data/logs /run/nginx
|
mkdir -p /app/data/config /app/data/storage /app/data/caddy /app/data/go /app/data/logs
|
||||||
|
|
||||||
# Add comment about Cloudron filesystem limitations
|
# Add comment about Cloudron filesystem limitations
|
||||||
echo "==> NOTE: Running in Cloudron environment with limited write access"
|
echo "==> NOTE: Running in Cloudron environment with limited write access"
|
||||||
@ -164,82 +164,135 @@ sed -i 's|s3.are_local_buckets: true|s3.are_local_buckets: false|g' /app/data/co
|
|||||||
|
|
||||||
# Install or verify required packages
|
# Install or verify required packages
|
||||||
echo "==> Checking for required packages"
|
echo "==> Checking for required packages"
|
||||||
if ! command -v nginx &> /dev/null; then
|
if ! command -v caddy &> /dev/null; then
|
||||||
echo "==> Installing NGINX"
|
echo "==> Installing Caddy"
|
||||||
apt-get update && apt-get install -y nginx
|
apt-get update && 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
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Set up NGINX to serve the web apps and proxy to the Museum server
|
# Set up Caddy to serve the web apps and proxy to the Museum server
|
||||||
echo "==> Setting up NGINX for web apps and API"
|
echo "==> Setting up Caddy for web apps and API"
|
||||||
|
|
||||||
# Create a custom NGINX configuration in the writable data directory
|
# Create a custom Caddy configuration in the writable data directory
|
||||||
cat > /app/data/nginx/ente.conf <<EOT
|
mkdir -p /app/data/caddy
|
||||||
worker_processes 1;
|
cat > /app/data/caddy/Caddyfile <<EOT
|
||||||
error_log stderr;
|
{
|
||||||
daemon off;
|
admin off
|
||||||
pid /app/data/nginx/nginx.pid;
|
auto_https off
|
||||||
|
log {
|
||||||
events {
|
output file /app/data/caddy/caddy.log
|
||||||
worker_connections 1024;
|
format console
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
http {
|
:3080 {
|
||||||
include /etc/nginx/mime.types;
|
log {
|
||||||
default_type application/octet-stream;
|
output file /app/data/caddy/access.log
|
||||||
access_log /dev/stdout combined;
|
format console
|
||||||
sendfile on;
|
}
|
||||||
keepalive_timeout 65;
|
|
||||||
|
|
||||||
# Define temp file paths
|
# Add security headers to enable WebAssembly and IndexedDB
|
||||||
client_body_temp_path /app/data/nginx/tmp;
|
header {
|
||||||
proxy_temp_path /app/data/nginx/tmp;
|
# Security headers
|
||||||
fastcgi_temp_path /app/data/nginx/tmp;
|
Strict-Transport-Security "max-age=31536000; includeSubDomains"
|
||||||
uwsgi_temp_path /app/data/nginx/tmp;
|
X-Content-Type-Options "nosniff"
|
||||||
scgi_temp_path /app/data/nginx/tmp;
|
X-Frame-Options "SAMEORIGIN"
|
||||||
|
Referrer-Policy "strict-origin-when-cross-origin"
|
||||||
|
|
||||||
server {
|
# Content Security Policy that allows WebAssembly
|
||||||
listen 8080;
|
Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' 'wasm-unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self' data:; connect-src 'self' ${CLOUDRON_APP_ORIGIN} https://*.${CLOUDRON_APP_DOMAIN}; worker-src 'self' blob:;"
|
||||||
|
|
||||||
|
# CORS headers for API access
|
||||||
|
Access-Control-Allow-Origin "*"
|
||||||
|
Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS"
|
||||||
|
Access-Control-Allow-Headers "Content-Type, Authorization"
|
||||||
|
Access-Control-Allow-Credentials "true"
|
||||||
|
}
|
||||||
|
|
||||||
|
# For debugging - public access to the config.js
|
||||||
|
handle /debug/config.js {
|
||||||
|
root * /app/data/caddy/public
|
||||||
|
file_server
|
||||||
|
}
|
||||||
|
|
||||||
|
# Create a special handler for index.html files to inject our config
|
||||||
|
@indexhtml {
|
||||||
|
path_regexp index .*\/index\.html$
|
||||||
|
}
|
||||||
|
|
||||||
|
# Handle the direct window variable configuration better
|
||||||
|
handle @indexhtml {
|
||||||
|
# Inject a non-defer, early-loading script that defines ENTE_CONFIG
|
||||||
|
respond_early_hints {
|
||||||
|
link "</config.js>; rel=preload; as=script"
|
||||||
|
}
|
||||||
|
header Content-Type "text/html; charset=utf-8"
|
||||||
|
replace_response_headers Content-Length ""
|
||||||
|
rewrite_early * {
|
||||||
|
# This injects the script into the head section of any index.html
|
||||||
|
r </head> <script>window.ENTE_CONFIG = { API_URL: "${CLOUDRON_APP_ORIGIN}/api" };</script></head>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Configuration available via JavaScript
|
||||||
|
handle /config.js {
|
||||||
|
header Content-Type "application/javascript"
|
||||||
|
respond "window.ENTE_CONFIG = { API_URL: '${CLOUDRON_APP_ORIGIN}/api' }; console.log('Ente config loaded with API_URL:', window.ENTE_CONFIG.API_URL);"
|
||||||
|
}
|
||||||
|
|
||||||
# Photos app - root path
|
# Photos app - root path
|
||||||
location / {
|
handle /photos* {
|
||||||
root /app/web/photos;
|
uri strip_prefix /photos
|
||||||
try_files \$uri \$uri/ /index.html;
|
root * /app/web/photos
|
||||||
|
try_files {path} /index.html
|
||||||
|
file_server
|
||||||
}
|
}
|
||||||
|
|
||||||
# Accounts app
|
# Accounts app
|
||||||
location /accounts/ {
|
handle /accounts/* {
|
||||||
alias /app/web/accounts/;
|
uri strip_prefix /accounts
|
||||||
try_files \$uri \$uri/ /accounts/index.html;
|
root * /app/web/accounts
|
||||||
|
try_files {path} /index.html
|
||||||
|
file_server
|
||||||
}
|
}
|
||||||
|
|
||||||
# Auth app
|
# Auth app
|
||||||
location /auth/ {
|
handle /auth/* {
|
||||||
alias /app/web/auth/;
|
uri strip_prefix /auth
|
||||||
try_files \$uri \$uri/ /auth/index.html;
|
root * /app/web/auth
|
||||||
|
try_files {path} /index.html
|
||||||
|
file_server
|
||||||
}
|
}
|
||||||
|
|
||||||
# Cast app
|
# Cast app
|
||||||
location /cast/ {
|
handle /cast/* {
|
||||||
alias /app/web/cast/;
|
uri strip_prefix /cast
|
||||||
try_files \$uri \$uri/ /cast/index.html;
|
root * /app/web/cast
|
||||||
|
try_files {path} /index.html
|
||||||
|
file_server
|
||||||
}
|
}
|
||||||
|
|
||||||
# API endpoints - proxy to Museum server
|
# API endpoints - proxy to Museum server
|
||||||
location /api/ {
|
handle /api/* {
|
||||||
proxy_pass http://localhost:8000;
|
reverse_proxy localhost:8080
|
||||||
proxy_http_version 1.1;
|
|
||||||
proxy_set_header Upgrade \$http_upgrade;
|
|
||||||
proxy_set_header Connection 'upgrade';
|
|
||||||
proxy_set_header Host \$host;
|
|
||||||
proxy_cache_bypass \$http_upgrade;
|
|
||||||
access_log /dev/stdout;
|
|
||||||
error_log /dev/stderr debug;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Health check endpoint for Cloudron
|
||||||
|
handle /healthcheck {
|
||||||
|
respond "OK" 200
|
||||||
|
}
|
||||||
|
|
||||||
|
# Default to photos app
|
||||||
|
handle {
|
||||||
|
root * /app/web/photos
|
||||||
|
try_files {path} /index.html
|
||||||
|
file_server
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
EOT
|
EOT
|
||||||
|
echo "==> Caddy configuration created at /app/data/caddy/Caddyfile"
|
||||||
echo "==> Custom NGINX configuration created at /app/data/nginx/ente.conf"
|
|
||||||
|
|
||||||
# Looking for Museum (Go server component)
|
# Looking for Museum (Go server component)
|
||||||
echo "==> Looking for Museum (Go server component)"
|
echo "==> Looking for Museum (Go server component)"
|
||||||
@ -363,21 +416,60 @@ if [ ! -f "/app/data/go/go.mod" ] && [ -f "$SERVER_DIR/go.mod" ]; then
|
|||||||
chmod 666 /app/data/go/go.mod /app/data/go/go.sum || echo "==> Warning: Could not set permissions"
|
chmod 666 /app/data/go/go.mod /app/data/go/go.sum || echo "==> Warning: Could not set permissions"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Create proper directories with correct permissions
|
||||||
|
mkdir -p /app/data/go/cache /app/data/go/pkg/mod /app/data/go/bin
|
||||||
|
chmod -R 777 /app/data/go
|
||||||
|
chown -R cloudron:cloudron /app/data/go
|
||||||
|
|
||||||
# Override version requirements and force module mode
|
# Override version requirements and force module mode
|
||||||
export GOFLAGS="-modfile=/app/data/go/go.mod -mod=mod -modcacherw"
|
export GOFLAGS="-modfile=/app/data/go/go.mod -mod=mod -modcacherw"
|
||||||
|
|
||||||
# Create a temporary directory for Go module cache and build in writable area
|
# Create a temporary directory for Go module cache and build in writable area
|
||||||
export GOCACHE=/app/data/go/cache
|
export GOCACHE=/app/data/go/cache
|
||||||
export GOMODCACHE=/app/data/go/modcache
|
export GOMODCACHE=/app/data/go/pkg/mod
|
||||||
mkdir -p $GOCACHE $GOMODCACHE
|
mkdir -p $GOCACHE $GOMODCACHE
|
||||||
echo "==> Set up Go environment in writable directories"
|
echo "==> Set up Go environment in writable directories"
|
||||||
|
|
||||||
# Set up more verbose logging for API debugging
|
# Set up more verbose logging for API debugging
|
||||||
export ENTE_LOG_LEVEL=debug
|
export ENTE_LOG_LEVEL=debug
|
||||||
|
|
||||||
# Test if API endpoint is reachable
|
# Start Caddy first before the Museum server to ensure port 3080 is available for health checks
|
||||||
echo "==> Testing API connectivity"
|
echo "==> Setting up Caddy before starting the Museum server"
|
||||||
curl -v http://localhost:8000/api/health || echo "API not yet available, this is normal during startup"
|
echo "==> Caddy will be listening on port 3080"
|
||||||
|
echo "==> Testing if port 3080 is already in use"
|
||||||
|
if netstat -tuln | grep -q ":3080 "; then
|
||||||
|
echo "==> WARNING: Port 3080 is already in use, Caddy may fail to start"
|
||||||
|
netstat -tuln | grep ":3080 "
|
||||||
|
else
|
||||||
|
echo "==> Port 3080 is available"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Only set permissions on the Caddy directory, not the web directory which is read-only
|
||||||
|
mkdir -p /app/data/caddy/logs
|
||||||
|
chmod -R 755 /app/data/caddy
|
||||||
|
chown -R cloudron:cloudron /app/data/caddy
|
||||||
|
|
||||||
|
# Start Caddy
|
||||||
|
echo "==> Starting Caddy"
|
||||||
|
caddy run --config /app/data/caddy/Caddyfile --adapter caddyfile &
|
||||||
|
CADDY_PID=$!
|
||||||
|
echo "==> Caddy started with PID $CADDY_PID"
|
||||||
|
|
||||||
|
# Check if Caddy started successfully
|
||||||
|
sleep 2
|
||||||
|
if ! ps -p $CADDY_PID > /dev/null; then
|
||||||
|
echo "==> ERROR: Caddy failed to start"
|
||||||
|
echo "==> Any logs available:"
|
||||||
|
if [ -f "/app/data/caddy/caddy.log" ]; then
|
||||||
|
cat /app/data/caddy/caddy.log
|
||||||
|
else
|
||||||
|
echo "No Caddy logs available yet"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "==> Caddy is running properly on port 3080"
|
||||||
|
echo "==> Testing Caddy connectivity"
|
||||||
|
curl -v http://localhost:3080/healthcheck || echo "==> Failed to connect to Caddy"
|
||||||
|
fi
|
||||||
|
|
||||||
# Determine available memory and set limits accordingly
|
# Determine available memory and set limits accordingly
|
||||||
if [[ -f /sys/fs/cgroup/cgroup.controllers ]]; then # cgroup v2
|
if [[ -f /sys/fs/cgroup/cgroup.controllers ]]; then # cgroup v2
|
||||||
@ -395,9 +487,66 @@ export ENTE_DB_PASSWORD="${CLOUDRON_POSTGRESQL_PASSWORD}"
|
|||||||
export ENTE_DB_HOST="${CLOUDRON_POSTGRESQL_HOST}"
|
export ENTE_DB_HOST="${CLOUDRON_POSTGRESQL_HOST}"
|
||||||
export ENTE_DB_PORT="${CLOUDRON_POSTGRESQL_PORT}"
|
export ENTE_DB_PORT="${CLOUDRON_POSTGRESQL_PORT}"
|
||||||
export ENTE_DB_NAME="${CLOUDRON_POSTGRESQL_DATABASE}"
|
export ENTE_DB_NAME="${CLOUDRON_POSTGRESQL_DATABASE}"
|
||||||
export ENTE_DB_SSLMODE="require"
|
export ENTE_DB_SSLMODE="disable"
|
||||||
export CONFIG_PATH="/app/data/config/config.yaml"
|
export CONFIG_PATH="/app/data/config/config.yaml"
|
||||||
|
|
||||||
|
# Check database connectivity
|
||||||
|
echo "==> Checking database connectivity"
|
||||||
|
MAX_RETRIES=5
|
||||||
|
RETRY_COUNT=0
|
||||||
|
while [ $RETRY_COUNT -lt $MAX_RETRIES ]; do
|
||||||
|
if PGPASSWORD="${CLOUDRON_POSTGRESQL_PASSWORD}" psql -h "${CLOUDRON_POSTGRESQL_HOST}" -p "${CLOUDRON_POSTGRESQL_PORT}" \
|
||||||
|
-U "${CLOUDRON_POSTGRESQL_USERNAME}" -d "${CLOUDRON_POSTGRESQL_DATABASE}" -c "SELECT 1" > /dev/null 2>&1; then
|
||||||
|
echo "==> Successfully connected to database"
|
||||||
|
break
|
||||||
|
else
|
||||||
|
echo "==> Failed to connect to database (attempt $((RETRY_COUNT+1))/$MAX_RETRIES)"
|
||||||
|
RETRY_COUNT=$((RETRY_COUNT+1))
|
||||||
|
sleep 5
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ $RETRY_COUNT -eq $MAX_RETRIES ]; then
|
||||||
|
echo "==> ERROR: Could not connect to database after $MAX_RETRIES attempts"
|
||||||
|
echo "==> Database connection details:"
|
||||||
|
echo "Host: ${CLOUDRON_POSTGRESQL_HOST}"
|
||||||
|
echo "Port: ${CLOUDRON_POSTGRESQL_PORT}"
|
||||||
|
echo "User: ${CLOUDRON_POSTGRESQL_USERNAME}"
|
||||||
|
echo "Database: ${CLOUDRON_POSTGRESQL_DATABASE}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Fix database migration state if needed
|
||||||
|
echo "==> Checking database migration state"
|
||||||
|
if [ -d "$SERVER_DIR/cmd/museum" ]; then
|
||||||
|
echo "==> Attempting to fix dirty migration state"
|
||||||
|
cd "$SERVER_DIR"
|
||||||
|
|
||||||
|
# Create migrations log directory
|
||||||
|
mkdir -p /app/data/logs/migrations
|
||||||
|
|
||||||
|
echo "==> Forcing migration version to 25"
|
||||||
|
if /usr/local/bin/gosu cloudron:cloudron env GOCACHE=/app/data/go/cache GOMODCACHE=/app/data/go/pkg/mod \
|
||||||
|
go run -modfile=/app/data/go/go.mod -mod=mod cmd/museum/main.go migrate force 25 \
|
||||||
|
> /app/data/logs/migrations/force.log 2>&1; then
|
||||||
|
echo "==> Successfully forced migration version"
|
||||||
|
else
|
||||||
|
echo "==> Failed to force migration version. Check /app/data/logs/migrations/force.log for details"
|
||||||
|
cat /app/data/logs/migrations/force.log
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "==> Running clean migrations"
|
||||||
|
if /usr/local/bin/gosu cloudron:cloudron env GOCACHE=/app/data/go/cache GOMODCACHE=/app/data/go/pkg/mod \
|
||||||
|
go run -modfile=/app/data/go/go.mod -mod=mod cmd/museum/main.go migrate up \
|
||||||
|
> /app/data/logs/migrations/up.log 2>&1; then
|
||||||
|
echo "==> Successfully ran migrations"
|
||||||
|
else
|
||||||
|
echo "==> Failed to run migrations. Check /app/data/logs/migrations/up.log for details"
|
||||||
|
cat /app/data/logs/migrations/up.log
|
||||||
|
echo "==> WARNING: Database migrations failed. The application may not work correctly."
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
# Additional environment variables
|
# Additional environment variables
|
||||||
export REMOTE_STORAGE_ENDPOINT="${S3_ENDPOINT}"
|
export REMOTE_STORAGE_ENDPOINT="${S3_ENDPOINT}"
|
||||||
export REMOTE_STORAGE_REGION="${S3_REGION}"
|
export REMOTE_STORAGE_REGION="${S3_REGION}"
|
||||||
@ -408,21 +557,61 @@ export REMOTE_STORAGE_PREFIX="${S3_PREFIX:-ente/}"
|
|||||||
|
|
||||||
# Change ownership to cloudron user
|
# Change ownership to cloudron user
|
||||||
chown -R cloudron:cloudron /app/data
|
chown -R cloudron:cloudron /app/data
|
||||||
chown -R cloudron:cloudron /run/nginx
|
|
||||||
|
|
||||||
# Start Museum server on port 8000 (different from the NGINX port 8080)
|
# Start Museum server on port 8080 for compatibility with the Caddy configuration
|
||||||
echo "==> Starting Museum server"
|
echo "==> Starting Museum server"
|
||||||
|
|
||||||
# Modify environment variables for frontend
|
# Modify environment variables for frontend
|
||||||
echo "==> Setting up environment variables for frontend"
|
echo "==> Setting up environment variables for frontend"
|
||||||
# For web frontend, these aren't changing
|
# Set frontend endpoint to the proper origin
|
||||||
export NEXT_PUBLIC_ENTE_ENDPOINT="${CLOUDRON_APP_ORIGIN}"
|
export NEXT_PUBLIC_ENTE_ENDPOINT="${CLOUDRON_APP_ORIGIN}/api"
|
||||||
|
echo "==> NEXT_PUBLIC_ENTE_ENDPOINT set to ${NEXT_PUBLIC_ENTE_ENDPOINT}"
|
||||||
|
|
||||||
|
# Also create a direct config in multiple formats to ensure it's properly loaded
|
||||||
|
echo "==> Creating runtime configuration for the web apps in multiple formats"
|
||||||
|
mkdir -p /app/data/runtime
|
||||||
|
|
||||||
|
# 1. Standard config.js
|
||||||
|
cat > /app/data/runtime/config.js <<EOT
|
||||||
|
// Direct configuration file for Ente web apps
|
||||||
|
window.ENTE_CONFIG = {
|
||||||
|
API_URL: "${CLOUDRON_APP_ORIGIN}/api"
|
||||||
|
};
|
||||||
|
|
||||||
|
// Log configuration loaded
|
||||||
|
console.log("Ente config loaded with API_URL:", window.ENTE_CONFIG.API_URL);
|
||||||
|
EOT
|
||||||
|
|
||||||
|
# 2. JSON format
|
||||||
|
cat > /app/data/runtime/config.json <<EOT
|
||||||
|
{
|
||||||
|
"API_URL": "${CLOUDRON_APP_ORIGIN}/api"
|
||||||
|
}
|
||||||
|
EOT
|
||||||
|
|
||||||
|
# 3. Environment variable format
|
||||||
|
cat > /app/data/runtime/env.js <<EOT
|
||||||
|
// Environment variables in JavaScript
|
||||||
|
window.process = window.process || {};
|
||||||
|
window.process.env = window.process.env || {};
|
||||||
|
window.process.env.NEXT_PUBLIC_ENTE_ENDPOINT = "${CLOUDRON_APP_ORIGIN}/api";
|
||||||
|
EOT
|
||||||
|
|
||||||
|
# Copy them to the Caddy public directory
|
||||||
|
mkdir -p /app/data/caddy/public
|
||||||
|
cp /app/data/runtime/config.js /app/data/caddy/public/
|
||||||
|
cp /app/data/runtime/config.json /app/data/caddy/public/
|
||||||
|
cp /app/data/runtime/env.js /app/data/caddy/public/
|
||||||
|
|
||||||
|
# Print the content of the config file for debugging
|
||||||
|
echo "==> Generated config.js content:"
|
||||||
|
cat /app/data/runtime/config.js
|
||||||
|
|
||||||
# First check for pre-built Museum binary
|
# First check for pre-built Museum binary
|
||||||
if find "$SERVER_DIR" -name "museum" -type f -executable | grep -q .; then
|
if find "$SERVER_DIR" -name "museum" -type f -executable | grep -q .; then
|
||||||
MUSEUM_BIN=$(find "$SERVER_DIR" -name "museum" -type f -executable | head -1)
|
MUSEUM_BIN=$(find "$SERVER_DIR" -name "museum" -type f -executable | head -1)
|
||||||
echo "==> Found Museum binary at $MUSEUM_BIN"
|
echo "==> Found Museum binary at $MUSEUM_BIN"
|
||||||
/usr/local/bin/gosu cloudron:cloudron "$MUSEUM_BIN" --port 8000 \
|
/usr/local/bin/gosu cloudron:cloudron "$MUSEUM_BIN" --port 8080 \
|
||||||
--storage.s3.endpoint="${S3_ENDPOINT}" \
|
--storage.s3.endpoint="${S3_ENDPOINT}" \
|
||||||
--storage.s3.region="${S3_REGION}" \
|
--storage.s3.region="${S3_REGION}" \
|
||||||
--storage.s3.bucket="${S3_BUCKET}" \
|
--storage.s3.bucket="${S3_BUCKET}" \
|
||||||
@ -433,7 +622,7 @@ if find "$SERVER_DIR" -name "museum" -type f -executable | grep -q .; then
|
|||||||
--storage.s3.areLocalBuckets=false \
|
--storage.s3.areLocalBuckets=false \
|
||||||
--storage.type="s3" \
|
--storage.type="s3" \
|
||||||
--config.path="/app/data/config/museum.yaml" \
|
--config.path="/app/data/config/museum.yaml" \
|
||||||
--database.sslmode="require" > /app/data/logs/museum-server.log 2>&1 &
|
--database.sslmode="disable" > /app/data/logs/museum-server.log 2>&1 &
|
||||||
SERVER_PID=$!
|
SERVER_PID=$!
|
||||||
echo "==> Museum server started with PID $SERVER_PID"
|
echo "==> Museum server started with PID $SERVER_PID"
|
||||||
# Next check for cmd/museum directory pattern
|
# Next check for cmd/museum directory pattern
|
||||||
@ -451,7 +640,8 @@ elif [ -d "$SERVER_DIR/cmd/museum" ]; then
|
|||||||
if [[ "${S3_ENDPOINT}" == *"wasabi"* ]]; then
|
if [[ "${S3_ENDPOINT}" == *"wasabi"* ]]; then
|
||||||
echo "==> Detected Wasabi S3 endpoint, adjusting settings"
|
echo "==> Detected Wasabi S3 endpoint, adjusting settings"
|
||||||
echo "==> Adding -mod=mod to go run to ignore version mismatch"
|
echo "==> Adding -mod=mod to go run to ignore version mismatch"
|
||||||
/usr/local/bin/gosu cloudron:cloudron go run -mod=mod cmd/museum/main.go --port 8000 \
|
cd "$SERVER_DIR" && \
|
||||||
|
/usr/local/bin/gosu cloudron:cloudron env GOCACHE=/app/data/go/cache GOMODCACHE=/app/data/go/pkg/mod PORT=8080 GIN_MODE=release go run -modfile=/app/data/go/go.mod -mod=mod cmd/museum/main.go --port 8080 \
|
||||||
--storage.s3.endpoint="${S3_ENDPOINT}" \
|
--storage.s3.endpoint="${S3_ENDPOINT}" \
|
||||||
--storage.s3.region="${S3_REGION}" \
|
--storage.s3.region="${S3_REGION}" \
|
||||||
--storage.s3.bucket="${S3_BUCKET}" \
|
--storage.s3.bucket="${S3_BUCKET}" \
|
||||||
@ -462,10 +652,11 @@ elif [ -d "$SERVER_DIR/cmd/museum" ]; then
|
|||||||
--storage.s3.areLocalBuckets=false \
|
--storage.s3.areLocalBuckets=false \
|
||||||
--storage.type="s3" \
|
--storage.type="s3" \
|
||||||
--config.path="/app/data/config/museum.yaml" \
|
--config.path="/app/data/config/museum.yaml" \
|
||||||
--database.sslmode="require" \
|
--database.sslmode="disable" \
|
||||||
--log.level=debug > /app/data/logs/museum-server.log 2>&1 &
|
--log.level=debug > /app/data/logs/museum-server.log 2>&1 &
|
||||||
else
|
else
|
||||||
/usr/local/bin/gosu cloudron:cloudron go run -mod=mod cmd/museum/main.go --port 8000 \
|
cd "$SERVER_DIR" && \
|
||||||
|
/usr/local/bin/gosu cloudron:cloudron env GOCACHE=/app/data/go/cache GOMODCACHE=/app/data/go/pkg/mod PORT=8080 GIN_MODE=release go run -modfile=/app/data/go/go.mod -mod=mod cmd/museum/main.go --port 8080 \
|
||||||
--storage.s3.endpoint="${S3_ENDPOINT}" \
|
--storage.s3.endpoint="${S3_ENDPOINT}" \
|
||||||
--storage.s3.region="${S3_REGION}" \
|
--storage.s3.region="${S3_REGION}" \
|
||||||
--storage.s3.bucket="${S3_BUCKET}" \
|
--storage.s3.bucket="${S3_BUCKET}" \
|
||||||
@ -476,7 +667,7 @@ elif [ -d "$SERVER_DIR/cmd/museum" ]; then
|
|||||||
--storage.s3.areLocalBuckets=false \
|
--storage.s3.areLocalBuckets=false \
|
||||||
--storage.type="s3" \
|
--storage.type="s3" \
|
||||||
--config.path="/app/data/config/museum.yaml" \
|
--config.path="/app/data/config/museum.yaml" \
|
||||||
--database.sslmode="require" \
|
--database.sslmode="disable" \
|
||||||
--log.level=debug > /app/data/logs/museum-server.log 2>&1 &
|
--log.level=debug > /app/data/logs/museum-server.log 2>&1 &
|
||||||
fi
|
fi
|
||||||
SERVER_PID=$!
|
SERVER_PID=$!
|
||||||
@ -491,7 +682,7 @@ elif [ -d "$SERVER_DIR/cmd/museum" ]; then
|
|||||||
RETRY_COUNT=0
|
RETRY_COUNT=0
|
||||||
while [ $RETRY_COUNT -lt $MAX_RETRIES ]; do
|
while [ $RETRY_COUNT -lt $MAX_RETRIES ]; do
|
||||||
echo "==> Testing API connection (attempt $((RETRY_COUNT+1))/$MAX_RETRIES)"
|
echo "==> Testing API connection (attempt $((RETRY_COUNT+1))/$MAX_RETRIES)"
|
||||||
if curl -s http://localhost:8000/api/health > /dev/null; then
|
if curl -s http://localhost:8080/api/health > /dev/null; then
|
||||||
echo "==> API is now responding"
|
echo "==> API is now responding"
|
||||||
break
|
break
|
||||||
else
|
else
|
||||||
@ -527,7 +718,8 @@ else
|
|||||||
export GOTOOLCHAIN=local
|
export GOTOOLCHAIN=local
|
||||||
|
|
||||||
echo "==> Running main.go with Go"
|
echo "==> Running main.go with Go"
|
||||||
/usr/local/bin/gosu cloudron:cloudron go run -mod=mod main.go --port 8000 \
|
cd "$MAIN_DIR" && \
|
||||||
|
/usr/local/bin/gosu cloudron:cloudron env GOCACHE=/app/data/go/cache GOMODCACHE=/app/data/go/pkg/mod PORT=8080 GIN_MODE=release go run -modfile=/app/data/go/go.mod -mod=mod main.go --port 8080 \
|
||||||
--storage.s3.endpoint="${S3_ENDPOINT}" \
|
--storage.s3.endpoint="${S3_ENDPOINT}" \
|
||||||
--storage.s3.region="${S3_REGION}" \
|
--storage.s3.region="${S3_REGION}" \
|
||||||
--storage.s3.bucket="${S3_BUCKET}" \
|
--storage.s3.bucket="${S3_BUCKET}" \
|
||||||
@ -538,6 +730,7 @@ else
|
|||||||
--storage.s3.areLocalBuckets=false \
|
--storage.s3.areLocalBuckets=false \
|
||||||
--storage.type="s3" \
|
--storage.type="s3" \
|
||||||
--config.path="/app/data/config/museum.yaml" \
|
--config.path="/app/data/config/museum.yaml" \
|
||||||
|
--database.sslmode="disable" \
|
||||||
--log.level=debug > /app/data/logs/museum-server.log 2>&1 &
|
--log.level=debug > /app/data/logs/museum-server.log 2>&1 &
|
||||||
SERVER_PID=$!
|
SERVER_PID=$!
|
||||||
echo "==> Museum server started with PID $SERVER_PID"
|
echo "==> Museum server started with PID $SERVER_PID"
|
||||||
@ -592,10 +785,10 @@ func main() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// Start the server
|
// Start the server
|
||||||
log.Println("Starting mock server on port 8000")
|
log.Println("Starting mock server on port 8080")
|
||||||
|
|
||||||
// Start in a goroutine to prevent blocking
|
// Start in a goroutine to prevent blocking
|
||||||
server := &http.Server{Addr: ":8000"}
|
server := &http.Server{Addr: ":8080"}
|
||||||
go func() {
|
go func() {
|
||||||
if err := server.ListenAndServe(); err != nil {
|
if err := server.ListenAndServe(); err != nil {
|
||||||
log.Fatalf("Server error: %v", err)
|
log.Fatalf("Server error: %v", err)
|
||||||
@ -612,15 +805,35 @@ EOT
|
|||||||
echo "==> Mock server started with PID $SERVER_PID to show error message"
|
echo "==> Mock server started with PID $SERVER_PID to show error message"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Serve the static web apps in the foreground using our custom nginx config
|
echo "==> Testing health check endpoint directly"
|
||||||
echo "==> Running NGINX in the foreground with custom configuration"
|
curl -v http://localhost:3080/healthcheck
|
||||||
nginx -c /app/data/nginx/ente.conf &
|
|
||||||
NGINX_PID=$!
|
|
||||||
echo "==> NGINX started with PID $NGINX_PID"
|
|
||||||
|
|
||||||
echo "==> Ente is now running!"
|
echo "==> Ente is now running!"
|
||||||
echo "==> Museum server: PID $SERVER_PID"
|
echo "==> Museum server: PID $SERVER_PID"
|
||||||
echo "==> NGINX: PID $NGINX_PID"
|
echo "==> Caddy: PID $CADDY_PID"
|
||||||
|
|
||||||
# Wait for the processes to finish (or be terminated)
|
# Function to inject the config.js script tag into index.html files
|
||||||
wait
|
inject_config_script() {
|
||||||
|
echo "==> Attempting to inject config.js script tag into index.html files"
|
||||||
|
|
||||||
|
# List of web app directories
|
||||||
|
WEB_APPS=("/app/web/photos" "/app/web/accounts" "/app/web/auth" "/app/web/cast")
|
||||||
|
|
||||||
|
for app_dir in "${WEB_APPS[@]}"; do
|
||||||
|
if [ -f "$app_dir/index.html" ]; then
|
||||||
|
echo "==> Processing $app_dir/index.html"
|
||||||
|
|
||||||
|
# Try to modify in place without creating a backup
|
||||||
|
sed -i 's|</head>|<script>window.ENTE_CONFIG = { API_URL: "'"${CLOUDRON_APP_ORIGIN}"'/api" };</script></head>|' "$app_dir/index.html" || echo "==> Cannot modify $app_dir/index.html - read-only file system"
|
||||||
|
else
|
||||||
|
echo "==> Skipping $app_dir - index.html not found"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
# Try to inject the config script but don't worry if it fails
|
||||||
|
inject_config_script || echo "==> NOTE: Could not inject configuration directly into HTML files"
|
||||||
|
|
||||||
|
# Wait for child processes to exit
|
||||||
|
wait $SERVER_PID
|
||||||
|
wait $CADDY_PID
|
Loading…
x
Reference in New Issue
Block a user