From 4b7816e117976e454cac3d336f2ded8894faedd6 Mon Sep 17 00:00:00 2001 From: phoenix Date: Wed, 22 Jul 2026 17:20:37 -0400 Subject: [PATCH 01/12] Adding image to store data --- docker-compose.yaml | 18 ++++++++++++++++++ garage.toml | 16 ++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 garage.toml diff --git a/docker-compose.yaml b/docker-compose.yaml index bb2612c..cddeede 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -56,6 +56,22 @@ services: - auth_db networks: - soaricarus-network + # --- storage service --- + maze: + image: dxflrs/garage:v2.3.0 + container_name: maze + restart: unless-stopped + ports: + - "3900:3900" # S3 API + - "3901:3901" # RPC for cluster communication + - "3902:3902" # S3 web interface + - "3903:3903" # Admin API + volumes: + - ./garage.toml:/etc/garage.toml:ro + - object_data:/var/lib/garage/meta + - object_data:/var/lib/garage/data + env_file: + - .env # PostgreSQL Database Service @@ -113,6 +129,8 @@ volumes: driver: local # Use the default local driver postgres_data_auth: driver: local # Use the default local driver + object_data: + driver: local # Use the default local driver networks: soaricarus-network: diff --git a/garage.toml b/garage.toml new file mode 100644 index 0000000..6c3d0ba --- /dev/null +++ b/garage.toml @@ -0,0 +1,16 @@ +metadata_dir = "/var/lib/garage/meta" +data_dir = "/var/lib/garage/data" +db_engine = "sqlite" +replication_factor = 1 + +rpc_bind_addr = "[::]:3901" +rpc_secret = "${GARAGE_RPC_SECRET}" + +[s3_api] +s3_region = "maze" +api_bind_addr = "[::]:3900" +root_domain = ".localhost" + +[s3_web] +bind_addr = "[::]:3902" +root_domain = ".localhost" -- 2.47.3 From 7460f0d157f0028f3ec57bde624b5c85bdc58644 Mon Sep 17 00:00:00 2001 From: phoenix Date: Wed, 22 Jul 2026 17:20:58 -0400 Subject: [PATCH 02/12] Updating some of the sample env --- .env.docker.sample | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/.env.docker.sample b/.env.docker.sample index e69d0fe..a93b670 100644 --- a/.env.docker.sample +++ b/.env.docker.sample @@ -11,3 +11,17 @@ POSTGRES_MAIN_DB=soaricarus_db POSTGRES_MAIN_HOST=main_db POSTGRES_MAIN_PORT=5432 DATABASE_URL=postgres://${POSTGRES_MAIN_USER}:${POSTGRES_MAIN_PASSWORD}@${POSTGRES_MAIN_HOST}:${POSTGRES_MAIN_PORT}/${POSTGRES_MAIN_DB} + +GARAGE_RPC_SECRET=c2bde5c3f9c04116a7563e25ea5ba6fab25319daa2fe8a952ad57d0b8159b590 +GARAGE_METADATA_DIR=/var/lib/garage/meta +GARAGE_DATA_DIR=/var/lib/garage/data +GARAGE_DB_ENGINE=sqlite +GARAGE_REPLICATION_FACTOR=1 +GARAGE_RPC_BIND_ADDR=[::]:3901 +GARAGE_S3_API_BIND_ADDR=[::]:3900 +GARAGE_S3_WEB_BIND_ADDR=[::]:3902 +GARAGE_S3_REGION=maze +GARAGE_ROOT_DOMAIN=.localhost +AWS_DEFAULT_REGION=maze +AWS_SECRET_ACCESS_KEY=3o4n7yfo34985yrfcq9238765ry3928475rcy349857ty394578cy +AWS_ACCESS_KEY_ID=2q39fnoy59q2347yfdrc327894ryfc0q2834rcyq023897 -- 2.47.3 From 7a209eeb5e121fadbae3f8d8b6ef2dc47550c58b Mon Sep 17 00:00:00 2001 From: phoenix Date: Thu, 23 Jul 2026 15:15:11 -0400 Subject: [PATCH 03/12] Removing garage.toml --- garage.toml | 16 ---------------- 1 file changed, 16 deletions(-) delete mode 100644 garage.toml diff --git a/garage.toml b/garage.toml deleted file mode 100644 index 6c3d0ba..0000000 --- a/garage.toml +++ /dev/null @@ -1,16 +0,0 @@ -metadata_dir = "/var/lib/garage/meta" -data_dir = "/var/lib/garage/data" -db_engine = "sqlite" -replication_factor = 1 - -rpc_bind_addr = "[::]:3901" -rpc_secret = "${GARAGE_RPC_SECRET}" - -[s3_api] -s3_region = "maze" -api_bind_addr = "[::]:3900" -root_domain = ".localhost" - -[s3_web] -bind_addr = "[::]:3902" -root_domain = ".localhost" -- 2.47.3 From 327d04e8a952fa4559d4d1205b7d3b3efd465ec0 Mon Sep 17 00:00:00 2001 From: phoenix Date: Thu, 23 Jul 2026 15:28:58 -0400 Subject: [PATCH 04/12] Revert "Removing garage.toml" This reverts commit 7a209eeb5e121fadbae3f8d8b6ef2dc47550c58b. --- garage.toml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 garage.toml diff --git a/garage.toml b/garage.toml new file mode 100644 index 0000000..6c3d0ba --- /dev/null +++ b/garage.toml @@ -0,0 +1,16 @@ +metadata_dir = "/var/lib/garage/meta" +data_dir = "/var/lib/garage/data" +db_engine = "sqlite" +replication_factor = 1 + +rpc_bind_addr = "[::]:3901" +rpc_secret = "${GARAGE_RPC_SECRET}" + +[s3_api] +s3_region = "maze" +api_bind_addr = "[::]:3900" +root_domain = ".localhost" + +[s3_web] +bind_addr = "[::]:3902" +root_domain = ".localhost" -- 2.47.3 From 2bfb8c6aeeb0a8df78b693c4fdde72f82700cc05 Mon Sep 17 00:00:00 2001 From: phoenix Date: Thu, 23 Jul 2026 15:31:41 -0400 Subject: [PATCH 05/12] Got garage to run in docker --- docker-compose.yaml | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/docker-compose.yaml b/docker-compose.yaml index cddeede..951ef58 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -68,10 +68,17 @@ services: - "3903:3903" # Admin API volumes: - ./garage.toml:/etc/garage.toml:ro - - object_data:/var/lib/garage/meta - - object_data:/var/lib/garage/data + - object_data:/var/lib/garage env_file: - .env + healthcheck: + test: ["CMD-SHELL", "curl -f http://localhost:3901/v0/status || exit 1"] + interval: 10s + timeout: 5s + retries: 5 + start_period: 30s + networks: + - soaricarus-network # PostgreSQL Database Service -- 2.47.3 From 8fae71b08665b5084f9b5ada4fb0219dc56d182a Mon Sep 17 00:00:00 2001 From: phoenix Date: Thu, 23 Jul 2026 16:05:21 -0400 Subject: [PATCH 06/12] Getting somewhere. Object Storage is initialized but not initializing hangs --- Dockerfile | 4 ++ docker-compose.yaml | 22 +++++++++++ scripts/init-garage.sh | 85 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 111 insertions(+) create mode 100755 scripts/init-garage.sh diff --git a/Dockerfile b/Dockerfile index 11cfe6b..0c2ac50 100644 --- a/Dockerfile +++ b/Dockerfile @@ -30,6 +30,10 @@ RUN --mount=type=ssh mkdir src && \ COPY src ./src COPY .env ./.env COPY migrations ./migrations +COPY scripts/init-garage.sh /scripts/init-garage.sh + +# Make it executable +RUN chmod +x /scripts/init-garage.sh RUN --mount=type=ssh \ cargo build --release --quiet diff --git a/docker-compose.yaml b/docker-compose.yaml index 951ef58..10eaefb 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -80,6 +80,28 @@ services: networks: - soaricarus-network + # --- Storage Initialization --- + maze-init: + # image: dxflrs/garage:v2.3.0 + image: alpine:latest + container_name: maze-init + depends_on: + maze: + condition: service_started + volumes: + - ./scripts:/scripts:ro + - object_data:/var/lib/garage + environment: + - AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID} + - AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY} + - GARAGE_RPC_SECRET=${GARAGE_RPC_SECRET} + env_file: + - .env + # entrypoint: ["/bin/bash"] + command: ["sh", "/scripts/init-garage.sh"] + restart: "no" # Run once and exit + networks: + - soaricarus-network # PostgreSQL Database Service main_db: diff --git a/scripts/init-garage.sh b/scripts/init-garage.sh new file mode 100755 index 0000000..87e399f --- /dev/null +++ b/scripts/init-garage.sh @@ -0,0 +1,85 @@ +#!/bin/bash +set -e + +# Use the credentials from your .env +BUCKET_NAME="soaricarus-storage" + +echo "âŗ Waiting for Garage to be ready..." +until curl -s -f "http://localhost:3901/v0/status" > /dev/null 2>&1; do + echo " Garage not ready yet, retrying in 2s..." + sleep 2 +done +echo "✅ Garage API is responding!" + +# Wait a bit more for Garage to fully initialize +sleep 5 + +# Check if layout is already applied +if garage layout show 2>/dev/null | grep -q "Current cluster layout"; then + echo "â„šī¸ Layout already applied, checking bucket..." +else + echo "đŸ“Ļ Applying cluster layout..." + + # Get node ID - this might need multiple attempts + MAX_RETRIES=10 + RETRY_COUNT=0 + while [ $RETRY_COUNT -lt $MAX_RETRIES ]; do + NODE_ID=$(garage node id 2>/dev/null | head -n1) + if [ -n "$NODE_ID" ]; then + break + fi + RETRY_COUNT=$((RETRY_COUNT + 1)) + echo " Waiting for node ID (attempt $RETRY_COUNT/$MAX_RETRIES)..." + sleep 2 + done + + if [ -z "$NODE_ID" ]; then + echo "❌ Failed to get node ID after $MAX_RETRIES attempts" + exit 1 + fi + + echo " Node ID: $NODE_ID" + garage layout assign --version 1 "$NODE_ID" + garage layout apply --version 1 + echo " ✅ Layout applied" + + # Wait for layout to stabilize + sleep 3 +fi + +# Check if bucket already exists +if garage bucket info "${BUCKET_NAME}" 2>/dev/null; then + echo "â„šī¸ Bucket '${BUCKET_NAME}' already exists. Skipping setup." + exit 0 +fi + +echo "đŸ“Ļ Creating bucket and configuring permissions..." + +# 1. Create the bucket +garage bucket create "${BUCKET_NAME}" +echo " ✅ Bucket created: ${BUCKET_NAME}" + +# 2. Check if key exists +if garage key info "${AWS_ACCESS_KEY_ID}" 2>/dev/null; then + echo " â„šī¸ Key already exists: ${AWS_ACCESS_KEY_ID}" +else + garage key create \ + --name "app-key" \ + "${AWS_ACCESS_KEY_ID}" \ + "${AWS_SECRET_ACCESS_KEY}" + echo " ✅ Key created: ${AWS_ACCESS_KEY_ID}" +fi + +# 3. Grant full permissions +garage bucket allow \ + --read \ + --write \ + --owner \ + "${BUCKET_NAME}" \ + --key "${AWS_ACCESS_KEY_ID}" +echo " ✅ Permissions granted" + +echo "🎉 Setup complete!" +echo " Bucket: ${BUCKET_NAME}" +echo " Access Key: ${AWS_ACCESS_KEY_ID}" +echo " Endpoint: http://maze:3900" -- 2.47.3 From 3965d86d54dd7ee6ee4ad14545acefe2c2a914e4 Mon Sep 17 00:00:00 2001 From: phoenix Date: Thu, 23 Jul 2026 16:21:40 -0400 Subject: [PATCH 07/12] Saving script --- scripts/init-garage.sh | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/scripts/init-garage.sh b/scripts/init-garage.sh index 87e399f..e519483 100755 --- a/scripts/init-garage.sh +++ b/scripts/init-garage.sh @@ -5,11 +5,13 @@ set -e BUCKET_NAME="soaricarus-storage" echo "âŗ Waiting for Garage to be ready..." -until curl -s -f "http://localhost:3901/v0/status" > /dev/null 2>&1; do - echo " Garage not ready yet, retrying in 2s..." - sleep 2 -done +# until curl -s -f "http://localhost:3901/v0/status" > /dev/null 2>&1; do + # echo " Garage not ready yet, retrying in 2s..." + # sleep 2 +# done +sleep 20 echo "✅ Garage API is responding!" +echo "... I think..." # Wait a bit more for Garage to fully initialize sleep 5 -- 2.47.3 From f116adffdbc21c893f59801c6c86f954fa7b4c64 Mon Sep 17 00:00:00 2001 From: phoenix Date: Thu, 23 Jul 2026 16:26:14 -0400 Subject: [PATCH 08/12] Saving changes. Nothing yet --- docker-compose.yaml | 9 +++++---- scripts/init-garage.sh | 46 +++++++++++++++++++----------------------- 2 files changed, 26 insertions(+), 29 deletions(-) diff --git a/docker-compose.yaml b/docker-compose.yaml index 10eaefb..a78b754 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -83,22 +83,23 @@ services: # --- Storage Initialization --- maze-init: # image: dxflrs/garage:v2.3.0 - image: alpine:latest + image: docker:latest container_name: maze-init depends_on: maze: condition: service_started volumes: - - ./scripts:/scripts:ro + - /var/run/docker.sock:/var/run/docker.sock # Mount Docker socket - object_data:/var/lib/garage environment: - AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID} - AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY} - GARAGE_RPC_SECRET=${GARAGE_RPC_SECRET} + - BUCKET_NAME=${S3_BUCKET_NAME} env_file: - .env - # entrypoint: ["/bin/bash"] - command: ["sh", "/scripts/init-garage.sh"] + entrypoint: ["/bin/sh"] + command: ["/scripts/init-garage.sh"] restart: "no" # Run once and exit networks: - soaricarus-network diff --git a/scripts/init-garage.sh b/scripts/init-garage.sh index e519483..2f26dd7 100755 --- a/scripts/init-garage.sh +++ b/scripts/init-garage.sh @@ -1,32 +1,29 @@ -#!/bin/bash +#!/bin/sh set -e -# Use the credentials from your .env BUCKET_NAME="soaricarus-storage" echo "âŗ Waiting for Garage to be ready..." -# until curl -s -f "http://localhost:3901/v0/status" > /dev/null 2>&1; do - # echo " Garage not ready yet, retrying in 2s..." - # sleep 2 -# done -sleep 20 +until docker exec maze curl -s -f "http://localhost:3901/v0/status" > /dev/null 2>&1; do + echo " Garage not ready yet, retrying in 2s..." + sleep 2 +done echo "✅ Garage API is responding!" -echo "... I think..." -# Wait a bit more for Garage to fully initialize -sleep 5 +sleep 3 # Check if layout is already applied -if garage layout show 2>/dev/null | grep -q "Current cluster layout"; then +if docker exec maze garage layout show 2>/dev/null | grep -q "Current cluster layout"; then echo "â„šī¸ Layout already applied, checking bucket..." else echo "đŸ“Ļ Applying cluster layout..." - # Get node ID - this might need multiple attempts + # Get node ID MAX_RETRIES=10 RETRY_COUNT=0 + NODE_ID="" while [ $RETRY_COUNT -lt $MAX_RETRIES ]; do - NODE_ID=$(garage node id 2>/dev/null | head -n1) + NODE_ID=$(docker exec maze garage node id 2>/dev/null | head -n1) if [ -n "$NODE_ID" ]; then break fi @@ -41,39 +38,38 @@ else fi echo " Node ID: $NODE_ID" - garage layout assign --version 1 "$NODE_ID" - garage layout apply --version 1 + docker exec maze garage layout assign --version 1 "$NODE_ID" + docker exec maze garage layout apply --version 1 echo " ✅ Layout applied" - # Wait for layout to stabilize sleep 3 fi -# Check if bucket already exists -if garage bucket info "${BUCKET_NAME}" 2>/dev/null; then +# Check if bucket exists +if docker exec maze garage bucket info "${BUCKET_NAME}" 2>/dev/null; then echo "â„šī¸ Bucket '${BUCKET_NAME}' already exists. Skipping setup." exit 0 fi echo "đŸ“Ļ Creating bucket and configuring permissions..." -# 1. Create the bucket -garage bucket create "${BUCKET_NAME}" +# Create the bucket +docker exec maze garage bucket create "${BUCKET_NAME}" echo " ✅ Bucket created: ${BUCKET_NAME}" -# 2. Check if key exists -if garage key info "${AWS_ACCESS_KEY_ID}" 2>/dev/null; then +# Check if key exists +if docker exec maze garage key info "${AWS_ACCESS_KEY_ID}" 2>/dev/null; then echo " â„šī¸ Key already exists: ${AWS_ACCESS_KEY_ID}" else - garage key create \ + docker exec maze garage key create \ --name "app-key" \ "${AWS_ACCESS_KEY_ID}" \ "${AWS_SECRET_ACCESS_KEY}" echo " ✅ Key created: ${AWS_ACCESS_KEY_ID}" fi -# 3. Grant full permissions -garage bucket allow \ +# Grant permissions +docker exec maze garage bucket allow \ --read \ --write \ --owner \ -- 2.47.3 From 3de818f28050a0dc4a164584ae6f6bd643857aec Mon Sep 17 00:00:00 2001 From: phoenix Date: Thu, 23 Jul 2026 17:19:29 -0400 Subject: [PATCH 09/12] Saving changes --- .env.docker.sample | 2 ++ docker-compose.yaml | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.env.docker.sample b/.env.docker.sample index a93b670..b21b599 100644 --- a/.env.docker.sample +++ b/.env.docker.sample @@ -25,3 +25,5 @@ GARAGE_ROOT_DOMAIN=.localhost AWS_DEFAULT_REGION=maze AWS_SECRET_ACCESS_KEY=3o4n7yfo34985yrfcq9238765ry3928475rcy349857ty394578cy AWS_ACCESS_KEY_ID=2q39fnoy59q2347yfdrc327894ryfc0q2834rcyq023897 + +S3_BUCKET_NAME=soaricarus-storage diff --git a/docker-compose.yaml b/docker-compose.yaml index a78b754..6f141c5 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -83,7 +83,7 @@ services: # --- Storage Initialization --- maze-init: # image: dxflrs/garage:v2.3.0 - image: docker:latest + image: docker:dind container_name: maze-init depends_on: maze: @@ -91,6 +91,7 @@ services: volumes: - /var/run/docker.sock:/var/run/docker.sock # Mount Docker socket - object_data:/var/lib/garage + - ./scripts:/scripts:ro # ← ADD THIS - mount the scripts directory environment: - AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID} - AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY} -- 2.47.3 From 75f4d9fa76fcb65fc5d1d16668f46766acc44cdb Mon Sep 17 00:00:00 2001 From: phoenix Date: Fri, 24 Jul 2026 12:23:48 -0400 Subject: [PATCH 10/12] Saving changes. No real progress yet --- docker-compose.yaml | 41 ++++++-------- garage/Dockerfile | 21 +++++++ garage/full-init-garage.sh | 109 +++++++++++++++++++++++++++++++++++++ garage/init-garage.sh | 36 ++++++++++++ scripts/init-garage.sh | 3 +- 5 files changed, 184 insertions(+), 26 deletions(-) create mode 100644 garage/Dockerfile create mode 100644 garage/full-init-garage.sh create mode 100755 garage/init-garage.sh diff --git a/docker-compose.yaml b/docker-compose.yaml index 6f141c5..e920bcf 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -11,6 +11,8 @@ services: - "8000:8000" env_file: - .env + volumes: + - shared_credentials:/shared:ro # Mount as read-only depends_on: main_db: condition: service_healthy @@ -58,7 +60,9 @@ services: - soaricarus-network # --- storage service --- maze: - image: dxflrs/garage:v2.3.0 + build: + context: ./garage + dockerfile: Dockerfile container_name: maze restart: unless-stopped ports: @@ -68,11 +72,20 @@ services: - "3903:3903" # Admin API volumes: - ./garage.toml:/etc/garage.toml:ro + - shared_credentials:/shared - object_data:/var/lib/garage + # - ./scripts:/scripts:ro # ← ADD THIS - mount the scripts directory env_file: - .env + environment: + - AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID} + - AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY} + - GARAGE_RPC_SECRET=${GARAGE_RPC_SECRET} + - BUCKET_NAME=${S3_BUCKET_NAME} healthcheck: test: ["CMD-SHELL", "curl -f http://localhost:3901/v0/status || exit 1"] + # test: ["CMD-SHELL", "echo 'What is to be done?'"] + # test: ["CMD-SHELL", "nc -z localhost 3900 || exit 1"] interval: 10s timeout: 5s retries: 5 @@ -80,30 +93,6 @@ services: networks: - soaricarus-network - # --- Storage Initialization --- - maze-init: - # image: dxflrs/garage:v2.3.0 - image: docker:dind - container_name: maze-init - depends_on: - maze: - condition: service_started - volumes: - - /var/run/docker.sock:/var/run/docker.sock # Mount Docker socket - - object_data:/var/lib/garage - - ./scripts:/scripts:ro # ← ADD THIS - mount the scripts directory - environment: - - AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID} - - AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY} - - GARAGE_RPC_SECRET=${GARAGE_RPC_SECRET} - - BUCKET_NAME=${S3_BUCKET_NAME} - env_file: - - .env - entrypoint: ["/bin/sh"] - command: ["/scripts/init-garage.sh"] - restart: "no" # Run once and exit - networks: - - soaricarus-network # PostgreSQL Database Service main_db: @@ -162,6 +151,8 @@ volumes: driver: local # Use the default local driver object_data: driver: local # Use the default local driver + shared_credentials: # New shared volume + driver: local networks: soaricarus-network: diff --git a/garage/Dockerfile b/garage/Dockerfile new file mode 100644 index 0000000..a0a6e15 --- /dev/null +++ b/garage/Dockerfile @@ -0,0 +1,21 @@ +# FROM dxflrs/garage:v2.3.0 +# Stage 1: Extract the garage binary from the official image +FROM dxflrs/garage:v2.3.0 as garage-base + +# Stage 2: Create a new image with a shell +FROM alpine:latest + +# Install necessary tools (curl, busybox for sh, etc.) +# The Garage image is based on Alpine, so we use apk +RUN apk add --no-cache curl busybox + +# Copy the garage binary from the official image +COPY --from=garage-base /garage /usr/local/bin/garage + +# Copy the init script +COPY init-garage.sh /init-garage.sh +RUN chmod +x /init-garage.sh + +# Use the init script as the entrypoint +# It will run setup, then exec garage +ENTRYPOINT ["/init-garage.sh"] diff --git a/garage/full-init-garage.sh b/garage/full-init-garage.sh new file mode 100644 index 0000000..c93be4b --- /dev/null +++ b/garage/full-init-garage.sh @@ -0,0 +1,109 @@ +#!/bin/sh +set -e + +BUCKET_NAME="${BUCKET_NAME:-soaricarus-storage}" +CREDENTIALS_FILE="/shared/garage-credentials.env" +SETUP_DONE="/shared/setup.done" + +# Function to write credentials to shared volume +write_credentials() { + local access_key="$1" + local secret_key="$2" + mkdir -p "$(dirname "$CREDENTIALS_FILE")" + cat > "$CREDENTIALS_FILE" << EOF +GARAGE_ACCESS_KEY_ID=$access_key +GARAGE_SECRET_ACCESS_KEY=$secret_key +GARAGE_BUCKET_NAME=$BUCKET_NAME +GARAGE_ENDPOINT=http://maze:3900 +EOF + touch "$SETUP_DONE" + echo "✅ Credentials saved to $CREDENTIALS_FILE" +} + +# Check if setup already done +if [ -f "$SETUP_DONE" ]; then + echo "â„šī¸ Setup already completed. Starting Garage..." + # Source credentials if needed for the main Garage process + # shellcheck source=/dev/null + [ -f "$CREDENTIALS_FILE" ] && . "$CREDENTIALS_FILE" + exec /usr/local/bin/garage "$@" +fi + +echo "🔧 Running initial setup..." + +# Start Garage in background for setup +echo "âŗ Starting Garage in background..." +/usr/local/bin/garage "$@" & +GARAGE_PID=$! + +# Wait for Garage API to be ready +echo "âŗ Waiting for Garage API..." +# until curl -s -f "http://localhost:3900/v0/status" > /dev/null 2>&1; do +# echo " Not ready yet, sleeping 2s..." +# sleep 2 +#done +echo "✅ Garage API is responding!" + +# Apply layout if not already applied +if ! /usr/local/bin/garage layout show 2>/dev/null | grep -q "Current cluster layout"; then + echo "đŸ“Ļ Applying cluster layout..." + NODE_ID=$(/usr/local/bin/garage node id | head -n1) + /usr/local/bin/garage layout assign --version 1 "$NODE_ID" + /usr/local/bin/garage layout apply --version 1 + echo " ✅ Layout applied" + sleep 3 +else + echo "â„šī¸ Layout already applied" +fi + +echo "Laid out" + +# Create bucket if it doesn't exist +if ! /usr/local/bin/garage bucket info "$BUCKET_NAME" 2>/dev/null; then + echo "đŸ“Ļ Creating bucket: $BUCKET_NAME" + /usr/local/bin/garage bucket create "$BUCKET_NAME" +else + echo "â„šī¸ Bucket $BUCKET_NAME already exists" +fi + +# Create or import key +# We'll use the credentials from .env if provided, otherwise generate new ones +if [ -n "$AWS_ACCESS_KEY_ID" ] && [ -n "$AWS_SECRET_ACCESS_KEY" ]; then + echo "🔑 Using pre-defined AWS credentials from .env" + if ! /usr/local/bin/garage key info "$AWS_ACCESS_KEY_ID" 2>/dev/null; then + # Key doesn't exist, import it + /usr/local/bin/garage key import "$AWS_ACCESS_KEY_ID" "$AWS_SECRET_ACCESS_KEY" "app-key" + echo " ✅ Key imported: $AWS_ACCESS_KEY_ID" + else + echo " â„šī¸ Key already exists: $AWS_ACCESS_KEY_ID" + fi + ACCESS_KEY="$AWS_ACCESS_KEY_ID" + SECRET_KEY="$AWS_SECRET_ACCESS_KEY" +else + echo "🔑 Generating new key..." + KEY_OUTPUT=$(/usr/local/bin/garage key create --name "app-key") + echo "$KEY_OUTPUT" + ACCESS_KEY=$(echo "$KEY_OUTPUT" | grep 'Key ID:' | awk '{print $3}') + SECRET_KEY=$(echo "$KEY_OUTPUT" | grep 'Secret key:' | awk '{print $3}') + echo " ✅ Key generated: $ACCESS_KEY" +fi + +# Grant permissions +/usr/local/bin/garage bucket allow --read --write --owner "$BUCKET_NAME" --key "$ACCESS_KEY" +echo " ✅ Permissions granted" + +# Write credentials to shared volume +write_credentials "$ACCESS_KEY" "$SECRET_KEY" + +echo "🎉 Setup complete!" +echo " Bucket: $BUCKET_NAME" +echo " Access Key: $ACCESS_KEY" + +# Stop the background Garage process +echo "âšī¸ Stopping background Garage process..." +kill "$GARAGE_PID" +wait "$GARAGE_PID" 2>/dev/null || true + +echo "🚀 Starting Garage in foreground..." +exec /usr/local/bin/garage "$@" + diff --git a/garage/init-garage.sh b/garage/init-garage.sh new file mode 100755 index 0000000..1650ede --- /dev/null +++ b/garage/init-garage.sh @@ -0,0 +1,36 @@ +#!/bin/sh +set -e + +BUCKET_NAME="${BUCKET_NAME:-soaricarus-storage}" +CREDENTIALS_FILE="/shared/garage-credentials.env" +SETUP_DONE="/shared/setup.done" + +echo "🔧 Running initial setup..." + +# Start Garage in background for setup +echo "âŗ Starting Garage in background..." +/usr/local/bin/garage "$@" & +GARAGE_PID=$! + +# Wait for Garage API to be ready +echo "âŗ Waiting for Garage API..." +# until curl -s -f "http://localhost:3900/v0/status" > /dev/null 2>&1; do +# echo " Not ready yet, sleeping 2s..." +# sleep 2 +#done +echo "✅ Garage API is responding!" + +# Apply layout if not already applied +#if ! /usr/local/bin/garage layout show 2>/dev/null | grep -q "Current cluster layout"; then +# echo "đŸ“Ļ Applying cluster layout..." +# NODE_ID=$(/usr/local/bin/garage node id | head -n1) +# echo $NODE_ID + # /usr/local/bin/garage layout assign --version 1 "$NODE_ID" + # /usr/local/bin/garage layout apply --version 1 +# echo " ✅ Layout applied" +# sleep 3 +#else + # echo "â„šī¸ Layout already applied" +# fi + +echo "Laid out" diff --git a/scripts/init-garage.sh b/scripts/init-garage.sh index 2f26dd7..b6b3792 100755 --- a/scripts/init-garage.sh +++ b/scripts/init-garage.sh @@ -4,7 +4,8 @@ set -e BUCKET_NAME="soaricarus-storage" echo "âŗ Waiting for Garage to be ready..." -until docker exec maze curl -s -f "http://localhost:3901/v0/status" > /dev/null 2>&1; do +# until docker exec maze curl -s -f "http://localhost:3901/v0/status" > /dev/null 2>&1; do +until docker exec maze nc -z "localhost 3900" > /dev/null 2>&1; do echo " Garage not ready yet, retrying in 2s..." sleep 2 done -- 2.47.3 From 6574d0ee8f5b6f7291776e4011a86b8b5b33c505 Mon Sep 17 00:00:00 2001 From: phoenix Date: Fri, 24 Jul 2026 15:33:18 -0400 Subject: [PATCH 11/12] I am tired boss --- docker-compose.yaml | 10 ++-- garage/entrypoint.sh | 126 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 132 insertions(+), 4 deletions(-) create mode 100755 garage/entrypoint.sh diff --git a/docker-compose.yaml b/docker-compose.yaml index e920bcf..a91c80a 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -60,9 +60,7 @@ services: - soaricarus-network # --- storage service --- maze: - build: - context: ./garage - dockerfile: Dockerfile + image: dxflrs/garage:v2.3.0 container_name: maze restart: unless-stopped ports: @@ -72,6 +70,7 @@ services: - "3903:3903" # Admin API volumes: - ./garage.toml:/etc/garage.toml:ro + - ./garage/entrypoint.sh:/entrypoint.sh:ro - shared_credentials:/shared - object_data:/var/lib/garage # - ./scripts:/scripts:ro # ← ADD THIS - mount the scripts directory @@ -82,10 +81,13 @@ services: - AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY} - GARAGE_RPC_SECRET=${GARAGE_RPC_SECRET} - BUCKET_NAME=${S3_BUCKET_NAME} + entrypoint: ["/entrypoint.sh"] + command: [] healthcheck: - test: ["CMD-SHELL", "curl -f http://localhost:3901/v0/status || exit 1"] + # test: ["CMD-SHELL", "curl -f http://localhost:3901/v0/status || exit 1"] # test: ["CMD-SHELL", "echo 'What is to be done?'"] # test: ["CMD-SHELL", "nc -z localhost 3900 || exit 1"] + test: ["CMD-SHELL", "/garage status | grep -q 'Health: ok' || exit 1"] interval: 10s timeout: 5s retries: 5 diff --git a/garage/entrypoint.sh b/garage/entrypoint.sh new file mode 100755 index 0000000..a614ab2 --- /dev/null +++ b/garage/entrypoint.sh @@ -0,0 +1,126 @@ +#!/garage +# This script runs as a garage command +# It will check if setup is needed and run initialization + +# Check if we should run setup (first run) +SETUP_MARKER="/var/lib/garage/.setup_done" +BUCKET_NAME="${BUCKET_NAME:-soaricarus-storage}" +CREDENTIALS_FILE="/shared/garage-credentials.env" + +# Function to check if Garage API is ready +is_garage_ready() { + # Try to get status, if it works, Garage is ready + /garage status 2>/dev/null | grep -q "Health: ok" + return $? +} + +# Function to wait for Garage to be ready +wait_for_garage() { + echo "âŗ Waiting for Garage to be ready..." + local max_attempts=30 + local attempt=0 + while [ $attempt -lt $max_attempts ]; do + if is_garage_ready; then + echo "✅ Garage is ready!" + return 0 + fi + attempt=$((attempt + 1)) + echo " Waiting... (attempt $attempt/$max_attempts)" + sleep 2 + done + echo "❌ Garage failed to become ready" + return 1 +} + +# Function to run setup +run_setup() { + echo "🔧 Running initial setup..." + + # Get node ID + NODE_ID=$(/garage node id | head -n1) + echo " Node ID: $NODE_ID" + + # Apply layout + /garage layout assign --version 1 "$NODE_ID" + /garage layout apply --version 1 + echo " ✅ Layout applied" + sleep 3 + + # Create bucket + if ! /garage bucket info "$BUCKET_NAME" 2>/dev/null; then + /garage bucket create "$BUCKET_NAME" + echo " ✅ Bucket created: $BUCKET_NAME" + else + echo " â„šī¸ Bucket already exists" + fi + + # Handle key + if [ -n "$AWS_ACCESS_KEY_ID" ] && [ -n "$AWS_SECRET_ACCESS_KEY" ]; then + # Import existing key + if ! /garage key info "$AWS_ACCESS_KEY_ID" 2>/dev/null; then + /garage key import "$AWS_ACCESS_KEY_ID" "$AWS_SECRET_ACCESS_KEY" "app-key" + echo " ✅ Key imported: $AWS_ACCESS_KEY_ID" + else + echo " â„šī¸ Key already exists: $AWS_ACCESS_KEY_ID" + fi + ACCESS_KEY="$AWS_ACCESS_KEY_ID" + SECRET_KEY="$AWS_SECRET_ACCESS_KEY" + else + # Generate new key + KEY_OUTPUT=$(/garage key create --name "app-key") + echo "$KEY_OUTPUT" + ACCESS_KEY=$(echo "$KEY_OUTPUT" | grep 'Key ID:' | awk '{print $3}') + SECRET_KEY=$(echo "$KEY_OUTPUT" | grep 'Secret key:' | awk '{print $3}') + echo " ✅ Key generated: $ACCESS_KEY" + fi + + # Grant permissions + /garage bucket allow --read --write --owner "$BUCKET_NAME" --key "$ACCESS_KEY" + echo " ✅ Permissions granted" + + # Write credentials to shared volume + mkdir -p "$(dirname "$CREDENTIALS_FILE")" + cat > "$CREDENTIALS_FILE" << EOF +GARAGE_ACCESS_KEY_ID=$ACCESS_KEY +GARAGE_SECRET_ACCESS_KEY=$SECRET_KEY +GARAGE_BUCKET_NAME=$BUCKET_NAME +GARAGE_ENDPOINT=http://maze:3900 +EOF + echo " ✅ Credentials saved to $CREDENTIALS_FILE" + + # Mark setup as done + touch "$SETUP_MARKER" + echo "🎉 Setup complete!" +} + +# Main execution + +# Check if we need to run setup +if [ ! -f "$SETUP_MARKER" ]; then + echo "đŸ“Ļ First run detected. Starting Garage for setup..." + + # Start Garage in background + /garage "$@" & + GARAGE_PID=$! + + # Wait for it to be ready + if wait_for_garage; then + # Run the setup + run_setup + else + echo "❌ Setup failed - Garage didn't become ready" + kill "$GARAGE_PID" 2>/dev/null + exit 1 + fi + + # Kill the background Garage + echo "âšī¸ Stopping background Garage..." + kill "$GARAGE_PID" + wait "$GARAGE_PID" 2>/dev/null || true + echo "🔄 Restarting Garage in foreground..." +else + echo "â„šī¸ Setup already completed. Starting Garage..." +fi + +# Start Garage in foreground +exec /garage "$@" -- 2.47.3 From e2a5e02aada4bc972fccfe9ddfeb24b364af4e05 Mon Sep 17 00:00:00 2001 From: phoenix Date: Fri, 24 Jul 2026 19:12:19 -0400 Subject: [PATCH 12/12] Trying --- docker-compose.yaml | 12 +-- garage/Dockerfile | 29 +++---- garage/entrypoint.sh | 201 +++++++++++++++++++------------------------ 3 files changed, 109 insertions(+), 133 deletions(-) diff --git a/docker-compose.yaml b/docker-compose.yaml index a91c80a..9960eaf 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -60,7 +60,9 @@ services: - soaricarus-network # --- storage service --- maze: - image: dxflrs/garage:v2.3.0 + build: + context: ./garage + dockerfile: Dockerfile container_name: maze restart: unless-stopped ports: @@ -81,13 +83,13 @@ services: - AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY} - GARAGE_RPC_SECRET=${GARAGE_RPC_SECRET} - BUCKET_NAME=${S3_BUCKET_NAME} - entrypoint: ["/entrypoint.sh"] - command: [] + # entrypoint: ["/entrypoint.sh"] + # command: [] healthcheck: - # test: ["CMD-SHELL", "curl -f http://localhost:3901/v0/status || exit 1"] + test: ["CMD-SHELL", "curl -f http://localhost:3901/v0/status || exit 1"] # test: ["CMD-SHELL", "echo 'What is to be done?'"] # test: ["CMD-SHELL", "nc -z localhost 3900 || exit 1"] - test: ["CMD-SHELL", "/garage status | grep -q 'Health: ok' || exit 1"] + # test: ["CMD-SHELL", "/garage status | grep -q 'Health: ok' || exit 1"] interval: 10s timeout: 5s retries: 5 diff --git a/garage/Dockerfile b/garage/Dockerfile index a0a6e15..5f4acaa 100644 --- a/garage/Dockerfile +++ b/garage/Dockerfile @@ -1,21 +1,18 @@ -# FROM dxflrs/garage:v2.3.0 -# Stage 1: Extract the garage binary from the official image -FROM dxflrs/garage:v2.3.0 as garage-base - -# Stage 2: Create a new image with a shell +# Use a base image with a shell (Alpine) FROM alpine:latest -# Install necessary tools (curl, busybox for sh, etc.) -# The Garage image is based on Alpine, so we use apk -RUN apk add --no-cache curl busybox +# Install necessary tools +RUN apk add --no-cache curl -# Copy the garage binary from the official image -COPY --from=garage-base /garage /usr/local/bin/garage +# Copy the Garage binary from the official image +COPY --from=dxflrs/garage:v2.3.0 /garage /usr/local/bin/garage -# Copy the init script -COPY init-garage.sh /init-garage.sh -RUN chmod +x /init-garage.sh +# Copy the entrypoint script +COPY entrypoint.sh /entrypoint.sh +RUN chmod +x /entrypoint.sh -# Use the init script as the entrypoint -# It will run setup, then exec garage -ENTRYPOINT ["/init-garage.sh"] +# Set the entrypoint +ENTRYPOINT ["/entrypoint.sh"] + +# Pass through any arguments to Garage +CMD [] diff --git a/garage/entrypoint.sh b/garage/entrypoint.sh index a614ab2..5273235 100755 --- a/garage/entrypoint.sh +++ b/garage/entrypoint.sh @@ -1,126 +1,103 @@ -#!/garage -# This script runs as a garage command -# It will check if setup is needed and run initialization +#!/bin/sh +set -e -# Check if we should run setup (first run) -SETUP_MARKER="/var/lib/garage/.setup_done" BUCKET_NAME="${BUCKET_NAME:-soaricarus-storage}" CREDENTIALS_FILE="/shared/garage-credentials.env" +SETUP_DONE="/shared/setup.done" +GARAGE_BIN="/usr/local/bin/garage" -# Function to check if Garage API is ready -is_garage_ready() { - # Try to get status, if it works, Garage is ready - /garage status 2>/dev/null | grep -q "Health: ok" - return $? -} - -# Function to wait for Garage to be ready -wait_for_garage() { - echo "âŗ Waiting for Garage to be ready..." - local max_attempts=30 - local attempt=0 - while [ $attempt -lt $max_attempts ]; do - if is_garage_ready; then - echo "✅ Garage is ready!" - return 0 - fi - attempt=$((attempt + 1)) - echo " Waiting... (attempt $attempt/$max_attempts)" - sleep 2 - done - echo "❌ Garage failed to become ready" - return 1 -} - -# Function to run setup -run_setup() { - echo "🔧 Running initial setup..." - - # Get node ID - NODE_ID=$(/garage node id | head -n1) - echo " Node ID: $NODE_ID" - - # Apply layout - /garage layout assign --version 1 "$NODE_ID" - /garage layout apply --version 1 - echo " ✅ Layout applied" - sleep 3 - - # Create bucket - if ! /garage bucket info "$BUCKET_NAME" 2>/dev/null; then - /garage bucket create "$BUCKET_NAME" - echo " ✅ Bucket created: $BUCKET_NAME" - else - echo " â„šī¸ Bucket already exists" - fi - - # Handle key - if [ -n "$AWS_ACCESS_KEY_ID" ] && [ -n "$AWS_SECRET_ACCESS_KEY" ]; then - # Import existing key - if ! /garage key info "$AWS_ACCESS_KEY_ID" 2>/dev/null; then - /garage key import "$AWS_ACCESS_KEY_ID" "$AWS_SECRET_ACCESS_KEY" "app-key" - echo " ✅ Key imported: $AWS_ACCESS_KEY_ID" - else - echo " â„šī¸ Key already exists: $AWS_ACCESS_KEY_ID" - fi - ACCESS_KEY="$AWS_ACCESS_KEY_ID" - SECRET_KEY="$AWS_SECRET_ACCESS_KEY" - else - # Generate new key - KEY_OUTPUT=$(/garage key create --name "app-key") - echo "$KEY_OUTPUT" - ACCESS_KEY=$(echo "$KEY_OUTPUT" | grep 'Key ID:' | awk '{print $3}') - SECRET_KEY=$(echo "$KEY_OUTPUT" | grep 'Secret key:' | awk '{print $3}') - echo " ✅ Key generated: $ACCESS_KEY" - fi - - # Grant permissions - /garage bucket allow --read --write --owner "$BUCKET_NAME" --key "$ACCESS_KEY" - echo " ✅ Permissions granted" - - # Write credentials to shared volume +# Function to write credentials +write_credentials() { + local access_key="$1" + local secret_key="$2" mkdir -p "$(dirname "$CREDENTIALS_FILE")" cat > "$CREDENTIALS_FILE" << EOF -GARAGE_ACCESS_KEY_ID=$ACCESS_KEY -GARAGE_SECRET_ACCESS_KEY=$SECRET_KEY +GARAGE_ACCESS_KEY_ID=$access_key +GARAGE_SECRET_ACCESS_KEY=$secret_key GARAGE_BUCKET_NAME=$BUCKET_NAME -GARAGE_ENDPOINT=http://maze:3900 +GARAGE_ENDPOINT=http://localhost:3900 EOF - echo " ✅ Credentials saved to $CREDENTIALS_FILE" - - # Mark setup as done - touch "$SETUP_MARKER" - echo "🎉 Setup complete!" + touch "$SETUP_DONE" + echo "✅ Credentials saved to $CREDENTIALS_FILE" } -# Main execution - -# Check if we need to run setup -if [ ! -f "$SETUP_MARKER" ]; then - echo "đŸ“Ļ First run detected. Starting Garage for setup..." - - # Start Garage in background - /garage "$@" & - GARAGE_PID=$! - - # Wait for it to be ready - if wait_for_garage; then - # Run the setup - run_setup - else - echo "❌ Setup failed - Garage didn't become ready" - kill "$GARAGE_PID" 2>/dev/null - exit 1 - fi - - # Kill the background Garage - echo "âšī¸ Stopping background Garage..." - kill "$GARAGE_PID" - wait "$GARAGE_PID" 2>/dev/null || true - echo "🔄 Restarting Garage in foreground..." -else +# Check if setup already completed +if [ -f "$SETUP_DONE" ]; then echo "â„šī¸ Setup already completed. Starting Garage..." + exec $GARAGE_BIN "$@" fi +echo "🔧 First-time setup - initializing Garage..." + +# Start Garage in background for setup (just the binary, no daemon subcommand) +echo "âŗ Starting Garage in background..." +$GARAGE_BIN "$@" & +GARAGE_PID=$! + +# Wait for Garage to be ready +echo "âŗ Waiting for Garage API..." +until curl -s -f "http://localhost:3901/v0/status" > /dev/null 2>&1; do + echo " Not ready yet, sleeping 2s..." + sleep 2 +done +echo "✅ Garage API is responding!" + +# Apply cluster layout +if ! $GARAGE_BIN layout show 2>/dev/null | grep -q "Current cluster layout"; then + echo "đŸ“Ļ Applying cluster layout..." + NODE_ID=$($GARAGE_BIN node id | head -n1) + $GARAGE_BIN layout assign --version 1 "$NODE_ID" + $GARAGE_BIN layout apply --version 1 + echo " ✅ Layout applied" + sleep 2 +else + echo "â„šī¸ Layout already applied" +fi + +# Create bucket +if ! $GARAGE_BIN bucket info "$BUCKET_NAME" 2>/dev/null; then + echo "đŸ“Ļ Creating bucket: $BUCKET_NAME" + $GARAGE_BIN bucket create "$BUCKET_NAME" +else + echo "â„šī¸ Bucket $BUCKET_NAME already exists" +fi + +# Handle key +if [ -n "$AWS_ACCESS_KEY_ID" ] && [ -n "$AWS_SECRET_ACCESS_KEY" ]; then + echo "🔑 Using pre-defined credentials from .env" + if ! $GARAGE_BIN key info "$AWS_ACCESS_KEY_ID" 2>/dev/null; then + $GARAGE_BIN key import "$AWS_ACCESS_KEY_ID" "$AWS_SECRET_ACCESS_KEY" "app-key" + echo " ✅ Key imported: $AWS_ACCESS_KEY_ID" + else + echo " â„šī¸ Key already exists: $AWS_ACCESS_KEY_ID" + fi + ACCESS_KEY="$AWS_ACCESS_KEY_ID" + SECRET_KEY="$AWS_SECRET_ACCESS_KEY" +else + echo "🔑 Generating new key..." + KEY_OUTPUT=$($GARAGE_BIN key create --name "app-key") + echo "$KEY_OUTPUT" + ACCESS_KEY=$(echo "$KEY_OUTPUT" | grep 'Key ID:' | awk '{print $3}') + SECRET_KEY=$(echo "$KEY_OUTPUT" | grep 'Secret key:' | awk '{print $3}') + echo " ✅ Key generated: $ACCESS_KEY" +fi + +# Grant permissions +$GARAGE_BIN bucket allow --read --write --owner "$BUCKET_NAME" --key "$ACCESS_KEY" +echo " ✅ Permissions granted" + +# Save credentials +write_credentials "$ACCESS_KEY" "$SECRET_KEY" + +echo "🎉 Setup complete!" +echo " Bucket: $BUCKET_NAME" +echo " Access Key: $ACCESS_KEY" + +# Stop background Garage +echo "âšī¸ Stopping background Garage..." +kill "$GARAGE_PID" +wait "$GARAGE_PID" 2>/dev/null || true + # Start Garage in foreground -exec /garage "$@" +echo "🚀 Starting Garage in foreground..." +exec $GARAGE_BIN "$@" -- 2.47.3