Automated deployment of self-hosted Ente Photos with Garage S3 storage on Incus containers.
Roberto Mello (roberto.mello@gmail.com)
- Linux host with Incus installed and configured
sudoaccessopensslandgitinstalled- Network configured for container IP assignment
git clone <this-repo> ente-incus
cd ente-incus
./setup.shThe interactive script will guide you through configuration.
| Container | Purpose |
|---|---|
| garage-s3 | S3-compatible object storage for photos |
| ente | Museum server (Ente API) |
| postgres | PostgreSQL database (optional) |
| step-ca | Internal TLS certificate authority (optional) |
- Static IP addresses for each container
- Support for default bridge or macvlan networks
- Local: Directory on host mounted into container
- iSCSI: Connect to remote iSCSI target (e.g., Synology NAS)
- Create new container, or use existing PostgreSQL server
- Recommendation: For production deployments, use a high availability PostgreSQL setup (e.g., Patroni, Stolon, or managed PostgreSQL service) rather than a single-container deployment
- Hardcoded: Specify email domain and fixed OTP (simpler for self-hosted)
- SMTP: Real email delivery for OTPs
- Release: Download pre-built binaries from GitHub
- Source: Clone and build from source (requires Go)
- Step-CA provides automatic certificate management for internal services
After running the setup, you'll find:
| File | Contents |
|---|---|
generated-secrets-*.txt |
All passwords and keys (save securely!) |
deployment-config-*.env |
Non-secret configuration values |
generated-proxy-configs/ |
Reverse proxy configs (Caddy, Traefik, nginx) |
- Configure reverse proxy using generated configs in
generated-proxy-configs/ - Set up DNS pointing your domains to the proxy
- Install Ente app (iOS/Android/Desktop)
- Configure server endpoint in app settings
- Create account using your configured email domain
ente-incus/
├── setup.sh # Main installer script
├── modules/
│ ├── garage.sh # Garage S3 deployment
│ ├── ente.sh # Museum server deployment
│ ├── postgresql.sh # PostgreSQL deployment
│ └── step-ca.sh # Step-CA deployment
├── templates/ # (reserved for future templates)
└── README.md
The modular design allows you to:
- Run individual modules separately
- Modify configuration templates
- Add new storage backends
- Extend with additional services
sudo incus list # Check container status
sudo incus info <container> # Detailed info
sudo incus exec <container> -- journalctl -xesudo incus exec <container> -- ip addr
sudo incus exec <container> -- ping 8.8.8.8sudo incus exec <container> -- systemctl status <service>
sudo incus exec <container> -- journalctl -u <service> -fsudo incus exec ente -- pg_isready -h <postgres-ip> -U enteThe setup script creates new containers. To redeploy:
# Remove existing containers
sudo incus delete --force garage-s3 ente postgres step-ca
# Run setup again
./setup.sh- Generated secrets are stored in plaintext files - secure them appropriately
- The hardcoded OTP mode is convenient but less secure than SMTP
- Review firewall rules to limit container network access
- Consider enabling Step-CA for internal TLS
MIT