Skip to content

feat: add object storage support (MinIO, Garage, Alarik) - #5462

Open
itzzjustmateo wants to merge 13 commits into
Dokploy:canaryfrom
itzzjustmateo:feat/object-storage
Open

itzzjustmateo wants to merge 13 commits into
Dokploy:canaryfrom
itzzjustmateo:feat/object-storage

Conversation

@itzzjustmateo

Copy link
Copy Markdown

Description

Adds object storage as a new service type in Dokploy, supporting MinIO, Garage, and Alarik providers.

What's included

  • Database schema for object storage services (migration 0198)
  • Service layer with deploy / update / remove / environment operations
  • tRPC router (objectstorage) wired into the API root
  • Create dialog with provider selection (MinIO, Garage, Alarik) and provider-specific defaults
  • Detail page with general settings, internal/external credentials, advanced settings, and update/delete actions
  • Integration across environments, breadcrumbs, overview, home totals, mounts, transfers, backups, and server queries
  • Official provider logos (MinIO, Garage, Alarik) used across the UI

Notes

  • MinIO was archived on April 25, 2026 — the create dialog recommends Garage or Alarik when MinIO is selected
  • Includes a small cleanup commit replacing @ts-ignore with @ts-expect-error and tidying configs

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update

How Has This Been Tested?

  • pnpm --filter @dokploy/server typecheck
  • pnpm --filter dokploy typecheck
  • Biome check on changed files
  • Migration applied and verified against a running database

Checklist

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes

itzzjustmateo and others added 9 commits July 29, 2026 18:20
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.
@greptile-apps

greptile-apps Bot commented Sep 14, 2026

Copy link
Copy Markdown
Contributor

Too many files changed for review (114 files, 100 file limit).

Bypass the limit by tagging @greptile-apps to review.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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".

Comment on lines +103 to +107
await fs.mkdir(configDir, { recursive: true });
await fs.writeFile(
configPath,
generateGarageConfig(region || "us-east-1"),
"utf-8",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge 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 👍 / 👎.

Comment on lines 66 to +70
redisId: text("redisId").references(() => redis.redisId, {
onDelete: "cascade",
}),
objectStorageId: text("objectStorageId").references(
() => objectstorage.objectStorageId,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge 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 👍 / 👎.

Comment on lines +96 to +100
const onSubmit = async (values: DockerProvider) => {
await mutateAsync({
externalPort: values.externalPort,
objectStorageId,
})

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 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 👍 / 👎.

Comment on lines +394 to +396
await checkServicePermissionAndAccess(ctx, objectStorageId, {
service: ["create"],
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge 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 👍 / 👎.

Comment on lines +39 to +41
return `metadata_dir = "/var/lib/garage/meta"
data_dir = "/var/lib/garage/data"
db_engine = "sqlite"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge 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 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant