hcengineering / hcengineering/platform

What is the correct s3 storage config and STORAGE_CONFIG ??

Open
#10,247 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
TypeScript
Stars
27.7k
Forks
2.2k
PR merge metrics
No merged PRs in 30d

Description

**Description:**
When I am trying to use Huly with DigitalOcean Spaces, uploads fail with **403 Forbidden** or **SignatureDoesNotMatch** error. The dashboard attempts to create buckets dynamically, which is not allowed by DigitalOcean Spaces.

**Steps to Reproduce:**

Configure Huly with a DigitalOcean Spaces bucket using environment variables:

```
DOCKER_NAME=huly
HULY_VERSION=v0.7.307
DESKTOP_CHANNEL=0.7.242
S3_ENDPOINT=https://sgp1.digitaloceanspaces.com
S3_ACCESS_KEY=
S3_SECRET_KEY=
STORAGE_CONFIG=s3|https://sgp1.digitaloceanspaces.com?accessKey=${S3_ACCESS_KEY}&secretKey=${S3_SECRET_KEY}®ion=sgp1&bucket=${BUCKET_NAME}

....and others
```

_**Try uploading a file via the dashboard.**_

**Expected Behavior:**

File uploads succeed using the existing bucket.

**Actual Behavior:**

Huly calls createBucket() on Spaces, causing 403 Forbidden.

Upload fails with SignatureDoesNotMatch.

Root Cause:

S3Service.make() tries to create buckets if rootBucket is not defined.

Passing bucket name in the query string is misinterpreted as needing bucket creation.

DigitalOcean Spaces does not support dynamic bucket creation.

Here's the compose code:

