diff --git a/CloudronManifest.json b/CloudronManifest.json
index 35e36dc..4c07ec7 100644
--- a/CloudronManifest.json
+++ b/CloudronManifest.json
@@ -6,29 +6,17 @@
"multiDomain": true,
"httpPort": 3900,
"httpPorts": {
- "GARAGE_S3": {
- "title": "Garage S3 Server Domain",
- "description": "The domain name for the Garage S3 API",
- "containerPort": 3900,
- "defaultValue": "garage-s3"
- },
- "GARAGE_RPC": {
- "title": "Garage RPC Server Domain",
- "description": "The domain name for the Garage RPC",
- "containerPort": 3901,
- "defaultValue": "garage-rpc"
- },
"GARAGE_WEB": {
- "title": "Garage WEB Server Domain",
- "description": "The domain name for the Garage web server",
+ "title": "Garage web server domain",
+ "description": "Buckets as static sites can be found here",
"containerPort": 3902,
- "defaultValue": "garage-web"
+ "defaultValue": "web"
},
"GARAGE_ADMIN": {
"title": "Garage Admin API Domain",
- "description": "The domain name for the Garage admin API",
+ "description": "For administering the Garage instance remotely",
"containerPort": 3903,
- "defaultValue": "garage-admin"
+ "defaultValue": "admin"
}
},
"addons": {
diff --git a/Dockerfile.template b/Dockerfile.template
new file mode 100644
index 0000000..e4ff5ee
--- /dev/null
+++ b/Dockerfile.template
@@ -0,0 +1,19 @@
+FROM cloudron/base:5.0.0
+
+# Garage wants these directories for storing stuff.
+# We want it here so that /app/data gets backed up.
+RUN mkdir -p /app/data/garage/data /app/data/garage/meta
+
+ADD https://garagehq.deuxfleurs.fr/_releases/VERSION/x86_64-unknown-linux-musl/garage /usr/bin/garage
+RUN chmod 755 /usr/bin/garage
+
+COPY garage.toml /garage/garage.toml
+# Create a symlink that will become dead; we'll fill it again
+# with the startup script.
+RUN ln -s /app/data/garage.toml /etc/garage.toml
+
+COPY start.bash /garage/start.bash
+RUN chmod 755 /garage/start.bash
+
+
+CMD [ "/garage/start.bash" ]
\ No newline at end of file
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..485a38d
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,21 @@
+VERSION?=v2.1.0
+IMAGE?=garage:latest
+DOMAIN?=garage
+
+templates:
+ sed -e 's/VERSION/'"${VERSION}"'/g' Dockerfile.template > Dockerfile
+
+build: templates
+ cloudron build
+
+install: build
+ cloudron install \
+ --location "${DOMAIN}" \
+ --secondary-domains \
+ GARAGE_WEB="web.${DOMAIN}",GARAGE_ADMIN="admin.${DOMAIN}"
+
+uninstall:
+ cloudron uninstall --app "${DOMAIN}"
+
+update:
+ cloudron update
\ No newline at end of file
diff --git a/README.md b/README.md
index c60ea7f..3edfb29 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,168 @@
+# cloudron-garage
-may need to, at some point in the sequence, indicate where things are.
-I'm using a private registry.
+This is a packaging of the open source S3 object store [garage](https://garagehq.deuxfleurs.fr/) for [Cloudron](https://www.cloudron.io/).
+
+This is built with Garage v2.1.0.
+
+## using the package
+
+Once installed, Garage... doesn't do much. If you install it at
+
+```
+s3.example.com
+```
+
+on your Cloudron, if you try and access the root domain, nothing is there.
+
+```
+
+ AccessDenied
+ Forbidden: Garage does not support anonymous access yet
+ /
+ garage
+
+```
+
+This is OK. Most things need to be done via the Terminal on your Garage instance. The following information comes from the [Garage documentation](https://garagehq.deuxfleurs.fr/documentation/quick-start/), and you should spend time there if you want to host your own S3 clone.
+
+### creating a layout
+
+First, you'll need to check your instance's status.
+
+```
+garage status
+```
+
+You'll get something like
+
+```
+==== HEALTHY NODES ====
+ID Hostname Address Tags Zone Capacity DataAvail Version
+55d03cf30e7164dd f3303a68-1d1f-4fc7-8db7-6cdc28d36c04 172.18.17.8:3901 NO ROLE ASSIGNED v2.1.0
+```
+
+You'll particularly want to note the `ID`.
+
+Now, you need to create a layout:
+
+```
+garage layout assign -z -c
+```
+
+or, concretely:
+
+```
+garage layout assign -z home -c 1G 55d03cf30e7164dd
+```
+
+This creates a zone named `home`, of size `1G`, and uses the ID for the instance we're running on Cloudron. (I have no idea if these are fragile values and break if you migrate or restore from backup at this point...)
+
+This stages, but does not commit, those values.
+
+```
+garage layout show
+```
+
+to see the planned changes; it will tell you what to do in order to apply your changes. This is probably (the first time)
+
+```
+garage layout apply --version 1
+```
+
+### creating a bucket
+
+To create a bucket:
+
+```
+garage bucket create www-site
+```
+
+This creates a bucket called `www-site`.
+
+```
+garage key create www-site-key
+```
+
+Creates a key id/secret pair for this bucket.
+
+Then, you have to grant permissions to that bucket with that key. As you can see, this can allow write-only, or read-only keys. (See the docs... write-only might not be possible?)
+
+```
+garage bucket allow \
+ --read \
+ --write \
+ --owner \
+ www-site \
+ --key www-site-key
+```
+
+From here, you can use standard S3 tooling (`awscli`, `mc`, CyberDuck, etc.) to interact with your bucket.
+
+### exposing a bucket as a website
+
+If you want to expose a bucket (like `www-site`) as a website, that can be done via the command line:
+
+```
+garage bucket website --allow www-site
+```
+
+(TODO/FIXME: This does not seem to work yet. Not sure how this plays with Cloudron's domain management.)
+
+
+## about the package
+
+Garage is written in Rust, and distributed in multiple ways; this package is built using [pre-built binaries from the Garage team](https://garagehq.deuxfleurs.fr/download/).
+
+### building
+
+To build the package,
+
+```
+make build
+```
+
+This runs `cloudron build`, and may (on first run) request a path to a registry. You can configure a private registry on your own Cloudron for this purpose.
+
+
+```
+//
+```
+
+
+You can override the version built by passing the variable `VERSION`:
+
+```
+make build VERSION=v2.1.0
+```
+
+### installing
+
+```
+make install
+```
+
+takes two environment variables
+
+```
+make install DOMAIN=garage.
+```
+
+The image defaults to `garage:latest`; `DOMAIN` determines where the application is installed on Cloudron. It is probably necessary to pass this. E.g.
+
+```
+make install DOMAIN=s3.superdomain.com
+```
+
+## uninstalling
+
+```
+make uninstall DOMAIN=
+```
+
+
+
+
+The package is built using the binary distribution from
cloudron install --image //com.jadud.garage:20251206-135933-1341d195f
diff --git a/garage.toml b/garage.toml
index c382b34..00a5828 100644
--- a/garage.toml
+++ b/garage.toml
@@ -1,26 +1,35 @@
metadata_dir = "/app/data/garage/meta"
+# It is possible to define multiple locations
+# Garage will try and smear data across those locations
+# It should be used carefully in a Cloudron context
# https://garagehq.deuxfleurs.fr/documentation/operations/multi-hdd/
-data_dir = [
- { path = "/app/data/garage/data", capacity = "1G" },
-]
+data_dir = "/app/data/garage/data"
+# Use SQLite as the metadata engine.
+# This will be stored at /app/data/garage/meta/db.sqlite
db_engine = "sqlite"
+# We are not a cluster
replication_factor = 1
+# The RPC does not want to be exposed publicly.
rpc_bind_addr = "[::]:3901"
-rpc_public_addr = "127.0.0.1:3901"
+# GARAGE_RPC_PUBLIC_ADDR is considered optional as of v2.1.0.
+# And, given that we are a 1-node cluster... no one should be talking to us.
+# rpc_public_addr = "127.0.0.1:3901"
rpc_secret_file = "/app/data/garage/rpc-secret"
[s3_api]
s3_region = "garage"
api_bind_addr = "[::]:3900"
-root_domain = ".s3.garage.localhost"
+root_domain = ".CLOUDRON_APP_DOMAIN"
[s3_web]
bind_addr = "[::]:3902"
-root_domain = ".web.garage.localhost"
+# This wants to be set dynamically in the startup.
+# That way, it can grab a Cloudron variable.
+root_domain = ".CLOUDRON_APP_DOMAIN"
index = "index.html"
# [k2v_api]
diff --git a/index.html b/index.html
new file mode 100644
index 0000000..9241588
--- /dev/null
+++ b/index.html
@@ -0,0 +1,8 @@
+
+
+ #hi
+
+
+ Hello.
+
+
\ No newline at end of file
diff --git a/start.bash b/start.bash
index 8900260..54a3120 100644
--- a/start.bash
+++ b/start.bash
@@ -4,22 +4,30 @@
# Any files there at image creation time will disappear.
# So, copy things in from elsewhere if they're needed at startup.
-# Make the working directories for garage. Files will get stored here.
-mkdir -p /app/data/garage/meta
-mkdir -p /app/data/garage/data
+if [[ ! -f /app/data/.initialized ]]; then
+ echo "Fresh installation, setting up data directory..."
+ # Setup commands here
+ touch /app/data/.initialized
-# Copy the config in. This is symlinked from /etc.
-# FIXME: Don't do this every time.
-cp /garage/garage.toml /app/data/garage.toml
+ # Make the working directories for garage. Files will get stored here.
+ mkdir -p /app/data/garage/meta
+ mkdir -p /app/data/garage/data
-# Generate an RPC secret file. This is used for clusters.
-# We don't have clusters, but garage wantses it.
-# It is precious to garage.
-openssl rand -hex 32 > /app/data/garage/rpc-secret
-chmod 600 /app/data/garage/rpc-secret
+ # Copy the config in. This is symlinked from /etc.
+ # cp /garage/garage.toml /app/data/garage.toml
+ # Note: it templates in the domain, which needs to be substituted at this point.
+ # If the end-user moves the domain... this will break.
+ sed -e 's/CLOUDRON_APP_DOMAIN/'"${CLOUDRON_APP_DOMAIN}"'/g' /garage/garage.toml > /app/data/garage.toml
+
+ # Generate an RPC secret file. This is used for clusters.
+ # We don't have clusters, but garage wantses it.
+ # It is precious to garage.
+ openssl rand -hex 32 > /app/data/garage/rpc-secret
+ chmod 600 /app/data/garage/rpc-secret
+
+ echo "Done with one-time init."
+fi
-# FIXME: Go back to info level.
-RUST_LOG=garage=debug
# Chown the things and run.
-chown -R cloudron:cloudron /tmp/garage /app/data/garage
+chown -R cloudron:cloudron /app/data/garage
gosu cloudron:cloudron /usr/bin/garage server