#1
Dropwizard is a lightweight and robust framework for building Java web services. Integrating MinIO—a self-hosted, S3-compatible object storage—complements Dropwizard applications needing to handle file uploads, backups, or media. By using Docker during development and Kubernetes for production deployments, you can manage storage configurations cleanly and securely.
This guide walks you through setting up MinIO in Dropwizard with Docker for dev and Kubernetes for prod. We’ll cover dependencies in the pom.xml, Docker setup, Dropwizard configuration files, and how to fetch production values from Kubernetes env vars.

1. Add Dependencies in pom.xml

Make sure your pom.xml includes these dependencies:
<dependencies>
  <!-- Dropwizard core -->
  <dependency>
    <groupId>io.dropwizard</groupId>
    <artifactId>dropwizard-core</artifactId>
    <version>${dropwizard.version}</version>
  </dependency>

  <!-- MinIO Java SDK -->
  <dependency>
    <groupId>io.minio</groupId>
    <artifactId>minio</artifactId>
    <version>8.5.3</version>
  </dependency>

  <!-- Kubernetes client (optional, for production integration) -->
  <dependency>
    <groupId>io.fabric8</groupId>
    <artifactId>kubernetes-client</artifactId>
    <version>${fabric8.version}</version>
  </dependency>
</dependencies>
In production, the Kubernetes client can help you fetch ConfigMaps or Secrets, though env vars are often simpler.

2. Run MinIO via Docker (Dev Mode)

To run MinIO during development, create a docker-compose.yml
version: '3.7'
services:
  minio:
    image: minio/minio
    environment:
      MINIO_ROOT_USER: minioadmin
      MINIO_ROOT_PASSWORD: minioadmin
    volumes:
      - minio-data:/data
    ports:
      - "9000:9000"
      - "9001:9001"
    command: server /data --console-address ":9001"

volumes:
  minio-data:
Launch with:
docker-compose up
MinIO will be accessible at http://localhost:9000, with a console at http://localhost:9001 (default credentials: minioadmin/minioadmin).

3. Configure Dropwizard for Development

Define MinIO settings in your config-dev.yml:
server:
  applicationConnectors:
    - type: http
      port: 8080

minio:
  endpoint: http://localhost:9000
  accessKey: minioadmin
  secretKey: minioadmin
  bucket: dev-bucket
Create a corresponding configuration class:
public class MinioSettings {
  @JsonProperty
  private String endpoint;
  @JsonProperty
  private String accessKey;
  @JsonProperty
  private String secretKey;
  @JsonProperty
  private String bucket;

  // getters
}
And your main app’s config:
public class MyAppConfig extends Configuration {
  @Valid
  @NotNull
  @JsonProperty("minio")
  private MinioSettings minio = new MinioSettings();

  public MinioSettings getMinio() {
    return minio;
  }
}
In your Application class, build the MinIO client using settings from config-dev.yml.
Run dev mode with:
java -jar target/myapp.jar server config-dev.yml

4. Configure Kubernetes for Production

In production, avoid storing credentials in files. Use env vars tied to Secrets and ConfigMaps:

Create a Secret and ConfigMap

kubectl create secret generic minio-secret \
  --from-literal=MINIO_ACCESS_KEY=produser \
  --from-literal=MINIO_SECRET_KEY=prodsecret

kubectl create configmap minio-config \
  --from-literal=MINIO_ENDPOINT=http://minio-service:9000 \
  --from-literal=MINIO_BUCKET=prod-bucket

Update config-prod.yml

Your configuration can reference env vars like this:
server:
  applicationConnectors:
    - type: http
      port: 8080

minio:
  endpoint: ${MINIO_ENDPOINT:}
  accessKey: ${MINIO_ACCESS_KEY:}
  secretKey: ${MINIO_SECRET_KEY:}
  bucket: ${MINIO_BUCKET:}

Kubernetes Deployment Snippet

Inject environment variables into your deployment:
env:
  - name: MINIO_ENDPOINT
    valueFrom:
      configMapKeyRef:
        name: minio-config
        key: MINIO_ENDPOINT
  - name: MINIO_BUCKET
    valueFrom:
      configMapKeyRef:
        name: minio-config
        key: MINIO_BUCKET
  - name: MINIO_ACCESS_KEY
    valueFrom:
      secretKeyRef:
        name: minio-secret
        key: MINIO_ACCESS_KEY
  - name: MINIO_SECRET_KEY
    valueFrom:
      secretKeyRef:
        name: minio-secret
        key: MINIO_SECRET_KEY
When the app starts, Dropwizard will substitute ${…} placeholders with the environment variable values.

5. Access MinIO in Your Code

In your Application class, create a MinIO client bean:
MinioClient client = MinioClient.builder()
    .endpoint(config.getMinio().getEndpoint())
    .credentials(config.getMinio().getAccessKey(), config.getMinio().getSecretKey())
    .build();
Use it inside your resources or services to upload/download objects. For example, a simple health check:
boolean exists = client.bucketExists(BucketExistsArgs.builder()
                    .bucket(config.getMinio().getBucket())
                    .build());

6. Why This Setup Matters

  • The dev environment uses Docker and local configs, making iteration faster and isolation clearer.
  • Production uses Kubernetes best practices—Secrets for credentials, ConfigMaps for endpoints, avoiding source control leaks.
  • Dropwizard’s flexible configuration loading makes it easy to switch between environments with just your CLI or Kubernetes spec.
By separating development and production configurations, you make your Dropwizard application cleaner, more secure, and easier to maintain. Docker gives you a fast dev environment, while Kubernetes ensures secure, scalable prod deployments. With MinIO in place, your app is ready for object storage tasks with an S3-compatible interface—whether it's uploading user content, managing backups, or serving media.

image quote pre code