#1
Struts is a lightweight Java web framework, and while SQLite isn’t commonly used in cloud deployments, it’s fantastic for local development due to its simplicity—no external server or credentials required. This guide focuses only on setting up SQLite in Struts: using Docker to run a containerized SQLite server for dev, and preparing configs for projects running in Kubernetes production (read-only or embedded use), keeping your configurations neat and tailored to each environment.

1. Add Dependencies in pom.xml

Start by including the necessary libraries:
<dependencies>
  <!-- Struts core framework -->
  <dependency>
    <groupId>org.apache.struts</groupId>
    <artifactId>struts2-core</artifactId>
    <version>${struts.version}</version>
  </dependency>

  <!-- SQLite JDBC driver -->
  <dependency>
    <groupId>org.xerial</groupId>
    <artifactId>sqlite-jdbc</artifactId>
    <version>${sqlite.version}</version>
  </dependency>

  <!-- Kubernetes client (optional, for production) -->
  <dependency>
    <groupId>io.fabric8</groupId>
    <artifactId>kubernetes-client</artifactId>
    <version>${fabric8.version}</version>
  </dependency>
</dependencies>
You’ll get Struts for web logic, the lightweight SQLite JDBC driver, and optional Kubernetes support for production.

2. Run SQLite Locally with Docker (for Dev)

While SQLite is file-based, you can still use a Docker container to manage and share DB files across development environments. A simple setup might use a shared volume:
version: '3'
services:
  sqlite-dev:
    image: nouchka/sqlite3
    volumes:
      - ./dev:/data
    working_dir: /data
    command: sh -c "sqlite3 devdb.sqlite"
Run this:
docker-compose up -d
This starts a container where devdb.sqlite lives in your ./dev directory. You can maintain the database file locally and share it among team members easily.

3. Create Dev Configuration: sqlite-dev.properties

Add this under src/main/resources:
db.driver=org.sqlite.JDBC
db.url=jdbc:sqlite:/data/devdb.sqlite
db.validationQuery=SELECT 1
Load it in your Struts helper or DAO:
Properties props = new Properties();
props.load(getClass().getResourceAsStream("/sqlite-dev.properties"));

Class.forName(props.getProperty("db.driver"));
try (Connection conn = DriverManager.getConnection(props.getProperty("db.url"));
     Statement stmt = conn.createStatement()) {
  stmt.executeQuery(props.getProperty("db.validationQuery"));
}
This lets you run queries against the local SQLite database file.

4. Prepare Kubernetes Config for Production

In production, SQLite still uses a file—but you'll likely mount a volume or use an embedded file in a container. You can configure the path via ConfigMap:
kubectl create configmap sqlite-config \
  --from-literal=DB_PATH=/data/proddb/db.sqlite \
  --from-literal=DB_DRIVER=org.sqlite.JDBC \
  --from-literal=DB_VALIDATION_QUERY=SELECT 1
No Secrets are needed—SQLite doesn't require passwords.

5. Create Production Configuration: sqlite-prod.properties

Add this to your application’s resources:
db.driver=${DB_DRIVER}
db.url=jdbc:sqlite:${DB_PATH}
db.validationQuery=${DB_VALIDATION_QUERY}
Since SQLite uses a file, your DEPOT or CRD should include a persistent file or volume mount at the configured path.

6. Kubernetes Deployment Snippet

Your container spec should include:
env:
  - name: DB_DRIVER
    valueFrom:
      configMapKeyRef:
        name: sqlite-config
        key: DB_DRIVER
  - name: DB_PATH
    valueFrom:
      configMapKeyRef:
        name: sqlite-config
        key: DB_PATH
  - name: DB_VALIDATION_QUERY
    valueFrom:
      configMapKeyRef:
        name: sqlite-config
        key: DB_VALIDATION_QUERY
volumeMounts:
  - mountPath: /data
    name: sqlite-storage
volumes:
  - name: sqlite-storage
    persistentVolumeClaim:
      claimName: sqlite-pvc
With this, the SQLite file is mounted at /data/proddb/db.sqlite in prod.

7. Example Struts Action for Health Check

Here’s a quick Struts action to verify the connection:
public class DbHealthAction extends ActionSupport {
  public String execute() {
    String url = System.getenv("DB_PATH") != null ?
                 "jdbc:sqlite:" + System.getenv("DB_PATH") :
                 getClass().getResource("/sqlite-dev.properties").getFile();

    try {
      Properties props = new Properties();
      props.load(getClass().getResourceAsStream(
          System.getenv("DB_PATH") != null ? "/sqlite-prod.properties" : "/sqlite-dev.properties"));
      Class.forName(props.getProperty("db.driver"));
      try (Connection conn = DriverManager.getConnection(props.getProperty("db.url"));
           Statement stmt = conn.createStatement()) {
        stmt.executeQuery(props.getProperty("db.validationQuery"));
        addActionMessage("Connected to SQLite successfully!");
        return SUCCESS;
      }
    } catch (Exception e) {
      addActionError("Connection failed: " + e.getMessage());
      return ERROR;
    }
  }
}
This works in both local and prod environments without changing application code.

Why This Setup Works

  • No need for full DB server locally—SQLite is self-contained and manageable.
  • Portable file-based DB—ideal for small-scale, schema-based or embedded scenarios.
  • Secure production deployment—Kubernetes configures paths, not passwords.
  • Single codebase—no logic branching; environment-specific .properties files handle it.
  • Clear separation—dev and prod configs live separately and do not overlap.
Even though SQLite isn't commonly used in cloud deployments, this setup lets you benefit from easy local prototyping and clean, kube-backed production modes with persistent storage. Great for small apps, embedded use cases, or proof-of-concept projects with Struts and SQLite!

image quote pre code