Struts remains a well-loved Java web framework, and when you pair it with Apache Derby (also known as JavaDB), you get a lightweight, embeddable SQL database that's ideal for small-scale apps, prototype development, or CI environments. With Docker and Kubernetes, you can keep environments tidy and your code unchanged across both development and production. Let's walk through the setup step-by-step.
1. Add Dependencies in pom.xml
Start by updating your Maven dependencies to include Struts, Derby, and Kubernetes support:
<dependencies>> <!-- Struts framework -->
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-core</artifactId>
<version>${struts.version}</version>
</dependency>
<!-- Apache Derby JDBC driver -->
<dependency>
<groupId>org.apache.derby</groupId>
<artifactId>derby</artifactId>
<version>${derby.version}</version>
</dependency>
<!-- Kubernetes client (optional for prod deployments) -->
<dependency>
<groupId>io.fabric8</groupId>
<artifactId>kubernetes-client</artifactId>
<version>${fabric8.version}</version>
</dependency>
</dependencies>
This setup ensures your Struts app has everything needed to talk to Derby locally and read production configuration from Kubernetes.
2. Run Derby in Docker for Development
Using Docker makes local setup simple and consistent:
docker run -d \
--name derby-dev \
-p 1527:1527 \
-v ~/derby-dbs:/dbs \
az82/docker-derby
- Port 1527 is the default network client port for Derby.
- Mounting
~/derby-dbs
ensures your data survives container restarts.
3. Create Development Configuration File
Under
src/main/resources
, add
derby-dev.properties
:
db.driver=org.apache.derby.jdbc.ClientDriver
db.url=jdbc:derby://localhost:1527/devdb;create=true
db.user=
db.password=
db.validationQuery=VALUES 1
Then, in your Struts DAO or helper class:
Properties props = new Properties();
props.load(getClass().getResourceAsStream("/derby-dev.properties"));
Class.forName(props.getProperty("db.driver"));
try (Connection conn = DriverManager.getConnection(
props.getProperty("db.url"),
props.getProperty("db.user"),
props.getProperty("db.password"));
Statement stmt = conn.createStatement()) {
stmt.executeQuery(props.getProperty("db.validationQuery"));
}
This ensures your application connects to the local Derby database via Docker.
4. Prepare Kubernetes Config for Production
For production, store database connection settings securely:
kubectl create configmap derby-config \
--from-literal=DB_DRIVER=org.apache.derby.jdbc.ClientDriver \
--from-literal=DB_URL=jdbc:derby://derby-service:1527/proddb;create=true \
--from-literal=DB_VALIDATION_QUERY=VALUES 1
Since Derby doesn’t require authentication by default, you don’t need a secret—just a clean, secure config map.
5. Create Production Config File
Include
derby-prod.properties
in your resources:
db.driver=${DB_DRIVER}
db.url=${DB_URL}
db.validationQuery=${DB_VALIDATION_QUERY}
No bundled credentials here—Kubernetes injects what's needed at runtime.
6. Customize Your Kubernetes Deployment
In your application’s Deployment YAML, add:
env:
- name: DB_DRIVER
valueFrom:
configMapKeyRef:
name: derby-config
key: DB_DRIVER
- name: DB_URL
valueFrom:
configMapKeyRef:
name: derby-config
key: DB_URL
- name: DB_VALIDATION_QUERY
valueFrom:
configMapKeyRef:
name: derby-config
key: DB_VALIDATION_QUERY
This allows your Struts application to adapt without any code changes between environments.
7. Add a Struts Health-Check Action
You can verify configuration with this Struts action:
public class DbHealthAction extends ActionSupport {
public String execute() {
String propsFile = System.getenv("DB_URL") != null
? "/derby-prod.properties"
: "/derby-dev.properties";
Properties props = new Properties();
props.load(getClass().getResourceAsStream(propsFile));
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 Derby successfully!"); return SUCCESS;
} catch (Exception e) {
addActionError("Connection failed: " + e.getMessage());
return ERROR;
}
}
}
This provides the same behavior in both development and production—only the properties file changes.
Why This Approach Shines
- Fast local DNA: Get up and running with Docker in minutes.
- Secure production: Use Kubernetes to manage configs instead of bundling them.
- One clean codebase: No conditionals—just swap out config files.
- Persistent storage: Use volumes locally, and Kubernetes for prod—data stays safe.
- Minimal hassle: Perfect for demos, small projects, or embedded database needs.
With Docker and Kubernetes managing configuration, adding Derby to a Struts app becomes effortless and environment-agnostic. Your team can focus on adding features, not tackling configuration hurdles. Happy coding!
image quote pre code