Struts may be from an earlier era in Java web frameworks, but that doesn't stop it from partnering beautifully with modern databases. TimescaleDB, a time-series database built on PostgreSQL, is perfect for storing metrics, logs, and events efficiently. This walkthrough focuses strictly on how to configure Struts to talk to TimescaleDB—using Docker in development and Kubernetes in production—and demonstrates clean separation of configuration for dev and prod environments.
1. Add Required Dependencies
To get started, include the following in your
pom.xml:
<dependencies>
<!-- Struts web framework -->
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-core</artifactId>
<version>${struts.version}</version>
</dependency>
<!-- PostgreSQL JDBC driver (compatible with TimescaleDB) -->
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>${postgresql.version}</version>
</dependency>
<!-- Kubernetes client (optional) -->
<dependency>
<groupId>io.fabric8</groupId>
<artifactId>kubernetes-client</artifactId>
<version>${fabric8.version}</version>
</dependency>
</dependencies>
TimescaleDB speaks the PostgreSQL protocol, so the standard JDBC driver works perfectly. The Kubernetes dependency becomes handy for production deployments but isn't strictly required.
2. Run TimescaleDB Locally with Docker
Keep local setup simple with Docker Compose:
version: '3'
services:
timescaledb:
image: timescale/timescaledb:latest-pg14
environment:
- POSTGRES_USER=devuser
- POSTGRES_PASSWORD=devpass
- POSTGRES_DB=devdb
ports:
- "5432:5432"
volumes:
- tsdb-data:/var/lib/postgresql/data
volumes:
tsdb-data:
Start it up:
docker-compose up -d
Your TimescaleDB instance is now accessible at
localhost:5432, database
devdb, user
devuser.
3. Create Development Config: timescale-dev.properties
Add this file to
src/main/resources:
db.driver=org.postgresql.Driver
db.url=jdbc:postgresql://localhost:5432/devdb?sslmode=disable
db.user=devuser
db.password=devpass
db.validationQuery=SELECT 1
Load it in Struts helper or DAO code:
Properties props = new Properties();
props.load(getClass().getResourceAsStream("/timescale-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"));
}
That's it—your app now connects to TimescaleDB locally for development.
4. Prepare Kubernetes Config for Production
Credentials and URLs shouldn't be hardcoded. Instead, use ConfigMaps and Secrets:
kubectl create configmap timescale-config \
--from-literal=DB_URL=jdbc:postgresql://timescale-service:5432/proddb?sslmode=disable \
--from-literal=DB_DRIVER=org.postgresql.Driver \
--from-literal=DB_VALIDATION_QUERY=SELECT 1
kubectl create secret generic timescale-secret \
--from-literal=DB_USER=produser \
--from-literal=DB_PASSWORD=prodpass
5. Create Production Config: timescale-prod.properties
Include this in your JAR under
resources:
db.driver=${DB_DRIVER}
db.url=${DB_URL}
db.user=${DB_USER}
db.password=${DB_PASSWORD}
db.validationQuery=${DB_VALIDATION_QUERY}
No application code needs to change—only the properties file changes depending on environment.
6. Kubernetes Deployment Snippet
Ensure your Pod spec or deployment YAML contains:
env:
- name: DB_DRIVER
valueFrom:
configMapKeyRef:
name: timescale-config
key: DB_DRIVER
- name: DB_URL
valueFrom:
configMapKeyRef:
name: timescale-config
key: DB_URL
- name: DB_VALIDATION_QUERY
valueFrom:
configMapKeyRef:
name: timescale-config
key: DB_VALIDATION_QUERY
- name: DB_USER
valueFrom:
secretKeyRef:
name: timescale-secret
key: DB_USER
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: timescale-secret
key: DB_PASSWORD
With this setup, your Struts app picks up production-ready settings at runtime without modifying code.
7. Example Struts Action to Verify Connection
Use this snippet to test connectivity:
public class DbHealthAction extends ActionSupport {
public String execute() {
String url = System.getenv("DB_URL");
String user = System.getenv("DB_USER");
String pass = System.getenv("DB_PASSWORD");
String validation = System.getenv("DB_VALIDATION_QUERY");
try (Connection conn = DriverManager.getConnection(url, user, pass);
Statement stmt = conn.createStatement()) {
stmt.executeQuery(validation);
addActionMessage("Connected to TimescaleDB successfully!");
return SUCCESS;
} catch (Exception e) {
addActionError("Connection failed: " + e.getMessage());
return ERROR;
}
}
}
No code branching based on environment—just one clean Struts action.
Why It Works
- Quick local dev setup with Docker and minimal config
- Secure production by avoiding hardcoded values and using Kubernetes Secrets
- One coherent codebase: the same JDBC logic works everywhere
- Environment clarity: separate files reduce risk of cross-env errors
With just Docker, Kubernetes, and two simple properties files, your Struts application becomes TimescaleDB-ready—efficient, scalable for time series data, and clean across both development and production environments. Enjoy building fast, reliable web apps with Struts and TimescaleDB!
image quote pre code