Adding better docs.
This deploys, works. Now, to figure out the WWW hosting and see if the admin API is secure.
This commit is contained in:
@@ -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": {
|
||||
|
||||
19
Dockerfile.template
Normal file
19
Dockerfile.template
Normal file
@@ -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" ]
|
||||
21
Makefile
Normal file
21
Makefile
Normal file
@@ -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
|
||||
166
README.md
166
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.
|
||||
|
||||
```
|
||||
<Error>
|
||||
<Code>AccessDenied</Code>
|
||||
<Message>Forbidden: Garage does not support anonymous access yet</Message>
|
||||
<Resource>/</Resource>
|
||||
<Region>garage</Region>
|
||||
</Error>
|
||||
```
|
||||
|
||||
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 <zone-name> -c <size> <node_id>
|
||||
```
|
||||
|
||||
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.
|
||||
|
||||
|
||||
```
|
||||
<registry-domain>/<username>/<package-name>
|
||||
```
|
||||
|
||||
|
||||
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.<domain>
|
||||
```
|
||||
|
||||
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=<domain>
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
The package is built using the binary distribution from
|
||||
|
||||
|
||||
cloudron install --image <registry-domain>/<user>/com.jadud.garage:20251206-135933-1341d195f
|
||||
|
||||
21
garage.toml
21
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]
|
||||
|
||||
8
index.html
Normal file
8
index.html
Normal file
@@ -0,0 +1,8 @@
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE>#hi</TITLE>
|
||||
</HEAD>
|
||||
<BODY>
|
||||
Hello.
|
||||
</BODY>
|
||||
</HTML>
|
||||
36
start.bash
36
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
|
||||
|
||||
Reference in New Issue
Block a user