Compare commits

...

210 Commits

Author SHA1 Message Date
Neeraj Gupta
8378af153b Tweak 2025-07-28 10:31:39 +05:30
Neeraj Gupta
7f57fd597c Tweak order 2025-07-28 10:24:58 +05:30
Neeraj Gupta
f7515f520c Update 2025-07-28 10:22:29 +05:30
Neeraj Gupta
b0ebbce292 Remove code magic 2025-07-28 10:09:54 +05:30
Neeraj Gupta
3d409ffd77 Try adding existing cert 2025-07-28 09:49:31 +05:30
Neeraj Gupta
6d45c3c4e5 Fix 7/n 2025-07-26 15:31:28 +05:30
Neeraj Gupta
35ca600c4e Fix 5/n 2025-07-26 15:19:24 +05:30
Neeraj Gupta
6fcf2732a8 Merge branch 'internal_photos_july25_2' into internal_ios_build 2025-07-26 15:11:57 +05:30
Neeraj Gupta
311e8f3939 Fix 5/n 2025-07-26 15:10:38 +05:30
Neeraj Gupta
da1ff4131c Fix build 4/n 2025-07-26 15:02:01 +05:30
Prateek Sunal
d0bbdfec8e chore: bump version 2025-07-26 14:58:41 +05:30
Prateek Sunal
e5f2ae8ac8 Merge remote-tracking branch 'origin/smart-album-nothingelse' into internal_photos_july25_2 2025-07-26 14:58:17 +05:30
Neeraj Gupta
a119babe21 Fix build 4/n 2025-07-26 14:57:07 +05:30
Neeraj Gupta
9dd9a8db80 Fix build 3/n 2025-07-26 14:52:29 +05:30
Neeraj Gupta
ea4282882e Fix build 2/n 2025-07-26 14:45:42 +05:30
Neeraj Gupta
862064d2e4 Fix build 2/n 2025-07-26 14:42:58 +05:30
ashilkn
191ec62215 bump up version 2025-07-26 14:31:20 +05:30
Neeraj Gupta
dabd703803 Fix build 1/n 2025-07-26 14:31:05 +05:30
ashilkn
be6bc3747b Merge gallery_rewrite 2025-07-26 14:30:35 +05:30
Neeraj Gupta
9f9eab3644 Update build workflow 2025-07-26 14:22:15 +05:30
ashilkn
88eb935d2f UI/UX improvement 2025-07-26 14:21:29 +05:30
Neeraj Gupta
91499c7775 Merge remote-tracking branch 'origin/main' into internal_photos_july25_2 2025-07-26 14:07:52 +05:30
Neeraj
d71f50b79b [CD] Github action for iOS test flight (#6650)
## Description

## Tests
2025-07-26 14:06:40 +05:30
Neeraj Gupta
25eaee57e9 Github action for iOS test flight 2025-07-26 14:04:05 +05:30
Neeraj
cf3b5897d2 [auth] Update apple-app-site-association for auth app (#6649)
## Description
This should fix some of the auto-fill issues for the auth app. 
## Tests
2025-07-26 13:33:42 +05:30
Neeraj Gupta
c00ad310ef Update apple-app-site-association for auth app 2025-07-26 13:29:00 +05:30
ashilkn
10101c697b Chore 2025-07-26 12:40:19 +05:30
ashilkn
8ad1b94b87 Minor UI fix 2025-07-26 12:39:08 +05:30
ashilkn
783f53bfdc Add option to change gallery layout from home gallery itself 2025-07-26 12:10:24 +05:30
Keerthana
3e5ba6f939 [docs] linting and minor updates for procedures in self-hosting (#6643)
## Description

This PR updates upgrading procedure to ensure lack of merge conflicts.
A minor grammar error in home page is fixed along with it.

It also fixes linting issues and minor grammatical errors.
2025-07-26 11:07:53 +05:30
Keerthana
b3c0681d54 [docs] fix linting for self-hosting 2025-07-26 08:34:34 +05:30
Keerthana
98951e2d2a [docs] substitute upgradation with upgrade 2025-07-26 07:58:20 +05:30
Keerthana
e8edacf924 [docs] change instructions for whitelisting admins 2025-07-26 07:52:30 +05:30
AmanRajSinghMourya
f254a7841b Merge branch 'advance_image_editor' into internal_photos_july25_2 2025-07-26 00:18:50 +05:30
Keerthana
508e83acd4 [docs] update upgradation for manual setup 2025-07-25 22:44:08 +05:30
Keerthana
702b03a288 [docs] revamp documentation for self-hosting (#6642)
## Description

This PR contains major revision for self-hosting documentation. Some
major changes are:

1. Up-to-date information for various installation methods
2. Documentation for configuration with examples
3. Documentation for administrative activities
4. Refactor community guides and include credits
5. Better UX for configuration by templated configuration

The setup includes Compose file that can be used for building from
source without hassle and
includes templated configuration files for ease-of-usage.

## Tests
- [x] I have tested the Docker Compose setup on my system
- [x] I have tested quickstart on my system
2025-07-25 20:21:46 +05:30
Keerthana
2c6f4228d2 [docs] remove redundant line for cluster initialization 2025-07-25 20:21:22 +05:30
Keerthana
95228cc0a6 [docs] remove paid sub template 2025-07-25 20:09:31 +05:30
Prateek Sunal
e583794d37 Merge remote-tracking branch 'origin/main' into internal_photos_july25_2 2025-07-25 20:01:43 +05:30
Prateek Sunal
87df2add67 Merge branch 'internal_photos_july25_2' of https://github.com/ente-io/ente into internal_photos_july25_2 2025-07-25 20:01:28 +05:30
Prateek Sunal
c074f66b38 Merge branch 'smart-album-nothingelse' into internal_photos_july25_2 2025-07-25 20:01:20 +05:30
Keerthana
754dd48367 [docs] update quickstart 2025-07-25 19:52:26 +05:30
Keerthana
2b4ed5b43c [docs] fix dead links 2025-07-25 19:22:23 +05:30
Keerthana
7c87f27539 [docs] rename topics for self-hosting 2025-07-25 18:54:27 +05:30
Keerthana
aae1caf37d [docs] revamp administration and document configuration examples 2025-07-25 17:22:52 +05:30
ashilkn
9bdf6305f7 Merge gallery_rewrite 2025-07-25 16:39:56 +05:30
ashilkn
0a6558bf48 Remove 'last year' and 'last month' header titles for groups 2025-07-25 16:38:22 +05:30
ashilkn
e13e27c10e Merge branch 'gallery_rewrite' into internal_photos_july25_2 2025-07-25 16:14:49 +05:30
ashilkn
7bd22fd5b8 Padding change 2025-07-25 16:14:33 +05:30
ashilkn
d1d7d03af2 Merge branch 'gallery_rewrite' into internal_photos_july25_2 2025-07-25 16:12:57 +05:30
ashilkn
32b7081b02 Remove unused file 2025-07-25 16:12:27 +05:30
ashilkn
676c3fd22c Update scroll bar thumb 2025-07-25 16:11:23 +05:30
ashilkn
b305d3c9bf Do not show scrollbar for small galleries 2025-07-25 16:07:19 +05:30
Neeraj
b833487c54 [mobile][photos] Fix date parsing (#6637)
## Description
Support more date format.

## Tests
Add more test cases to the test file.
2025-07-25 15:06:06 +05:30
Prateek Sunal
ba2cf287ce chore: push changes 2025-07-25 14:08:29 +05:30
Prateek Sunal
619d7676f6 Merge branch 'smart-album-nothingelse' into internal_photos_july25_2 2025-07-25 14:08:14 +05:30
Prateek Sunal
0d7cbd3187 chore: bump version 2025-07-25 13:05:05 +05:30
Prateek Sunal
a292d09d8c Merge branch 'smart-album-nothingelse' into internal_photos_july25_2 2025-07-25 13:04:45 +05:30
Keerthana
bd58becd38 [docs] omit dead links for bucket CORS 2025-07-25 11:39:12 +05:30
AmanRajSinghMourya
d6fa9d1257 Add tests for partial month-year and ordinal date formats 2025-07-25 11:38:52 +05:30
AmanRajSinghMourya
ee42e71168 Enhance date parsing to support month-year format 2025-07-25 11:38:41 +05:30
Keerthana
75d919e815 [docs] refactor FAQ and installation section 2025-07-25 10:46:21 +05:30
AmanRajSinghMourya
ed7cc5f8c1 Add SVG delete icon and update image editor UI to use it 2025-07-25 09:51:08 +05:30
AmanRajSinghMourya
aede55eb72 Fix: adjust spacing in the image editor app bar 2025-07-25 09:50:45 +05:30
ashilkn
7450996f4d Merge branch 'gallery_rewrite' into internal_photos_july25_2 2025-07-24 20:13:05 +05:30
ashilkn
463602c425 Use different haptics depending on Platform that comes when using the scrollbar 2025-07-24 20:12:17 +05:30
ashilkn
f37d94a2bd Merge branch 'gallery_rewrite' into internal_photos_july25_2 2025-07-24 19:49:38 +05:30
ashilkn
ee864ee0a5 Move Gallery setting to top of General section 2025-07-24 19:49:01 +05:30
ashilkn
d48b4392f5 Merge branch 'gallery_rewrite' into internal_photos_july25_2 2025-07-24 19:45:45 +05:30
ashilkn
4c61fd248d Move Gallery settings from General->Advanced to General 2025-07-24 19:45:05 +05:30
ashilkn
8feb69d711 Merge branch 'gallery_rewrite' into internal_photos_july25_2 2025-07-24 19:24:12 +05:30
ashilkn
446195b8f6 Minor improvement 2025-07-24 19:21:26 +05:30
ashilkn
382cd90ea1 Fix group selection state not persisting on PinnedGroupHeader when scrolling 2025-07-24 19:21:12 +05:30
AmanRajSinghMourya
7a35748e30 Minor fix 2025-07-24 17:33:27 +05:30
AmanRajSinghMourya
21d59fa0a3 Fix: adjust padding and spacing in crop rotate bar UI 2025-07-24 17:30:14 +05:30
AmanRajSinghMourya
b89a9a7307 Fix options for background selections 2025-07-24 17:28:02 +05:30
Neeraj Gupta
24266e9eca Bump version 2025-07-24 17:23:42 +05:30
Neeraj Gupta
3419197817 Merge branch 'fixNow' into internal_photos_july25_2 2025-07-24 17:23:11 +05:30
Keerthana
d30fb6fc3c [docs] rename migration guides for auth 2025-07-24 16:50:33 +05:30
Neeraj Gupta
6d59e51ffa Bump version 2025-07-24 16:26:38 +05:30
Neeraj Gupta
16bc189c2b Merge branch 'fixQuery' into internal_photos_july25_2 2025-07-24 16:25:39 +05:30
Keerthana
637f11ac23 [docs] complete installation procedures 2025-07-24 16:21:13 +05:30
AmanRajSinghMourya
e9da23aff9 Refactor: remove unused safe area configurations from image editor 2025-07-24 16:00:36 +05:30
AmanRajSinghMourya
d466b77f0e Fix: show custom warning dialog 2025-07-24 15:59:34 +05:30
ashilkn
c942257c5f bump up version 2025-07-24 14:55:54 +05:30
ashilkn
bc7d265812 Fix build error 2025-07-24 14:52:38 +05:30
ashilkn
f7ee1099c4 Merge flutter_3.27 2025-07-24 14:45:32 +05:30
ashilkn
f6852885b1 Change from flutter pub get 2025-07-24 14:39:34 +05:30
AmanRajSinghMourya
0289a5535e Fix pubspec.lock file 2025-07-24 14:20:41 +05:30
AmanRajSinghMourya
8242916172 Merge branch 'main' into advance_image_editor 2025-07-24 14:17:31 +05:30
ashilkn
ee1686370b Merge branch 'flutter_3.27' into internal_photos_july25_2 2025-07-24 14:07:49 +05:30
ashilkn
c94e817205 update README file 2025-07-24 14:05:46 +05:30
ashilkn
4669107647 Update workflows 2025-07-24 14:05:26 +05:30
ashilkn
dcf0192257 Resolve merge conflicts and merge gallery_rewrite 2025-07-24 14:00:14 +05:30
ashilkn
7d9cfd8587 Run flutter pub get after upgrading to flutter 3.27.4 2025-07-24 13:43:05 +05:30
ashilkn
a0686dc8bd Regenerate pubspec.lock after upgrading to flutter 3.27.4 2025-07-24 13:42:08 +05:30
ashilkn
8330e2902c Auto generated changes to pubspec.lock 2025-07-24 12:38:59 +05:30
ashilkn
8613d0d338 Auto genenrated translation related files changes 2025-07-24 12:38:20 +05:30
ashilkn
a33938a620 Resolve merge conflicts and merge main 2025-07-24 12:36:39 +05:30
ashilkn
506fc51675 Merge remote-tracking branch 'origin/advance_image_editor' into internal_photos_july25_2 2025-07-24 12:30:28 +05:30
ashilkn
6751648aae Merge remote-tracking branch 'origin/smart-album-nothingelse' into internal_photos_july25_2 2025-07-24 12:26:56 +05:30
ashilkn
f8fe2bd7f2 Stop usage of continously animating widget which is offscreen and taken up compute 2025-07-24 11:29:43 +05:30
ashilkn
59888840b5 Fix limitSelectionToOne not working regression 2025-07-24 10:55:34 +05:30
ashilkn
be3568c3ba Remove jump to date UI hook and fix pinned header bug 2025-07-24 10:29:22 +05:30
ashilkn
d606d9c1e0 Fix jump to date bug 2025-07-24 00:28:27 +05:30
ashilkn
bb9dd31520 Fix bug in gallery 2025-07-24 00:21:47 +05:30
ashilkn
a8cc1ab4f0 Resolve merge conflicts for cherry-picking jump to date wip 2025-07-24 00:11:30 +05:30
AmanRajSinghMourya
c87065b1c2 Merge branch 'main' into advance_image_editor 2025-07-24 00:00:54 +05:30
ashilkn
88aa5fbfe1 Fix error 2025-07-23 23:55:39 +05:30
AmanRajSinghMourya
b8bb3d5730 Add google_fonts dependency and include image-editor assets 2025-07-23 23:48:07 +05:30
AmanRajSinghMourya
cf75528f5e Add new image editor functionality to detail page 2025-07-23 23:47:49 +05:30
AmanRajSinghMourya
7a6fb1ba31 Implemented new image editor 2025-07-23 23:47:03 +05:30
AmanRajSinghMourya
774292bdea Custom widget for editor & constants 2025-07-23 23:45:35 +05:30
AmanRajSinghMourya
4dd7305c46 New app bar for editor 2025-07-23 23:44:36 +05:30
AmanRajSinghMourya
3d952a2ecc Add new color for image editor 2025-07-23 23:42:58 +05:30
AmanRajSinghMourya
9386e3796c Add svg assets of image editor 2025-07-23 23:42:45 +05:30
ashilkn
77d7d358f3 Minor refactoring and removing unnecessary work on Gallery widget 2025-07-23 20:50:13 +05:30
ashilkn
cd46db3d30 Show 'last year', 'last week' and 'last month' headers in gallery when appropriate 2025-07-23 16:05:03 +05:30
ashilkn
4f00296933 Fix build error 2025-07-23 15:55:09 +05:30
ashilkn
7ff2c8f424 Make group by feature functional on gallery 2025-07-23 15:54:56 +05:30
ashilkn
c34d214313 Stop using custom object and use simple map for message passing compatibility between isolates 2025-07-23 12:13:00 +05:30
ashilkn
b209779f59 Use records for making data compatible for message passing between isolates 2025-07-23 12:04:21 +05:30
ashilkn
51891996a2 Handle edge case 2025-07-22 11:18:15 +05:30
ashilkn
5fd861b60a Remove uneccessary global keys and widgets 2025-07-22 11:04:20 +05:30
ashilkn
caa092f6c5 Increase gallery length limit threshold above which scroll bar divisions will be made visible 2025-07-21 17:27:12 +05:30
ashilkn
bbcb6dc702 Disable vertical padding on scrollbars in gallery that don't need vertical padding 2025-07-21 16:57:03 +05:30
ashilkn
662f4a3fb7 chore 2025-07-21 16:48:20 +05:30
ashilkn
b053b0082f Change bottom padding of scrollbar if file selection sheet is up/down 2025-07-21 16:43:22 +05:30
ashilkn
3578df0ac0 Make gallery configurable to not show PinnedGroupHeader and use it where necessary 2025-07-21 15:08:56 +05:30
ashilkn
50ea38d471 Make hero animation work when opening a gallery 2025-07-18 19:06:03 +05:30
ashilkn
43c06d93c7 Rename final scrollbar 2025-07-18 18:09:07 +05:30
ashilkn
ecad643ea6 Remove old scrollbar 2025-07-18 18:08:19 +05:30
ashilkn
9241755d44 Minor change 2025-07-18 18:07:19 +05:30
ashilkn
3ff0356dd2 Fix flutter error 2025-07-18 17:57:32 +05:30
ashilkn
3fdb906834 Support limitSelectionToOne and showSelect all on new gallery 2025-07-18 17:40:36 +05:30
ashilkn
f32b98c1bc Clean up 2025-07-18 16:05:49 +05:30
ashilkn
764921ec69 Make it possible to pass different vertical paddings for scrollbar 2025-07-18 15:56:41 +05:30
ashilkn
06397a4992 Add empty state for gallery 2025-07-18 15:38:24 +05:30
ashilkn
f232fc401d Add support for disableScroll in galler 2025-07-18 14:45:11 +05:30
ashilkn
a10dcd01b0 Add support for GroupType.none 2025-07-18 14:36:42 +05:30
AmanRajSinghMourya
552003600a Add pro_image_editor package 2025-07-18 13:47:58 +05:30
ashilkn
9b289d7845 Minor UI change 2025-07-17 16:37:38 +05:30
ashilkn
21a843fb3b Remove stale code 2025-07-17 16:34:29 +05:30
ashilkn
401c8e160a Custom ScrollPhysics to avoid extreme overscroll when using scrollbar 2025-07-17 14:43:53 +05:30
ashilkn
c2374ed14e Double tap home button to animate to start of home gallery 2025-07-17 14:43:15 +05:30
ashilkn
dc6221c977 Simplify figuring out where to pin PinnedGroupHeader and change it when height of gallery's header changes 2025-07-17 14:01:41 +05:30
ashilkn
5b4d4b86f7 Add docs 2025-07-16 16:48:40 +05:30
ashilkn
6423901165 Remove shadow of PeopleAppBar 2025-07-16 15:37:50 +05:30
ashilkn
4672b44d48 Do not show shadow on PinnedGroupHeader if scroll offset of gallery is zero. This is to give the illusion that the header is only pinned when gallery is scrolled from 0 offset 2025-07-16 15:09:30 +05:30
ashilkn
576f85055e Add top padding for gallery scrollbar 2025-07-16 14:33:46 +05:30
ashilkn
8a4ef26a6e Update animation duration 2025-07-16 14:14:45 +05:30
ashilkn
8541657ee0 Enlarge PinnedGroupHeader when using scrollbar for better UX 2025-07-16 12:39:11 +05:30
ashilkn
7340e5a100 Fix scroll bar divisions not appearing 2025-07-16 11:14:29 +05:30
ashilkn
30f8162ee4 Fix logic 2025-07-16 10:57:16 +05:30
ashilkn
ef08c4bd96 Remove shadow under GalleryAppBar to fix UI issue when group header is pinned to top 2025-07-16 10:47:25 +05:30
ashilkn
776c3158a7 Do not show scrollbar divisions if gallery isn't long enough 2025-07-16 10:34:30 +05:30
ashilkn
56d0acc501 Add corrections to where the scroll dividers are placed 2025-07-15 19:20:39 +05:30
ashilkn
e3a5cd060d Update haptic feedback type 2025-07-15 19:01:50 +05:30
ashilkn
e4f10d0e69 Add haptic feedback when going through sections when using the scrollbar 2025-07-15 15:53:37 +05:30
ashilkn
03c116c2ba Avoid redundant setState call 2025-07-15 15:52:42 +05:30
ashilkn
c318162feb Add solid color for background of PinnedGroupHeader 2025-07-15 12:48:07 +05:30
ashilkn
60485e98c2 UI for elements depicting scroll bar divisions 2025-07-15 12:38:08 +05:30
Keerthana
76e30fe959 [docs] refine requirements 2025-07-15 12:22:49 +05:30
ashilkn
2bee2fe71c Remove first scrollbar division since it doesn't add value in terms of UX 2025-07-15 12:11:42 +05:30
ashilkn
1b1e82ebbd Add bottom padding to new gallery scrollbar 2025-07-15 12:07:38 +05:30
ashilkn
d319b244ee Filter out scroll position divisions that are too close to each other 2025-07-15 11:45:28 +05:30
ashilkn
880594398d Make the scrollbar divisions meant for years actually show years 2025-07-14 18:27:52 +05:30
ashilkn
a475cc9933 Create a new scrollbar tha works like a normal scrollbar but intended to also show scroll positions of different years. UI works, need to next show the actual values at positions 2025-07-14 15:18:28 +05:30
Keerthana
b260648192 [docs] linting and complete get started 2025-07-14 15:04:18 +05:30
Keerthana
034eb69473 [docs] simplify S3 configuration 2025-07-14 09:52:25 +05:30
Keerthana
f06403adc7 [docs] refactor standalone and from source docs 2025-07-14 09:52:25 +05:30
Keerthana
b580d6ce35 [docs] refactor get started 2025-07-14 09:52:25 +05:30
Keerthana
caf664f11d [docs] restructure administration section 2025-07-14 09:52:25 +05:30
Keerthana
2d90c14890 [docs] restructure installation and guides section 2025-07-14 09:52:25 +05:30
Keerthana
4d078c094c [docs] restructure self-hosting navigation 2025-07-14 09:52:25 +05:30
Keerthana
cbfcbe8da2 [docs] reduce verbose description in quickstart 2025-07-14 09:52:25 +05:30
Keerthana
d0f637b154 [server][script] enhance reading choice and refactor choice 2025-07-14 09:52:25 +05:30
ashilkn
4d8d0d1b07 Make selection work on the new group header widget 2025-07-12 17:20:24 +05:30
ashilkn
59b07f3507 Use bouncing scroll physics for gallery 2025-07-12 15:32:44 +05:30
ashilkn
38e5135878 Fix bug in PinnedGroupHeader when gallery is reloaded or setState is called in gallery 2025-07-12 15:31:57 +05:30
ashilkn
2426b7405c Improve performance of deciding what title to show on the PinnedGroupHeader based on group 2025-07-12 14:37:08 +05:30
ashilkn
567582b423 Resolve merge conflicts and merge main 2025-07-10 15:01:50 +05:30
ashilkn
937af3da37 clean up 2025-07-10 11:59:27 +05:30
ashilkn
da4e0aa826 chore 2025-07-09 16:52:44 +05:30
ashilkn
372c4d9086 Create a widget (yet to be stateful) that acts as a 'pinned header' for each group in gallery when gallery is scrolled 2025-07-09 16:43:10 +05:30
ashilkn
80e28ee1a3 chore 2025-07-09 16:34:58 +05:30
ashilkn
6e14aaaad7 Create a working custom scroll bar without support for header and footer 2025-07-07 15:55:07 +05:30
ashilkn
28be02bb9a Create a scrollOffsetToGroupID map to be used in custom scroll bar 2025-07-07 14:00:32 +05:30
ashilkn
93851db27a Refactor 2025-07-07 13:59:26 +05:30
ashilkn
8a0f61a1c7 Refactor + add header and footer of gallery 2025-07-07 13:38:41 +05:30
ashilkn
f70c284b58 Use better name 2025-07-04 14:34:09 +05:30
ashilkn
27faef415f Use better names 2025-07-04 12:32:43 +05:30
ashilkn
fd05961303 Improve performance of group building function by not eagerly computing each group header's title and instead, offload it to the GroupHeaderWidget to compute lazily when it's built 2025-07-04 12:31:12 +05:30
ashilkn
23728107a3 Remove unused parameter 2025-07-04 12:11:17 +05:30
ashilkn
cde42eb43a Use better name 2025-07-04 11:53:16 +05:30
ashilkn
ce380b3b7a Log time taken for computing GalleryGroups and it's sectionLayout + add keys to GalleryFileWidget to fix issues 2025-07-04 11:03:25 +05:30
ashilkn
1cc80aab75 Make selection work with new gallery 2025-07-03 16:18:43 +05:30
ashilkn
0d55ae1a6d Fix spacing issue 2025-07-03 15:34:14 +05:30
ashilkn
ad892c1055 Fix incorrect logic of finding index of file in gallery 2025-07-03 15:24:56 +05:30
ashilkn
29f7a54950 Layout calculation fixes and use better names 2025-07-03 11:41:30 +05:30
ashilkn
2b258f984d Change names 2025-07-03 10:56:39 +05:30
ashilkn
3cf4d3ee31 Merge branch 'main' into gallery_rewrite 2025-07-03 10:40:35 +05:30
ashilkn
b1386b8f57 Extract group building code to a function for better readability 2025-07-03 10:37:59 +05:30
ashilkn
6d576adce0 Display group header widget 2025-06-20 17:09:23 +05:30
ashilkn
af6942e99d Populate grid rows with actual thumbnails 2025-06-20 16:26:33 +05:30
ashilkn
bb75627383 Populate grid rows with placeholders 2025-06-20 16:00:21 +05:30
ashilkn
828ade2609 Get a bare-bones structure of the new gallery working 2025-06-20 14:54:47 +05:30
ashilkn
36880fac6d Custom render sliver for a completely lazyloading gallery and improved scroll performance 2025-06-20 10:40:28 +05:30
ashilkn
328b2f5961 Create FixedExtentSectionLayout to keep layout data of each section (group) in gallery 2025-06-20 09:51:57 +05:30
ashilkn
3244686058 Create GallerySections model for holding data about a gallery 2025-06-20 09:50:16 +05:30
160 changed files with 8486 additions and 2797 deletions

View File

@@ -1,70 +0,0 @@
name: "Windows build & Sign (auth)"
on:
workflow_dispatch: # Allow manually running the action
env:
FLUTTER_VERSION: "3.24.3"
permissions:
contents: write
jobs:
build-windows:
runs-on: windows-latest
environment: "auth-win-build"
defaults:
run:
working-directory: mobile/apps/auth
steps:
- name: Checkout code and submodules
uses: actions/checkout@v4
with:
submodules: recursive
- name: Install Flutter ${{ env.FLUTTER_VERSION }}
uses: subosito/flutter-action@v2
with:
channel: "stable"
flutter-version: ${{ env.FLUTTER_VERSION }}
cache: true
- name: Create artifacts directory
run: mkdir artifacts
- name: Build Windows installer
run: |
flutter config --enable-windows-desktop
# dart pub global activate flutter_distributor
dart pub global activate --source git https://github.com/ente-io/flutter_distributor_fork --git-ref develop --git-path packages/flutter_distributor
make innoinstall
flutter_distributor package --platform=windows --targets=exe --skip-clean
mv dist/**/*-windows-setup.exe artifacts/ente-${{ github.ref_name }}-installer.exe
- name: Retain Windows EXE and DLLs
run: cp -r build/windows/x64/runner/Release ente-${{ github.ref_name }}-windows
- name: Sign files with Trusted Signing
uses: azure/trusted-signing-action@v0
with:
azure-tenant-id: ${{ secrets.AZURE_TENANT_ID }}
azure-client-id: ${{ secrets.AZURE_CLIENT_ID }}
azure-client-secret: ${{ secrets.AZURE_CLIENT_SECRET }}
endpoint: ${{ secrets.AZURE_ENDPOINT }}
trusted-signing-account-name: ${{ secrets.AZURE_CODE_SIGNING_NAME }}
certificate-profile-name: ${{ secrets.AZURE_CERT_PROFILE_NAME }}
files: |
${{ github.workspace }}/mobile/apps/auth/artifacts/ente-${{ github.ref_name }}-installer.exe
${{ github.workspace }}/mobile/apps/auth/ente-${{ github.ref_name }}-windows/auth.exe
file-digest: SHA256
timestamp-rfc3161: http://timestamp.acs.microsoft.com
timestamp-digest: SHA256
- name: Zip Windows EXE and DLLs
run: tar.exe -a -c -f artifacts/ente-${{ github.ref_name }}-windows.zip ente-${{ github.ref_name }}-windows
- name: Generate checksums
run: sha256sum artifacts/ente-* > artifacts/sha256sum-windows

View File

@@ -4,7 +4,7 @@ on:
workflow_dispatch: # Allow manually running the action
env:
FLUTTER_VERSION: "3.24.3"
FLUTTER_VERSION: "3.27.4"
permissions:
contents: write

View File

@@ -8,7 +8,7 @@ on:
- ".github/workflows/mobile-lint.yml"
env:
FLUTTER_VERSION: "3.24.3"
FLUTTER_VERSION: "3.27.4"
permissions:
contents: read

View File

@@ -9,7 +9,7 @@ on:
- "photos-v*"
env:
FLUTTER_VERSION: "3.24.3"
FLUTTER_VERSION: "3.27.4"
permissions:
contents: write

View File

@@ -0,0 +1,190 @@
name: "Internal Release V2 (photos)"
on:
workflow_dispatch: # Manual trigger only
env:
FLUTTER_VERSION: "3.27.4"
ANDROID_KEYSTORE_PATH: "keystore/ente_photos_key.jks"
jobs:
build:
runs-on: macos-15 # Required for iOS builds
environment: "ios-build"
permissions:
contents: write
defaults:
run:
working-directory: mobile/apps/photos
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
submodules: recursive
- name: Install Apple Certificate
env:
MAC_OS_CERTIFICATE: ${{ secrets.MAC_OS_CERTIFICATE }}
MAC_OS_CERTIFICATE_PASSWORD: ${{ secrets.MAC_OS_CERTIFICATE_PASSWORD }}
KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }}
run: |
# Create variables
CERTIFICATE_PATH=$RUNNER_TEMP/build_certificate.p12
KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db
# Import certificate from secrets
echo -n "$MAC_OS_CERTIFICATE" | base64 --decode -o $CERTIFICATE_PATH
# Create temporary keychain
security create-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
security set-keychain-settings -lut 21600 $KEYCHAIN_PATH
security unlock-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
# Import certificate to keychain
security import $CERTIFICATE_PATH -P "$MAC_OS_CERTIFICATE_PASSWORD" -A -t cert -f pkcs12 -k $KEYCHAIN_PATH
security set-key-partition-list -S apple-tool:,apple: -k "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
# Make the keychain the default
security list-keychain -d user -s $KEYCHAIN_PATH
- name: Add provisioning profiles
run: |
# Decode and install all provisioning profiles
PROFILES_HOME="$HOME/Library/MobileDevice/Provisioning Profiles"
mkdir -p "$PROFILES_HOME"
IFS=$'\n'
for profile in ${{ secrets.MAC_OS_PROFILES_BASE64 }}; do
PROFILE_PATH="$(mktemp "$PROFILES_HOME"/$(uuidgen).mobileprovision)"
echo "$profile" | base64 --decode > "$PROFILE_PATH"
echo "Saved provisioning profile to $PROFILE_PATH"
done
# Common Setup
- name: Setup JDK 17
uses: actions/setup-java@v1
with:
java-version: 17
- name: Install Flutter
uses: subosito/flutter-action@v2
with:
flutter-version: ${{ env.FLUTTER_VERSION }}
cache: true
- name: Get Flutter dependencies
run: flutter pub get
# Android Build
- name: Setup Android signing key
uses: timheuer/base64-to-file@v1
with:
fileName: ${{ env.ANDROID_KEYSTORE_PATH }}
encodedString: ${{ secrets.SIGNING_KEY_PHOTOS }}
# - name: Build Android AAB
# run: |
# flutter build appbundle \
# --dart-define=cronetHttpNoPlay=true \
# --release \
# --flavor playstore
# env:
# SIGNING_KEY_PATH: ${{ env.ANDROID_KEYSTORE_PATH }}
# SIGNING_KEY_ALIAS: ${{ secrets.SIGNING_KEY_ALIAS_PHOTOS }}
# SIGNING_KEY_PASSWORD: ${{ secrets.SIGNING_KEY_PASSWORD_PHOTOS }}
# SIGNING_STORE_PASSWORD: ${{ secrets.SIGNING_STORE_PASSWORD_PHOTOS }}
# iOS Build (new secure implementation)
- name: Install fastlane
run: gem install fastlane
- name: Update CocoaPods Specs
run: pod repo update
working-directory: mobile/apps/photos/ios
- name: Install CocoaPods dependencies
run: |
rm -f Podfile.lock
pod install
working-directory: mobile/apps/photos/ios
- name: Create ExportOptions.plist
run: |
cat <<EOF > ios/ExportOptions.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>method</key>
<string>app-store</string>
<key>teamID</key>
<string>${{ secrets.IOS_TEAM_ID }}</string>
<key>provisioningProfiles</key>
<dict>
<key>io.ente.photos</key>
<string>match AppStore io.ente.photos</string>
<key>io.ente.frame</key>
<string>match AppStore io.ente.frame</string>
<key>io.ente.frame.EntePeopleWidget</key>
<string>match AppStore io.ente.frame.EntePeopleWidget</string>
<key>io.ente.frame.EnteAlbumWidget</key>
<string>match AppStore io.ente.frame.EnteAlbumWidget</string>
<key>io.ente.frame.EnteMemoryWidget</key>
<string>match AppStore io.ente.frame.EnteMemoryWidget</string>
</dict>
</dict>
</plist>
EOF
- name: Setup App Store Connect API Key
run: |
echo '${{ secrets.IOS_API_KEY }}' > api_key.json
chmod 600 api_key.json
- name: Build iOS IPA
run: |
flutter build ipa \
--release \
--export-options-plist=ios/ExportOptions.plist \
--dart-define=cronetHttpNoPlay=true
env:
SIGNING_TEAM_ID: ${{ secrets.IOS_TEAM_ID }}
# Uploads
# - name: Upload to Play Store
# uses: r0adkll/upload-google-play@v1
# with:
# serviceAccountJsonPlainText: ${{ secrets.SERVICE_ACCOUNT_JSON }}
# packageName: io.ente.photos
# releaseFiles: build/app/outputs/bundle/playstoreRelease/app-playstore-release.aab
# track: internal
- name: Upload to TestFlight
run: |
fastlane pilot upload \
--api_key_path api_key.json \
--ipa "build/ios/ipa/Ente Photos.ipa" \
--skip_waiting_for_build_processing \
--apple_id ${{ secrets.IOS_APPLE_ID }} \
--app_identifier "io.ente.photos"
env:
APP_STORE_CONNECT_API_KEY_ID: ${{ secrets.IOS_API_KEY_ID }}
APP_STORE_CONNECT_ISSUER_ID: ${{ secrets.IOS_ISSUER_ID }}
FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD: ${{ secrets.IOS_APP_SPECIFIC_PASSWORD }}
- name: Clean sensitive files
run: |
rm -f api_key.json
rm -f ${{ env.ANDROID_KEYSTORE_PATH }}
- name: Notify Discord
uses: sarisia/actions-status-discord@v1
with:
webhook: ${{ secrets.DISCORD_INTERNAL_RELEASE_WEBHOOK }}
title: "🚀 Dual Platform Release Uploaded"
description: |
**Android**: [Play Store Internal](https://play.google.com/store/apps/details?id=io.ente.photos)
**iOS**: TestFlight build processing
color: 0x00ff00

View File

@@ -26,6 +26,9 @@ export default defineConfig({
},
},
sidebar: sidebar,
outline: {
level: [2, 3],
},
socialLinks: [
{ icon: "github", link: "https://github.com/ente-io/ente/" },
{ icon: "twitter", link: "https://twitter.com/enteio" },

View File

@@ -207,22 +207,22 @@ export const sidebar = [
text: "Migration",
collapsed: true,
items: [
{ text: "Introduction", link: "/auth/migration-guides/" },
{ text: "Introduction", link: "/auth/migration/" },
{
text: "From Authy",
link: "/auth/migration-guides/authy/",
link: "/auth/migration/authy/",
},
{
text: "From Steam",
link: "/auth/migration-guides/steam/",
link: "/auth/migration/steam/",
},
{
text: "From others",
link: "/auth/migration-guides/import",
link: "/auth/migration/import",
},
{
text: "Exporting your data",
link: "/auth/migration-guides/export",
link: "/auth/migration/export",
},
],
},
@@ -239,76 +239,84 @@ export const sidebar = [
],
},
{
text: "Self hosting",
text: "Self-hosting",
collapsed: true,
items: [
{ text: "Getting started", link: "/self-hosting/" },
{
text: "Connecting to custom server",
link: "/self-hosting/guides/custom-server/",
text: "Quickstart",
link: "/self-hosting/",
},
{
text: "Creating accounts",
link: "/self-hosting/creating-accounts",
},
{
text: "Configuring your server",
link: "/self-hosting/museum",
},
{
text: "Configuring S3",
link: "/self-hosting/guides/configuring-s3",
},
{
text: "Reverse proxy",
link: "/self-hosting/reverse-proxy",
},
{
text: "Guides",
text: "Installation",
collapsed: true,
items: [
{ text: "Introduction", link: "/self-hosting/guides/" },
{
text: "Administering your server",
link: "/self-hosting/guides/admin",
text: "Requirements",
link: "/self-hosting/installation/requirements",
},
{
text: "Configuring CLI for your instance",
link: "/self-hosting/guides/selfhost-cli",
text: "Quickstart script (Recommended)",
link: "/self-hosting/installation/quickstart",
},
{
text: "Running Ente from source",
link: "/self-hosting/guides/from-source",
text: "Docker Compose",
link: "/self-hosting/installation/compose",
},
{
text: "Running Ente without Docker",
link: "/self-hosting/guides/standalone-ente",
text: "Manual setup (without Docker)",
link: "/self-hosting/installation/manual",
},
{
text: "Environment variables and defaults",
link: "/self-hosting/installation/env-var",
},
{
text: "Configuration",
link: "/self-hosting/installation/config",
},
{
text: "Post-installation steps",
link: "/self-hosting/installation/post-install/",
},
{
text: "Upgrade",
link: "/self-hosting/installation/upgrade",
},
],
},
{
text: "Troubleshooting",
text: "Administration",
collapsed: true,
items: [
{
text: "General",
link: "/self-hosting/troubleshooting/misc",
text: "User management",
link: "/self-hosting/administration/users",
},
{
text: "Bucket CORS",
link: "/self-hosting/troubleshooting/bucket-cors",
text: "Reverse proxy",
link: "/self-hosting/administration/reverse-proxy",
},
{
text: "Uploads",
link: "/self-hosting/troubleshooting/uploads",
text: "Object storage",
link: "/self-hosting/administration/object-storage",
},
{
text: "Docker / quickstart",
link: "/self-hosting/troubleshooting/docker",
text: "Ente CLI",
link: "/self-hosting/administration/cli",
},
{
text: "Ente CLI secrets",
link: "/self-hosting/troubleshooting/keyring",
text: "Backup",
link: "/self-hosting/administration/backup",
},
],
},
{
text: "Development",
collapsed: true,
items: [
{
text: "Building mobile apps",
link: "/self-hosting/development/mobile-build",
},
],
},
@@ -321,31 +329,26 @@ export const sidebar = [
link: "/self-hosting/guides/tailscale",
},
{
text: "Ente with External S3",
link: "/self-hosting/guides/external-s3",
text: "Running Ente using systemd",
link: "/self-hosting/guides/systemd",
},
],
},
{
text: "FAQ",
text: "Troubleshooting",
collapsed: true,
items: [
{ text: "General", link: "/self-hosting/faq/" },
{
text: "Verification code",
link: "/self-hosting/faq/otp",
text: "General",
link: "/self-hosting/troubleshooting/misc",
},
{
text: "Shared albums",
link: "/self-hosting/faq/sharing",
text: "Uploads",
link: "/self-hosting/troubleshooting/uploads",
},
{
text: "Backups",
link: "/self-hosting/faq/backup",
},
{
text: "Environment variables",
link: "/self-hosting/faq/environment",
text: "Docker / quickstart",
link: "/self-hosting/troubleshooting/docker",
},
],
},

View File

@@ -105,8 +105,7 @@ Ente Auth offers various import and export options for your codes.
automatically via the CLI.
- **Import:** Import codes from various other authentication apps.
For detailed instructions, refer to the
[migration guides](../migration-guides/).
For detailed instructions, refer to the [migration guides](../migration/).
### Deduplicate codes

View File

@@ -6,7 +6,7 @@ description: >
# Welcome!
![Ducky: Ente's Mascot](/public/ducky.png){width=50% style="margin: 0 auto"}
![Ducky: Ente's Mascot](/ducky.png){width=50% style="margin: 0 auto"}
## Introduction
@@ -14,16 +14,16 @@ Ente (pronounced en-_tay_) is a end-to-end encrypted platform for privately,
reliably, and securely storing your data on the cloud, over which 2 applications
have been developed and made available for mobile, web and desktop, namely:
- **Ente Photos** - An alternative to Google Photos and Apple Photos
- **Ente Auth** - A free 2FA alternative to Authy
- **Ente Photos** - An alternative to Google Photos and Apple Photos.
- **Ente Auth** - A free 2FA alternative to Authy.
## History
Ente was the founded by Vishnu Mohandas (he's also Ente's CEO) in response to
privacy concerns with major tech companies. The underlying motivation was the
understanding that big tech had no incentive to fix their act, but with
end-to-end encrypted cross platform apps, there was a way for people to take
back control over their own data without sacrificing on features.
Ente was founded by Vishnu Mohandas (Ente's CEO) in response to privacy concerns
with major tech companies. The underlying motivation was the understanding that
big tech had no incentive to fix their act, but with end-to-end encrypted cross
platform apps, there was a way for people to take back control over their own
data without sacrificing on features.
### Origin of the name
@@ -76,7 +76,7 @@ and stay updated:
If you encounter any issues with any of the products that's not answered by our
documentation, please reach out to our team by sending an email to
[support@ente.io](mailto:support@ente.io)
[support@ente.io](mailto:support@ente.io).
For community support, please post your queries on
[Discord](https://discord.gg/z2YVKkycX3)
For community support, please post your queries on our
[Discord](https://discord.gg/z2YVKkycX3) server.

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 154 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

View File

@@ -0,0 +1,47 @@
---
title: Backups - Self-hosting
description: General introduction to backing up your self hosted Ente instance
---
# Backing up your Ente instance
A functional Ente backend needs three things:
1. Museum (the API server)
2. Postgres (the database)
3. Object storage (any S3-compatible object storage)
Thus, when thinking about backups:
1. For Museum, you should backup your `museum.yaml`, `credentials.yaml` or any
other custom configuration that you created.
2. The entire data volume needs to be backed up for the database and object
storage.
A common oversight is taking a lot of care for backing up the object storage,
even going as far as enabling replication and backing up the the multiple object
storage volumes, but not applying the same care to the database backup.
While the actual encrypted photos are indeed stored in the object storage,
**this encrypted data will not be usable without the database** since the
database contains information like a file specific encryption key.
Viewed differently, to decrypt your data you need three pieces of information:
1. The encrypted file data itself (which comes from the object storage backup).
2. The encrypted file and collection specific encryption keys (which come from
the database backup).
3. The master key (which comes from your password).
If you're starting out with self hosting, we recommend keeping plaintext backup
of your photos.
[You can use the CLI or the desktop app to automate this](/photos/faq/export).
Once you get more comfortable with the various parts, you can try backing up
your instance.
If you rely on your instance backup, ensure that you do full restoration to
verify that you are able to access your data.
As the industry saying goes, a backup without a restore is no backup at all.

View File

@@ -0,0 +1,83 @@
---
title: Ente CLI for Self-hosted Instance - Self-hosting
description: Guide to configuring Ente CLI for Self Hosted Instance
---
# Ente CLI for self-hosted instance
If you are self-hosting, you can configure Ente CLI to export data & perform
basic administrative actions.
## Step 1: Configure endpoint
To do this, first configure the CLI to use your server's endpoint.
Define `config.yaml` and place it in `~/.ente/` or directory specified by
`ENTE_CLI_CONFIG_DIR` or directory where Ente CLI is present.
```yaml
# Set the API endpoint to your domain where Museum is being served.
endpoint:
api: http://localhost:8080
```
## Step 2: Whitelist admins
You can whitelist administrator users by following this
[guide](/self-hosting/administration/users#whitelist-admins).
## Step 3: Add an account
::: info You can not create new accounts using Ente CLI.
You can only log in to your existing accounts.
To create a new account, use Ente Photos (or Ente Auth) web application, desktop
or mobile.
:::
You can add your existing account using Ente CLI.
```shell
ente account add
```
This should prompt you for authentication details and export directory. Your
account should be added after successful authentication.
It can be used for exporting data (for plain-text backup), managing Ente Auth
and performing administrative actions.
## Step 4: Increase storage and account validity
You can use `ente admin update-subscription` to increase storage quota and
account validity (duration).
For infinite storage and validity, use the following command:
```shell
ente admin update-subscription -a <admin-user-mail> -u <user-email-to-update> --no-limit
# Set a limit
ente admin update-subscription -a <admin-user-mail> -u <user-email-to-update> --no-limit False
```
::: info The users must be registered on the server with same e-mail address.
If the commands are failing, ensure:
1. `<admin-user-mail>` is whitelisted as administrator user in `museum.yaml`.
For more information, check this
[guide](/self-hosting/administration/users#whitelist-admins).
2. `<user-email-to-update>` is a registered user with completed verification.
:::
For more information, check out the documentation for setting
[storage and account validity](https://github.com/ente-io/ente/blob/main/cli/docs/generated/ente_admin_update-subscription.md)
using the CLI.
## References
1. [Ente CLI Documentation](https://github.com/ente-io/ente/blob/main/cli/docs/generated)

View File

@@ -0,0 +1,139 @@
---
title: Configuring Object Storage - Self-hosting
description:
Configure Object Storage for storing files along with some troubleshooting
tips
---
# Configuring Object Storage
Ente relies on [S3-compatible](https://docs.aws.amazon.com/s3/) cloud storage
for storing files (photos, thumbnails and videos) as objects.
Ente ships MinIO as S3-compatible storage by default in quickstart and Docker
Compose for quick testing.
This document outlines configuration of S3 buckets and enabling replication for
further usage.
## Museum
The S3-compatible buckets have to be configured in `museum.yaml` file.
### General Configuration
Some of the common configuration that can be done at top-level are:
1. **SSL Configuration:** If you need to configure SSL (i. e., the buckets are
accessible via HTTPS), you'll need to set `s3.are_local_buckets` to `false`.
2. **Path-style URLs:** Disabling `s3.are_local_buckets` also switches to the
subdomain-style URLs for the buckets. However, some S3 providers such as
MinIO do not support this.
Set `s3.use_path_style_urls` to `true` for such cases.
### Replication
> [!IMPORTANT]
>
> Replication works only if all 3 storage buckets are configured (2 hot and 1
> cold storage).
>
> For more information, check
> [this discussion](https://github.com/ente-io/ente/discussions/3167#discussioncomment-10585970)
> and our article on ensuring [reliability](https://ente.io/reliability/).
Replication is disabled by default in self-hosted instance. Only the first
bucket (`b2-eu-cen`) is used.
Only the names are specifically fixed, you can put any other keys in
configuration body.
Use the `s3.hot_storage.primary` option if you'd like to set one of the other
pre-defined buckets as the primary bucket.
### Bucket configuration
The keys `b2-eu-cen` (primary storage), `wasabi-eu-central-2-v3` (secondary
storage) and `scw-eu-fr-v3` (cold storage) are hardcoded, however, the keys and
secret can be anything.
It has no relation to Backblaze, Wasabi or Scaleway.
Each bucket's endpoint, region, key and secret should be configured accordingly
if using an external bucket.
Additionally, you can enable SSL and path-style URL for specific buckets, which
provides flexibility for storage. If this is not configured, top level
configuration (`s3.are_local_buckets` and `s3.use_path_style_urls`) is used.
A sample configuration for `b2-eu-cen` is provided, which can be used for other
2 buckets as well:
```yaml
b2-eu-cen:
are_local_buckets: true
use_path_style_urls: true
key: <key>
secret: <secret>
endpoint: localhost:3200
region: eu-central-2
bucket: b2-eu-cen
```
## CORS (Cross-Origin Resource Sharing)
If you cannot upload a photo due to CORS error, you need to fix the CORS
configuration of your bucket.
Use the content provided below for creating a `cors.json` file:
```json
{
"CORSRules": [
{
"AllowedOrigins": ["*"],
"AllowedHeaders": ["*"],
"AllowedMethods": ["GET", "HEAD", "POST", "PUT", "DELETE"],
"MaxAgeSeconds": 3000,
"ExposeHeaders": ["Etag"]
}
]
}
```
You may have to change the `AllowedOrigins` to allow only certain origins (your
Ente web apps and Museum) for security.
Assuming you have AWS CLI on your system and that you have configured it with
your access key and secret, you can execute the below command to set bucket
CORS. Make sure to enter the right path for the `cors.json` file.
```shell
aws s3api put-bucket-cors --bucket YOUR_S3_BUCKET --cors-configuration /path/to/cors.json
```
### MinIO
Assuming you have configured an alias for MinIO account using the command:
```shell
mc alias set storage-account-alias minio-endpoint minio-key minio-secret
```
where,
1. `storage-account-alias` is a valid storage account alias name
2. `minio-endpoint` is the endpoint where MinIO is being served without the
protocol (http or https). Example: `localhost:3200`
3. `minio-key` is the MinIO username defined in `MINIO_ROOT_USER`
4. `minio-secret` is the MinIO password defined in `MINIO_PASSWORD`
To set the `AllowedOrigins` Header, you can use the following command:.
```shell
mc admin config set storage-account-alias api cors_allow_origin="*"
```
You can create also `.csv` file and dump the list of origins you would like to
allow and replace the `*` with path to the CSV file.

View File

@@ -0,0 +1,101 @@
---
Title: Configuring Reverse Proxy - Self-hosting
Description: Configuring reverse proxy for Museum and other services
---
# Reverse proxy
Reverse proxy helps in making application services accessible via the Internet
without exposing multiple ports for various services.
It also allows configuration of HTTPS through SSL certificate management.
We highly recommend using HTTPS for Museum (Ente's server). For security
reasons, Museum will not accept incoming HTTP traffic.
## Pre-requisites
1. **Reverse Proxy:** We recommend using Caddy for simplicity of configuration
and automatic certificate generation and management, although you can use
other alternatives such as NGINX, Traefik, etc.
Install Caddy using the following command on Debian/Ubuntu-based systems:
```shell
sudo apt install caddy
```
Start the service and enable it to start upon system boot.
```shell
sudo systemctl start caddy
sudo systemctl enable caddy
```
## Step 1: Configure A or AAAA records
Set up the appropriate records for the endpoints in your DNS management
dashboard (usually associated with your domain registrar).
`A` or `AAAA` records pointing to your server's IP address are sufficient.
DNS propagation can take a few minutes to take effect.
![cloudflare](/cloudflare.png)
## Step 2: Configure reverse proxy
After installing Caddy, `Caddyfile` is created at `/etc/caddy/`. Edit
`/etc/caddy/Caddyfile` to configure reverse proxies.
You can edit the minimal configuration provided below for your own needs.
> yourdomain.tld is an example. Replace it with your own domain.
```groovy
# For Museum
api.ente.yourdomain.tld {
reverse_proxy http://localhost:8080
}
# For Ente Photos web app
web.ente.yourdomain.tld {
reverse_proxy http://localhost:3000
}
# For Ente Accounts web app
accounts.ente.yourdomain.tld {
reverse_proxy http://localhost:3001
}
# For Ente Albums web app
albums.ente.yourdomain.tld {
reverse_proxy http://localhost:3002
}
# For Ente Auth web app
auth.ente.yourdomain.tld {
reverse_proxy http://localhost:3003
}
# For Ente Cast web app
cast.ente.yourdomain.tld {
reverse_proxy http://localhost:3004
}
```
## Step 3: Reload reverse proxy
Reload Caddy for changes to take effect.
```shell
sudo systemctl caddy reload
```
## Step 4: Verify the setup
Ente Photos web app should be up on https://web.ente.yourdomain.tld and Museum
at https://api.ente.yourdomain.tld.
> [!TIP] If you are using other reverse proxy servers such as NGINX, Traefik,
> etc., please check out their documentation.

View File

@@ -0,0 +1,139 @@
---
title: User Management - Self-hosting
description: Guide to configuring Ente CLI for Self Hosted Instance
---
# User Management
You may wish to self-host Ente for your family or close circle. In such cases,
you may wish to enable administrative access for few users, disable new
registrations, manage one-time tokens (OTTs), etc.
This document covers the details on how you can administer users on your server.
## Whitelist admins
The administrator users have to be explicitly whitelisted in `museum.yaml`. You
can achieve this the following steps:
1. Connect to `ente_db` (the database used for storing data related to Ente).
```shell
# Change the DB name and DB user name if you use different
# values.
# If using Docker
docker exec -it <postgres-ente-container-name>
psql -U pguser -d ente_db
# Or when using psql directly
psql -U pguser -d ente_db
```
2. Get the user ID of the first user by running the following SQL query:
```sql
SELECT * from users;
```
3. Edit `internal.admins` or `internal.admin` (if you wish to whitelist only
single user) in `museum.yaml` to add the user ID you wish to whitelist.
- For multiple admins:
```yaml
internal:
admins:
- <user_id>
```
- For single admin:
```yaml
internal:
admin: <user_id>
```
4. Restart Museum by restarting the cluster
::: tip Restart your Compose clusters whenever you make changes
If you have edited the Compose file or configuration file (`museum.yaml`), make
sure to recreate the cluster's containers.
You can do this by the following command:
```shell
docker compose down && docker compose up -d
```
:::
## Increase storage and account validity
You can use Ente CLI for increasing storage quota and account validity for users
on your instance. Check this guide for more
[information](/self-hosting/administration/cli#step-4-increase-storage-and-account-validity)
## Handle user verification codes
Ente currently relies on verification codes for completion of registration.
These are accessible in server logs. If using Docker Compose, they can be
accessed by running `sudo docker compose logs` in the cluster folder where
Compose file resides.
However, you may wish to streamline this workflow. You can follow one of the 2
methods if you wish to have many users in the system.
### Use hardcoded OTTs
You can configure to use hardcoded OTTs only for specific emails, or based on
suffix.
A sample configuration for the same is provided below, which is to be used in
`museum.yaml`:
```yaml
internal:
hardcoded-ott:
emails:
- "example@example.org,123456"
local-domain-suffix: "@example.org"
local-domain-value: 012345
```
This sets OTT to 123456 for the email address example@example.com and 012345 for
emails having @example.com as suffix.
### Send email with verification code
You can configure SMTP for sending verification code e-mails to users, which is
efficient if you do not know mail addresses of people for who you want to
hardcode OTTs or if you are serving larger audience.
Set the host and port accordingly with your credentials in `museum.yaml`
```yaml
smtp:
host:
port:
# Optional username and password if using local relay server
username:
password:
# Email address used for sending emails (this mail's credentials have to be provided)
email:
# Optional name for sender
sender-name:
```
## Disable registrations
For security purposes, you may choose to disable registrations on your instance.
You can disable new registrations by using the following configuration in
`museum.yaml`.
```yaml
internal:
disable-registration: true
```

View File

@@ -1,27 +0,0 @@
---
title: Creating accounts
description: Creating accounts on your deployment
---
# Creating accounts
Once Ente is up and running, the Ente Photos web app will be accessible on
`http://localhost:3000`. Open this URL in your browser and proceed with creating
an account.
The default API endpoint for museum will be `localhost:8080`.
![endpoint](/endpoint.png)
To complete your account registration you will need to enter a 6-digit
verification code.
This code can be found in the server logs, which should already be shown in your
quickstart terminal. Alternatively, you can open the server logs with the
following command from inside the `my-ente` folder:
```sh
sudo docker compose logs
```
![otp](/otp.png)

View File

@@ -1,65 +0,0 @@
---
title: Backups
description: General introduction to backing up your self hosted Ente instance
---
# Backing up your Ente instance
> [!WARNING]
>
> This is not meant to be a comprehensive and bullet proof guide. There are many
> moving parts, and small mistakes might make your backups unusable.
>
> Please treat this only as a general introduction. And remember to test your
> restores.
At the minimum, a functional Ente backend needs three things:
1. Museum (the API server)
2. Postgres (the database)
3. Object storage (any S3-compatible object storage)
When thinking about backups, this translates into backing up the relevant state
from each of these:
1. For museum, you'd want to backup your `museum.yaml`, `credentials.yaml` or
any other custom configuration that you created. In particular, you should
backup the
[secrets that are specific to your instance](https://github.com/ente-io/ente/blob/74377a93d8e20e969d9a2531f32f577b5f0ef090/server/configurations/local.yaml#L188)
(`key.encryption`, `key.hash` and `jwt.secret`).
2. For postgres, the entire data volume needs to be backed up.
3. For object storage, the entire data volume needs to be backed up.
A common oversight is taking a lot of care for backing up the object storage,
even going as far as enabling replication and backing up the the multiple object
storage volumes, but not applying the same care to the database backup.
While the actual encrypted photos are indeed stored in the object storage,
**this encrypted data will not be usable without the database** since the
database contains information like a file specific encryption key.
Viewed differently, to decrypt your data you need three pieces of information:
1. The encrypted file data itself (which comes from the object storage backup).
2. The ([encrypted](https://ente.io/architecture/)) file and collection specific
encryption keys (which come from the database backup).
3. The master key (which comes from your password).
---
If you're starting out with self hosting, our recommendation is to start by
keeping a plaintext backup of your photos.
[You can use the CLI or the desktop app to automate this](/photos/faq/export).
Once you get more comfortable with the various parts, you can try backing up
your instance. As a reference,
[this document outlines how Ente itself treats backups](https://ente.io/reliability).
If you stop doing plaintext backups and instead rely on your instance backup,
ensure that you do the full restore process also to verify you can get back your
data. As the industry saying goes, a backup without a restore is no backup at
all.

View File

@@ -1,52 +0,0 @@
---
title: "Environment Variables and Ports"
description:
"Information about all the Environment Variables needed to run Ente"
---
# Environment variables and ports
A self-hosted Ente instance requires specific endpoints in both Museum (the
server) and web apps. This document outlines the essential environment variables
and port mappings of the web apps.
Here's the list of important variables that a self hoster should know about:
### Museum
1. `NEXT_PUBLIC_ENTE_ENDPOINT`
The above environment variable is used to configure Museums endpoint. Where
Museum is running and which port it is listening on. This endpoint should be
configured for all the apps to connect to your self hosted endpoint.
All the apps (regardless of platform) by default connect to api.ente.io - which
is our production instance of Museum.
### Web Apps
> [!IMPORTANT] Web apps don't need to be configured with the below endpoints.
> Web app environment variables are being documented here just so that the users
> know everything in detail. Checkout
> [Configuring your Server](/self-hosting/museum) to configure endpoints for
> particular app.
In Ente, all the web apps are separate NextJS applications. Therefore, they are
all configured via environment variables. The photos app (Ente Photos) has
information about and connects to other web apps like albums, cast, etc.
1. `NEXT_PUBLIC_ENTE_ALBUMS_ENDPOINT`
This environment variable is used to configure and declare the endpoint for the
Albums web app.
## Ports
The below format is according to how ports are mapped in Docker.
Typically,`<host>:<container-port>`
1. `8080:8080`: Museum (Ente's server)
2. `3000:3000`: Ente Photos web app
3. `3001:3001`: Ente Accounts web app
4. `3003:3003`: [Ente Auth web app](https://ente.io/auth/)
5. `3004:3004`: [Ente Cast web app](http://ente.io/cast)

View File

@@ -1,47 +0,0 @@
---
title: FAQ - Self hosting
description: Frequently asked questions about self hosting Ente
---
# Frequently Asked Questions
### Do Ente Photos and Ente Auth share the same backend?
Yes. The apps share the same backend, the same database and the same object
storage namespace. The same user account works for both of them.
### Can I just self host Ente Auth?
Yes, if you wish, you can self-host the server and use it only for the 2FA auth
app. The starter Docker compose will work fine for either Photos or Auth (or
both!).
> You currently don't need to configure the S3 object storage (e.g. minio
> containers) if you're only using your self hosted Ente instance for auth.
### Can I use the server with _X_ as the object storage?
Yes. As long as whatever X you're using provides an S3 compatible API, you can
use it as the underlying object storage. For example, the starter self-hosting
Docker compose file we offer uses MinIO, and on our production deployments we
use Backblaze/Wasabi/Scaleway. But that's not the full list - as long as the
service you intend to use has a S3 compatible API, it can be used.
### How do I increase storage space for users on my self hosted instance?
See the [guide for administering your server](/self-hosting/guides/admin). In
particular, you can use the `ente admin update-subscription` CLI command to
increase the
[storage and account validity](https://github.com/ente-io/ente/blob/main/cli/docs/generated/ente_admin_update-subscription.md)
of accounts on your instance.
### How can I become an admin on my self hosted instance?
The first user you create on your instance is treated as an admin.
If you want, you can modify this behaviour by providing an explicit list of
admins in the [configuration](/self-hosting/guides/admin#becoming-an-admin).
### Can I disable registration of new accounts on my self hosted instance?
Yes. See `internal.disable-registration` in local.yaml.

View File

@@ -1,45 +0,0 @@
---
title: Verification code
description: Getting the OTP for a self hosted Ente
---
# Verification code
The self-hosted Ente by default does not send out emails, so you can pick the
verification code by:
- Getting it from the server logs, or
- Reading it from the DB (otts table)
The easiest option when getting started is to look for it in the server (museum)
logs. If you're already running the docker compose cluster using the quickstart
script, you should be already seeing the logs in your terminal. Otherwise you
can go to the folder (e.g. `my-ente`) where your `compose.yaml` is, then run
`docker compose logs museum --follow`. Once you can see the logs, look for a
line like:
```
... Skipping sending email to email@example.com: *Verification code: 112089*
```
That is the verification code.
> [!TIP]
>
> You can also configure your instance to send out emails so that you can get
> your verification code via emails by using the `smtp` section in the config.
You can also set pre-defined hardcoded OTTs for certain users when running
locally by creating a `museum.yaml` and adding the `internal.hardcoded-ott`
configuration setting to it. See
[local.yaml](https://github.com/ente-io/ente/blob/main/server/configurations/local.yaml)
in the server source code for details about how to define this.
> [!NOTE]
>
> If you're not able to get the OTP with the above methods, make sure that you
> are actually connecting to your self hosted instance and not to Ente's
> production servers. e.g. you can use the network requests tab in the browser
> console to verify that the API requests are going to your server instead of
> `api.ente.io`.

View File

@@ -1,104 +0,0 @@
---
title: Album sharing
description: Getting album sharing to work using an self-hosted Ente
---
# Is public sharing available for self-hosted instances?
Yes.
You'll need to run two instances of the web app, one is regular web app, but
another one is the same code but running on a different origin (i.e. on a
different hostname or different port).
Then, you need to tell the regular web app to use your second instance to
service public links. You can do this by setting the
`NEXT_PUBLIC_ENTE_ALBUMS_ENDPOINT` to point to your second instance when running
or building the regular web app.
For more details, see
[.env](https://github.com/ente-io/ente/blob/main/web/apps/photos/.env) and
[.env.development](https://github.com/ente-io/ente/blob/main/web/apps/photos/.env.development).
As a concrete example, assuming we have a Ente server running on
`localhost:8080`, we can start two instances of the web app, passing them
`NEXT_PUBLIC_ENTE_ALBUMS_ENDPOINT` that points to the origin
("scheme://host[:port]") of the second "albums" instance.
The first one, the normal web app
```sh
NEXT_PUBLIC_ENTE_ENDPOINT=http://localhost:8080 \
NEXT_PUBLIC_ENTE_ALBUMS_ENDPOINT=http://localhost:3002 \
yarn dev:photos
```
The second one, the same code but acting as the "albums" app (the only
difference is the port it is running on):
```sh
NEXT_PUBLIC_ENTE_ENDPOINT=http://localhost:8080 \
NEXT_PUBLIC_ENTE_ALBUMS_ENDPOINT=http://localhost:3002 \
yarn dev:albums
```
If you also want to change the prefix (the origin) in the generated public
links, to use your custom albums endpoint in the generated public link instead
of albums.ente.io, set `apps.public-albums` property in museum's configuration
For example, when running using the starter docker compose file, you can do this
by creating a `museum.yaml` and defining the following configuration there:
```yaml
apps:
public-albums: http://localhost:3002
```
(For more details, see
[local.yaml](https://github.com/ente-io/ente/blob/main/server/configurations/local.yaml)
in the server's source code).
## Dockerfile example
Here is an example of a Dockerfile by @Dylanger on our community Discord. This
runs a standalone self-hosted version of the public albums app in production
mode.
```Dockerfile
FROM node:20-alpine as builder
WORKDIR /app
COPY . .
ARG NEXT_PUBLIC_ENTE_ENDPOINT=https://your.ente.example.org
ARG NEXT_PUBLIC_ENTE_ALBUMS_ENDPOINT=https://your.albums.example.org
RUN yarn install && yarn build
FROM node:20-alpine
WORKDIR /app
COPY --from=builder /app/apps/photos/out .
RUN npm install -g serve
ENV PORT=3000
EXPOSE ${PORT}
CMD serve -s . -l tcp://0.0.0.0:${PORT}
```
Note that this only runs the public albums app, but the same principle can be
used to run both the normal Ente photos app and the public albums app. There is
a slightly more involved example showing how to do this also provided by in a
community contributed guide about
[configuring external S3](/self-hosting/guides/external-s3).
You will also want to tell museum about your custom shared albums endpoint so
that it uses that instead of the default URL when creating share links. You can
configure that in museum's `config.yaml`:
```
apps:
public-albums: https://your.albums.example.org
```

View File

@@ -1,88 +0,0 @@
---
title: Server admin
description: Administering your custom self-hosted Ente instance using the CLI
---
## Becoming an admin
By default, the first user (and only the first user) created on the system is
considered as an admin.
This facility is provided as a convenience for people who are getting started
with self hosting. For more serious deployments, we recommend creating an
explicit whitelist of admins.
> [!NOTE]
>
> The first user is only treated as the admin if the list of admins in the
> configuration is empty.
>
> Also, if at some point you delete the first user, then you will need to define
> a whitelist to make some other user as the admin if you wish (since the first
> account has been deleted).
To whitelist the user IDs that can perform admin actions on the server, use the
following steps:
- Create a `museum.yaml` in the directory where you're starting museum from. For
example, if you're running using `docker compose up`, then this file should be
in the same directory as `compose.yaml` (generally, `server/museum.yaml`).
> Docker might've created an empty `museum.yaml` _directory_ on your machine
> previously. If so, delete that empty directory and create a new file named
> `museum.yaml`.
- In this `museum.yaml` we can add overrides over the default configuration.
For whitelisting the admin userIDs we need to define an `internal.admins`. See
the "internal" section in
[local.yaml](https://github.com/ente-io/ente/blob/main/server/configurations/local.yaml)
in the server source code for details about how to define this.
Here is an example. Suppose we wanted to whitelist a user with ID
`1580559962386440`, we can create the following `museum.yaml`
```yaml
internal:
admins:
- 1580559962386440
```
You can use
[account list](https://github.com/ente-io/ente/blob/main/cli/docs/generated/ente_account_list.md)
command to find the user id of any account.
# Administering your custom server
> [!NOTE] For the first user (admin) to perform administrative actions using the
> CLI, their userID must be whitelisted in the `museum.yaml` configuration file
> under `internal.admins`. While the first user is automatically granted admin
> privileges on the server, this additional step is required for CLI operations.
You can use
[Ente's CLI](https://github.com/ente-io/ente/releases?q=tag%3Acli-v0) to
administer your self hosted server.
First we need to get your CLI to connect to your custom server. Define a
config.yaml and put it either in the same directory as CLI or path defined in
env variable `ENTE_CLI_CONFIG_PATH`
```yaml
endpoint:
api: "http://localhost:8080"
```
Now you should be able to
[add an account](https://github.com/ente-io/ente/blob/main/cli/docs/generated/ente_account_add.md),
and subsequently increase the
[storage and account validity](https://github.com/ente-io/ente/blob/main/cli/docs/generated/ente_admin_update-subscription.md)
using the CLI.
> [!NOTE]
>
> The CLI command to add an account does not create Ente accounts. It only adds
> existing accounts to the list of (existing) accounts that the CLI can use.
## Backups
See this [FAQ](/self-hosting/faq/backup).

View File

@@ -1,123 +0,0 @@
---
title: Configuring S3 buckets
description:
Configure S3 endpoints to fix upload errors or use your self hosted ente
from outside localhost
---
# Architecture
![Client, Museum, S3](/client-museum-s3.png)
There are three components involved in uploading a file:
1. The client (e.g. the web app or the mobile app)
2. Ente's server (museum)
3. The S3-compatible object storage (e.g. MinIO in the default starter)
For the uploads to work, all three of them need to be able to reach each other.
This is because the client uploads directly to the object storage.
A file upload flows as follows:
1. Client that wants to upload a file asks museum where it should upload the
file to
2. museum creates pre-signed URLs for the S3 bucket that was configured
3. Client directly uploads to the S3 buckets these URLs
4. Client finally informs museum that a file has been uploaded to this URL
The upshot of this is that _both_ the client and museum should be able to reach
your S3 bucket.
## Configuring S3
The URL for the S3 bucket is configured in
[scripts/compose/credentials.yaml](https://github.com/ente-io/ente/blob/main/server/scripts/compose/credentials.yaml#L10).
You can edit this file directly while testing, though it is more robust to
create a `museum.yaml` (in the same folder as the Docker compose file) and to
setup your custom configuration there.
> [!TIP] For more details about these configuration objects, see the
> documentation for the `s3` object in
> [configurations/local.yaml](https://github.com/ente-io/ente/blob/main/server/configurations/local.yaml).
By default, you only need to configure the endpoint for the first bucket.
The Docker compose file is shipped with MinIO as the self hosted S3 compatible
storage. By default, MinIO server is served on `localhost:3200` and the MinIO UI
on `localhost:3201`.
For example, in a localhost network situation, the way this connection works is,
museum (`1`) and MinIO (`2`) run on the same Docker network and the web app
(`3`) will also be hosted on your localhost. This enables all the three
components of the setup to communicate with each other seamlessly.
The same principle applies if you're deploying to your custom domain.
## Replication
![Replication](/replication.png)
<p align="center">Community contributed diagram of Ente's replication process</p>
> [!IMPORTANT]
>
> As of now, replication works only if all the 3 storage type needs are
> fulfilled (1 hot, 1 cold and 1 glacier storage).
>
> [Reference](https://github.com/ente-io/ente/discussions/3167#discussioncomment-10585970)
If you're wondering why there are 3 buckets on the MinIO UI - that's because our
production instance uses these to perform
[replication](https://ente.io/reliability/).
If you're also wondering about why the bucket names are specifically what they
are, it's because that is exactly what we are using on our production instance.
We use `b2-eu-cen` as hot, `wasabi-eu-central-2-v3` as cold (also the secondary
hot) and `scw-eu-fr-v3` as glacier storage. As of now, all of this is hardcoded.
Hence, the same hardcoded configuration is applied when you self host Ente.
In a self hosted Ente instance replication is turned off by default. When
replication is turned off, only the first bucket (`b2-eu-cen`) is used, and the
other two are ignored. Only the names here are specifically fixed, but in the
configuration body you can put any other keys. It does not have any relation
with `b2`, `wasabi` or even `scaleway`.
Use the `s3.hot_storage.primary` option if you'd like to set one of the other
predefined buckets as the primary bucket.
## SSL Configuration
> [!NOTE]
>
> If you need to configure SSL, you'll need to turn off `s3.are_local_buckets`
> (which disables SSL in the default starter compose template).
Disabling `s3.are_local_buckets` also switches to the subdomain style URLs for
the buckets. However, not all S3 providers support these. In particular, MinIO
does not work with these in default configuration. So in such cases you'll also
need to enable `s3.use_path_style_urls`.
## Summary
Set the S3 bucket `endpoint` in `credentials.yaml` to a `yourserverip:3200` or
some such IP / hostname that is accessible from both where you are running the
Ente clients (e.g. the mobile app) and also from within the Docker compose
cluster.
### Example
An example `museum.yaml` when you're trying to connect to museum running on your
computer from your phone on the same WiFi network:
```yaml
s3:
are_local_buckets: true
b2-eu-cen:
key: test
secret: testtest
endpoint: http://<YOUR-WIFI-IP>:3200
region: eu-central-2
bucket: b2-eu-cen
```

View File

@@ -1,115 +0,0 @@
---
title: Custom server
description: Using a custom self-hosted server with Ente client apps and CLI
---
# Connecting to a custom server
You can modify various Ente client apps and CLI to connect to a self hosted
custom server endpoint.
[[toc]]
## Mobile
The pre-built Ente apps from GitHub / App Store / Play Store / F-Droid can be
easily configured to use a custom server.
You can tap 7 times on the onboarding screen to bring up a page where you can
configure the endpoint the app should be connecting to.
![Setting a custom server on the onboarding screen](custom-server.png)
## Desktop and web
Same as the mobile app, you can tap 7 times on the onboarding screen to
configure the endpoint the app should connect to.
<div align="center">
![Setting a custom server on the onboarding screen on desktop or self-hosted web
apps](web-dev-settings.png){width=400px}
</div>
This works on both the desktop app and web app (if you deploy on your own).
To make it easier to identify when a custom server is being used, app will
thereafter show the endpoint in use (if not Ente's production server) at the
bottom of the login prompt:
![Custom server indicator on the onboarding screen](web-custom-endpoint-indicator.png)
Similarly, it'll be shown at other screens during the login flow. After login,
you can also see it at the bottom of the sidebar.
Note that the custom server configured this way is cleared when you reset the
state during logout. In particular, the app also does a reset when you press the
change email button during the login flow.
### Building from source
Alternatively (e.g. if you don't wish to configure this setting and just want to
change the endpoint the client connects to by default), you can build the app
from source and use the `NEXT_PUBLIC_ENTE_ENDPOINT` environment variable to tell
it which server to connect to. For example:
```sh
NEXT_PUBLIC_ENTE_ENDPOINT=http://localhost:8080 yarn dev:photos
```
For more details, see
[hosting the web app](https://help.ente.io/self-hosting/guides/web-app).
## CLI
> [!NOTE]
>
> You can download the CLI from
> [here](https://github.com/ente-io/ente/releases?q=tag%3Acli-v0)
Define a config.yaml and put it either in the same directory as where you run
the CLI from ("current working directory"), or in the path defined in env
variable `ENTE_CLI_CONFIG_PATH`:
```yaml
endpoint:
api: "http://localhost:8080"
```
(Another
[example](https://github.com/ente-io/ente/blob/main/cli/config.yaml.example))
## Find the hostname of your server
If you want to access your museum within your own network, you can use the
`hostname` command to find a addressable local network hostname or IP for your
computer, and then use it by suffixing it with the port number.
First, run
```sh
hostname
```
The result will look something like this
```sh
my-computer.local
```
You will need to replace the server endpoint with an address that uses your
server's hostname and the port number. Here's an example:
```
http://my-computer.local:8080
```
Note that this will only work within your network. To access it from outside the
network, you need to use the public IP or hostname.
> [!TIP]
>
> If you're having trouble uploading from your mobile app, it is likely that
> museum is not able to connect to your S3 storage. See the
> [Configuring S3](/self-hosting/guides/configuring-s3) guide for more details.

View File

@@ -1,158 +0,0 @@
---
title: DB Migration
description:
Migrating your self hosted Postgres 12 database to newer Postgres versions
---
# Migrating Postgres 12 to 15
The old sample docker compose file used Postgres 12, which is now nearing end of
life, so we've updated it to Postgres 15. Postgres major versions changes
require a migration step. This document mentions some approaches you can use.
> [!TIP]
>
> Ente itself does not use any specific Postgres 12 or Postgres 15 features, and
> will talk to either happily. It should also work with newer Postgres versions,
> but let us know if you run into any problems and we'll update this page.
### Taking a backup
`docker compose exec` allows us to run a command against a running container. We
can use it to run the `pg_dumpall` command on the postgres container to create a
plaintext backup.
Assuming your cluster is already running, and you are in the `ente/server`
directory, you can run the following (this command uses the default credentials,
you'll need to change these to match your setup):
```sh
docker compose exec postgres env PGPASSWORD=pgpass PGUSER=pguser PG_DB=ente_db pg_dumpall >pg12.backup.sql
```
This will produce a `pg12.backup.sql` in your current directory. You can open it
in a text editor (it can be huge!) to verify that it looks correct.
We won't be needing this file, this backup is recommended just in case something
goes amiss with the actual migration.
> If you need to restore from this plaintext backup, you could subsequently run
> something like:
>
> ```sh
> docker compose up postgres
> cat pg12.backup.sql | docker compose exec -T postgres env PGPASSWORD=pgpass psql -U pguser -d ente_db
> ```
## The migration
At the high level, the steps are
1. Stop your cluster.
2. Start just the postgres container after changing the image to
`pgautoupgrade/pgautoupgrade:15-bookworm`.
3. Once the in-place migration completes, stop the container, and change the
image to `postgres:15`.
#### 1. Stop the cluster
Stop your running Ente cluster.
```sh
docker compose down
```
#### 2. Run `pgautoupgrade`
Modify your `compose.yaml`, changing the image for the "postgres" container from
"postgres:12" to "pgautoupgrade/pgautoupgrade:15-bookworm"
```diff
diff a/server/compose.yaml b/server/compose.yaml
postgres:
- image: postgres:12
+ image: pgautoupgrade/pgautoupgrade:15-bookworm
ports:
```
[pgautoupgrade](https://github.com/pgautoupgrade/docker-pgautoupgrade) is a
community docker image that performs an in-place migration.
After making the change, run only the `postgres` container in the cluster
```sh
docker compose up postgres
```
The container will start and peform an in-place migration. Once it is done, it
will start postgres normally. You should see something like this is the logs
```
postgres-1 | Automatic upgrade process finished with no errors reported
...
postgres-1 | ... starting PostgreSQL 15...
```
At this point, you can stop the container (`CTRL-C`).
#### 3. Finish by changing image
Modify `compose.yaml` again, changing the image to "postgres:15".
```diff
diff a/server/compose.yaml b/server/compose.yaml
postgres:
- image: pgautoupgrade/pgautoupgrade:15-bookworm
+ image: postgres:15
ports:
```
And cleanup the temporary containers by
```sh
docker compose down --remove-orphans
```
Migration is now complete. You can start your Ente cluster normally.
```sh
docker compose up
```
## Migration elsewhere
The above instructions are for Postgres running inside docker, as the sample
docker compose file does. There are myriad other ways to run Postgres, and the
migration sequence then will depend on your exact setup.
Two common approaches are
1. Backup and restore, the `pg_dumpall` + `psql` import sequence described in
[Taking a backup](#taking-a-backup) above.
2. In place migrations using `pg_upgrade`, which is what the
[pgautoupgrade](#the-migration) migration above does under the hood.
The first method, backup and restore, is low tech and will work similarly in
most setups. The second method is more efficient, but requires a bit more
careful preparation.
As another example, here is how one can migrate 12 to 15 when running Postgres
on macOS, installed using Homebrew.
1. Stop your postgres. Make sure there are no more commands shown by
`ps aux | grep '[p]ostgres'`.
2. Install postgres15.
3. Migrate data using `pg_upgrade`:
```sh
/opt/homebrew/Cellar/postgresql@15/15.8/bin/pg_upgrade -b /opt/homebrew/Cellar/postgresql@12/12.18_1/bin -B /opt/homebrew/Cellar/postgresql@15/15.8/bin/ -d /opt/homebrew/var/postgresql@12 -D /opt/homebrew/var/postgresql@15
```
4. Start postgres 15 and verify version using `SELECT VERSION()`.

View File

@@ -1,261 +0,0 @@
---
title: External S3 buckets
description:
Self hosting Ente's server and photos web app when using an external S3
bucket
---
# Hosting server and web app using external S3
> [!NOTE]
>
> This is a community contributed guide, and some of these steps ~~might be~~
> ARE out of sync with the upstream changes. This document is retained for
> reference purposes, but if something is not working correctly, please see the
> latest [READMEs](https://github.com/ente-io/ente/blob/main/server/README.md)
> in the repository and/or other guides in [self-hosting](/self-hosting/).
This guide is for self hosting the server and the web application of Ente Photos
using docker compose and an external S3 bucket. So we assume that you already
have the keys and secrets for the S3 bucket. The plan is as follows:
1. Create a `compose.yaml` file
2. Set up the `.credentials.env` file
3. Run `docker-compose up`
4. Create an account and increase storage quota
5. Fix potential CORS issue with your bucket
## 1. Create a `compose.yaml` file
After cloning the main repository with
```bash
git clone https://github.com/ente-io/ente.git
# Or git clone git@github.com:ente-io/ente.git
cd ente
```
Create a `compose.yaml` file at the root of the project with the following
content (there is nothing to change here):
```yaml
services:
museum:
build:
context: server
args:
GIT_COMMIT: local
ports:
- 8080:8080 # API
- 2112:2112 # Prometheus metrics
depends_on:
postgres:
condition: service_healthy
# Wait for museum to ping pong before starting the webapp.
healthcheck:
test: [
"CMD",
"echo",
"1", # I don't know what to put here
]
environment:
# no need to touch these
ENTE_DB_HOST: postgres
ENTE_DB_PORT: 5432
ENTE_DB_NAME: ente_db
ENTE_DB_USER: pguser
ENTE_DB_PASSWORD: pgpass
env_file:
- ./.credentials.env
volumes:
- custom-logs:/var/logs
- museum.yaml:/museum.yaml:ro
networks:
- internal
web:
build:
context: web
ports:
- 8081:80
- 8082:80
depends_on:
museum:
condition: service_healthy
env_file:
- ./.credentials.env
postgres:
image: postgres:12
ports:
- 5432:5432
environment:
POSTGRES_USER: pguser
POSTGRES_PASSWORD: pgpass
POSTGRES_DB: ente_db
# Wait for postgres to be accept connections before starting museum.
healthcheck:
test: ["CMD", "pg_isready", "-q", "-d", "ente_db", "-U", "pguser"]
interval: 1s
timeout: 5s
retries: 20
volumes:
- postgres-data:/var/lib/postgresql/data
networks:
- internal
volumes:
custom-logs:
postgres-data:
networks:
internal:
```
It maybe be added in the future, but if it does not exist, create a `Dockerfile`
in the `web` directory with the following content:
```Dockerfile
# syntax=docker/dockerfile:1
FROM node:21-bookworm-slim as ente-builder
WORKDIR /app
RUN apt update && apt install -y ca-certificates && rm -rf /var/lib/apt/lists/*
COPY . .
RUN yarn install
ENV NEXT_PUBLIC_ENTE_ENDPOINT=DOCKER_RUNTIME_REPLACE_ENDPOINT
ENV NEXT_PUBLIC_ENTE_ALBUMS_ENDPOINT=DOCKER_RUNTIME_REPLACE_ALBUMS_ENDPOINT
RUN yarn build
FROM nginx:1.25-alpine-slim
COPY --from=ente-builder /app/apps/photos/out /usr/share/nginx/html
COPY <<EOF /etc/nginx/conf.d/default.conf
server {
listen 80 default_server;
root /usr/share/nginx/html;
location / {
try_files \$uri \$uri.html \$uri/ =404;
}
error_page 404 /404.html;
location = /404.html {
internal;
}
}
EOF
ARG ENDPOINT="http://localhost:8080"
ENV ENDPOINT "$ENDPOINT"
ARG ALBUMS_ENDPOINT="http://localhost:8082"
ENV ALBUMS_ENDPOINT "$ALBUMS_ENDPOINT"
COPY <<EOF /docker-entrypoint.d/replace_ente_endpoints.sh
echo "Replacing endpoints"
echo " Endpoint: \$ENDPOINT"
echo " Albums Endpoint: \$ALBUMS_ENDPOINT"
replace_enpoints() {
sed -i -e 's,DOCKER_RUNTIME_REPLACE_ENDPOINT,'"\$ENDPOINT"',g' \$1
sed -i -e 's,DOCKER_RUNTIME_REPLACE_ALBUMS_ENDPOINT,'"\$ALBUMS_ENDPOINT"',g' \$1
}
for jsfile in `find '/usr/share/nginx/html' -type f -name '*.js'`
do
replace_enpoints "\$jsfile"
done
EOF
RUN chmod +x /docker-entrypoint.d/replace_ente_endpoints.sh
```
This runs nginx inside to handle both the web & album URLs so we don't have to
make two web images with different port.
- `DOCKER_RUNTIME_REPLACE_ENDPOINT` this is your public museum API URL.
- `DOCKER_RUNTIME_REPLACE_ALBUMS_ENDPOINT` this is the shared albums URL (for
more details about configuring shared albums, see
[faq/sharing](/self-hosting/faq/sharing)).
Note how above we had updated the `compose.yaml` file for the server with
```yaml
web:
build:
context: web
ports:
- 8081:80
- 8082:80
```
so that web and album both point to the same container and nginx will handle it.
## 2. Set up the `.credentials.env` file
Create a `.credentials.env` file at the root of the project with the following
content (here you need to set the correct value of each variable):
<!-- The following code block should have language env, but vitepress currently
doesn't support that language, so use sh as a reasonable fallback instead. -->
```sh
# run `go run tools/gen-random-keys/main.go` in the server directory to generate the keys
ENTE_KEY_ENCRYPTION=
ENTE_KEY_HASH=
ENTE_JWT_SECRET=
# if you deploy it on a server under a domain, you need to set the correct value of the following variables
# it can be changed later
# The backend server URL (Museum) to be used by the webapp
ENDPOINT=http://localhost:8080
# The URL of the public albums webapp (also need to be updated in museum.yml so the correct links are generated)
ALBUMS_ENDPOINT=http://localhost:8082
```
Create the `museum.yaml` with additional configuration, this will be mounted
(read-only) into the container:
```yaml
s3:
are_local_buckets: false
# For some self-hosted S3 deployments you (e.g. Minio) you might need to disable bucket subdomains
use_path_style_urls: true
# The key must be named like so
b2-eu-cen:
key: $YOUR_S3_KEY
secret: $YOUR_S3_SECRET
endpoint: $YOUR_S3_ENDPOINT
region: $YOUR_S3_REGION
bucket: $YOUR_S3_BUCKET_NAME
# The same value as the one specified in ALBUMS_ENDPOINT
apps:
public-albums: http://localhost:8082
```
## 3. Run `docker-compose up`
Run `docker-compose up` at the root of the project (add `-d` to run it in the
background).
## 4. Create an account and increase storage quota
Open `http://localhost:8080` or whatever Endpoint you mentioned for the web app
and create an account. If your SMTP related configurations are all set and
right, you will receive an email with your OTT in it. There are two work arounds
to retrieve the OTP, checkout
[this document](https://help.ente.io/self-hosting/faq/otp) for getting your
OTT's..
If you successfully log in, select any plan and increase the storage quota with
the following command:
```bash
docker compose exec -i postgres psql -U pguser -d ente_db -c "INSERT INTO storage_bonus (bonus_id, user_id, storage, type, valid_till) VALUES ('self-hosted-myself', (SELECT user_id FROM users), 1099511627776, 'ADD_ON_SUPPORT', 0)"
```
After few reloads, you should see 1 To of quota.
## Related
Some other users have also shared their setups.
- [Using Traefik](https://github.com/ente-io/ente/pull/3663)
- [Building custom images from source (Linux)](https://github.com/ente-io/ente/discussions/3778)
- [Troubleshooting Bucket CORS](/self-hosting/troubleshooting/bucket-cors)

View File

@@ -1,229 +0,0 @@
---
title: Ente from Source
description: Getting started self hosting Ente Photos and/or Ente Auth
---
# Ente from Source
> [!WARNING] NOTE The below documentation will cover instructions about
> self-hosting the web app manually. If you want to deploy Ente hassle free, use
> the [one line](https://ente.io/blog/self-hosting-quickstart/) command to setup
> Ente. This guide might be deprecated in the near future.
## Installing Docker
Refer to
[How to install Docker from the APT repository](https://docs.docker.com/engine/install/ubuntu/#install-using-the-repository)
for detailed instructions.
## Start the server
```sh
git clone https://github.com/ente-io/ente
cd ente/server
docker compose up --build
```
> [!TIP]
>
> You can also use a pre-built Docker image from `ghcr.io/ente-io/server`
> ([More info](https://github.com/ente-io/ente/blob/main/server/docs/docker.md))
Install the necessary dependencies for running the web client
```sh
# installing npm and yarn
sudo apt update
sudo apt install nodejs npm
sudo npm install -g yarn // to install yarn globally
```
Then in a separate terminal, you can run (e.g) the web client
```sh
cd ente/web
git submodule update --init --recursive
yarn install
NEXT_PUBLIC_ENTE_ENDPOINT=http://localhost:8080 yarn dev
```
That's about it. If you open http://localhost:3000, you will be able to create
an account on a Ente Photos web app running on your machine, and this web app
will be connecting to the server running on your local machine at
`localhost:8080`.
For the mobile apps, you don't even need to build, and can install normal Ente
apps and configure them to use your
[custom self-hosted server](/self-hosting/guides/custom-server/).
> If you want to build the mobile apps from source, see the instructions
> [here](/self-hosting/guides/mobile-build).
## Web app with Docker and Compose
The instructoins in previous section were just a temporary way to run the web
app locally. To run the web apps as services, the user has to build a docker
image manually.
> [!IMPORTANT]
>
> Recurring changes might be made by the team or from community if more
> improvements can be made so that we are able to build a full-fledged docker
> image.
```dockerfile
FROM node:20-bookworm-slim as builder
WORKDIR ./ente
COPY . .
COPY apps/ .
# Will help default to yarn versoin 1.22.22
RUN corepack enable
# Endpoint for Ente Server
ENV NEXT_PUBLIC_ENTE_ENDPOINT=https://your-ente-endpoint.com
ENV NEXT_PUBLIC_ENTE_ALBUMS_ENDPOINT=https://your-albums-endpoint.com
RUN yarn cache clean
RUN yarn install --network-timeout 1000000000
RUN yarn build:photos && yarn build:accounts && yarn build:auth && yarn build:cast
FROM node:20-bookworm-slim
WORKDIR /app
COPY --from=builder /ente/apps/photos/out /app/photos
COPY --from=builder /ente/apps/accounts/out /app/accounts
COPY --from=builder /ente/apps/auth/out /app/auth
COPY --from=builder /ente/apps/cast/out /app/cast
RUN npm install -g serve
ENV PHOTOS=3000
EXPOSE ${PHOTOS}
ENV ACCOUNTS=3001
EXPOSE ${ACCOUNTS}
ENV AUTH=3002
EXPOSE ${AUTH}
ENV CAST=3003
EXPOSE ${CAST}
# The albums app does not have navigable pages on it, but the
# port will be exposed in-order to self up the albums endpoint
# `apps.public-albums` in museum.yaml configuration file.
ENV ALBUMS=3004
EXPOSE ${ALBUMS}
CMD ["sh", "-c", "serve /app/photos -l tcp://0.0.0.0:${PHOTOS} & serve /app/accounts -l tcp://0.0.0.0:${ACCOUNTS} & serve /app/auth -l tcp://0.0.0.0:${AUTH} & serve /app/cast -l tcp://0.0.0.0:${CAST}"]
```
The above is a multi-stage Dockerfile which creates a production ready static
output of the 4 apps (Photos, Accounts, Auth and Cast) and serves the static
content with Caddy.
Looking at 2 different node base-images doing different tasks in the same
Dockerfile would not make sense, but the Dockerfile is divided into two just to
improve the build efficiency as building this Dockerfile will arguably take more
time.
Lets build a Docker image from the above Dockerfile. Copy and paste the above
Dockerfile contents in the root of your web directory which is inside
`ente/web`. Execute the below command to create an image from this Dockerfile.
```sh
# Build the image
docker build -t <image-name>:<tag> --no-cache --progress plain .
```
You can always edit the Dockerfile and remove the steps for apps which you do
not intend to install on your system (like auth or cast) and opt out of those.
Regarding Albums App, take a note that they are not apps with navigable pages,
if accessed on the web-browser they will simply redirect to ente.web.io.
## compose.yaml
Moving ahead, we need to paste the below contents into the compose.yaml inside
`ente/server/compose.yaml` under the services section.
```yaml
ente-web:
image: <image-name> # name of the image you used while building
ports:
- 3000:3000
- 3001:3001
- 3002:3002
- 3003:3003
- 3004:3004
environment:
- NODE_ENV=development
restart: always
```
Now, we're good to go. All we are left to do now is start the containers.
```sh
docker compose up -d # --build
# Accessing the logs
docker compose logs <container-name>
```
## Configure App Endpoints
> [!NOTE] Previously, this was dependent on the env variables
> `NEXT_ENTE_PUBLIC_ACCOUNTS_ENDPOINT` and etc. Please check the below
> documentation to update your setup configurations
You can configure the web endpoints for the other apps including Accounts,
Albums Family and Cast in your `museum.yaml` configuration file. Checkout
[`local.yaml`](https://github.com/ente-io/ente/blob/543411254b2bb55bd00a0e515dcafa12d12d3b35/server/configurations/local.yaml#L76-L89)
to configure the endpoints. Make sure to setup up your DNS Records accordingly
to the similar URL's you set up in `museum.yaml`.
Next part is to configure the web server.
# Web server configuration
The last step ahead is configuring reverse_proxy for the ports on which the apps
are being served (you will have to make changes, if you have cusotmized the
ports). The web server of choice in this guide is
[Caddy](https://caddyserver.com) because with caddy you don't have to manually
configure/setup SSL ceritifcates as caddy will take care of that.
```groovy
photos.yourdomain.com {
reverse_proxy http://localhost:3001
# for logging
log {
level error
}
}
auth.yourdomain.com {
reverse_proxy http://localhost:3002
}
# and so on ...
```
Next, start the caddy server :).
```sh
# If caddy service is not enabled
sudo systemctl enable caddy
sudo systemctl daemon-reload
sudo systemctl start caddy
```
## Contributing
Please start a discussion on the Github Repo if you have any suggestions for the
Dockerfile, You can also share your setups on Github Discussions.

View File

@@ -1,5 +1,5 @@
---
title: Self Hosting
title: Guides - Self-hosting
description: Guides for self hosting Ente Photos and/or Ente Auth
---
@@ -10,14 +10,12 @@ walkthroughs, tutorials and other FAQ pages in this directory.
See the sidebar for existing guides. In particular:
- If you're just looking to get started, see
[configure custom server](custom-server/).
- If you're just looking to get started, see installation.
- For various admin related tasks, e.g. increasing the storage quota on your
self hosted instance, see [administering your custom server](admin).
- For various administrative tasks, e.g. increasing the storage quota for user
on your self-hosted instance, see
[user management](/self-hosting/administration/users).
- For configuring your S3 buckets to get the object storage to work from your
mobile device or for fixing an upload errors, see
[configuring S3](configuring-s3). There is also a longer
[community contributed guide](external-s3) for a more self hosted setup of
both the server and web app using external S3 buckets for object storage.
[object storage](/self-hosting/administration/object-storage).

View File

@@ -1,39 +0,0 @@
---
title: CLI for Self Hosted Instance
description: Guide to configuring Ente CLI for Self Hosted Instance
---
## Self Hosting
If you are self-hosting the server, you can still configure CLI to export data &
perform basic admin actions.
To do this, first configure the CLI to point to your server. Define a
config.yaml and put it either in the same directory as CLI binary or path
defined in env variable `ENTE_CLI_CONFIG_DIR`
```yaml
endpoint:
api: "http://localhost:8080"
```
You should be able to
[add an account](https://github.com/ente-io/ente/blob/main/cli/docs/generated/ente_account_add.md),
and subsequently increase the
[storage and account validity](https://github.com/ente-io/ente/blob/main/cli/docs/generated/ente_admin_update-subscription.md)
using the CLI.
For the admin actions, you first need to whitelist admin users. You can create
`server/museum.yaml`, and whitelist add the admin userID `internal.admins`. See
[local.yaml](https://github.com/ente-io/ente/blob/main/server/configurations/local.yaml#L211C1-L232C1)
in the server source code for details about how to define this.
You can use
[account list](https://github.com/ente-io/ente/blob/main/cli/docs/generated/ente_account_list.md)
command to find the user id of any account.
```yaml
internal:
admins:
# - 1580559962386440
```

View File

@@ -1,116 +0,0 @@
---
title: Installing Ente Standalone (without Docker)
description: Installing and setting up Ente standalone without docker.
---
# Installing and Deploying Ente Standalone (without Docker)
## Running Museum (Ente's server) without Docker
First, start by installing all the dependencies to get your machine ready for
development.
```sh
# For MacOS
brew tap homebrew/core
brew update
brew install go
# For Ubuntu based distros
sudo apt update && sudo apt upgrade
sudo apt install golang-go
```
Alternatively, you can also download the latest binaries from
['All Release'](https://go.dev/dl/) page from the official website.
```sh
brew install postgres@15
# Link the postgres keg
brew link postgresql@15
brew install libsodium
# For Ubuntu based distros
sudo apt install postgresql
sudo apt install libsodium23 libsodium-dev
```
The package `libsodium23` might be installed already in some cases.
Installing pkg-config
```sh
brew install pkg-config
# For Ubuntu based distros
sudo apt install pkg-config
```
## Starting Postgres
### With pg_ctl
```sh
pg_ctl -D /usr/local/var/postgres -l logfile start
```
Dependeing on the Operating System type the path for postgres binary or
configuration file might be different, please check if the command keeps failing
for you.
Ideally, if you are on a Linux system with systemd as the init. You can also
start postgres as a systemd service. After Installation execute the following
commands:
```sh
sudo systemctl enable postgresql
sudo systemctl daemon-reload && sudo systemctl start postgresql
```
### Create user
```sh
createuser -s postgres
```
## Start Museum
Start by cloning ente to your system.
```sh
git clone https://github.com/ente-io/ente
```
```sh
export ENTE_DB_USER=postgres
cd ente/server
go run cmd/museum/main.go
```
You can also add the export line to your shell's RC file, to avoid exporting the
environment variable every time.
For live reloads, install [air](https://github.com/air-verse/air#installation).
Then you can just call air after declaring the required environment variables.
For example,
```sh
ENTE_DB_USER=postgres
air
```
## Museum as a background service
Please check the below links if you want to run Museum as a service, both of
them are battle tested.
1. [How to run museum as a systemd service](https://gist.github.com/mngshm/a0edb097c91d1dc45aeed755af310323)
2. [Museum.service](https://github.com/ente-io/ente/blob/23e678889189157ecc389c258267685934b83631/server/scripts/deploy/museum.service#L4)
Once you are done with setting and running Museum, all you are left to do is run
the web app and reverse_proxy it with a webserver. You can check the following
resources for Deploying your web app.
1. [Hosting the Web App](https://help.ente.io/self-hosting/guides/web-app).
2. [Running Ente Web app as a systemd Service](https://gist.github.com/mngshm/72e32bd483c2129621ed0d74412492fd)

View File

@@ -1,14 +0,0 @@
---
title: System requirements
description: System requirements for running Ente's server
---
# System requirements
There aren't any "minimum" system requirements as such, the server process is
very light weight - it's just a single go binary, and it doesn't do any server
side ML, so I feel it should be able to run on anything reasonable.
We've used the server quite easily on small cloud instances, old laptops etc. A
community member also reported being able to run the server on
[very low-end embedded devices](https://github.com/ente-io/ente/discussions/594).

View File

@@ -0,0 +1,23 @@
---
title: Running Ente using systemd - Self-hosting
description: Running Ente services (Museum and web application) via systemd
---
# Running Ente using `systemd`
On Linux distributions using `systemd` as initialization system, Ente can be
configured to run as a background service, upon system startup by service files.
## Museum as a background service
Please check the below links if you want to run Museum as a service, both of
them are battle tested.
1. [How to run museum as a systemd service](https://gist.github.com/mngshm/a0edb097c91d1dc45aeed755af310323)
2. [Museum.service](https://github.com/ente-io/ente/blob/23e678889189157ecc389c258267685934b83631/server/scripts/deploy/museum.service#L4)
Once you are done with setting and running Museum, all you are left to do is run
the web app and set up reverse proxy. Check out the documentation for
[more information](/self-hosting/installation/manual#step-3-configure-web-application).
> **Credits:** [mngshm](https://github.com/mngshm)

View File

@@ -1,5 +1,5 @@
---
title: Self Hosting with Tailscale (Community)
title: Self-hosting with Tailscale - Self-hosting
description: Guides for self-hosting Ente Photos and/or Ente Auth with Tailscale
---
@@ -347,3 +347,5 @@ This will list all account details. Copy Acount ID.
> ente-museum-1 container from linux terminal. Run
> `docker restart ente-museum-1`. All well, now you will have 100TB storage.
> Repeat if for any other accounts you want to give unlimited storage access.
> **Credits:** [A4alli](https://github.com/A4alli)

View File

@@ -1,195 +0,0 @@
---
title: Hosting the web apps
description:
Building and hosting Ente's web apps, connecting it to your self-hosted
server
---
> [!WARNING] NOTE This page covers documentation around self-hosting the web app
> manually. If you want to deploy Ente hassle free, please use the
> [one line](https://ente.io/blog/self-hosting-quickstart/) command to setup
> Ente. This guide might be deprecated in the near future.
# Web app
The getting started instructions mention using `yarn dev` (which is an alias of
`yarn dev:photos`) to serve your web app.
> [!IMPORTANT] Please note that Ente's Web App supports the Yarn version 1.22.xx
> or 1.22.22 specifically. Make sure to install the right version or modify your
> yarn installation to meet the requirements. The user might end up into unknown
> version and dependency related errors if yarn is on different version.
```sh
cd ente/web
yarn install
NEXT_PUBLIC_ENTE_ENDPOINT=http://localhost:8080 yarn dev:photos
```
This is fine for trying the web app and verifying that your self-hosted server
is working as expected etc. But if you would like to use the web app for a
longer term, then it is recommended to follow the Docker approach.
## With Docker/Docker Compose (Recommended)
> [!IMPORTANT]
>
> Recurring changes might be made by the team or from community if more
> improvements can be made so that we are able to build a full-fledged docker
> image.
```dockerfile
FROM node:20-bookworm-slim as builder
WORKDIR ./ente
COPY . .
COPY apps/ .
# Will help default to yarn versoin 1.22.22
RUN corepack enable
# Endpoint for Ente Server
ENV NEXT_PUBLIC_ENTE_ENDPOINT=https://changeme.com
ENV NEXT_PUBLIC_ENTE_ALBUMS_ENDPOINT=https://changeme.com
RUN yarn cache clean
RUN yarn install --network-timeout 1000000000
RUN yarn build:photos && yarn build:accounts && yarn build:auth && yarn build:cast
FROM node:20-bookworm-slim
WORKDIR /app
COPY --from=builder /ente/apps/photos/out /app/photos
COPY --from=builder /ente/apps/accounts/out /app/accounts
COPY --from=builder /ente/apps/auth/out /app/auth
COPY --from=builder /ente/apps/cast/out /app/cast
RUN npm install -g serve
ENV PHOTOS=3000
EXPOSE ${PHOTOS}
ENV ACCOUNTS=3001
EXPOSE ${ACCOUNTS}
ENV AUTH=3002
EXPOSE ${AUTH}
ENV CAST=3003
EXPOSE ${CAST}
# The albums app does not have navigable pages on it, but the
# port will be exposed in-order to self up the albums endpoint
# `apps.public-albums` in museum.yaml configuration file.
ENV ALBUMS=3004
EXPOSE ${ALBUMS}
CMD ["sh", "-c", "serve /app/photos -l tcp://0.0.0.0:${PHOTOS} & serve /app/accounts -l tcp://0.0.0.0:${ACCOUNTS} & serve /app/auth -l tcp://0.0.0.0:${AUTH} & serve /app/cast -l tcp://0.0.0.0:${CAST}"]
```
The above is a multi-stage Dockerfile which creates a production ready static
output of the 4 apps (Photos, Accounts, Auth and Cast) and serves the static
content with Caddy.
Looking at 2 different node base-images doing different tasks in the same
Dockerfile would not make sense, but the Dockerfile is divided into two just to
improve the build efficiency as building this Dockerfile will arguably take more
time.
Lets build a Docker image from the above Dockerfile. Copy and paste the above
Dockerfile contents in the root of your web directory which is inside
`ente/web`. Execute the below command to create an image from this Dockerfile.
```sh
# Build the image
docker build -t <image-name>:<tag> --no-cache --progress plain .
```
You can always edit the Dockerfile and remove the steps for apps which you do
not intend to install on your system (like auth or cast) and opt out of those.
Regarding Albums App, please take a note that they are not web pages with
navigable pages, if accessed on the web-browser they will simply redirect to
ente.web.io.
## compose.yaml
Moving ahead, we need to paste the below contents into the compose.yaml inside
`ente/server/compose.yaml` under the services section.
```yaml
ente-web:
image: <image-name> # name of the image you used while building
ports:
- 3000:3000
- 3001:3001
- 3002:3002
- 3003:3003
- 3004:3004
environment:
- NODE_ENV=development
restart: always
```
Now, we're good to go. All we are left to do now is start the containers.
```sh
docker compose up -d # --build
# Accessing the logs
docker compose logs <container-name>
```
## Configure App Endpoints
> [!NOTE] Previously, this was dependent on the env variables
> `NEXT_ENTE_PUBLIC_ACCOUNTS_ENDPOINT` and etc. Please check the below
> documentation to update your setup configurations
You can configure the web endpoints for the other apps including Accounts,
Albums Family and Cast in your `museum.yaml` configuration file. Checkout
[`local.yaml`](https://github.com/ente-io/ente/blob/543411254b2bb55bd00a0e515dcafa12d12d3b35/server/configurations/local.yaml#L76-L89)
to configure the endpoints. Make sure to setup up your DNS Records accordingly
to the similar URL's you set up in `museum.yaml`.
Next part is to configure the web server.
# Web server configuration
The last step ahead is configuring reverse_proxy for the ports on which the apps
are being served (you will have to make changes, if you have cusotmized the
ports). The web server of choice in this guide is
[Caddy](https://caddyserver.com) because with caddy you don't have to manually
configure/setup SSL ceritifcates as caddy will take care of that.
```sh
photos.yourdomain.com {
reverse_proxy http://localhost:3001
# for logging
log {
level error
}
}
auth.yourdomain.com {
reverse_proxy http://localhost:3002
}
# and so on ...
```
Next, start the caddy server :).
```sh
# If caddy service is not enabled
sudo systemctl enable caddy
sudo systemctl daemon-reload
sudo systemctl start caddy
```
## Contributing
Please start a discussion on the Github Repo if you have any suggestions for the
Dockerfile, You can also share your setups on Github Discussions.

View File

@@ -1,37 +1,29 @@
---
title: Self Hosting
description: Getting started self hosting Ente Photos and/or Ente Auth
title: Quickstart - Self-hosting
description: Getting started with self-hosting Ente
---
# Self Hosting
# Quickstart
The entire source code for Ente is open source,
[including the servers](https://ente.io/blog/open-sourcing-our-server/). This is
the same code we use for our own cloud service.
If you're looking to spin up Ente on your server, you are in the right place!
Our entire source code
([including the server](https://ente.io/blog/open-sourcing-our-server/)) is open
source. This is the same code we use on production.
For a quick preview, make sure your system meets the requirements mentioned
below. After trying the preview, you can explore other ways of self-hosting Ente
on your server as described in the documentation.
## Requirements
### Hardware
- A system with at least 1 GB of RAM and 1 CPU core
- [Docker Compose](https://docs.docker.com/compose/)
The server is capable of running on minimal resource requirements as a
lightweight Go binary, since most of the intensive computational tasks are done
on the client. It performs well on small cloud instances, old laptops, and even
[low-end embedded devices](https://github.com/ente-io/ente/discussions/594).
> For more details, check out the
> [requirements page](/self-hosting/installation/requirements).
### Software
#### Operating System
Any Linux or \*nix operating system, Ubuntu or Debian is recommended to have a
good Docker experience. Non-Linux operating systems tend to provide poor
experience with Docker and difficulty with troubleshooting and assistance.
#### Docker
Required for running Ente's server, web application and dependent services
(database and object storage)
## Getting started
## Set up the server
Run this command on your terminal to setup Ente.
@@ -39,17 +31,57 @@ Run this command on your terminal to setup Ente.
sh -c "$(curl -fsSL https://raw.githubusercontent.com/ente-io/ente/main/server/quickstart.sh)"
```
The above `curl` command pulls the Docker image, creates a directory `my-ente`
in the current working directory, prompts to start the cluster and starts all the containers required to run Ente.
This creates a directory `my-ente` in the current working directory, prompts to
start the cluster with needed containers after pulling the images required to
run Ente.
![quickstart](/quickstart.png)
::: note Make sure to modify the default values in `compose.yaml` and
`museum.yaml` if you wish to change endpoints, bucket configuration or server
configuration. :::
![self-hosted-ente](/web-app.webp)
## Try the web app
> [!TIP] Important:
> If you have used quickstart for self-hosting Ente and are facing issues while > trying to run the cluster due to MinIO buckets not being created, please check [troubleshooting MinIO](/self-hosting/troubleshooting/docker#minio-provisioning-error)
>
>
Open Ente Photos web app at `http://<machine-ip>:3000` (or
`http://localhost:3000` if using on same local machine). Select **Don't have an
account?** to create a new user.
Follow the prompts to sign up.
<div style="display: flex; gap: 10px;">
<img alt="Onboarding screen" src="/onboarding.png" style="width: 50%; height: auto;">
<img alt="Sign up page" src="/sign-up.png" style="width: 50%; height: auto;">
</div>
Enter the verification code by checking the cluster logs using
`sudo docker compose logs`.
![Verification Code](/otp.png)
Upload a picture via the web user interface.
Alternatively, if using Ente Auth, get started by adding an account (assuming
you are running Ente Auth at `http://<machine-ip>:3002` or
`http://localhost:3002`).
## Try the mobile app
You can install Ente Photos from [here](/photos/faq/installing) and Ente Auth
from [here](/auth/faq/installing).
Connect to your server from
[mobile apps](/self-hosting/installation/post-install/#step-6-configure-apps-to-use-your-server).
## What next?
You may wish to install using a different way for your needs. Check the
"Installation" section for information regarding that.
You can import your pictures from Google Takeout or from other services to Ente
Photos. For more information, check out our
[migration guide](/photos/migration/) for more information.
You can import your codes from other authenticator providers to Ente Auth. Check
out our [migration guide](/auth/migration/) for more information.
## Queries?

View File

@@ -0,0 +1,64 @@
---
title: Docker Compose - Self-hosting
description: Running Ente with Docker Compose from source
---
# Docker Compose
If you wish to run Ente via Docker Compose from source, do the following:
## Requirements
Check out the [requirements](/self-hosting/installation/requirements) page to
get started.
## Step 1: Clone the repository
Clone the repository. Change into the `server/config` directory of the
repository, where the Compose file for running the cluster is present.
Run the following command for the same:
```sh
git clone https://github.com/ente-io/ente
cd ente/server/config
```
## Step 2: Populate the configuration file and environment variables
In order to run the cluster, you will have to provide environment variable
values.
Copy the configuration files for modification by the following command inside
`server/config` directory of the repository.
This allows you to modify configuration without having to face hassle while
pulling in latest changes.
```shell
# Inside the cloned repository's directory (usually `ente`)
cd server/config
cp example.env .env
cp example.yaml museum.yaml
```
Change the values present in `.env` file along with `museum.yaml` file
accordingly.
## Step 3: Start the cluster
Start the cluster by running the following command:
```sh
docker compose up --build
```
This builds Museum and web applications based on the Dockerfile and starts the
containers needed for Ente.
::: tip
Check out [post-installations steps](/self-hosting/installation/post-install/)
for further usage.
:::

View File

@@ -0,0 +1,206 @@
---
title: Configuration - Self-hosting
description:
"Information about all the configuration variables needed to run Ente with
museum.yaml"
---
# Configuration
Museum is designed to be configured either via environment variables or via
YAML. We recommend using YAML for maintaining your configuration as it can be
backed up easily, helping in restoration.
## Configuration File
Museum's configuration file (`museum.yaml`) is responsible for making database
configuration, bucket configuration, internal configuration, etc. accessible for
other internal services.
By default, Museum runs in local environment, thus `local.yaml` configuration is
loaded.
If `ENVIRONMENT` environment variable is set (say, to `production`), Museum will
attempt to load `configurations/production.yaml`.
If `credentials-file` is defined and found, it overrides the defaults.
Use `museum.yaml` file for declaring configuration over `local.yaml`.
All configuration values can be overridden via environment variables using the
`ENTE_` prefix and replacing dots (`.`) or hyphens (`-`) with underscores (`_`).
Museum reads configuration from `museum.yaml`. Any environment variables
prefixed with `ENTE_` takes precedence.
For example,
```yaml
s3:
b2-eu-cen:
endpoint:
```
in `museum.yaml` is read as `s3.b2-eu-cen.endpoint` by Museum.
`ENTE_S3_B2_EU_CEN_ENDPOINT` declared as environment variable is same as the
above and `ENTE_S3_B2_EU_CEN_ENDPOINT` overrides `s3.b2-eu-cen.endpoint`.
### General Settings
| Variable | Description | Default |
| ------------------ | --------------------------------------------------------- | ------------------ |
| `credentials-file` | Path to optional credentials override file | `credentials.yaml` |
| `credentials-dir` | Directory to look for credentials (TLS, service accounts) | `credentials/` |
| `log-file` | Log output path. Required in production. | `""` |
### HTTP
| Variable | Description | Default |
| -------------- | --------------------------------- | ------- |
| `http.use-tls` | Enables TLS and binds to port 443 | `false` |
### App Endpoints
The web apps for Ente (Auth, Cast, Albums) use different endpoints.
These endpoints are configurable in `museum.yaml` under the apps.\* section.
Upon configuration, the application will start utilizing the specified endpoints
instead of Ente's production instances or local endpoints (overridden values
used for Compose and quickstart for ease of use.)
| Variable | Description | Default |
| -------------------- | ------------------------------------------------------- | -------------------------- |
| `apps.public-albums` | Albums app base endpoint for public sharing | `https://albums.ente.io` |
| `apps.cast` | Cast app base endpoint | `https://cast.ente.io` |
| `apps.accounts` | Accounts app base endpoint (used for passkey-based 2FA) | `https://accounts.ente.io` |
### Database
| Variable | Description | Default |
| ------------- | -------------------------- | ----------- |
| `db.host` | DB hostname | `localhost` |
| `db.port` | DB port | `5432` |
| `db.name` | Database name | `ente_db` |
| `db.sslmode` | SSL mode for DB connection | `disable` |
| `db.user` | Database username | |
| `db.password` | Database password | |
| `db.extra` | Additional DSN parameters | |
### Object Storage
The `s3` section within `museum.yaml` is by default configured to use local
MinIO buckets when using `quickstart.sh` or Docker Compose.
If you wish to use an external S3 provider, you can edit the configuration with
your provider's credentials, and set `are_local_buckets` to `false`.
MinIO uses the port `3200` for API Endpoints. Web Console can be accessed at
http://localhost:3201 by enabling port `3201` in the Compose file.
If you face any issues related to uploads then check out
[CORS](/self-hosting/administration/object-storage#cors-cross-origin-resource-sharing)
and [troubleshooting](/self-hosting/troubleshooting/uploads) sections.
| Variable | Description | Default |
| -------------------------------------- | -------------------------------------------- | ------- |
| `s3.b2-eu-cen` | Primary hot storage S3 config | |
| `s3.wasabi-eu-central-2-v3.compliance` | Whether to disable compliance lock on delete | `true` |
| `s3.scw-eu-fr-v3` | Optional secondary S3 config | |
| `s3.wasabi-eu-central-2-derived` | Derived data storage | |
| `s3.are_local_buckets` | Use local MinIO-compatible storage | `false` |
| `s3.use_path_style_urls` | Enable path-style URLs for MinIO | `false` |
### Encryption Keys
These values are used for encryption of user e-mails. Default values are
provided by Museum.
They are generated by random in quickstart script, so no intervention is
necessary if using quickstart.
However, if you are using Ente for long-term needs and you have not installed
Ente via quickstart, consider generating values for these along with [JWT](#jwt)
by following the steps described below:
```shell
# If you have not cloned already
git clone https://github.com/ente-io/ente
# Generate the values
cd ente/server
go run tools/gen-random-keys/main.go
```
| Variable | Description | Default |
| ---------------- | ------------------------------ | ----------- |
| `key.encryption` | Key for encrypting user emails | Pre-defined |
| `key.hash` | Hash key | Pre-defined |
### JWT
| Variable | Description | Default |
| ------------ | ----------------------- | ---------- |
| `jwt.secret` | Secret for signing JWTs | Predefined |
### Email
| Variable | Description | Default |
| ------------------ | ---------------------------- | ------- |
| `smtp.host` | SMTP server host | |
| `smtp.port` | SMTP server port | |
| `smtp.username` | SMTP auth username | |
| `smtp.password` | SMTP auth password | |
| `smtp.email` | Sender email address | |
| `smtp.sender-name` | Custom name for email sender | |
| `transmail.key` | Zeptomail API key | |
### WebAuthn Passkey Support
| Variable | Description | Default |
| -------------------- | ---------------------------- | --------------------------- |
| `webauthn.rpid` | Relying Party ID | `localhost` |
| `webauthn.rporigins` | Allowed origins for WebAuthn | `["http://localhost:3001"]` |
### Internal
| Variable | Description | Default |
| -------------------------------------------- | --------------------------------------------- | ------- |
| `internal.silent` | Suppress external effects (e.g. email alerts) | `false` |
| `internal.health-check-url` | External healthcheck URL | |
| `internal.hardcoded-ott` | Predefined OTPs for testing | |
| `internal.hardcoded-ott.emails` | E-mail addresses with hardcoded OTTs | `[]` |
| `internal.hardcoded-ott.local-domain-suffix` | Suffix for which hardcoded OTT is to be used | |
| `internal.hardcoded-ott.local-domain-value` | Hardcoded OTT value for the above suffix | |
| `internal.admins` | List of admin user IDs | `[]` |
| `internal.admin` | Single admin user ID | |
| `internal.disable-registration` | Disable user registration | `false` |
### Replication
By default, replication of objects (photos, thumbnails, videos) is disabled and
only one bucket is used.
To enable replication, set `replication.enabled` to `true`. For this to work, 3
buckets have to be configured in total.
| Variable | Description | Default |
| -------------------------- | ------------------------------------ | ----------------- |
| `replication.enabled` | Enable replication across buckets | `false` |
| `replication.worker-url` | Cloudflare Worker for replication | |
| `replication.worker-count` | Number of goroutines for replication | `6` |
| `replication.tmp-storage` | Temp directory for replication | `tmp/replication` |
### Background Jobs
This configuration is for enabling background cron jobs for tasks such as
sending mails, removing unused objects (clean up) and worker configuration for
the same.
| Variable | Description | Default |
| --------------------------------------------- | --------------------------------------- | ------- |
| `jobs.cron.skip` | Skip all cron jobs | `false` |
| `jobs.remove-unreported-objects.worker-count` | Workers for removing unreported objects | `1` |
| `jobs.clear-orphan-objects.enabled` | Enable orphan cleanup | `false` |
| `jobs.clear-orphan-objects.prefix` | Prefix filter for orphaned objects | |

View File

@@ -0,0 +1,53 @@
---
title: Environment variables and defaults - Self-hosting
description:
"Information about all the configuration variables needed to run Ente along
with description on default configuration"
---
# Environment variables and defaults
The environment variables needed for running Ente and the default configuration
are documented below:
## Environment Variables
A self-hosted Ente instance has to specify endpoints for both Museum (the
server) and web apps.
This document outlines the essential environment variables and port mappings of
the web apps.
Here's the list of environment variables that is used by the cluster:
| Service | Environment Variable | Description | Default Value |
| ---------- | --------------------- | ----------------------------------------------------------------------------------------------- | ------------------------------- |
| `web` | `ENTE_API_ORIGIN` | Alias for `NEXT_PUBLIC_ENTE_ENDPOINT`. API Endpoint for Ente's API (Museum). | http://localhost:8080 |
| `web` | `ENTE_ALBUMS_ORIGIN` | Alias for `NEXT_PUBLIC_ENTE_ALBUMS_ENDPOINT`. Base URL for Ente Album, used for public sharing. | http://localhost:3002 |
| `postgres` | `POSTGRES_USER` | Username for PostgreSQL database | `pguser` |
| `postgres` | `POSTGRES_DB` | Name of database for use with Ente | `ente_db` |
| `postgres` | `POSTGRES_PASSWORD` | Password for PostgreSQL database's user | Randomly generated (quickstart) |
| `minio` | `MINIO_ROOT_USER` | Username for MinIO | Randomly generated (quickstart) |
| `minio` | `MINIO_ROOT_PASSWORD` | Password for MinIO | Randomly generated (quickstart) |
## Default Configuration
Self-hosted Ente clusters have certain default configuration for ease of use,
which is documented below to understand its behavior:
### Ports
The below format is according to how ports are mapped in Docker when using the
quickstart script. The mapping is of the format `<host-port>:<container-port>`
in `ports` in compose file.
| Service | Type | Host Port | Container Port |
| ------------------------------------------------------- | -------- | --------- | -------------- |
| Museum | Server | 8080 | 8080 |
| Ente Photos | Web | 3000 | 3000 |
| Ente Accounts | Web | 3001 | 3001 |
| Ente Albums | Web | 3002 | 3002 |
| [Ente Auth](https://ente.io/auth/) | Web | 3003 | 3003 |
| [Ente Cast](https://help.ente.io/photos/features/cast/) | Web | 3004 | 3004 |
| MinIO | S3 | 3200 | 3200 |
| PostgreSQL | Database | | 5432 |

View File

@@ -0,0 +1,215 @@
---
title: Manual setup (without Docker) - Self-hosting
description: Installing and setting up Ente without Docker
---
# Manual setup (without Docker)
If you wish to run Ente from source without using Docker, follow the steps
described below:
## Requirements
1. **Go:** Install Go on your system. This is needed for building Museum (Ente's
server)
```shell
sudo apt update && sudo apt upgrade
sudo apt install golang-go
```
Alternatively, you can also download the latest binaries from the
[official website](https://go.dev/dl/).
2. **PostgreSQL and `libsodium`:** Install PostgreSQL (database) and `libsodium`
(high level API for encryption) via package manager.
```shell
sudo apt install postgresql
sudo apt install libsodium23 libsodium-dev
```
Start the database using `systemd` automatically when the system starts.
```shell
sudo systemctl enable postgresql
sudo systemctl start postgresql
```
Ensure the database is running using
```shell
sudo systemctl status postgresql
```
3. **`pkg-config`:** Install `pkg-config` for dependency handling.
```shell
sudo apt install pkg-config
```
4. **yarn, npm and Node.js:** Needed for building the web application.
Install npm and Node using your package manager.
```shell
sudo apt install npm nodejs
```
Install yarn by following the
[official documentation](https://yarnpkg.com/getting-started/install)
5. **Git:** Needed for cloning the repository and pulling in latest changes
6. **Caddy:** Used for setting reverse proxy and file servers
7. **Object Storage:** Ensure you have an object storage configured for usage,
needed for storing files. You can choose to run MinIO or Garage locally
without Docker, however, an external bucket will be reliable and suited for
long-term storage.
## Step 1: Clone the repository
Start by cloning Ente's repository from GitHub to your local machine.
```shell
git clone https://github.com/ente-io/ente
```
## Step 2: Configure Museum (Ente's server)
1. Install all the needed dependencies for the server.
```shell
# Change into server directory, where the source code for Museum is
# present inside the repo
cd ente/server
# Install the needed dependencies
go mod tidy
```
2. Build the server. The server binary should be available as `./main` relative
to `server` directory
``` shell
go build cmd/museum/main.go
```
3. Create `museum.yaml` file inside `server` for configuring the needed
variables. You can copy the templated configuration file for editing with
ease.
```shell
cp config/example.yaml ./museum.yaml
```
4. Run the server
```shell
./main
```
Museum should be accessible at `http://localhost:8080`
## Step 3: Configure Web Application
1. Install the dependencies for web application. Enable corepack if prompted.
```shell
# Change into web directory, this is where all the applications
# will be managed and built
cd web
# Install dependencies
yarn install
```
2. Configure the environment variables in your corresponding shell's
configuration file (`.bashrc`, `.zshrc`)
```shell
# Replace this with actual endpoint for Museum
export NEXT_PUBLIC_ENTE_ENDPOINT=http://localhost:8080
# Replace this with actual endpoint for Albums
export NEXT_PUBLIC_ENTE_ALBUMS_ENDPOINT=http://localhost:3002
```
3. Build the needed applications (Photos, Accounts, Auth, Cast) as per your
needs:
```shell
# These commands are executed inside web directory
# Build photos. Build output to be served is present at apps/photos/out
yarn build
# Build accounts. Build output to be served is present at apps/accounts/out
yarn build:accounts
# Build auth. Build output to be served is present at apps/auth/out
yarn build:auth
# Build cast. Build output to be served is present at apps/cast/out
yarn build:cast
```
4. Copy the output files to `/var/www/ente/apps` for easier management.
```shell
mkdir -p /var/www/ente/apps
# Photos
sudo cp -r apps/photos/out /var/www/ente/apps/photos
# Accounts
sudo cp -r apps/accounts/out /var/www/ente/apps/accounts
# Auth
sudo cp -r apps/auth/out /var/www/ente/apps/auth
# Cast
sudo cp -r apps/cast/out /var/www/ente/apps/cast
```
5. Set up file server using Caddy by editing `Caddyfile`, present at
`/etc/caddy/Caddyfile`.
```groovy
# Replace the ports with domain names if you have subdomains configured and need HTTPS
:3000 {
root * /var/www/ente/apps/out/photos
file_server
try_files {path} {path}.html /index.html
}
:3001 {
root * /var/www/ente/apps/out/accounts
file_server
try_files {path} {path}.html /index.html
}
:3002 {
root * /var/www/ente/apps/out/photos
file_server
try_files {path} {path}.html /index.html
}
:3003 {
root * /var/www/ente/apps/out/auth
file_server
try_files {path} {path}.html /index.html
}
:3004 {
root * /var/www/ente/apps/out/cast
file_server
try_files {path} {path}.html /index.html
}
```
The web application for Ente Photos should be accessible at
http://localhost:3000, check out the
[default ports](/self-hosting/installation/env-var#ports) for more
information.
::: tip
Check out [post-installations steps](/self-hosting/installation/post-install/)
for further usage.
:::

View File

Before

Width:  |  Height:  |  Size: 246 KiB

After

Width:  |  Height:  |  Size: 246 KiB

View File

@@ -0,0 +1,172 @@
---
title: Post-installation steps - Self-hosting
description: Steps to be followed post-installation for smooth experience
---
# Post-installation steps
A list of steps that should be done after installing Ente are described below:
## Step 1: Creating first user
The first user to be created will be treated as an admin user by default.
Once Ente is up and running, the Ente Photos web app will be accessible on
`http://localhost:3000`.
Select **Don't have an account?** to create a new user. Follow the prompts to
sign up.
<div style="display: flex; gap: 10px;">
<img alt="Onboarding screen" src="/onboarding.png" style="width: 50%; height: auto;">
<img alt="Sign up page" src="/sign-up.png" style="width: 50%; height: auto;">
</div>
Enter the verification code to complete registration.
This code can be found in the server logs, which should be shown in your
terminal where you started the Docker Compose cluster.
If not, access the server logs inside the folder where Compose file resides.
```shell
sudo docker compose logs
```
If running Museum without Docker, the code should be visible in the terminal
(stdout).
![otp](/otp.png)
## Step 2: Whitelist admins
1. Connect to `ente_db` (the database used for storing data related to Ente).
```shell
# Change the DB name and DB user name if you use different
# values.
# If using Docker docker exec -it <postgres-ente-container-name>
psql -U pguser -d ente_db
# Or when using psql directly
psql -U pguser -d ente_db
```
2. Get the user ID of the first user by running the following PSQL command:
```sql
SELECT * from users;
```
3. Edit `internal.admins` or `internal.admin` (if you wish to whitelist only
single user) in `museum.yaml` to add the user ID you wish to whitelist.
- For multiple admins:
```yaml
internal:
admins:
- <user_id>
```
- For single admin:
```yaml
internal:
admin: <user_id>
```
4. Restart Museum by restarting the cluster
::: tip Restart your Compose clusters whenever you make changes
If you have edited the Compose file or configuration file (`museum.yaml`), make
sure to recreate the cluster's containers.
You can do this by the following command:
```shell
docker compose down && docker compose up -d
```
:::
## Step 3: Configure application endpoints
You may wish to access some of the applications such as Auth, Albums, Cast via
your instance's endpoints through the application instead of our production
instances.
You can do so by editing the `apps` section in `museum.yaml` to use the base
endpoints of the corresponding web applications.
```yaml
# Replace yourdomain.tld with actual domain
apps:
public-albums: https://albums.ente.yourdomain.tld
cast: https://cast.ente.yourdomain.tld
auth: https://auth.ente.yourdomain.tld
```
## Step 4: Make it publicly accessible
You may wish to access Ente on public Internet. You can do so by configuring a
reverse proxy with software such as Caddy, NGINX, Traefik.
Check out our [documentation](/self-hosting/administration/reverse-proxy) for
more information.
If you do not wish to make it accessible via Internet, we recommend you to use
[Tailscale](/self-hosting/guides/tailscale) for convenience. Alternately, you
can use your IP address for accessing the application in your local network,
though this poses challenges with respect to object storage.
## Step 5: Download mobile and desktop app
You can install Ente Photos by following the
[installation section](/photos/faq/installing).
You can also install Ente Auth (if you are planning to use Auth) by following
the [installation section](/auth/faq/installing).
## Step 6: Configure apps to use your server
You can modify Ente mobile apps and CLI to connect to your server.
### Mobile
Tap the onboarding screen 7 times to modify developer settings. Enter your Ente
server's endpoint.
<div style="display: flex; gap: 10px;">
<img src="/developer-settings.png" alt="Developer Settings" height="50%" width="50%" />
<img src="/developer-settings-endpoint.png" alt="Developer Settings - Server Endpoint" height="50%" width="50%" />
</div>
### Desktop
Tap 7 times on the onboarding screen to configure the server endpoint to be
used.
<div align="center">
![Setting a custom server on the onboarding screen on desktop or self-hosted web
apps](web-dev-settings.png){width=400px}
</div>
## Step 7: Configure Ente CLI
You can download Ente CLI from
[here](https://github.com/ente-io/ente/releases?q=tag%3Acli)
Check our [documentation](/self-hosting/administration/cli) on how to use Ente
CLI for managing self-hosted instances.
::: info For upgrading
Check out our [upgrading documentation](/self-hosting/installation/upgrade) for
various installation methods.
:::

View File

Before

Width:  |  Height:  |  Size: 138 KiB

After

Width:  |  Height:  |  Size: 138 KiB

View File

@@ -0,0 +1,42 @@
---
title: Quickstart script (Recommended) - Self-hosting
description: Self-hosting Ente with quickstart script
---
# Quickstart script (Recommended)
We provide a quickstart script which can be used for self-hosting Ente on your
machine in less than a minute.
## Requirements
Check out the [requirements](/self-hosting/installation/requirements) page to
get started.
## Getting started
Run this command on your terminal to setup Ente.
```sh
sh -c "$(curl -fsSL https://raw.githubusercontent.com/ente-io/ente/main/server/quickstart.sh)"
```
The above `curl` command does the following:
1. Creates a directory `./my-ente` in working directory.
2. Starts the containers required to run Ente upon prompting.
You should be able to access the web application at
[http://localhost:3000](http://localhost:3000) or
[http://machine-ip:3000](http://<machine-ip>:3000)
The data accessed by Museum is stored in `./data` folder inside `my-ente`
directory. It contains extra configuration files that is to be used (push
notification credentials, etc.)
::: tip
Check out [post-installation steps](/self-hosting/installation/post-install/)
for further usage.
:::

View File

@@ -0,0 +1,41 @@
---
title: Requirements - Self-hosting
description: Requirements for self-hosting Ente
---
# Requirements
Ensure your system meets these requirements and has the needed software
installed for a smooth experience.
## Hardware
The server is capable of running on minimal resource requirements as a
lightweight Go binary, since most of the intensive computational tasks are done
on the client. It performs well on small cloud instances, old laptops, and even
[low-end embedded devices](https://github.com/ente-io/ente/discussions/594).
- **Storage:** An Unix-compatible filesystem such as ZFS, EXT4, BTRFS, etc. if
using PostgreSQL container as it requires a filesystem that supports
user/group permissions.
- **RAM:** A minimum of 1 GB of RAM is required for running the cluster (if
using quickstart script).
- **CPU:** A minimum of 1 CPU core is required.
## Software
- **Operating System:** Any Linux or \*nix operating system, Ubuntu or Debian is
recommended to have a good Docker experience. Non-Linux operating systems tend
to provide poor experience with Docker and difficulty with troubleshooting and
assistance.
- **Docker:** Required for running Ente's server, web application and dependent
services (database and object storage). Ente also requires **Docker Compose
plugin** to be installed.
> [!NOTE]
>
> Ente requires **Docker Compose version 2.30 or higher**.
>
> Furthermore, Ente uses the command `docker compose`, `docker-compose` is no
> longer supported.

View File

@@ -0,0 +1,77 @@
---
title: Upgrade - Self-hosting
description: Upgrading self-hosted Ente
---
# Upgrade your server
Upgrading Ente depends on the method of installation you have chosen.
## Quickstart
::: tip For Docker users
You can free up some disk space by deleting older images that were used by
obsolette containers.
```shell
docker image prune
```
:::
Pull in the latest images in the directory where the Compose file resides.
Restart the cluster to recreate containers with newer images.
Run the following command inside `my-ente` directory (default name used in
quickstart):
```shell
docker compose pull && docker compose up -d
```
## Docker Compose
You can pull in the latest source code from Git and build a new cluster based on
the updated source code.
1. Pull the latest changes from `main`.
```shell
# Assuming you have cloned repository to ente
cd ente
# Pull changes
git pull
```
2. Recreate the cluster.
```shell
cd server/config
# Stop and remove containers if they are running
docker compose down
# Build with latest code
docker compose up --build
```
## Manual Setup
You can pull in the latest source code from Git and build a new cluster based on
the updated source code.
1. Pull the latest changes from `main`.
```shell
# Assuming you have cloned repository to ente
cd ente
# Pull changes and only keep changes from remote.
# This is needed to keep yarn.lock up-to-date.
# This resets all changes made in the local repository.
# Make sure to stash changes if you have made any.
git fetch origin
git reset --hard main
```
2. Follow the steps described in
[manual setup](/self-hosting/installation/manual#step-3-configure-web-application)
for Museum and web applications.

View File

@@ -1,77 +0,0 @@
---
title: Configuring your server
description: Guide to writing a museum.yaml
---
# Configuring your server
Ente's monolithic server is called **museum**.
`museum.yaml` is a YAML configuration file used to configure museum. By default,
[`local.yaml`](https://github.com/ente-io/ente/tree/main/server/configurations/local.yaml)
is provided, but its settings are overridden with those from `museum.yaml`.
If you used our quickstart script, your `my-ente` directory will include a
`museum.yaml` file with preset configurations for encryption keys, secrets,
PostgreSQL and MinIO.
> [!TIP]
>
> Always do `docker compose down` inside your `my-ente` directory. If you've
> made changes to `museum.yaml`, restart the containers with
> `docker compose up -d ` to see your changes in action.
## S3 buckets
The `s3` section within `museum.yaml` is by default configured to use local
MinIO buckets.
If you wish to use an external S3 provider, you can edit the configuration with
your provider's credentials, and set `are_local_buckets` to `false`.
Check out [Configuring S3](/self-hosting/guides/configuring-s3.md) to understand
more about configuring S3 buckets.
MinIO uses the port `3200` for API Endpoints and their web app runs over
`:3201`. You can login to MinIO Web Console by opening `localhost:3201` in your
browser.
If you face any issues related to uploads then checkout
[Troubleshooting bucket CORS](/self-hosting/troubleshooting/bucket-cors) and
[Frequently encountered S3 errors](/self-hosting/guides/configuring-s3#frequently-encountered-errors).
## Web apps
The web apps for Ente Photos is divided into multiple sub-apps like albums,
cast, auth, etc. These endpoints are configurable in `museum.yaml` under the
`apps.*` section.
For example,
```yaml
apps:
public-albums: https://albums.myente.xyz
cast: https://cast.myente.xyz
accounts: https://accounts.myente.xyz
family: https://family.myente.xyz
```
> [!IMPORTANT] By default, all the values redirect to our publicly hosted
> production services. For example, if `public-albums` is not configured your
> shared album will use the `albums.ente.io` URL.
After you are done with filling the values, restart museum and the app will
start utilizing those endpoints instead of Ente's production instances.
Once you have configured all the necessary endpoints, `cd` into `my-ente` and
stop all the Docker containers with `docker compose down` and restart them with
`docker compose up -d`.
Similarly, you can use the default
[`local.yaml`](https://github.com/ente-io/ente/tree/main/server/configurations/local.yaml)
as a reference for building a functioning `museum.yaml` for many other
functionalities like SMTP, Discord notifications, Hardcoded-OTTs, etc.
## References
- [Environment variables and ports](/self-hosting/faq/environment)

View File

@@ -1,53 +0,0 @@
---
Title: Configuring Reverse Proxy
Description: configuring reverse proxy for Museum and other endpoints
---
# Reverse proxy
Ente's server (museum) runs on port `:8080`, web app on `:3000` and the other
apps from ports `3001-3004`.
We highly recommend using HTTPS for Museum (`8080`). For security reasons museum
will not accept incoming HTTP traffic.
Head over to your DNS management dashboard and setup the appropriate records for
the endpoints. Mostly, `A` or `AAAA` records targeting towards your server's IP
address should be sufficient. The rest of the work will be done by the web
server on your machine.
![cloudflare](/cloudflare.png)
### Caddy
Setting up a reverse proxy with Caddy is easy and straightforward.
Firstly, install Caddy on your server.
```sh
sudo apt install caddy
```
After the installation is complete, a `Caddyfile` is created on the path
`/etc/caddy/`. This file is used to configure reverse proxies among other
things.
```groovy
# Caddyfile - myente.xyz is just an example.
api.myente.xyz {
reverse_proxy http://localhost:8080
}
ente.myente.xyz {
reverse_proxy http://localhost:3000
}
#...and so on for other endpoints
```
After a hard-reload, the Ente Photos web app should be up on
https://ente.myente.xyz.
If you are using a different tool for reverse proxy (like nginx), please check
out their documentation.

View File

@@ -1,70 +0,0 @@
---
title: Bucket CORS
description: Troubleshooting CORS issues with S3 Buckets
---
# Fix potential CORS issues with your Buckets
## For AWS S3
If you cannot upload a photo due to a CORS issue, you need to fix the CORS
configuration of your bucket.
Create a `cors.json` file with the following content:
```json
{
"CORSRules": [
{
"AllowedOrigins": ["*"],
"AllowedHeaders": ["*"],
"AllowedMethods": ["GET", "HEAD", "POST", "PUT", "DELETE"],
"MaxAgeSeconds": 3000,
"ExposeHeaders": ["Etag"]
}
]
}
```
You may want to change the `AllowedOrigins` to a more restrictive value.
If you are using AWS for S3, you can execute the below command to get rid of
CORS. Make sure to enter the right path for the `cors.json` file.
```bash
aws s3api put-bucket-cors --bucket YOUR_S3_BUCKET --cors-configuration /path/to/cors.json
```
## For Self-hosted Minio Instance
::: warning
- MinIO does not support bucket CORS in the community edition which is used by
default. For more information, check
[this discussion](https://github.com/minio/minio/discussions/20841). However,
global CORS configuration is possible.
- MinIO does not take JSON CORS file as the input, instead you will have to
build a CORS.xml file or just convert the above `cors.json` to XML.
:::
A minor requirement here is the tool `mc` for managing buckets via command line
interface. Checkout the `mc set alias` document to configure alias for your
instance and bucket. After this you will be prompted for your AccessKey and
Secret, which is your username and password.
```sh
mc cors set <your-minio>/<your-bucket-name /path/to/cors.xml
```
or, if you just want to just set the `AllowedOrigins` Header, you can use the
following command to do so.
```sh
mc admin config set <your-minio>/<your-bucket-name> api cors_allow_origin="*"
```
You can create also `.csv` file and dump the list of origins you would like to
allow and replace the `*` with `path` to the CSV file.
Now, uploads should be working fine.

View File

@@ -1,19 +1,19 @@
---
title: Docker Errors
description: Fixing docker related errors when trying to self host Ente
title: Troubleshooting Docker-related errors - Self-hosting
description: Fixing Docker-related errors when trying to self-host Ente
---
# Docker
# Troubleshooting Docker-related errors
## configs
Remember to restart your cluster to ensure changes that you make in the
`configs` section in `compose.yaml` get picked up.
```sh
docker compose down
docker compose up
```
> [!TIP] Restart after changes
>
> Remember to restart your cluster to ensure changes that you make in the
> `compose.yaml` and `museum.yaml` get picked up.
>
> ```shell
> docker compose down
> docker compose up
> ```
## post_start
@@ -45,15 +45,12 @@ minio-provision:
entrypoint: |
sh -c '
#!/bin/sh
while ! mc alias set h0 http://minio:3200 your_minio_user your_minio_pass
do
echo "waiting for minio..."
sleep 0.5
done
cd /data
mc mb -p b2-eu-cen
mc mb -p wasabi-eu-central-2-v3
mc mb -p scw-eu-fr-v3
@@ -90,57 +87,54 @@ museum-1 | /etc/ente/cmd/museum/main.go:124 +0x44c
museum-1 exited with code 2
```
Then the issue is that the password you're using is not the password postgres is
expecting (duh), and a potential scenario where that can happen is something
like this:
Then the issue is that the password you're using is not the password PostgreSQL
is expecting.
1. On a machine, you create a new cluster with `quickstart.sh`.
There are 2 possibilities:
2. Later you delete that folder, but then create another cluster with
`quickstart.sh`. Each time `quickstart.sh` runs, it creates new credentials,
and then when it tries to spin up the docker compose cluster, use them to
connect to the postgres running within.
1. When you have created a cluster in `my-ente` directory on running
`quickstart.sh` and later deleted it, only to create another cluster with
same `my-ente` directory.
3. However, you would already have a docker volume from the first run of
`quickstart.sh`. Since the folder name is the same in both cases `my-ente`,
Docker will reuse the existing volumes (`my-ente_postgres-data`,
`my-ente_minio-data`). So your postgres is running off the old credentials,
and you're trying to connect to it using the new ones, and the error arises.
However, by deleting the directory, the Docker volumes are not deleted.
The solution is to delete the stale docker volume. **Be careful**, this will
delete all data in those volumes (any thing you uploaded etc), so first
understand if this is the exact problem you are facing before deleting those
volumes.
Thus the older volumes with previous cluster's credentials are used for new
cluster and the error arises.
If you're sure of what you're doing, the volumes can be deleted by
Deletion of the stale Docker volume can solve this. **Be careful**, this
will delete all data in those volumes (any thing you uploaded etc). Do this
if you are sure this is the exact problem.
```sh
docker volume ls
```
```shell
docker volume ls
```
to list them, and then delete the ones that begin with `my-ente` using
`docker volume rm`. You can delete all stale volumes by using
`docker system prune` with the `--volumes` flag, but be _really_ careful,
that'll delete all volumes (Ente or otherwise) on your machine that are not
currently in use by a running docker container.
to list them, and then delete the ones that begin with `my-ente` using
`docker volume rm`. You can delete all stale volumes by using
`docker system prune` with the `--volumes` flag, but be _really_ careful,
that'll delete all volumes (Ente or otherwise) on your machine that are not
currently in use by a running Docker container.
An alternative way is to delete the volumes along with removal of cluster's
containers using `docker compose` inside `my-ente` directory.
An alternative way is to delete the volumes along with removal of cluster's
containers using `docker compose` inside `my-ente` directory.
```sh
docker compose down --volumes
```
```sh
docker compose down --volumes
```
If you're unsure about removing volumes, another alternative is to rename your
`my-ente` folder. Docker uses the folder name to determine the volume name
prefix, so giving it a different name will cause Docker to create a volume
afresh for it.
If you're unsure about removing volumes, another alternative is to rename
your `my-ente` folder. Docker uses the folder name to determine the volume
name prefix, so giving it a different name will cause Docker to create a
volume afresh for it.
## MinIO provisioning error
If you have used our quickstart script for self-hosting Ente (new users will be unaffected) and are using the default MinIO container for object storage, you may run into issues while starting the cluster after pulling latest images with provisioning MinIO and creating buckets.
MinIO has deprecated the `mc config` command in favor of `mc alias set`
resulting in failure in execution of the command for creating bucket using
`post_start` hook.
You may encounter similar logs while trying to start the cluster:
You may encounter similar logs while trying to start the cluster if you are
using the older command (provided by default in `quickstart.sh`):
```
my-ente-minio-1 -> | Waiting for minio...
@@ -148,30 +142,27 @@ my-ente-minio-1 -> | Waiting for minio...
my-ente-minio-1 -> | Waiting for minio...
```
MinIO has deprecated the `mc config` command in favor of `mc alias set` resulting in failure in execution of the command for creating bucket using `post_start` hook.
This can be resolved by changing `mc config host h0 add http://minio:3200 $minio_user $minio_pass` to `mc alias set h0 http://minio:3200 $minio_user $minio_pass`
This can be resolved by changing
`mc config host h0 add http://minio:3200 $minio_user $minio_pass` to
`mc alias set h0 http://minio:3200 $minio_user $minio_pass`
Thus the updated `post_start` will look as follows for `minio` service:
``` yaml
minio:
```yaml
minio:
...
post_start:
- command: |
sh -c '
#!/bin/sh
while ! mc alias set h0 http://minio:3200 your_minio_user your_minio_pass 2>/dev/null
do
echo "Waiting for minio..."
sleep 0.5
done
cd /data
mc mb -p b2-eu-cen
mc mb -p wasabi-eu-central-2-v3
mc mb -p scw-eu-fr-v3
'
```
```

View File

@@ -1,5 +1,5 @@
---
title: Ente CLI Secrets
title: Ente CLI Secrets - Self-hosting
description: A quick hotfix for keyring errors while running Ente CLI.
---
@@ -13,9 +13,8 @@ Follow the below steps to run Ente CLI and also avoid keyrings errors.
Run:
```sh
```shell
# export the secrets path
export ENTE_CLI_SECRETS_PATH=./<path-to-secrets.txt>
./ente-cli
@@ -33,7 +32,7 @@ Then one of the following:
And you are good to go.
## Ref
## References
- [Ente CLI Secrets Path](https://www.reddit.com/r/selfhosted/comments/1gc09il/comment/lu2hox2/?utm_source=share&utm_medium=web3x&utm_name=web3xcss&utm_term=1&utm_content=share_button)
- [Keyrings](https://man7.org/linux/man-pages/man7/keyrings.7.html)

View File

@@ -1,8 +1,10 @@
---
title: General troubleshooting cases
title: General troubleshooting cases - Self-hosting
description: Fixing various errors when trying to self host Ente
---
# Troubleshooting
## Functionality not working on self hosted instance
If some specific functionality (e.g. album listing, video playback) does not

View File

@@ -1,5 +1,5 @@
---
title: Uploads
title: Uploads - Self-hosting
description: Fixing upload errors when trying to self host Ente
---
@@ -9,23 +9,14 @@ Here are some errors our community members frequently encountered with the
context and potential fixes.
Fundamentally in most situations, the problem is because of minor mistakes or
misconfiguration. Please make sure to reverse proxy museum and MinIO API
misconfiguration. Please make sure to reverse proxy Museum and MinIO API
endpoint to a domain and check your S3 credentials and whole configuration file
for any minor misconfigurations.
It is also suggested that the user setups bucket CORS or global CORS on MinIO or
any external S3 service provider they are connecting to. To setup bucket CORS,
please [read this](/self-hosting/troubleshooting/bucket-cors).
## What is S3 and how is it incorporated in Ente ?
S3 is an cloud storage protocol made by Amazon (specifically AWS). S3 is
designed to store files and data as objects inside buckets and it is mostly used
for online backups and storing different types of files.
Ente's Docker setup is shipped with [MinIO](https://min.io/) as its default S3
provider. MinIO supports the Amazon S3 protocol and leverages your disk storage
to dump all the uploaded files as encrypted object blobs.
please
[read this](/self-hosting/administration/object-storage#cors-cross-origin-resource-sharing).
## 403 Forbidden

View File

@@ -1,14 +0,0 @@
---
title: Yarn errors
description: Fixing yarn install errors when trying to self host Ente
---
# Yarn
If `yarn install` is failing, make sure you are using Yarn v1 (also known as
"Yarn Classic"):
- https://classic.yarnpkg.com/lang/en/docs/install
For more details, see the
[getting started instructions](https://github.com/ente-io/ente/blob/main/web/docs/new.md).

View File

@@ -46,7 +46,7 @@ You can alternatively install the build from PlayStore or F-Droid.
## 🧑‍💻 Building from source
1. [Install Flutter v3.24.3](https://flutter.dev/docs/get-started/install).
1. [Install Flutter v3.27.4](https://flutter.dev/docs/get-started/install).
2. Pull in all submodules with `git submodule update --init --recursive`

View File

@@ -0,0 +1,6 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M12.0117 17.6875C15.0497 17.6875 17.5117 15.225 17.5117 12.1875C17.5117 9.15 15.0497 6.6875 12.0117 6.6875C8.97372 6.6875 6.51172 9.1495 6.51172 12.1875C6.51172 15.2255 8.97422 17.6875 12.0117 17.6875Z" stroke="white" stroke-width="2" stroke-linejoin="round"/>
<path d="M19.4773 4.50781L18.2473 5.74481M5.53081 18.3753L4.50781 19.4048M11.9973 20.6793V22.1793M21.9973 11.6798H19.9973M18.7633 18.1708L19.9973 19.4048" stroke="white" stroke-width="2" stroke-linecap="round"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M12.0117 8.67969C11.5521 8.67969 11.097 8.77022 10.6723 8.94611C10.2477 9.122 9.86185 9.37981 9.53685 9.70481C9.21184 10.0298 8.95403 10.4157 8.77814 10.8403C8.60225 11.2649 8.51172 11.7201 8.51172 12.1797C8.51172 12.6393 8.60225 13.0944 8.77814 13.5191C8.95403 13.9437 9.21184 14.3296 9.53685 14.6546C9.86185 14.9796 10.2477 15.2374 10.6723 15.4133C11.097 15.5892 11.5521 15.6797 12.0117 15.6797" fill="white"/>
<path d="M2 12.1797H4M5.022 4.50769L6.0485 5.53419M12 1.67969V3.67969" stroke="white" stroke-width="2" stroke-linecap="round"/>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M12 22C6.477 22 2 17.523 2 12C2 6.477 6.477 2 12 2C17.523 2 22 6.477 22 12C22 17.523 17.523 22 12 22ZM12 20C14.1217 20 16.1566 19.1571 17.6569 17.6569C19.1571 16.1566 20 14.1217 20 12C20 9.87827 19.1571 7.84344 17.6569 6.34315C16.1566 4.84285 14.1217 4 12 4C9.87827 4 7.84344 4.84285 6.34315 6.34315C4.84285 7.84344 4 9.87827 4 12C4 14.1217 4.84285 16.1566 6.34315 17.6569C7.84344 19.1571 9.87827 20 12 20ZM12 18V6C13.5913 6 15.1174 6.63214 16.2426 7.75736C17.3679 8.88258 18 10.4087 18 12C18 13.5913 17.3679 15.1174 16.2426 16.2426C15.1174 17.3679 13.5913 18 12 18Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 695 B

View File

@@ -0,0 +1,5 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M5 6C5.55228 6 6 5.55228 6 5C6 4.44772 5.55228 4 5 4C4.44772 4 4 4.44772 4 5C4 5.55228 4.44772 6 5 6Z" stroke="black" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M1.66797 7.9974C1.66797 5.01184 1.66797 3.51906 2.59546 2.59156C3.52296 1.66406 5.01574 1.66406 8.0013 1.66406C10.9868 1.66406 12.4796 1.66406 13.4072 2.59156C14.3346 3.51906 14.3346 5.01184 14.3346 7.9974C14.3346 10.9829 14.3346 12.4757 13.4072 13.4033C12.4796 14.3307 10.9868 14.3307 8.0013 14.3307C5.01574 14.3307 3.52296 14.3307 2.59546 13.4033C1.66797 12.4757 1.66797 10.9829 1.66797 7.9974Z" stroke="black"/>
<path d="M3.33203 14C6.247 10.5166 9.51476 5.92267 14.3304 9.02823" stroke="black"/>
</svg>

After

Width:  |  Height:  |  Size: 788 B

View File

@@ -0,0 +1,4 @@
<svg width="21" height="21" viewBox="0 0 21 21" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M3 12.9896C3 15.7394 3 17.1143 3.85427 17.9687C4.70854 18.8229 6.08348 18.8229 8.83333 18.8229C11.5832 18.8229 12.9581 18.8229 13.8124 17.9687C14.6667 17.1143 14.6667 15.7394 14.6667 12.9896C14.6667 10.2398 14.6667 8.86483 13.8124 8.01053C12.9581 7.15625 11.5832 7.15625 8.83333 7.15625C6.08348 7.15625 4.70854 7.15625 3.85427 8.01053C3 8.86483 3 10.2398 3 12.9896Z" stroke="white" stroke-width="1.25" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M12.5168 2.15625L11.3953 3.08136C10.7984 3.57378 10.5 3.81999 10.5 4.12595H11.3333C14.476 4.12595 16.0474 4.12595 17.0237 5.10226C18 6.07857 18 7.64993 18 10.7926V11.3229" stroke="white" stroke-width="1.25" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 828 B

View File

@@ -0,0 +1,6 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M2.00391 15C2.00391 18.87 5.13391 22 9.00391 22L7.95392 20.25" stroke="white" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M22 9C22 5.13 18.87 2 15 2L16.05 3.75" stroke="white" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M7 5V12C7 14.357 7 15.5355 7.73223 16.2678C8.46447 17 9.64298 17 12 17H19" stroke="white" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M17.0039 19V12C17.0039 9.64298 17.0039 8.46447 16.2717 7.73223C15.5394 7 14.3609 7 12.0039 7H5.00391" stroke="white" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 750 B

View File

@@ -0,0 +1,6 @@
<svg width="29" height="31" viewBox="0 0 29 31" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M23 9.125L22.2977 20.4868C22.1182 23.3896 22.0285 24.841 21.3009 25.8846C20.9411 26.4005 20.478 26.8359 19.9408 27.1631C18.8544 27.825 17.4002 27.825 14.4917 27.825C11.5795 27.825 10.1234 27.825 9.03626 27.1619C8.49877 26.8341 8.03547 26.3979 7.67584 25.8811C6.94846 24.8359 6.86071 23.3824 6.68522 20.4756L6 9.125" stroke="#FF3A2C" stroke-width="1.7" stroke-linecap="round"/>
<path d="M4.29688 4.99792H24.6969M19.0933 4.99792L18.3197 3.40188C17.8058 2.34168 17.5487 1.81157 17.1055 1.48097C17.0072 1.40763 16.9031 1.3424 16.7941 1.28591C16.3033 1.03125 15.7142 1.03125 14.536 1.03125C13.3282 1.03125 12.7243 1.03125 12.2253 1.29659C12.1147 1.35539 12.0092 1.42327 11.9098 1.49951C11.4614 1.84351 11.2109 2.39301 10.71 3.49201L10.0235 4.99792" stroke="#FF3A2C" stroke-width="1.7" stroke-linecap="round"/>
<path d="M11.6719 21.5969V14.7969" stroke="#FF3A2C" stroke-width="1.7" stroke-linecap="round"/>
<path d="M17.3281 21.5969V14.7969" stroke="#FF3A2C" stroke-width="1.7" stroke-linecap="round"/>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M21 7.8C21 6.11984 21 5.27976 20.673 4.63803C20.3854 4.07354 19.9265 3.6146 19.362 3.32698C18.7202 3 17.8802 3 16.2 3H7.8C6.11984 3 5.27976 3 4.63803 3.32698C4.07354 3.6146 3.6146 4.07354 3.32698 4.63803C3 5.27976 3 6.11984 3 7.8V16.2C3 17.8802 3 18.7202 3.32698 19.362C3.6146 19.9265 4.07354 20.3854 4.63803 20.673C5.27976 21 6.11984 21 7.8 21H16.2C17.8802 21 18.7202 21 19.362 20.673C19.9265 20.3854 20.3854 19.9265 20.673 19.362C21 18.7202 21 17.8802 21 16.2V7.8ZM6 7H11V8.5H6V7ZM19 19H5L19 5V19ZM14.5 16V18H16V16H18V14.5H16V12.5H14.5V14.5H12.5V16H14.5Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 685 B

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 8.5 KiB

View File

@@ -0,0 +1,3 @@
<svg width="18" height="19" viewBox="0 0 18 19" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M13.6511 8.0918C13.2317 7.97762 12.7903 7.91667 12.3346 7.91667C10.2236 7.91667 8.41814 9.22492 7.6848 11.0748M13.6511 8.0918C15.7739 8.66967 17.3346 10.6109 17.3346 12.9167C17.3346 15.6781 15.0961 17.9167 12.3346 17.9167C11.0541 17.9167 9.88589 17.4352 9.0013 16.6435M13.6511 8.0918C13.8771 7.52182 14.0013 6.90042 14.0013 6.25C14.0013 3.48857 11.7627 1.25 9.0013 1.25C6.23988 1.25 4.0013 3.48857 4.0013 6.25C4.0013 6.90042 4.12549 7.52182 4.35145 8.0918M7.6848 11.0748C7.4588 11.6448 7.33464 12.2662 7.33464 12.9167C7.33464 14.3975 7.97839 15.728 9.0013 16.6435M7.6848 11.0748C6.16085 10.66 4.92654 9.5425 4.35145 8.0918M9.0013 16.6435C8.11672 17.4352 6.94856 17.9167 5.66797 17.9167C2.90654 17.9167 0.667969 15.6781 0.667969 12.9167C0.667969 10.6109 2.22875 8.66967 4.35145 8.0918" stroke="white" stroke-width="1.25" stroke-linecap="round"/>
</svg>

After

Width:  |  Height:  |  Size: 957 B

View File

@@ -0,0 +1,4 @@
<svg width="21" height="21" viewBox="0 0 21 21" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M18.8333 8.55726V12.4461M14.25 3.0142C13.8337 2.9999 13.4168 2.99917 13 3.00042M14.25 17.989C13.8337 18.0034 13.4168 18.0041 13 18.0029M16.5456 3.4492C17.3442 3.85264 17.9928 4.5037 18.3932 5.30417M18.4167 15.6514C18.0184 16.4737 17.36 17.1426 16.5456 17.554" stroke="white" stroke-width="1.25" stroke-linecap="round"/>
<path d="M10.5052 5.08751C10.5052 3.45579 9.97371 3.00579 8.42187 3.00579C6.31214 3.00579 3.87715 2.79751 2.67428 4.87934C2.17188 5.74886 2.17188 6.91622 2.17188 9.25093V11.749C2.17188 14.0838 2.17188 15.2511 2.67428 16.1207C3.87715 18.2025 6.31214 17.9942 8.42187 17.9942C9.97371 17.9942 10.5052 17.5442 10.5052 15.9125V5.08751Z" stroke="white" stroke-width="1.25"/>
</svg>

After

Width:  |  Height:  |  Size: 800 B

View File

@@ -0,0 +1,8 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M7.5 10.5C8.32843 10.5 9 9.82843 9 9C9 8.17157 8.32843 7.5 7.5 7.5C6.67157 7.5 6 8.17157 6 9C6 9.82843 6.67157 10.5 7.5 10.5Z" fill="white"/>
<path d="M12 8.25C12.8284 8.25 13.5 7.57843 13.5 6.75C13.5 5.92157 12.8284 5.25 12 5.25C11.1716 5.25 10.5 5.92157 10.5 6.75C10.5 7.57843 11.1716 8.25 12 8.25Z" fill="white"/>
<path d="M16.5 10.5C17.3284 10.5 18 9.82843 18 9C18 8.17157 17.3284 7.5 16.5 7.5C15.6716 7.5 15 8.17157 15 9C15 9.82843 15.6716 10.5 16.5 10.5Z" fill="white"/>
<path d="M17.25 15C18.0784 15 18.75 14.3284 18.75 13.5C18.75 12.6716 18.0784 12 17.25 12C16.4216 12 15.75 12.6716 15.75 13.5C15.75 14.3284 16.4216 15 17.25 15Z" fill="white"/>
<path d="M14.25 18.75C15.0784 18.75 15.75 18.0784 15.75 17.25C15.75 16.4216 15.0784 15.75 14.25 15.75C13.4216 15.75 12.75 16.4216 12.75 17.25C12.75 18.0784 13.4216 18.75 14.25 18.75Z" fill="white"/>
<path d="M12.405 1.49219C10.9924 1.43766 9.58338 1.66894 8.26234 2.17214C6.9413 2.67535 5.73548 3.44013 4.71716 4.42063C3.69884 5.40113 2.889 6.57716 2.33618 7.87821C1.78336 9.17927 1.49895 10.5786 1.5 11.9922C1.49997 12.5482 1.62818 13.0967 1.87466 13.5951C2.12115 14.0934 2.47927 14.5282 2.92117 14.8656C3.36308 15.2031 3.87685 15.434 4.42255 15.5405C4.96825 15.647 5.53116 15.6262 6.0675 15.4797L6.9075 15.2472C7.24166 15.156 7.59237 15.1431 7.9323 15.2097C8.27223 15.2762 8.5922 15.4204 8.8673 15.6309C9.14239 15.8414 9.36516 16.1125 9.51827 16.4232C9.67138 16.7339 9.75068 17.0758 9.75 17.4222V20.2422C9.75 20.8389 9.98706 21.4112 10.409 21.8332C10.831 22.2551 11.4033 22.4922 12 22.4922C13.4136 22.4932 14.8129 22.2088 16.114 21.656C17.415 21.1032 18.5911 20.2933 19.5716 19.275C20.5521 18.2567 21.3168 17.0509 21.82 15.7299C22.3233 14.4088 22.5545 12.9998 22.5 11.5872C22.3912 8.94469 21.2927 6.43974 19.4226 4.56963C17.5525 2.69952 15.0475 1.60101 12.405 1.49219ZM18.4875 18.2247C17.6501 19.1015 16.6432 19.7989 15.528 20.2747C14.4127 20.7504 13.2125 20.9945 12 20.9922C11.8011 20.9922 11.6103 20.9132 11.4697 20.7725C11.329 20.6319 11.25 20.4411 11.25 20.2422V17.4222C11.25 16.4276 10.8549 15.4738 10.1517 14.7705C9.44839 14.0673 8.49456 13.6722 7.5 13.6722C7.16295 13.6722 6.82743 13.7176 6.5025 13.8072L5.6625 14.0397C5.34876 14.1238 5.01987 14.1345 4.70133 14.0709C4.38279 14.0074 4.08317 13.8714 3.82569 13.6734C3.56821 13.4754 3.35979 13.2207 3.2166 12.9292C3.07341 12.6376 2.9993 12.317 3 11.9922C2.99907 10.78 3.24301 9.58019 3.71719 8.46463C4.19136 7.34907 4.886 6.34079 5.75942 5.50028C6.63285 4.65978 7.66706 4.00437 8.8 3.57339C9.93295 3.1424 11.1413 2.94471 12.3525 2.99219C14.6079 3.10966 16.7398 4.05844 18.3368 5.6554C19.9338 7.25237 20.8825 9.3843 21 11.6397C21.0512 12.8516 20.8548 14.0613 20.4228 15.1947C19.9908 16.3282 19.3323 17.3617 18.4875 18.2322V18.2247Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

@@ -0,0 +1,3 @@
<svg width="25" height="24" viewBox="0 0 25 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M10.163 17H14.836M12.5 3V4M18.864 5.636L18.157 6.343M21.5 12H20.5M4.5 12H3.5M6.843 6.343L6.136 5.636M8.964 15.536C8.26487 14.8367 7.7888 13.9458 7.59598 12.9759C7.40316 12.006 7.50225 11.0008 7.88073 10.0872C8.25921 9.17366 8.90007 8.39284 9.72229 7.84349C10.5445 7.29414 11.5111 7.00093 12.5 7.00093C13.4889 7.00093 14.4555 7.29414 15.2777 7.84349C16.0999 8.39284 16.7408 9.17366 17.1193 10.0872C17.4977 11.0008 17.5968 12.006 17.404 12.9759C17.2112 13.9458 16.7351 14.8367 16.036 15.536L15.488 16.083C15.1745 16.3962 14.9259 16.7682 14.7564 17.1776C14.5868 17.587 14.4997 18.0259 14.5 18.469V19C14.5 19.5304 14.2893 20.0391 13.9142 20.4142C13.5391 20.7893 13.0304 21 12.5 21C11.9696 21 11.4609 20.7893 11.0858 20.4142C10.7107 20.0391 10.5 19.5304 10.5 19V18.469C10.5 17.574 10.144 16.715 9.512 16.083L8.964 15.536Z" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 1011 B

View File

@@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M7.49478 13.752C10.5833 10.1634 17.5788 3.1538 20.5387 3.00347C22.3699 2.82808 18.7218 9.32449 10.0785 16.4329M11.4581 10.0439L13.7157 12.3239M3 20.8536C3.70948 18.3462 3.26187 19.5784 3.50407 16.6909C3.63306 16.2634 3.89258 14.9367 5.51358 14.2755C7.35618 13.5239 8.70698 14.6601 9.05612 15.194C10.0847 16.3092 10.2039 17.6942 9.05612 19.2764C7.9083 20.8586 4.50352 21.2517 3 20.8536Z" stroke="white" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 582 B

View File

@@ -0,0 +1,3 @@
<svg width="21" height="20" viewBox="0 0 21 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M15.0449 2.83799C14.7701 2.62935 14.3777 2.6834 14.1689 2.95811C13.9603 3.23293 14.0143 3.62529 14.2891 3.83408L15.25 4.56455C16.056 5.17686 16.6055 5.59611 16.9619 5.95713C16.9896 5.98516 17.0149 6.01299 17.0391 6.03916H8C4.89347 6.03916 2.3751 8.55765 2.375 11.6642C2.375 14.7708 4.89341 17.2892 8 17.2892H11.333C11.6782 17.2892 11.958 17.0093 11.958 16.6642C11.9579 16.3191 11.6781 16.0392 11.333 16.0392H8C5.58376 16.0392 3.625 14.0804 3.625 11.6642C3.6251 9.24801 5.58382 7.28916 8 7.28916H17.0488C17.0218 7.31866 16.9934 7.35003 16.9619 7.38193C16.6055 7.74294 16.056 8.16221 15.25 8.77451L14.2891 9.50498C14.0142 9.71375 13.9602 10.1061 14.1689 10.381C14.3778 10.6557 14.7701 10.7089 15.0449 10.5001L16.0059 9.76963C16.7807 9.18098 17.4174 8.6996 17.8516 8.25986C18.2952 7.81041 18.625 7.30951 18.625 6.66904C18.6248 6.02878 18.2952 5.52855 17.8516 5.0792C17.4174 4.63943 16.7808 4.15716 16.0059 3.56846L15.0449 2.83799Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@@ -0,0 +1,4 @@
<svg width="16" height="20" viewBox="0 0 16 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M7.76819 16.3867V5.71094C6.34676 6.99951 3.50391 9.44665 3.50391 12.9695C3.50391 15.5767 6.34676 16.4224 7.76819 16.3867Z" fill="white"/>
<path d="M15.1412 12.8481C15.1412 7.85094 7.99833 0.710938 7.99833 0.710938C7.99833 0.710938 0.855469 7.85094 0.855469 12.8481C0.95579 14.6453 1.76312 16.3298 3.10118 17.5338C4.43975 18.7395 6.56975 19.2738 7.99833 19.2738C9.4269 19.2738 11.5569 18.7381 12.8955 17.5338C14.2335 16.3298 15.0409 14.6453 15.1412 12.8481Z" stroke="white" stroke-width="1.42857" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 657 B

View File

@@ -0,0 +1,3 @@
<svg width="25" height="24" viewBox="0 0 25 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M21 0.585938V19.4999H2.087L21 0.585938ZM6.916 17.4999H19V5.41394L6.916 17.4999ZM21 20.9999V22.9999H2V20.9999H21Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 241 B

View File

@@ -0,0 +1,3 @@
<svg width="25" height="25" viewBox="0 0 25 25" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M2.20312 6.32812C2.20313 5.23411 2.63772 4.1849 3.41131 3.41131C4.1849 2.63772 5.23411 2.20313 6.32812 2.20312H17.3281C18.4221 2.20313 19.4714 2.63772 20.2449 3.41131C21.0185 4.1849 21.4531 5.23411 21.4531 6.32812V11.2781C21.0135 11.0536 20.553 10.8726 20.0781 10.7377V6.32812C20.0781 5.59878 19.7884 4.89931 19.2727 4.38358C18.7569 3.86786 18.0575 3.57812 17.3281 3.57812H6.32812C5.59878 3.57812 4.89931 3.86786 4.38358 4.38358C3.86786 4.89931 3.57812 5.59878 3.57812 6.32812V17.3281C3.57812 18.0575 3.86786 18.7569 4.38358 19.2727C4.89931 19.7884 5.59878 20.0781 6.32812 20.0781H10.7377C10.8743 20.5585 11.0545 21.0168 11.2781 21.4531H6.32812C5.23411 21.4531 4.1849 21.0185 3.41131 20.2449C2.63772 19.4714 2.20313 18.4221 2.20312 17.3281V6.32812ZM9.04237 15.3385C9.459 15.5461 10.0324 15.7606 10.7611 15.8734C10.6314 16.3144 10.5421 16.7664 10.4944 17.2236C9.77616 17.1113 9.07928 16.8902 8.42775 16.5677C8.11828 16.4169 7.82365 16.2374 7.54775 16.0315C7.44444 15.9533 7.34487 15.8702 7.24937 15.7826L7.22875 15.7634L7.22187 15.7565L7.21912 15.7537L7.21637 15.7524C7.08692 15.6238 7.01382 15.4491 7.01318 15.2667C7.01254 15.0842 7.08439 14.909 7.21294 14.7796C7.34148 14.6501 7.51619 14.577 7.69863 14.5764C7.88107 14.5757 8.05629 14.6476 8.18575 14.7761L8.18987 14.7789L8.22012 14.8064C8.25129 14.8339 8.30217 14.8751 8.37275 14.9301C8.51575 15.0374 8.7385 15.1873 9.04237 15.3385ZM8.39062 10.4531C8.7553 10.4531 9.10503 10.3083 9.3629 10.0504C9.62076 9.79253 9.76562 9.4428 9.76562 9.07812C9.76562 8.71345 9.62076 8.36372 9.3629 8.10585C9.10503 7.84799 8.7553 7.70312 8.39062 7.70312C8.02595 7.70312 7.67622 7.84799 7.41835 8.10585C7.16049 8.36372 7.01562 8.71345 7.01562 9.07812C7.01562 9.4428 7.16049 9.79253 7.41835 10.0504C7.67622 10.3083 8.02595 10.4531 8.39062 10.4531ZM16.6406 9.07812C16.6406 9.4428 16.4958 9.79253 16.2379 10.0504C15.98 10.3083 15.6303 10.4531 15.2656 10.4531C14.901 10.4531 14.5512 10.3083 14.2934 10.0504C14.0355 9.79253 13.8906 9.4428 13.8906 9.07812C13.8906 8.71345 14.0355 8.36372 14.2934 8.10585C14.5512 7.84799 14.901 7.70312 15.2656 7.70312C15.6303 7.70312 15.98 7.84799 16.2379 8.10585C16.4958 8.36372 16.6406 8.71345 16.6406 9.07812ZM24.2031 18.0156C24.2031 19.6567 23.5512 21.2305 22.3908 22.3908C21.2305 23.5512 19.6567 24.2031 18.0156 24.2031C16.3746 24.2031 14.8008 23.5512 13.6404 22.3908C12.48 21.2305 11.8281 19.6567 11.8281 18.0156C11.8281 16.3746 12.48 14.8008 13.6404 13.6404C14.8008 12.48 16.3746 11.8281 18.0156 11.8281C19.6567 11.8281 21.2305 12.48 22.3908 13.6404C23.5512 14.8008 24.2031 16.3746 24.2031 18.0156ZM18.7031 15.2656C18.7031 15.0833 18.6307 14.9084 18.5018 14.7795C18.3728 14.6506 18.198 14.5781 18.0156 14.5781C17.8333 14.5781 17.6584 14.6506 17.5295 14.7795C17.4006 14.9084 17.3281 15.0833 17.3281 15.2656V17.3281H15.2656C15.0833 17.3281 14.9084 17.4006 14.7795 17.5295C14.6506 17.6584 14.5781 17.8333 14.5781 18.0156C14.5781 18.198 14.6506 18.3728 14.7795 18.5018C14.9084 18.6307 15.0833 18.7031 15.2656 18.7031H17.3281V20.7656C17.3281 20.948 17.4006 21.1228 17.5295 21.2518C17.6584 21.3807 17.8333 21.4531 18.0156 21.4531C18.198 21.4531 18.3728 21.3807 18.5018 21.2518C18.6307 21.1228 18.7031 20.948 18.7031 20.7656V18.7031H20.7656C20.948 18.7031 21.1228 18.6307 21.2518 18.5018C21.3807 18.3728 21.4531 18.198 21.4531 18.0156C21.4531 17.8333 21.3807 17.6584 21.2518 17.5295C21.1228 17.4006 20.948 17.3281 20.7656 17.3281H18.7031V15.2656Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 3.5 KiB

View File

@@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M12 2C12.83 1.99993 13.6285 2.3174 14.2319 2.88731C14.8353 3.45722 15.1978 4.23637 15.245 5.065L15.25 5.25L15.251 13.202L15.331 13.271C16.2621 14.1024 16.8485 15.2521 16.975 16.494L16.994 16.746L17 17C17.0001 17.8238 16.7967 18.6349 16.4079 19.3612C16.019 20.0874 15.4567 20.7063 14.7709 21.1629C14.0852 21.6194 13.2973 21.8994 12.4772 21.9781C11.6572 22.0567 10.8304 21.9315 10.0704 21.6135C9.31039 21.2956 8.64073 20.7948 8.12093 20.1557C7.60113 19.5166 7.24731 18.7589 7.09092 17.9501C6.93453 17.1412 6.98042 16.3063 7.2245 15.5195C7.46858 14.7326 7.9033 14.0183 8.49 13.44L8.67 13.27L8.749 13.202L8.75 5.25C8.74983 4.4513 9.04378 3.68051 9.57573 3.08474C10.1077 2.48897 10.8404 2.10995 11.634 2.02L11.816 2.005L12 2ZM12 3.5C11.5607 3.50004 11.1374 3.66533 10.8143 3.96305C10.4912 4.26076 10.2919 4.66912 10.256 5.107L10.25 5.25V13.945L9.941 14.169C9.35063 14.5984 8.90932 15.2017 8.67884 15.8944C8.44835 16.5871 8.44024 17.3345 8.65563 18.0321C8.87102 18.7296 9.29913 19.3423 9.88004 19.7845C10.4609 20.2266 11.1656 20.476 11.8953 20.4979C12.625 20.5197 13.3432 20.3127 13.9495 19.9061C14.5558 19.4994 15.0197 18.9134 15.2764 18.2299C15.533 17.5465 15.5696 16.7999 15.3809 16.0947C15.1922 15.3895 14.7877 14.7609 14.224 14.297L14.059 14.17L13.752 13.945L13.75 5.25C13.75 4.78587 13.5656 4.34075 13.2374 4.01256C12.9092 3.68437 12.4641 3.5 12 3.5ZM12 8C12.1989 8 12.3897 8.07902 12.5303 8.21967C12.671 8.36032 12.75 8.55109 12.75 8.75V14.615C13.3201 14.7942 13.8071 15.1716 14.123 15.6788C14.4389 16.1861 14.5627 16.7896 14.4721 17.3803C14.3814 17.9709 14.0823 18.5096 13.6288 18.8988C13.1754 19.2879 12.5976 19.5019 12 19.5019C11.4024 19.5019 10.8246 19.2879 10.3712 18.8988C9.91772 18.5096 9.61859 17.9709 9.52794 17.3803C9.4373 16.7896 9.56112 16.1861 9.877 15.6788C10.1929 15.1716 10.6799 14.7942 11.25 14.615V8.75C11.25 8.55109 11.329 8.36032 11.4697 8.21967C11.6103 8.07902 11.8011 8 12 8Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@@ -0,0 +1,7 @@
<svg width="21" height="21" viewBox="0 0 21 21" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M10.5 16.3359V18.8359" stroke="white" stroke-opacity="0.6" stroke-width="1.25" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M10.5 8.83594V12.1693" stroke="white" stroke-opacity="0.6" stroke-width="1.25" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M10.5 2.16406V4.66406" stroke="white" stroke-opacity="0.6" stroke-width="1.25" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M7.16599 6.7474C7.16599 6.04415 7.09652 5.23249 7.79099 4.83153C8.08106 4.66406 8.47049 4.66406 9.24936 4.66406H11.7494C12.5282 4.66406 12.9176 4.66406 13.2077 4.83153C13.9021 5.23249 13.8327 6.04415 13.8327 6.7474C13.8327 7.45064 13.9021 8.2623 13.2077 8.66326C12.9176 8.83073 12.5282 8.83073 11.7494 8.83073H9.24936C8.47049 8.83073 8.08106 8.83073 7.79099 8.66326C7.09652 8.2623 7.16599 7.45064 7.16599 6.7474Z" stroke="white" stroke-opacity="0.6" stroke-width="1.25" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M3.83006 14.2474C3.83006 13.5441 3.76058 12.7325 4.45506 12.3316C4.74512 12.1641 5.13455 12.1641 5.91339 12.1641H15.0801C15.8589 12.1641 16.2483 12.1641 16.5384 12.3316C17.2328 12.7325 17.1634 13.5441 17.1634 14.2474C17.1634 14.9506 17.2328 15.7623 16.5384 16.1632C16.2483 16.3307 15.8589 16.3307 15.0801 16.3307H5.91339C5.13455 16.3307 4.74512 16.3307 4.45506 16.1632C3.76058 15.7623 3.83006 14.9506 3.83006 14.2474Z" stroke="white" stroke-opacity="0.6" stroke-width="1.25" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -0,0 +1,5 @@
<svg width="21" height="21" viewBox="0 0 21 21" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M7.1699 6.7474C7.1699 6.04415 7.10042 5.23249 7.7949 4.83153C8.08496 4.66406 8.47438 4.66406 9.25322 4.66406H10.0865C10.8654 4.66406 11.2548 4.66406 11.5449 4.83153C12.2394 5.23249 12.1699 6.04415 12.1699 6.7474C12.1699 7.45064 12.2394 8.2623 11.5449 8.66326C11.2548 8.83073 10.8654 8.83073 10.0865 8.83073H9.25322C8.47438 8.83073 8.08496 8.83073 7.7949 8.66326C7.10042 8.2623 7.1699 7.45064 7.1699 6.7474Z" stroke="white" stroke-width="1.25" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M7.1699 14.2474C7.1699 13.5441 7.10042 12.7325 7.7949 12.3316C8.08496 12.1641 8.47438 12.1641 9.25322 12.1641H15.0865C15.8654 12.1641 16.2548 12.1641 16.5449 12.3316C17.2394 12.7325 17.1699 13.5441 17.1699 14.2474C17.1699 14.9506 17.2394 15.7623 16.5449 16.1632C16.2548 16.3307 15.8654 16.3307 15.0865 16.3307H9.25322C8.47438 16.3307 8.08496 16.3307 7.7949 16.1632C7.10042 15.7623 7.1699 14.9506 7.1699 14.2474Z" stroke="white" stroke-width="1.25" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M3.83203 2.16406V18.8307" stroke="white" stroke-width="1.25" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -0,0 +1,5 @@
<svg width="21" height="21" viewBox="0 0 21 21" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M13.8301 6.7474C13.8301 6.04415 13.8996 5.23249 13.2051 4.83153C12.915 4.66406 12.5256 4.66406 11.7468 4.66406H10.9135C10.1346 4.66406 9.7452 4.66406 9.45512 4.83153C8.76062 5.23249 8.83012 6.04415 8.83012 6.7474C8.83012 7.45064 8.76062 8.2623 9.45512 8.66326C9.7452 8.83073 10.1346 8.83073 10.9135 8.83073H11.7468C12.5256 8.83073 12.915 8.83073 13.2051 8.66326C13.8996 8.2623 13.8301 7.45064 13.8301 6.7474Z" stroke="white" stroke-opacity="0.6" stroke-width="1.25" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M13.8301 14.2474C13.8301 13.5441 13.8996 12.7325 13.2051 12.3316C12.915 12.1641 12.5256 12.1641 11.7468 12.1641H5.91345C5.13462 12.1641 4.7452 12.1641 4.45512 12.3316C3.76062 12.7325 3.83012 13.5441 3.83012 14.2474C3.83012 14.9506 3.76062 15.7623 4.45512 16.1632C4.7452 16.3307 5.13462 16.3307 5.91345 16.3307H11.7468C12.5256 16.3307 12.915 16.3307 13.2051 16.1632C13.8996 15.7623 13.8301 14.9506 13.8301 14.2474Z" stroke="white" stroke-opacity="0.6" stroke-width="1.25" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M17.168 2.16406V18.8307" stroke="white" stroke-opacity="0.6" stroke-width="1.25" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -0,0 +1,3 @@
<svg width="24" height="25" viewBox="0 0 24 25" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M14.0573 15.1667L14.732 17.0147C14.9587 17.636 15.7107 17.9773 16.412 17.7747C17.112 17.5747 17.496 16.9067 17.2693 16.2853L14.536 8.80533C14.2733 8.08267 13.636 7.516 12.8227 7.28267C11.4227 6.88 9.91733 7.56133 9.46267 8.804L6.73333 16.284C6.50667 16.9067 6.89067 17.5733 7.59067 17.776C8.29067 17.976 9.044 17.636 9.27067 17.0147L9.944 15.1667H14.0573ZM13.084 12.5H10.9173L12 9.53467L13.084 12.5ZM6.66667 4.5H17.3333C18.0406 4.5 18.7189 4.78095 19.219 5.28105C19.719 5.78115 20 6.45942 20 7.16667V17.8333C20 18.5406 19.719 19.2189 19.219 19.719C18.7189 20.219 18.0406 20.5 17.3333 20.5H6.66667C5.95942 20.5 5.28115 20.219 4.78105 19.719C4.28095 19.2189 4 18.5406 4 17.8333V7.16667C4 6.45942 4.28095 5.78115 4.78105 5.28105C5.28115 4.78095 5.95942 4.5 6.66667 4.5Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 895 B

View File

@@ -0,0 +1,5 @@
<svg width="21" height="21" viewBox="0 0 21 21" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M2.5 11L16 10.5L15.5 11.5L15 12.5C14.1667 13.1667 12.4 14.5 12 14.5C11.6 14.5 10.8333 15.8333 10.5 16.5L8.5 18H7.5L6 17L4.5 15.5L2 13.5L2.5 11Z" fill="white"/>
<path d="M16.3346 10.6052L11.2836 15.6699C9.79772 17.1598 9.05472 17.9048 8.14291 17.9871C7.99217 18.0008 7.84051 18.0008 7.68977 17.9871C6.77793 17.9048 6.03496 17.1598 4.54902 15.6699L2.86536 13.9816C1.9355 13.0492 1.9355 11.5376 2.86536 10.6052M16.3346 10.6052L9.59997 3.85229M16.3346 10.6052H2.86536M2.86536 10.6052L9.59997 3.85229M9.59997 3.85229L7.91635 2.16406" stroke="white" stroke-width="1.25" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M18.8333 17.1641C18.8333 18.0846 18.0872 18.8307 17.1667 18.8307C16.2462 18.8307 15.5 18.0846 15.5 17.1641C15.5 16.2436 17.1667 14.6641 17.1667 14.6641C17.1667 14.6641 18.8333 16.2436 18.8333 17.1641Z" stroke="white" stroke-width="1.25" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 1020 B

View File

@@ -0,0 +1,4 @@
<svg width="21" height="21" viewBox="0 0 21 21" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M12.168 16.3307L9.75705 9.45398C8.63754 6.2607 8.07778 4.66406 7.16797 4.66406C6.25816 4.66406 5.6984 6.2607 4.57888 9.45398L2.16797 16.3307M4.2513 10.4974H10.0846" stroke="white" stroke-width="1.25" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M18.8067 12.1145V15.8645M18.8067 12.1145C18.846 11.4286 18.8475 10.9061 18.7652 10.4796C18.571 9.47428 17.5205 8.86845 16.504 8.74519C15.5311 8.62726 14.7503 8.8777 13.9603 10.0288M18.8067 12.1145H16.437C16.073 12.1145 15.7058 12.1321 15.355 12.2296C13.2111 12.8256 13.3683 15.8321 15.5185 16.2027C15.7573 16.2439 16.0011 16.2615 16.243 16.2507C16.8076 16.2255 17.3286 15.9527 17.7758 15.607C18.2994 15.2019 18.8067 14.6365 18.8067 13.7812V12.1145Z" stroke="white" stroke-width="1.25" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 904 B

View File

@@ -0,0 +1,4 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M12.5 17.5H7.5" stroke="white" stroke-width="1.25" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M10.0013 2.5V17.5007M10.0013 2.5C11.1575 2.5 12.6426 2.52545 13.825 2.64707C14.3251 2.69849 14.5751 2.72421 14.7964 2.81492C15.2568 3.00357 15.6278 3.41718 15.7675 3.89733C15.8346 4.12817 15.8346 4.39159 15.8346 4.91845M10.0013 2.5C8.84514 2.5 7.36003 2.52545 6.17764 2.64707C5.67755 2.69849 5.4275 2.72421 5.20619 2.81492C4.74584 3.00357 4.37477 3.41718 4.23511 3.89733C4.16797 4.12817 4.16797 4.39159 4.16797 4.91845" stroke="white" stroke-width="1.25" stroke-linecap="round"/>
</svg>

After

Width:  |  Height:  |  Size: 701 B

View File

@@ -0,0 +1,7 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M2.49609 12C2.49609 7.52166 2.49609 5.28249 3.88733 3.89124C5.27858 2.5 7.51775 2.5 11.9961 2.5C16.4744 2.5 18.7136 2.5 20.1049 3.89124C21.4961 5.28249 21.4961 7.52166 21.4961 12C21.4961 16.4783 21.4961 18.7175 20.1049 20.1088C18.7136 21.5 16.4744 21.5 11.9961 21.5C7.51775 21.5 5.27858 21.5 3.88733 20.1088C2.49609 18.7175 2.49609 16.4783 2.49609 12Z" stroke="white" stroke-width="1.5" stroke-linejoin="round"/>
<path d="M9.99609 15.5C9.99609 16.3284 9.32452 17 8.49609 17C7.66766 17 6.99609 16.3284 6.99609 15.5C6.99609 14.6716 7.66766 14 8.49609 14C9.32452 14 9.99609 14.6716 9.99609 15.5Z" stroke="white" stroke-width="1.5"/>
<path d="M17 8.5C17 7.67157 16.3284 7 15.5 7C14.6716 7 14 7.67157 14 8.5C14 9.32843 14.6716 10 15.5 10C16.3284 10 17 9.32843 17 8.5Z" stroke="white" stroke-width="1.5"/>
<path d="M8.49609 14V7" stroke="white" stroke-width="1.5" stroke-linecap="round"/>
<path d="M15.5 10V17" stroke="white" stroke-width="1.5" stroke-linecap="round"/>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1,4 @@
<svg width="21" height="20" viewBox="0 0 21 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M3 6.66406H13C15.7614 6.66406 18 8.90265 18 11.6641C18 14.4255 15.7614 16.6641 13 16.6641H9.66667" stroke="white" stroke-width="1.25" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M6.33333 3.33594L5.37183 4.06637C3.79061 5.26761 3 5.86823 3 6.66927C3 7.47031 3.79061 8.07093 5.37183 9.27219L6.33333 10.0026" stroke="white" stroke-width="1.25" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 516 B

View File

@@ -43,7 +43,7 @@ post_install do |installer|
target.build_configurations.each do |config|
config.build_settings.delete 'IPHONEOS_DEPLOYMENT_TARGET'
config.build_settings['EXCLUDED_ARCHS[sdk=iphonesimulator*]'] = 'arm64'
config.build_settings['DEVELOPMENT_TEAM'] = '6Z68YJY9Q2'
end
end
end

View File

@@ -5,7 +5,7 @@ import 'package:adaptive_theme/adaptive_theme.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:home_widget/home_widget.dart' as hw;
import 'package:logging/logging.dart';
import 'package:media_extension/media_extension_action_types.dart';
@@ -145,7 +145,9 @@ class _EnteAppState extends State<EnteApp> with WidgetsBindingObserver {
supportedLocales: appSupportedLocales,
localeListResolutionCallback: localResolutionCallBack,
localizationsDelegates: const [
...AppLocalizations.localizationsDelegates,
GlobalMaterialLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
S.delegate,
],
),
@@ -168,7 +170,9 @@ class _EnteAppState extends State<EnteApp> with WidgetsBindingObserver {
supportedLocales: appSupportedLocales,
localeListResolutionCallback: localResolutionCallBack,
localizationsDelegates: const [
...AppLocalizations.localizationsDelegates,
GlobalMaterialLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
S.delegate,
],
),

View File

@@ -233,6 +233,8 @@ extension CustomColorScheme on ColorScheme {
? const Color(0xFF424242)
: const Color(0xFFFFFFFF);
Color get imageEditorPrimaryColor => const Color.fromRGBO(8, 194, 37, 1);
Color get defaultBackgroundColor =>
brightness == Brightness.light ? backgroundBaseLight : backgroundBaseDark;

View File

@@ -783,6 +783,7 @@ class MessageLookup extends MessageLookupByLibrary {
"custom": MessageLookupByLibrary.simpleMessage("Custom"),
"customEndpoint": m20,
"darkTheme": MessageLookupByLibrary.simpleMessage("Dark"),
"day": MessageLookupByLibrary.simpleMessage("Day"),
"dayToday": MessageLookupByLibrary.simpleMessage("Today"),
"dayYesterday": MessageLookupByLibrary.simpleMessage("Yesterday"),
"declineTrustInvite":
@@ -1112,6 +1113,7 @@ class MessageLookup extends MessageLookupByLibrary {
"grantPermission":
MessageLookupByLibrary.simpleMessage("Grant permission"),
"greenery": MessageLookupByLibrary.simpleMessage("The green life"),
"groupBy": MessageLookupByLibrary.simpleMessage("Group by"),
"groupNearbyPhotos":
MessageLookupByLibrary.simpleMessage("Group nearby photos"),
"guestView": MessageLookupByLibrary.simpleMessage("Guest view"),
@@ -1212,8 +1214,10 @@ class MessageLookup extends MessageLookupByLibrary {
"language": MessageLookupByLibrary.simpleMessage("Language"),
"lastTimeWithThem": m45,
"lastUpdated": MessageLookupByLibrary.simpleMessage("Last updated"),
"lastWeek": MessageLookupByLibrary.simpleMessage("Last week"),
"lastYearsTrip":
MessageLookupByLibrary.simpleMessage("Last year\'s trip"),
"layout": MessageLookupByLibrary.simpleMessage("Layout"),
"leave": MessageLookupByLibrary.simpleMessage("Leave"),
"leaveAlbum": MessageLookupByLibrary.simpleMessage("Leave album"),
"leaveFamily": MessageLookupByLibrary.simpleMessage("Leave family"),
@@ -2054,6 +2058,8 @@ class MessageLookup extends MessageLookupByLibrary {
"thisIsPersonVerificationId": m100,
"thisIsYourVerificationId": MessageLookupByLibrary.simpleMessage(
"This is your Verification ID"),
"thisMonth": MessageLookupByLibrary.simpleMessage("This month"),
"thisWeek": MessageLookupByLibrary.simpleMessage("This week"),
"thisWeekThroughTheYears":
MessageLookupByLibrary.simpleMessage("This week through the years"),
"thisWeekXYearsAgo": m101,
@@ -2068,6 +2074,7 @@ class MessageLookup extends MessageLookupByLibrary {
"thisWillRemovePublicLinksOfAllSelectedQuickLinks":
MessageLookupByLibrary.simpleMessage(
"This will remove public links of all selected quick links."),
"thisYear": MessageLookupByLibrary.simpleMessage("This year"),
"throughTheYears": m102,
"toEnableAppLockPleaseSetupDevicePasscodeOrScreen":
MessageLookupByLibrary.simpleMessage(

View File

@@ -12296,6 +12296,56 @@ class S {
);
}
/// `This week`
String get thisWeek {
return Intl.message(
'This week',
name: 'thisWeek',
desc: '',
args: [],
);
}
/// `Last week`
String get lastWeek {
return Intl.message(
'Last week',
name: 'lastWeek',
desc: '',
args: [],
);
}
/// `This month`
String get thisMonth {
return Intl.message(
'This month',
name: 'thisMonth',
desc: '',
args: [],
);
}
/// `This year`
String get thisYear {
return Intl.message(
'This year',
name: 'thisYear',
desc: '',
args: [],
);
}
/// `Group by`
String get groupBy {
return Intl.message(
'Group by',
name: 'groupBy',
desc: '',
args: [],
);
}
/// `Unable to generate face thumbnails`
String get faceThumbnailGenerationFailed {
return Intl.message(
@@ -12395,6 +12445,26 @@ class S {
args: [],
);
}
/// `Layout`
String get layout {
return Intl.message(
'Layout',
name: 'layout',
desc: '',
args: [],
);
}
/// `Day`
String get day {
return Intl.message(
'Day',
name: 'day',
desc: '',
args: [],
);
}
}
class AppLocalizationDelegate extends LocalizationsDelegate<S> {

View File

@@ -1789,6 +1789,11 @@
"cLTitle6": "Resumable Uploads and Downloads",
"cLDesc6": "No more waiting for uploads/downloads to complete before you can close the app. All uploads and downloads now have the ability to be paused midway, and resume from where you left off.",
"indexingPausedStatusDescription": "Indexing is paused. It will automatically resume when the device is ready. The device is considered ready when its battery level, battery health, and thermal status are within a healthy range.",
"thisWeek": "This week",
"lastWeek": "Last week",
"thisMonth": "This month",
"thisYear": "This year",
"groupBy": "Group by",
"faceThumbnailGenerationFailed": "Unable to generate face thumbnails",
"fileAnalysisFailed": "Unable to analyze file",
"editAutoAddPeople": "Edit auto-add people",
@@ -1798,5 +1803,7 @@
"gettingReady": "Getting ready",
"addSomePhotosDesc1": "Add some photos or pick ",
"addSomePhotosDesc2": "familiar faces",
"addSomePhotosDesc3": "\nto begin with"
}
"addSomePhotosDesc3": "\nto begin with",
"layout" : "Layout",
"day": "Day"
}

View File

@@ -0,0 +1,168 @@
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
class FixedExtentGridRow extends MultiChildRenderObjectWidget {
final double width, height, spacing;
final TextDirection textDirection;
const FixedExtentGridRow({
super.key,
required this.width,
required this.height,
required this.spacing,
required this.textDirection,
required super.children,
});
@override
RenderObject createRenderObject(BuildContext context) {
return RenderFixedExtentGridRow(
width: width,
height: height,
spacing: spacing,
textDirection: textDirection,
);
}
@override
void updateRenderObject(
BuildContext context,
RenderFixedExtentGridRow renderObject,
) {
renderObject.width = width;
renderObject.height = height;
renderObject.spacing = spacing;
renderObject.textDirection = textDirection;
}
@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties.add(DoubleProperty('width', width));
properties.add(DoubleProperty('height', height));
properties.add(DoubleProperty('spacing', spacing));
properties.add(EnumProperty<TextDirection>('textDirection', textDirection));
}
}
class _GridRowParentData extends ContainerBoxParentData<RenderBox> {}
class RenderFixedExtentGridRow extends RenderBox
with
ContainerRenderObjectMixin<RenderBox, _GridRowParentData>,
RenderBoxContainerDefaultsMixin<RenderBox, _GridRowParentData> {
RenderFixedExtentGridRow({
List<RenderBox>? children,
required double width,
required double height,
required double spacing,
required TextDirection textDirection,
}) : _width = width,
_height = height,
_spacing = spacing,
_textDirection = textDirection {
addAll(children);
}
double get width => _width;
double _width;
set width(double value) {
if (_width == value) return;
_width = value;
markNeedsLayout();
}
double get height => _height;
double _height;
set height(double value) {
if (_height == value) return;
_height = value;
markNeedsLayout();
}
double get spacing => _spacing;
double _spacing;
set spacing(double value) {
if (_spacing == value) return;
_spacing = value;
markNeedsLayout();
}
TextDirection get textDirection => _textDirection;
TextDirection _textDirection;
set textDirection(TextDirection value) {
if (_textDirection == value) return;
_textDirection = value;
markNeedsLayout();
}
@override
void setupParentData(RenderBox child) {
if (child.parentData is! _GridRowParentData) {
child.parentData = _GridRowParentData();
}
}
double get intrinsicWidth => width * childCount + spacing * (childCount - 1);
@override
double computeMinIntrinsicWidth(double height) => intrinsicWidth;
@override
double computeMaxIntrinsicWidth(double height) => intrinsicWidth;
@override
double computeMinIntrinsicHeight(double width) => height;
@override
double computeMaxIntrinsicHeight(double width) => height;
@override
void performLayout() {
var child = firstChild;
if (child == null) {
size = constraints.smallest;
return;
}
size = Size(constraints.maxWidth, height);
final childConstraints = BoxConstraints.tight(Size(width, height));
final flipMainAxis = textDirection == TextDirection.rtl;
var offset = Offset(flipMainAxis ? size.width - width : 0, 0);
final dx = (flipMainAxis ? -1 : 1) * (width + spacing);
while (child != null) {
child.layout(childConstraints, parentUsesSize: false);
final childParentData = child.parentData! as _GridRowParentData;
childParentData.offset = offset;
offset += Offset(dx, 0);
child = childParentData.nextSibling;
}
}
@override
double? computeDistanceToActualBaseline(TextBaseline baseline) {
return defaultComputeDistanceToHighestActualBaseline(baseline);
}
@override
bool hitTestChildren(BoxHitTestResult result, {required Offset position}) {
return defaultHitTestChildren(result, position: position);
}
@override
void paint(PaintingContext context, Offset offset) {
defaultPaint(context, offset);
}
@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties.add(DoubleProperty('width', width));
properties.add(DoubleProperty('height', height));
properties.add(DoubleProperty('spacing', spacing));
properties.add(EnumProperty<TextDirection>('textDirection', textDirection));
}
}

View File

@@ -0,0 +1,52 @@
import 'package:flutter/material.dart';
// Used to store layout information for a section (group) in a gallery
class FixedExtentSectionLayout {
final double tileHeight, mainAxisStride;
final int firstIndex, lastIndex, bodyFirstIndex;
final double minOffset, maxOffset, bodyMinOffset;
final double headerExtent, spacing;
final IndexedWidgetBuilder builder;
const FixedExtentSectionLayout({
required this.firstIndex,
required this.lastIndex,
required this.minOffset,
required this.maxOffset,
required this.headerExtent,
required this.tileHeight,
required this.spacing,
required this.builder,
}) : bodyFirstIndex = firstIndex + 1,
bodyMinOffset = minOffset + headerExtent,
mainAxisStride = tileHeight + spacing;
bool hasChild(int index) => firstIndex <= index && index <= lastIndex;
bool hasChildAtOffset(double scrollOffset) =>
minOffset <= scrollOffset && scrollOffset <= maxOffset;
double indexToLayoutOffset(int index) {
index -= bodyFirstIndex;
if (index < 0) return minOffset;
return bodyMinOffset + index * mainAxisStride;
}
int getMinChildIndexForScrollOffset(double scrollOffset) {
scrollOffset -= bodyMinOffset;
if (mainAxisStride == 0 || !scrollOffset.isFinite || scrollOffset < 0) {
return firstIndex;
}
return bodyFirstIndex + scrollOffset ~/ mainAxisStride;
}
int getMaxChildIndexForScrollOffset(double scrollOffset) {
scrollOffset -= bodyMinOffset;
if (mainAxisStride == 0 || !scrollOffset.isFinite || scrollOffset < 0) {
return firstIndex;
}
return bodyFirstIndex + (scrollOffset / mainAxisStride).ceil() - 1;
}
}

Some files were not shown because too many files have changed in this diff Show More