-
Notifications
You must be signed in to change notification settings - Fork 11
Feature/nextcloud garages3 primary storage #40
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| <?php | ||
|
|
||
| $bucket = getenv('GARAGES3_BUCKET') ?: 'nextcloud'; | ||
| $key = getenv('GARAGES3_KEY'); | ||
| $secret = getenv('GARAGES3_SECRET'); | ||
|
|
||
| if ($key === false || $key === '' || $secret === false || $secret === '') { | ||
| throw new RuntimeException('GARAGES3_KEY and GARAGES3_SECRET must be set for Garage S3 primary storage.'); | ||
| } | ||
|
|
||
| $CONFIG = [ | ||
| 'objectstore' => [ | ||
| 'class' => '\\OC\\Files\\ObjectStore\\S3', | ||
| 'arguments' => [ | ||
| 'bucket' => $bucket, | ||
| 'hostname' => getenv('GARAGES3_HOSTNAME') ?: 'host.docker.internal', | ||
| 'port' => (int) (getenv('GARAGES3_PORT') ?: 3900), | ||
| 'region' => getenv('GARAGES3_REGION') ?: 'garage', | ||
| 'key' => $key, | ||
| 'secret' => $secret, | ||
| 'use_ssl' => filter_var(getenv('GARAGES3_USE_SSL') ?: 'false', FILTER_VALIDATE_BOOLEAN), | ||
| 'use_path_style' => filter_var(getenv('GARAGES3_USE_PATH_STYLE') ?: 'true', FILTER_VALIDATE_BOOLEAN), | ||
| 'autocreate' => filter_var(getenv('GARAGES3_AUTOCREATE') ?: 'true', FILTER_VALIDATE_BOOLEAN), | ||
| 'verify_bucket_exists' => filter_var(getenv('GARAGES3_VERIFY_BUCKET_EXISTS') ?: 'true', FILTER_VALIDATE_BOOLEAN), | ||
| ], | ||
| ], | ||
| ]; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Having instructions in some README on how to add the service to a docker-compose.override.yml removes the need for a Makefile. You could even have a folder with examples of docker-compose.override.yml files already prepared for each scenario (e.g., one example for garages3) with a README in that examples folder explaining how to use them and adding the docker-compose.override.yml to the .gitignore. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| COMPOSE ?= docker compose | ||
| GARAGES3_COMPOSE_FILE ?= docker-compose-garages3.yml | ||
|
|
||
| .PHONY: up-garages3 down-garages3 bootstrap-garages3 garage-status-garages3 start-garages3 wait-nextcloud-garages3 setup-garages3 | ||
|
|
||
| up-garages3: | ||
| $(COMPOSE) -f $(GARAGES3_COMPOSE_FILE) up -d garage | ||
|
|
||
| down-garages3: | ||
| $(COMPOSE) -f $(GARAGES3_COMPOSE_FILE) down | ||
|
|
||
| garage-status-garages3: | ||
| $(COMPOSE) -f $(GARAGES3_COMPOSE_FILE) exec -T garage /garage status | ||
|
|
||
| bootstrap-garages3: | ||
| ./scripts/bootstrap-garages3.sh | ||
|
|
||
| start-garages3: | ||
| $(COMPOSE) -f $(GARAGES3_COMPOSE_FILE) up -d db app web cron | ||
|
|
||
| wait-nextcloud-garages3: | ||
| @until $(COMPOSE) -f $(GARAGES3_COMPOSE_FILE) exec --user www-data app php occ status --output=json 2>/dev/null | grep -q '"installed":true'; do echo "Awaiting Nextcloud"; sleep 10; done | ||
|
|
||
| setup-garages3: | ||
| $(MAKE) bootstrap-garages3 | ||
| $(MAKE) start-garages3 | ||
| $(MAKE) wait-nextcloud-garages3 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -105,6 +105,39 @@ docker compose exec -u www-data app ./occ db:convert-filecache-bigint | |
|
|
||
| You can do this using environments and creating a file called `docker-compose.override.yml` to add new services. | ||
|
|
||
| ### Garage S3 primary storage | ||
|
|
||
| Use `docker-compose-garages3.yml` when you want Nextcloud to store files in a Garage S3 bucket instead of the local `data/` directory. | ||
|
|
||
| The stack expects these values in `.env`: | ||
|
|
||
| - `GARAGES3_BUCKET` | ||
| - `GARAGES3_KEY` | ||
| - `GARAGES3_KEY_ID` | ||
| - `GARAGES3_SECRET` | ||
| - `GARAGES3_HOSTNAME`, defaulting to `host.docker.internal` | ||
| - `GARAGES3_PORT`, defaulting to `3900` | ||
| - `GARAGES3_REGION`, defaulting to `garage` | ||
|
|
||
| Create the bucket and access key in Garage before starting Nextcloud with this compose file. `GARAGES3_KEY_ID` must contain the Garage access key ID used by Nextcloud. | ||
|
|
||
| The Garage service uses `garage/garage.toml`. Update `rpc_secret` before using it in a real environment. | ||
|
|
||
| Use `make up-garages3` to start Garage, and `make bootstrap-garages3` to create the Garage bucket and access key. | ||
| The bootstrap updates `.env` in place with the generated Garage credentials. | ||
| Use `make setup-garages3` to run the full setup and wait for Nextcloud to report as installed. | ||
| The stack now uses PostgreSQL 16. If you already created the database volume with an older PostgreSQL major version, recreate or migrate that volume once before starting the updated compose file. | ||
|
|
||
| For a clean local installation, use `make reset-garages3`. | ||
| Use `make setup-garages3` if you want to keep the existing local state and only rerun the setup steps. | ||
|
|
||
| Basic flow: | ||
|
|
||
| 1. Copy `.env.example` to `.env` if needed. | ||
| 2. Update `garage/garage.toml` and replace the placeholder `rpc_secret`. | ||
| 3. Run `make setup-garages3`. | ||
| 4. Open the Nextcloud URL and finish the initial admin setup if it is still pending. | ||
|
|
||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This block in the project’s main README may be intimidating; it might be better to put it in a docs folder and also have more detailed project documentation. With a docs folder, you can even set up GitHub Pages later (a static site) with something like a “Read the Docs” style. |
||
| ### PHP | ||
|
|
||
| - Create your `.ini` file at `volumes/php/` folder. Example: `volumes/php/xdebug.ini` | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,121 @@ | ||
| networks: | ||
| reverse-proxy: | ||
| external: true | ||
| name: reverse-proxy | ||
| internal: | ||
| driver: bridge | ||
|
|
||
| services: | ||
| db: | ||
| image: postgres:16 | ||
| restart: always | ||
| volumes: | ||
| - ./volumes/postgres/data:/var/lib/postgresql/data | ||
| environment: | ||
| - POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-SECRET_PASSWORD} | ||
| - POSTGRES_DB=${POSTGRES_DB:-nextcloud} | ||
| - POSTGRES_USER=${POSTGRES_USER:-nextcloud} | ||
| networks: | ||
| - internal | ||
|
|
||
| garage: | ||
| image: dxflrs/garage:v1.0.0 | ||
| restart: unless-stopped | ||
| network_mode: host | ||
| volumes: | ||
| - ./garage/garage.toml:/etc/garage.toml | ||
| - ./garage/meta:/var/lib/garage/meta | ||
| - ./garage/data:/var/lib/garage/data | ||
|
Comment on lines
+21
to
+28
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think that to avoid duplicating the docker-compose.yml file for every new service, the ideal is to have in some README the instructions for how to create the docker-compose.override.yml file and how to add the new service to it. That way, you can run docker compose up without issues, and the changes won’t impact anything when versioned files are updated—plus it reduces the number of files to maintain in the future. |
||
|
|
||
| app: | ||
| build: | ||
| context: .docker/app | ||
| args: | ||
| NEXTCLOUD_VERSION: ${NEXTCLOUD_VERSION:-stable-fpm} | ||
| restart: unless-stopped | ||
| volumes: | ||
| - ./volumes/nextcloud:/var/www/html | ||
| - ./app-hooks/post-installation:/docker-entrypoint-hooks.d/post-installation | ||
| - ./.docker/garages3.config.php:/var/www/html/config/garages3.config.php:ro | ||
| environment: | ||
| - POSTGRES_DB=${POSTGRES_DB:-nextcloud} | ||
| - POSTGRES_USER=${POSTGRES_USER:-nextcloud} | ||
| - POSTGRES_PASSWORD | ||
| - POSTGRES_HOST=db | ||
| - NEXTCLOUD_ADMIN_USER | ||
| - NEXTCLOUD_ADMIN_PASSWORD | ||
| - NEXTCLOUD_ADMIN_EMAIL | ||
| - NEXTCLOUD_TRUSTED_DOMAINS | ||
| - SMTP_HOST | ||
| - SMTP_SECURE | ||
| - SMTP_PORT | ||
| - SMTP_AUTHTYPE | ||
| - SMTP_NAME | ||
| - SMTP_PASSWORD | ||
| - MAIL_FROM_ADDRESS | ||
| - MAIL_DOMAIN | ||
| - TZ | ||
| - GARAGES3_BUCKET | ||
| - GARAGES3_KEY_ID=${GARAGES3_KEY_ID:-${GARAGES3_KEY:-}} | ||
| - GARAGES3_SECRET=${GARAGES3_SECRET:-} | ||
| - GARAGES3_HOSTNAME=${GARAGES3_HOSTNAME:-host.docker.internal} | ||
| - GARAGES3_PORT=${GARAGES3_PORT:-3900} | ||
| - GARAGES3_REGION=${GARAGES3_REGION:-garage} | ||
| - GARAGES3_USE_SSL=${GARAGES3_USE_SSL:-0} | ||
| - GARAGES3_USE_PATH_STYLE=${GARAGES3_USE_PATH_STYLE:-1} | ||
| - GARAGES3_AUTOCREATE=${GARAGES3_AUTOCREATE:-1} | ||
| - GARAGES3_VERIFY_BUCKET_EXISTS=${GARAGES3_VERIFY_BUCKET_EXISTS:-1} | ||
| extra_hosts: | ||
| - host.docker.internal:host-gateway | ||
| depends_on: | ||
| - db | ||
| - garage | ||
| networks: | ||
| - internal | ||
|
|
||
| web: | ||
| build: .docker/web | ||
| restart: unless-stopped | ||
| volumes: | ||
| - ./volumes/nextcloud:/var/www/html:ro | ||
| - ./volumes/nginx/includes:/etc/nginx/conf.d/includes:rw | ||
| environment: | ||
| - VIRTUAL_HOST | ||
| - LETSENCRYPT_HOST | ||
| - LETSENCRYPT_EMAIL | ||
| - TZ | ||
| depends_on: | ||
| - app | ||
| networks: | ||
| - internal | ||
| - reverse-proxy | ||
|
|
||
| cron: | ||
| build: | ||
| context: .docker/app | ||
| args: | ||
| NEXTCLOUD_VERSION: ${NEXTCLOUD_VERSION:-stable-fpm} | ||
| restart: unless-stopped | ||
| environment: | ||
| - TZ | ||
| - GARAGES3_BUCKET | ||
| - GARAGES3_KEY_ID=${GARAGES3_KEY_ID:-${GARAGES3_KEY:-}} | ||
| - GARAGES3_SECRET=${GARAGES3_SECRET:-} | ||
| - GARAGES3_HOSTNAME=${GARAGES3_HOSTNAME:-host.docker.internal} | ||
| - GARAGES3_PORT=${GARAGES3_PORT:-3900} | ||
| - GARAGES3_REGION=${GARAGES3_REGION:-garage} | ||
| - GARAGES3_USE_SSL=${GARAGES3_USE_SSL:-0} | ||
| - GARAGES3_USE_PATH_STYLE=${GARAGES3_USE_PATH_STYLE:-1} | ||
| - GARAGES3_AUTOCREATE=${GARAGES3_AUTOCREATE:-1} | ||
| - GARAGES3_VERIFY_BUCKET_EXISTS=${GARAGES3_VERIFY_BUCKET_EXISTS:-1} | ||
| volumes: | ||
| - ./volumes/nextcloud:/var/www/html | ||
| - ./.docker/garages3.config.php:/var/www/html/config/garages3.config.php:ro | ||
| extra_hosts: | ||
| - host.docker.internal:host-gateway | ||
| depends_on: | ||
| - db | ||
| - garage | ||
| networks: | ||
| - internal | ||
| entrypoint: /cron.sh | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| meta/* | ||
| data/* | ||
| !.gitignore | ||
| !meta/.gitkeep | ||
| !data/.gitkeep |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| metadata_dir = "/var/lib/garage/meta" | ||
| data_dir = "/var/lib/garage/data" | ||
| db_engine = "lmdb" | ||
| metadata_auto_snapshot_interval = "6h" | ||
|
|
||
| replication_factor = 3 | ||
|
|
||
| compression_level = 2 | ||
|
|
||
| rpc_bind_addr = "[::]:3901" | ||
| rpc_public_addr = ":3901" | ||
| rpc_secret = "99eed281cbe8f1ae7bba15bc4091f57bdbacf913f0e2487ad53b65d88c4955fa" | ||
|
|
||
| [s3_api] | ||
| s3_region = "garage" | ||
| api_bind_addr = "[::]:3900" | ||
| root_domain = ".s3.garage" | ||
|
|
||
| [s3_web] | ||
| bind_addr = "[::]:3902" | ||
| root_domain = ".web.garage" | ||
| index = "index.html" |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,5 +3,18 @@ POSTGRES_DB=nextcloud | |
| POSTGRES_USER=nextcloud | ||
| NEXTCLOUD_ADMIN_USER=admin | ||
| NEXTCLOUD_ADMIN_PASSWORD=admin | ||
| NEXTCLOUD_TRUSTED_DOMAINS=mydomain.coop | ||
| NEXTCLOUD_TRUSTED_DOMAINS=localhost,127.0.0.1,localhost:8080,127.0.0.1:8080 | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The Nextcloud Docker image treats Useful? React with 👍 / 👎. |
||
| CA_STORE=/usr/local/share/ca-certificates | ||
| NEXTCLOUD_VERSION=stable-apache | ||
|
|
||
| GARAGES3_BUCKET=nextcloud | ||
| GARAGES3_KEY= | ||
| GARAGES3_KEY_ID= | ||
| GARAGES3_SECRET= | ||
| GARAGES3_HOSTNAME=garage | ||
| GARAGES3_PORT=3900 | ||
| GARAGES3_REGION=garage | ||
| GARAGES3_USE_SSL=false | ||
| GARAGES3_USE_PATH_STYLE=true | ||
| GARAGES3_AUTOCREATE=true | ||
| GARAGES3_VERIFY_BUCKET_EXISTS=true | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The bootstrap writes the usable S3 access key to
GARAGES3_KEY_IDand stores only the human key name (nextcloud-app) inGARAGES3_KEY, while this compose file only exportsGARAGES3_KEY_IDto the app/cron containers. With the documentedmake setup-garages3flow, this line leaves$keyempty and throws at startup; if a user manually exportsGARAGES3_KEY, Nextcloud would authenticate with the key name rather than the Garage access key ID. ReadGARAGES3_KEY_IDor map it intoGARAGES3_KEYhere.Useful? React with 👍 / 👎.