feat: add object storage support (MinIO, Garage, Alarik) - #5462
itzzjustmateo wants to merge 13 commits into
Conversation
Updated README.md to enhance texts and visuals.
Add MinIO, Garage, and Alarik object storage support as a new service type. Includes the database schema, migration 0198, service layer with deploy/update/remove operations, tRPC router, and integration across mounts, transfers, overview, backups, and server queries.
Add the object storage management interface: create dialog with provider selection, detail page with general settings, credentials, advanced settings, and update/delete actions. Wire object storage into the environment page, breadcrumbs, overview, home totals, and service management flows.
Add the official MinIO, Garage, and Alarik logos used across the object storage UI.
Replace @ts-ignore comments with @ts-expect-error across the codebase, sort UI component exports, fix shell escaping in server setup, guard Stripe initialization, and update biome/gitignore/package configs.
|
Too many files changed for review (114 files, 100 file limit). Bypass the limit by tagging |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 72bca30867
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| await fs.mkdir(configDir, { recursive: true }); | ||
| await fs.writeFile( | ||
| configPath, | ||
| generateGarageConfig(region || "us-east-1"), | ||
| "utf-8", |
There was a problem hiding this comment.
Write Garage config on the target server
When a Garage service is assigned to a remote server, these filesystem calls still write garage.toml on the Dokploy web server. The subsequently created remote Docker service bind-mounts the same /etc/dokploy/.../garage.toml path on the target host, where the file was never created, so Garage deployments to remote servers fail when Swarm validates the bind source.
Useful? React with 👍 / 👎.
| redisId: text("redisId").references(() => redis.redisId, { | ||
| onDelete: "cascade", | ||
| }), | ||
| objectStorageId: text("objectStorageId").references( | ||
| () => objectstorage.objectStorageId, |
There was a problem hiding this comment.
Authorize Object Storage mount operations
Adding Object Storage mounts here requires updating the mount router's remove, one, and update service-ID chains as well. Those chains omit mount.objectStorageId, so they skip checkServicePermissionAndAccess for every Object Storage mount; any authenticated user who retains or obtains a mount ID can read, modify, or delete it without the owning service's volume permission.
Useful? React with 👍 / 👎.
| const onSubmit = async (values: DockerProvider) => { | ||
| await mutateAsync({ | ||
| externalPort: values.externalPort, | ||
| objectStorageId, | ||
| }) |
There was a problem hiding this comment.
Persist the MinIO console port
The form exposes consolePort, but its save request only includes externalPort; the corresponding API schema and mutation also only accept/update externalPort. Since deployment publishes MinIO port 9001 only when os.consolePort is set, saving a console port silently discards it and leaves the displayed external console URL unreachable.
Useful? React with 👍 / 👎.
| await checkServicePermissionAndAccess(ctx, objectStorageId, { | ||
| service: ["create"], | ||
| }); |
There was a problem hiding this comment.
Scope object storage updates to the active organization
For a user who retains an Object Storage ID after losing access to its organization, checkServicePermissionAndAccess only validates membership and role in the currently active organization; owners and admins bypass its per-service list. This handler never verifies the object's owning project organization, unlike one and remove, so such a user can update another organization's Object Storage while active in an organization where they are privileged.
Useful? React with 👍 / 👎.
| return `metadata_dir = "/var/lib/garage/meta" | ||
| data_dir = "/var/lib/garage/data" | ||
| db_engine = "sqlite" |
There was a problem hiding this comment.
Persist Garage metadata alongside its data
Garage is configured to store its SQLite metadata separately under /var/lib/garage/meta, while the creation path adds only one default volume at /var/lib/garage/data. Each redeploy force-replaces the Swarm task, so the unmounted metadata directory is discarded even though the data volume survives; existing bucket and object metadata is then lost or inaccessible after a redeploy.
Useful? React with 👍 / 👎.
Description
Adds object storage as a new service type in Dokploy, supporting MinIO, Garage, and Alarik providers.
What's included
0198)objectstorage) wired into the API rootNotes
@ts-ignorewith@ts-expect-errorand tidying configsType of Change
How Has This Been Tested?
pnpm --filter @dokploy/server typecheckpnpm --filter dokploy typecheckChecklist