Hi guys,
I am deploying using the Docker Compose and trying to manage the dependencies and move them into their individual services. I seem to have figured out the Postgres and Redis configurations (unverified, but they have passed the erroring out portion during startup) and I have hit a problem with the S3 configurations.
This is the error i’m getting:
err: {
"type": "EnvironmentResourceError",
"message": "Can't open S3 bucket '{bucket}', and the Speckle server configuration has disabled creation of the bucket.: Invalid URL",
"stack":
EnvironmentResourceError: Can't open S3 bucket '{bucket}', and the Speckle server configuration has disabled creation of the bucket.: Invalid URL
at /speckle-server/packages/server/dist/modules/blobstorage/repositories/blobs.js:88:19
at async ensureConditions (/speckle-server/packages/server/dist/modules/blobstorage/index.js:17:5)
at async Object.init (/speckle-server/packages/server/dist/modules/blobstorage/index.js:22:5)
at async Object.init (/speckle-server/packages/server/dist/modules/index.js:116:9)
at async init (/speckle-server/packages/server/dist/app.js:280:5)
caused by: TypeError [ERR_INVALID_URL]: Invalid URL
at new NodeError (node:internal/errors:405:5)
at new URL (node:internal/url:676:13)
at parseUrl (/speckle-server/node_modules/@aws-sdk/url-parser/dist-cjs/index.js:7:38)
at toEndpointV1 (/speckle-server/node_modules/@aws-sdk/middleware-endpoint/dist-cjs/adaptors/toEndpointV1.js:12:38)
at customEndpointProvider (/speckle-server/node_modules/@aws-sdk/middleware-endpoint/dist-cjs/resolveEndpointConfig.js:10:99)
"name": "EnvironmentResourceError",
"jse_shortmsg": "Can't open S3 bucket '{bucket}', and the Speckle server configuration has disabled creation of the bucket.",
"jse_cause": {
"type": "TypeError",
"message": "Invalid URL",
"stack":
TypeError [ERR_INVALID_URL]: Invalid URL
at new NodeError (node:internal/errors:405:5)
at new URL (node:internal/url:676:13)
at parseUrl (/speckle-server/node_modules/@aws-sdk/url-parser/dist-cjs/index.js:7:38)
at toEndpointV1 (/speckle-server/node_modules/@aws-sdk/middleware-endpoint/dist-cjs/adaptors/toEndpointV1.js:12:38)
at customEndpointProvider (/speckle-server/node_modules/@aws-sdk/middleware-endpoint/dist-cjs/resolveEndpointConfig.js:10:99)
"input": "{S3_ENDPOINT}",
"code": "ERR_INVALID_URL"
},
"jse_info": {
"bucket": "//REDACTED",
"code": "ENVIRONMENT_RESOURCE_ERROR",
"statusCode": 502
}
}
(side note probably missing a $
to print the actual bucket name in the log)
I have verified the S3_ACCESS_KEY
and S3_SECRET_KEY
works using AWS-cli. Also filling S3_PUBLIC_ENDPOINT
doesn’t seem to make a difference. I’ve even made the bucket public read (for now) as per outlined in this post. (Please tell me if this is outdated or not too so I may know how to make the bucket auth only for example)
I’ve tried various formats (http(s)://)s3(.region).amazonaws.com
I’ll post my yml for completeness just in case it matters:
name: "speckle-server"
services:
####
# Speckle Server dependencies (Reverse proxy only)
#######
reverse-proxy:
image: traefik:v2.5
restart: always
command:
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--entrypoints.websecure.address=:443"
- "--entryPoints.web.address=:80"
- "--entrypoints.web.http.redirections.entrypoint.to=websecure"
- "--entrypoints.websecure.http.tls.domains[0].main=//REDACTED"
- "--entrypoints.websecure.http.tls.domains[0].sans=//REDACTED"
- "--certificatesresolvers.myresolver.acme.email=//REDACTED"
- "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme-v1.json"
- "--certificatesresolvers.myresolver.acme.httpchallenge.entrypoint=web"
ports:
- "80:80"
- "443:443"
- "8080:8080"
volumes:
- "./letsencrypt:/letsencrypt"
- "/var/run/docker.sock:/var/run/docker.sock:ro"
####
# Speckle Server (now using external services)
#######
speckle-ingress:
image: speckle/speckle-docker-compose-ingress:2
restart: always
ports: []
environment:
FILE_SIZE_LIMIT_MB: "100"
NGINX_ENVSUBST_OUTPUT_DIR: "/etc/nginx"
labels:
- "traefik.enable=true"
- "traefik.http.routers.speckle-ingress.rule=Host(`//REDACTED`)"
- "traefik.http.routers.speckle-ingress.entrypoints=websecure"
- "traefik.http.routers.speckle-ingress.tls.certresolver=myresolver"
- "traefik.http.services.speckle-ingress.loadbalancer.server.port=8080"
depends_on:
- speckle-server
- speckle-frontend-2
speckle-frontend-2:
image: speckle/speckle-frontend-2:2
restart: always
environment:
NUXT_PUBLIC_SERVER_NAME: "local"
NUXT_PUBLIC_API_ORIGIN: "${SPECKLE_SERVER_URL}"
NUXT_PUBLIC_BACKEND_API_ORIGIN: "http://speckle-server:3000"
# External Redis connection (Upstash)
NUXT_REDIS_URL: "${EXTERNAL_REDIS_URL}"
NUXT_PUBLIC_BASE_URL: "${SPECKLE_SERVER_URL}"
NUXT_PUBLIC_LOG_LEVEL: 'warn'
LOG_LEVEL: 'info'
LOG_PRETTY: 'true'
depends_on:
- speckle-server
speckle-server:
image: speckle/speckle-server:2
restart: always
healthcheck:
test:
[
"CMD",
"/nodejs/bin/node",
"-e",
"try { require('node:http').request({headers: {'Content-Type': 'application/json'}, port:3000, hostname:'127.0.0.1', path:'/graphql?query={serverInfo{version}}', method: 'GET', timeout: 2000 }, (res) => { body = ''; res.on('data', (chunk) => {body += chunk;}); res.on('end', () => {process.exit(res.statusCode != 200 || body.toLowerCase().includes('error'));}); }).end(); } catch { process.exit(1); }",
]
interval: 10s
timeout: 3s
retries: 30
ports:
- "3000:3000"
environment:
CANONICAL_URL: "${SPECKLE_SERVER_URL}"
SPECKLE_AUTOMATE_URL: "http://127.0.0.1:3030"
# External Redis
REDIS_URL: "${EXTERNAL_REDIS_URL}"
# External S3-compatible storage (AWS S3)
S3_ENDPOINT: "{S3_ENDPOINT}"
S3_PUBLIC_ENDPOINT : "{S3_ENDPOINT}"
S3_BUCKET: "${S3_BUCKET}"
S3_REGION: "{S3_REGION}"
S3_ACCESS_KEY: "${S3_AKEY}"
S3_SECRET_KEY: "${S3_SKEY}"
S3_CREATE_BUCKET: "false" # Bucket already created
FILE_SIZE_LIMIT_MB: 100
SESSION_SECRET: "${SPECKLE_SESSION_SECRET}"
STRATEGY_LOCAL: "true"
DEBUG: "speckle:*"
# External PostgreSQL
POSTGRES_URL: "${PG_HOST}"
POSTGRES_USER: "${PG_USER}"
POSTGRES_PASSWORD: "${PG_PASS}"
POSTGRES_DB: "${PG_DB}"
POSTGRES_PORT: "${PG_PORT:-5432}"
ENABLE_MP: "false"
FRONTEND_ORIGIN: "${SPECKLE_SERVER_URL}"
LOG_LEVEL: 'info'
LOG_PRETTY: 'true'
preview-service:
image: speckle/speckle-preview-service:2
restart: always
# Remove MinIO dependency for S3 testing
depends_on:
speckle-server:
condition: service_healthy
mem_limit: "1000m"
memswap_limit: "1000m"
environment:
DEBUG: "preview-service:*"
REDIS_URL: "${EXTERNAL_REDIS_URL}"
PORT: "3001"
webhook-service:
image: speckle/speckle-webhook-service:2
restart: always
depends_on:
speckle-server:
condition: service_healthy
environment:
DEBUG: "webhook-service:*"
PG_CONNECTION_STRING: "postgresql://${PG_USER}:${PG_PASS}@${PG_HOST}:${PG_PORT:-5432}/${PG_DB}"
fileimport-service:
image: speckle/speckle-fileimport-service:2
restart: always
depends_on:
speckle-server:
condition: service_healthy
environment:
DEBUG: "fileimport-service:*"
PG_CONNECTION_STRING: "postgresql://${PG_USER}:${PG_PASS}@${PG_HOST}:${PG_PORT:-5432}/${PG_DB}"
# External S3-compatible storage (AWS S3)
S3_ENDPOINT: "{S3_ENDPOINT}"
S3_PUBLIC_ENDPOINT : "{S3_ENDPOINT}"
S3_BUCKET: "${S3_BUCKET}"
S3_REGION: "{S3_REGION}"
S3_ACCESS_KEY: "${S3_AKEY}"
S3_SECRET_KEY: "${S3_SKEY}"
S3_CREATE_BUCKET: "false" # Bucket already created
REDIS_URL: "${EXTERNAL_REDIS_URL}"
SPECKLE_SERVER_URL: "http://speckle-server:3000"
networks:
default:
name: speckle-server
I forgot to add, the Docker Compose getting started doc 's link to advanced configurations, point to itself, so its not much of a help.