```

name: ${DOCKER_NAME}
services:
nginx:
image: "nginx:1.21.3"
container_name: huly-nginx
ports:
- 80
volumes:
- ../files/volumes/nginx/.huly.nginx:/etc/nginx/conf.d/default.conf
depends_on:
- front
restart: unless-stopped

cockroach:
image: cockroachdb/cockroach:latest-v24.2
container_name: huly-cockroach
command: start-single-node --accept-sql-without-tls
environment:
- COCKROACH_DATABASE=${CR_DATABASE}
- COCKROACH_USER=${CR_USERNAME}
- COCKROACH_PASSWORD=${CR_USER_PASSWORD}
volumes:
- cr_data:/cockroach/cockroach-data
- cr_certs:/cockroach/certs
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/health?ready=1"]
interval: 10s
timeout: 5s
retries: 10
restart: unless-stopped

redpanda:
image: docker.redpanda.com/redpandadata/redpanda:v24.3.6
container_name: huly-redpanda
command:
- redpanda
- start
- --kafka-addr internal://0.0.0.0:9092,external://0.0.0.0:19092
- --advertise-kafka-addr internal://redpanda:9092,external://localhost:19092
- --pandaproxy-addr internal://0.0.0.0:8082,external://0.0.0.0:18082
- --advertise-pandaproxy-addr internal://redpanda:8082,external://localhost:18082
- --schema-registry-addr internal://0.0.0.0:8081,external://0.0.0.0:18081
- --rpc-addr redpanda:33145
- --advertise-rpc-addr redpanda:33145
- --mode dev-container
- --smp 1
- --default-log-level=info
volumes:
- redpanda:/var/lib/redpanda/data
environment:
- REDPANDA_SUPERUSER_USERNAME=${REDPANDA_ADMIN_USER}
- REDPANDA_SUPERUSER_PASSWORD=${REDPANDA_ADMIN_PWD}
healthcheck:
test:
["CMD-SHELL", "rpk cluster health | grep -q 'Healthy:.*true' || exit 1"]
interval: 15s
timeout: 10s
retries: 20
start_period: 45s
restart: unless-stopped
elastic:
image: "elasticsearch:7.14.2"
container_name: huly-elasticsearch
command: |
/bin/sh -c "./bin/elasticsearch-plugin list | grep -q ingest-attachment || yes | ./bin/elasticsearch-plugin install --silent ingest-attachment;
/usr/local/bin/docker-entrypoint.sh eswrapper"
volumes:
- elastic:/usr/share/elasticsearch/data
environment:
- ELASTICSEARCH_PORT_NUMBER=9200
- BITNAMI_DEBUG=true
- discovery.type=single-node
- ES_JAVA_OPTS=-Xms1024m -Xmx1024m
- http.cors.enabled=true
- http.cors.allow-origin=http://localhost:8082
healthcheck:
interval: 20s
retries: 10
test: curl -s http://localhost:9200/_cluster/health | grep -vq '"status":"red"'
restart: unless-stopped

rekoni:
image: hardcoreeng/rekoni-service:${HULY_VERSION}
container_name: huly-rekoni
environment:
- SECRET=${SECRET}
deploy:
resources:
limits:
memory: 800M
restart: unless-stopped

transactor:
image: hardcoreeng/transactor:${HULY_VERSION}
container_name: huly-transactor
environment:
- SERVER_PORT=3333
- SERVER_SECRET=${SECRET}
- DB_URL=${CR_DB_URL}
- STORAGE_CONFIG=s3|https://sgp1.digitaloceanspaces.com?accessKey=${S3_ACCESS_KEY}&secretKey=${S3_SECRET_KEY}®ion=sgp1&bucket=${BUCKET_NAME}
- FRONT_URL=https://${HOST_ADDRESS}
- ACCOUNTS_URL=http://account:3000
- FULLTEXT_URL=http://fulltext:4700
- STATS_URL=http://stats:4900
- LAST_NAME_FIRST=${LAST_NAME_FIRST:-true}
- QUEUE_CONFIG=redpanda:9092
- MAIL_URL=http://mail:8097
- EMAIL_SERVICE_URL=http://mail:8097
depends_on:
cockroach:
condition: service_healthy
redpanda:
condition: service_healthy
elastic:
condition: service_healthy
restart: unless-stopped

collaborator:
image: hardcoreeng/collaborator:${HULY_VERSION}
container_name: huly-collaborator
environment:
- COLLABORATOR_PORT=3078
- SECRET=${SECRET}
- ACCOUNTS_URL=http://account:3000
- STATS_URL=http://stats:4900
- STORAGE_CONFIG=s3|https://sgp1.digitaloceanspaces.com?accessKey=${S3_ACCESS_KEY}&secretKey=${S3_SECRET_KEY}®ion=sgp1&bucket=${BUCKET_NAME}
depends_on:
- account
- stats
restart: unless-stopped

account:
image: hardcoreeng/account:${HULY_VERSION}
container_name: huly-account
environment:
- SERVER_PORT=3000
- SERVER_SECRET=${SECRET}
- DB_URL=${CR_DB_URL}
- TRANSACTOR_URL=ws://transactor:3333;wss://${HOST_ADDRESS}/_transactor
- STORAGE_CONFIG=s3|https://sgp1.digitaloceanspaces.com?accessKey=${S3_ACCESS_KEY}&secretKey=${S3_SECRET_KEY}®ion=sgp1&bucket=${BUCKET_NAME}
- FRONT_URL=https://${HOST_ADDRESS}
- STATS_URL=https://${HOST_ADDRESS}/stats
- MODEL_ENABLED=*
- ACCOUNTS_URL=https://${HOST_ADDRESS}
- ACCOUNT_PORT=3000
- QUEUE_CONFIG=redpanda:9092
- DISABLE_SIGNUP=${DISABLE_SIGNUP:-false}
- MAIL_URL=http://mail:8097
- EMAIL_SERVICE_URL=http://mail:8097
depends_on:
- cockroach
- transactor
- redpanda
restart: unless-stopped

workspace:
image: hardcoreeng/workspace:${HULY_VERSION}
container_name: huly-workspace
environment:
- SERVER_SECRET=${SECRET}
- DB_URL=${CR_DB_URL}
- TRANSACTOR_URL=ws://transactor:3333;wss://${HOST_ADDRESS}/_transactor
- STORAGE_CONFIG=s3|https://sgp1.digitaloceanspaces.com?accessKey=${S3_ACCESS_KEY}&secretKey=${S3_SECRET_KEY}®ion=sgp1&bucket=${BUCKET_NAME}
- MODEL_ENABLED=*
- ACCOUNTS_URL=http://account:3000
- STATS_URL=http://stats:4900
- QUEUE_CONFIG=redpanda:9092
- ACCOUNTS_DB_URL=${CR_DB_URL}
depends_on:
- cockroach
- transactor
- account
- redpanda
restart: unless-stopped

front:
image: hardcoreeng/front:${HULY_VERSION}
container_name: huly-front
environment:
- SERVER_PORT=8080
- SERVER_SECRET=${SECRET}
- LOVE_ENDPOINT=https://${HOST_ADDRESS}/_love
- ACCOUNTS_URL=https://${HOST_ADDRESS}/_accounts
- ACCOUNTS_URL_INTERNAL=http://account:3000
- REKONI_URL=https://${HOST_ADDRESS}/_rekoni
- CALENDAR_URL=https://${HOST_ADDRESS}/_calendar
- GMAIL_URL=https://${HOST_ADDRESS}/_gmail
- TELEGRAM_URL=https://${HOST_ADDRESS}/_telegram
- STATS_URL=https://${HOST_ADDRESS}/_stats
- PRINT_URL=http${SECURE:+s}://${HOST_ADDRESS}/_print
- UPLOAD_URL=/files
- ELASTIC_URL=http://elastic:9200
- COLLABORATOR_URL=wss://${HOST_ADDRESS}/_collaborator
- STORAGE_CONFIG=s3|https://sgp1.digitaloceanspaces.com?accessKey=${S3_ACCESS_KEY}&secretKey=${S3_SECRET_KEY}®ion=sgp1&bucket=${BUCKET_NAME}
- TITLE=${TITLE:-Huly Self Host}
- DEFAULT_LANGUAGE=${DEFAULT_LANGUAGE:-en}
- LAST_NAME_FIRST=${LAST_NAME_FIRST:-true}
- DESKTOP_UPDATES_CHANNEL=${HULY_VERSION}
- LIVEKIT_WS=${LIVEKIT_HOST}
- DISABLE_SIGNUP=${DISABLE_SIGNUP:-false}
depends_on:
- account
- collaborator
- elastic
restart: unless-stopped

fulltext:
image: hardcoreeng/fulltext:${HULY_VERSION}
container_name: huly-fulltext
environment:
- SERVER_SECRET=${SECRET}
- DB_URL=${CR_DB_URL}
- FULLTEXT_DB_URL=http://elastic:9200
- ELASTIC_INDEX_NAME=huly_storage_index
- REKONI_URL=http://rekoni:4004
- ACCOUNTS_URL=http://account:3000
- STATS_URL=http://stats:4900
- STORAGE_CONFIG=s3|https://sgp1.digitaloceanspaces.com?accessKey=${S3_ACCESS_KEY}&secretKey=${S3_SECRET_KEY}®ion=sgp1&bucket=${BUCKET_NAME}
- QUEUE_CONFIG=redpanda:9092
depends_on:
elastic:
condition: service_healthy
redpanda:
condition: service_healthy
cockroach:
condition: service_healthy
rekoni:
condition: service_started
restart: unless-stopped

stats:
image: hardcoreeng/stats:${HULY_VERSION}
container_name: huly-stats
environment:
- PORT=4900
- SERVER_SECRET=${SECRET}
restart: unless-stopped

mail:
image: hardcoreeng/mail:${HULY_VERSION}
container_name: huly-mail
environment:
- PORT=8097
- SOURCE=${SMTP_FROM}
- SMTP_HOST=${SMTP_HOST}
- SMTP_PORT=${SMTP_PORT}
- SMTP_USERNAME=${SMTP_USERNAME}
- SMTP_PASSWORD=${SMTP_PASSWORD}
restart: unless-stopped

love:
image: hardcoreeng/love:${HULY_VERSION}
container_name: huly-love
environment:
- SERVER_PORT=8096
- SERVER_SECRET=${SECRET}
- SECRET=${SECRET}
- ACCOUNTS_URL=http://account:3000
- DB_URL=${CR_DB_URL}
- LIVEKIT_HOST=${LIVEKIT_HOST}
- LIVEKIT_API_KEY=${LIVEKIT_API_KEY}
- LIVEKIT_API_SECRET=${LIVEKIT_API_SECRET}
- STORAGE_CONFIG=s3|https://sgp1.digitaloceanspaces.com?accessKey=${S3_ACCESS_KEY}&secretKey=${S3_SECRET_KEY}®ion=sgp1&bucket=${BUCKET_NAME}
depends_on:
- account
- cockroach
restart: unless-stopped
print:
image: hardcoreeng/print:${HULY_VERSION}
container_name: print
ports:
- 4005:4005
environment:
- STORAGE_CONFIG=s3|https://sgp1.digitaloceanspaces.com?accessKey=${S3_ACCESS_KEY}&secretKey=${S3_SECRET_KEY}®ion=sgp1&bucket=${BUCKET_NAME}
- STATS_URL=http://stats:4900
- SECRET=${SECRET}
- ACCOUNTS_URL=http://account:3000
restart: unless-stopped
depends_on:
- front
- cockroach

volumes:
elastic:
cr_data:
cr_certs:
redpanda:

networks:
default:
driver: bridge
```

Please add s3, mails and push notifications documentation properly. There are little-to-no resources/github-issues that are actually useful. I have worked on 5+ project management tool and none of them felt as overwhelming to configure and initialize as huly.

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.