How to Configure S3 or MinIO as the Media Storage Backend in OpenWA

Set STORAGE_TYPE=s3 in your environment variables and provide the endpoint, access credentials, region, and bucket name to switch OpenWA from local disk storage to any S3-compatible object store including AWS S3 or MinIO.

OpenWA (Open WhatsApp) is an open-source automation framework that defaults to storing media files in a local ./data/media directory. According to the rmyndharis/OpenWA source code, you can configure S3 or MinIO as the media storage backend by updating the storage configuration section and providing specific connection parameters that the StorageService consumes during initialization.

Understanding the Storage Architecture

OpenWA handles all incoming and outgoing media files (images, videos, documents) through the StorageService located in [src/common/storage/storage.service.ts](https://github.com/rmyndharis/OpenWA/blob/main/src/common/storage/storage.service.ts). By default, the service operates in local mode, writing files to the filesystem. To switch to cloud storage, you must change the config.storage.type value to 's3', which triggers the S3-compatible client initialization path.

Configuring S3 or MinIO as the Media Storage Backend

Set the Storage Type to S3

The application determines which storage backend to instantiate based on the storage.type configuration value. In [src/config/configuration.ts](https://github.com/rmyndharis/OpenWA/blob/main/src/config/configuration.ts#L80-L84), the default is defined as 'local', but you can override this via the STORAGE_TYPE environment variable.

STORAGE_TYPE=s3

When STORAGE_TYPE is set to s3, the factory method in StorageService instantiates the S3 client instead of the local filesystem adapter.

Provide S3/MinIO Connection Credentials

The S3 client initialization in [src/common/storage/storage.service.ts](https://github.com/rmyndharis/OpenWA/blob/main/src/common/storage/storage.service.ts#L40-L58) reads configuration from either environment variables or the config.storage.s3 object. The following parameters are required:

  • S3_ENDPOINT / storage.s3.endpoint — The URL of the object store API (e.g., http://localhost:9000 for MinIO or https://s3.amazonaws.com for AWS).
  • S3_ACCESS_KEY_ID / storage.s3.accessKeyId — The access key ID for authentication.
  • S3_SECRET_ACCESS_KEY / storage.s3.secretAccessKey — The secret access key for authentication.
  • S3_REGION / storage.s3.region — The AWS region (any valid string works for MinIO).
  • S3_BUCKET / storage.s3.bucket — The target bucket name (defaults to openwa if not specified).

The source code explicitly sets forcePathStyle: true in the S3 client configuration, ensuring compatibility with MinIO and other non-AWS S3-compatible services that use path-style addressing.

Configuration Examples for OpenWA

MinIO Configuration

For a local MinIO instance running on port 9000, configure your .env file as follows:

STORAGE_TYPE=s3
S3_ENDPOINT=http://localhost:9000
S3_ACCESS_KEY_ID=minioadmin
S3_SECRET_ACCESS_KEY=minioadmin
S3_REGION=us-east-1
S3_BUCKET=openwa-media

AWS S3 Configuration

To use Amazon S3 as the backend:

STORAGE_TYPE=s3
S3_ENDPOINT=https://s3.amazonaws.com
S3_ACCESS_KEY_ID=YOUR_AWS_ACCESS_KEY
S3_SECRET_ACCESS_KEY=YOUR_AWS_SECRET_KEY
S3_REGION=us-east-1
S3_BUCKET=openwa-media

Programmatic Override

If you prefer to hardcode values directly in the application configuration instead of using environment variables, modify [src/config/configuration.ts](https://github.com/rmyndharis/OpenWA/blob/main/src/config/configuration.ts):

export default () => ({
  // ... other config
  storage: {
    type: 's3',
    s3: {
      endpoint: 'http://localhost:9000',
      accessKeyId: 'minioadmin',
      secretAccessKey: 'minioadmin',
      region: 'us-east-1',
      bucket: 'openwa-media',
    },
  },
});

S3 Client Initialization Details

When the application starts, the StorageService performs the following operations as implemented in the source code:

  1. Client Creation (lines 40-58): Constructs the S3 client using the provided credentials and endpoint, with forcePathStyle: true enabled for MinIO compatibility.
  2. Bucket Initialization (lines 70-90): Calls initializeS3Bucket() to check if the configured bucket exists. If the bucket is missing, the service automatically creates it with private ACL settings.

After restarting the application (e.g., npm run start:prod or your Docker container), verify the configuration by checking the logs for the message:


[StorageService] S3 bucket 'openwa-media' is available

Once this message appears, all media uploads and downloads will route through the configured S3 or MinIO endpoint instead of the local filesystem.

Summary

  • OpenWA uses the StorageService class to abstract media storage operations, supporting both local filesystem and S3-compatible backends.
  • Set STORAGE_TYPE=s3 to switch from local storage to an object store.
  • Provide S3_ENDPOINT, S3_ACCESS_KEY_ID, S3_SECRET_ACCESS_KEY, S3_REGION, and S3_BUCKET to authenticate and target the correct bucket.
  • The S3 client forces path-style requests, ensuring MinIO works without additional configuration.
  • The application automatically creates the specified bucket if it does not already exist during startup.

Frequently Asked Questions

Does OpenWA support MinIO as a storage backend?

Yes. OpenWA supports any S3-compatible object store, including MinIO, DigitalOcean Spaces, and Wasabi. The S3 client explicitly enables forcePathStyle: true in [src/common/storage/storage.service.ts](https://github.com/rmyndharis/OpenWA/blob/main/src/common/storage/storage.service.ts#L40-L58), which is required for MinIO compatibility.

What happens if the S3 bucket does not exist?

OpenWA automatically creates the bucket during initialization if it is missing. The initializeS3Bucket() method in [src/common/storage/storage.service.ts](https://github.com/rmyndharis/OpenWA/blob/main/src/common/storage/storage.service.ts#L70-L90) checks for bucket existence and executes a CreateBucket command when necessary, applying private ACL permissions by default.

Can I migrate existing local media to S3 after switching the configuration?

The configuration change only affects new media operations. Existing files stored locally in ./data/media will not be automatically migrated to S3. You must manually upload existing files to your S3 bucket and update any database references if you require historical media to be accessible via the new backend.

Is it possible to use different storage backends for different media types?

No. According to the current implementation in [src/common/storage/storage.service.ts](https://github.com/rmyndharis/OpenWA/blob/main/src/common/storage/storage.service.ts), OpenWA initializes a single global storage backend at startup. All media—images, videos, audio, and documents—use the same storage configuration defined by STORAGE_TYPE and the associated credentials.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →