0
# Server Deployment
1
2
H2 Database Engine provides multiple server components for deploying databases in client/server mode. This includes TCP servers for database connections, web servers for the H2 Console administration interface, and PostgreSQL compatibility servers for existing PostgreSQL client applications.
3
4
## Server Components
5
6
### TcpServer
7
8
High-performance TCP/IP database server for client connections.
9
10
```java { .api }
11
public class TcpServer implements Service {
12
// Server lifecycle
13
public void start() throws SQLException;
14
public void stop();
15
public boolean isRunning(boolean traceError);
16
17
// Configuration
18
public String getURL();
19
public int getPort();
20
public String getStatus();
21
public boolean getAllowOthers();
22
public void setPort(int port);
23
public void setAllowOthers(boolean allowOthers);
24
25
// SSL support
26
public void setSSL(boolean ssl);
27
public boolean getSSL();
28
}
29
```
30
31
**Usage Examples:**
32
33
```java
34
// Start TCP server programmatically
35
TcpServer server = new TcpServer();
36
server.setPort(9092);
37
server.setAllowOthers(true); // Allow remote connections
38
server.start();
39
40
System.out.println("Server running at: " + server.getURL());
41
System.out.println("Server status: " + server.getStatus());
42
43
// Stop server
44
server.stop();
45
```
46
47
**Command Line Usage:**
48
```bash
49
# Start TCP server on default port 9092
50
java -cp h2-*.jar org.h2.tools.Server -tcp
51
52
# Start on custom port with remote access
53
java -cp h2-*.jar org.h2.tools.Server -tcp -tcpPort 9093 -tcpAllowOthers
54
55
# Start with SSL encryption
56
java -cp h2-*.jar org.h2.tools.Server -tcp -tcpSSL -tcpPort 9094
57
```
58
59
**Client Connection:**
60
```java
61
// Connect to TCP server
62
Connection conn = DriverManager.getConnection(
63
"jdbc:h2:tcp://localhost:9092/~/mydb", "sa", "password");
64
65
// SSL connection
66
Connection sslConn = DriverManager.getConnection(
67
"jdbc:h2:ssl://localhost:9094/~/mydb", "sa", "password");
68
```
69
70
### WebServer
71
72
HTTP server providing the H2 Console web-based administration interface.
73
74
```java { .api }
75
public class WebServer implements Service {
76
// Server lifecycle
77
public void start() throws SQLException;
78
public void stop();
79
public boolean isRunning(boolean traceError);
80
81
// Configuration
82
public String getURL();
83
public int getPort();
84
public String getStatus();
85
public boolean getAllowOthers();
86
public void setPort(int port);
87
public void setAllowOthers(boolean allowOthers);
88
89
// SSL and security
90
public void setSSL(boolean ssl);
91
public boolean getSSL();
92
public void setAllowSecureCreation(boolean allowSecureCreation);
93
94
// Authentication
95
public void setCommandHistoryAllowed(boolean allowed);
96
public void setShutdownHandler(ShutdownHandler shutdownHandler);
97
}
98
```
99
100
**Usage Examples:**
101
102
```java
103
// Start web console programmatically
104
WebServer webServer = new WebServer();
105
webServer.setPort(8082);
106
webServer.setAllowOthers(true); // Allow remote access
107
webServer.start();
108
109
System.out.println("H2 Console available at: " + webServer.getURL());
110
111
// Configure for production
112
webServer.setAllowSecureCreation(false); // Disable database creation via web
113
webServer.setCommandHistoryAllowed(false); // Disable command history
114
115
// Stop server
116
webServer.stop();
117
```
118
119
**Command Line Usage:**
120
```bash
121
# Start web console on default port 8082
122
java -cp h2-*.jar org.h2.tools.Server -web
123
124
# Start on custom port with remote access
125
java -cp h2-*.jar org.h2.tools.Server -web -webPort 8083 -webAllowOthers
126
127
# Start with SSL
128
java -cp h2-*.jar org.h2.tools.Server -web -webSSL -webPort 8443
129
130
# Disable browser opening
131
java -cp h2-*.jar org.h2.tools.Server -web -webDaemon
132
```
133
134
**Web Console Access:**
135
- Default URL: `http://localhost:8082`
136
- HTTPS URL: `https://localhost:8443` (with SSL)
137
- Login with database connection details
138
139
### PgServer
140
141
PostgreSQL protocol compatibility server for existing PostgreSQL clients.
142
143
```java { .api }
144
public class PgServer implements Service {
145
// Server lifecycle
146
public void start() throws SQLException;
147
public void stop();
148
public boolean isRunning(boolean traceError);
149
150
// Configuration
151
public String getURL();
152
public int getPort();
153
public String getStatus();
154
public boolean getAllowOthers();
155
public void setPort(int port);
156
public void setAllowOthers(boolean allowOthers);
157
158
// PostgreSQL compatibility
159
public void setKeyFile(String keyFile);
160
public void setKey(String key, String value);
161
}
162
```
163
164
**Usage Examples:**
165
166
```java
167
// Start PostgreSQL compatibility server
168
PgServer pgServer = new PgServer();
169
pgServer.setPort(5435); // Different from default PostgreSQL port 5432
170
pgServer.setAllowOthers(true);
171
pgServer.start();
172
173
System.out.println("PostgreSQL server available at: " + pgServer.getURL());
174
175
// Stop server
176
pgServer.stop();
177
```
178
179
**Command Line Usage:**
180
```bash
181
# Start PostgreSQL server on default port 5435
182
java -cp h2-*.jar org.h2.tools.Server -pg
183
184
# Start on custom port
185
java -cp h2-*.jar org.h2.tools.Server -pg -pgPort 5436 -pgAllowOthers
186
```
187
188
**PostgreSQL Client Connection:**
189
```bash
190
# Connect using psql
191
psql -h localhost -p 5435 -U sa -d ~/mydb
192
193
# Connection string for PostgreSQL clients
194
postgresql://sa@localhost:5435/~/mydb
195
```
196
197
## Multi-Server Deployment
198
199
### Combined Server Startup
200
201
Start multiple server types simultaneously:
202
203
```java { .api }
204
public class Server extends Tool implements Runnable, ShutdownHandler {
205
// Factory methods for specific servers
206
public static Server createTcpServer(String... args) throws SQLException;
207
public static Server createWebServer(String... args) throws SQLException;
208
public static Server createPgServer(String... args) throws SQLException;
209
210
// Combined server management
211
public static void main(String... args);
212
public Server start() throws SQLException;
213
public void stop();
214
public String getStatus();
215
}
216
```
217
218
**Usage Examples:**
219
220
```java
221
// Start all servers programmatically
222
Server tcpServer = Server.createTcpServer("-tcpPort", "9092", "-tcpAllowOthers");
223
Server webServer = Server.createWebServer("-webPort", "8082", "-webAllowOthers");
224
Server pgServer = Server.createPgServer("-pgPort", "5435", "-pgAllowOthers");
225
226
tcpServer.start();
227
webServer.start();
228
pgServer.start();
229
230
System.out.println("All servers started");
231
System.out.println("TCP: " + tcpServer.getURL());
232
System.out.println("Web: " + webServer.getURL());
233
System.out.println("PG: " + pgServer.getURL());
234
235
// Stop all servers
236
tcpServer.stop();
237
webServer.stop();
238
pgServer.stop();
239
```
240
241
**Command Line Combined Startup:**
242
```bash
243
# Start all server types
244
java -cp h2-*.jar org.h2.tools.Server -tcp -web -pg
245
246
# With custom ports
247
java -cp h2-*.jar org.h2.tools.Server \
248
-tcp -tcpPort 9092 -tcpAllowOthers \
249
-web -webPort 8082 -webAllowOthers \
250
-pg -pgPort 5435 -pgAllowOthers
251
```
252
253
## Server Configuration
254
255
### TCP Server Configuration
256
257
```java
258
public class TcpServerConfig {
259
public static void startConfiguredTcpServer() throws SQLException {
260
TcpServer server = new TcpServer();
261
262
// Basic configuration
263
server.setPort(9092);
264
server.setAllowOthers(true);
265
266
// Performance tuning
267
server.setDaemon(true); // Run as daemon thread
268
269
// Security
270
server.setSSL(true); // Enable SSL/TLS
271
272
server.start();
273
274
// Server information
275
System.out.println("TCP Server Configuration:");
276
System.out.println(" URL: " + server.getURL());
277
System.out.println(" Port: " + server.getPort());
278
System.out.println(" SSL: " + server.getSSL());
279
System.out.println(" Allow Others: " + server.getAllowOthers());
280
System.out.println(" Status: " + server.getStatus());
281
}
282
}
283
```
284
285
### Web Server Configuration
286
287
```java
288
public class WebServerConfig {
289
public static void startConfiguredWebServer() throws SQLException {
290
WebServer server = new WebServer();
291
292
// Basic configuration
293
server.setPort(8082);
294
server.setAllowOthers(true);
295
296
// Security settings
297
server.setSSL(true);
298
server.setAllowSecureCreation(false); // Prevent database creation
299
server.setCommandHistoryAllowed(false); // Disable command history
300
301
// Add shutdown handler
302
server.setShutdownHandler(new ShutdownHandler() {
303
@Override
304
public void shutdown() {
305
System.out.println("Web server shutting down...");
306
}
307
});
308
309
server.start();
310
311
System.out.println("Web Console available at: " + server.getURL());
312
}
313
}
314
```
315
316
## Service Interface
317
318
All server components implement the Service interface:
319
320
```java { .api }
321
public interface Service {
322
void start() throws SQLException;
323
void stop();
324
boolean isRunning(boolean traceError);
325
String getURL();
326
int getPort();
327
String getStatus();
328
}
329
```
330
331
**Custom Service Implementation:**
332
333
```java
334
public class CustomDatabaseService implements Service {
335
private TcpServer tcpServer;
336
private WebServer webServer;
337
private boolean running = false;
338
339
@Override
340
public void start() throws SQLException {
341
tcpServer = new TcpServer();
342
tcpServer.setPort(9092);
343
tcpServer.setAllowOthers(true);
344
345
webServer = new WebServer();
346
webServer.setPort(8082);
347
webServer.setAllowOthers(false); // Local access only for web console
348
349
tcpServer.start();
350
webServer.start();
351
352
running = true;
353
System.out.println("Custom database service started");
354
}
355
356
@Override
357
public void stop() {
358
if (tcpServer != null) tcpServer.stop();
359
if (webServer != null) webServer.stop();
360
running = false;
361
System.out.println("Custom database service stopped");
362
}
363
364
@Override
365
public boolean isRunning(boolean traceError) {
366
return running &&
367
(tcpServer == null || tcpServer.isRunning(traceError)) &&
368
(webServer == null || webServer.isRunning(traceError));
369
}
370
371
@Override
372
public String getURL() {
373
return tcpServer != null ? tcpServer.getURL() : null;
374
}
375
376
@Override
377
public int getPort() {
378
return tcpServer != null ? tcpServer.getPort() : -1;
379
}
380
381
@Override
382
public String getStatus() {
383
return "TCP: " + (tcpServer != null ? tcpServer.getStatus() : "stopped") +
384
", Web: " + (webServer != null ? webServer.getStatus() : "stopped");
385
}
386
}
387
```
388
389
## Servlet Integration
390
391
### WebServlet
392
393
Integrate H2 Console into existing web applications:
394
395
```java { .api }
396
public class WebServlet extends HttpServlet {
397
// Servlet lifecycle
398
public void init() throws ServletException;
399
public void destroy();
400
401
// HTTP methods
402
protected void doGet(HttpServletRequest request, HttpServletResponse response)
403
throws ServletException, IOException;
404
protected void doPost(HttpServletRequest request, HttpServletResponse response)
405
throws ServletException, IOException;
406
}
407
```
408
409
**Web.xml Configuration:**
410
```xml
411
<servlet>
412
<servlet-name>H2Console</servlet-name>
413
<servlet-class>org.h2.server.web.WebServlet</servlet-class>
414
<init-param>
415
<param-name>webAllowOthers</param-name>
416
<param-value>false</param-value>
417
</init-param>
418
<load-on-startup>1</load-on-startup>
419
</servlet>
420
421
<servlet-mapping>
422
<servlet-name>H2Console</servlet-name>
423
<url-pattern>/h2-console/*</url-pattern>
424
</servlet-mapping>
425
```
426
427
### JakartaWebServlet
428
429
Jakarta EE support for modern application servers:
430
431
```java { .api }
432
public class JakartaWebServlet extends HttpServlet {
433
// Same interface as WebServlet but for Jakarta EE
434
public void init() throws ServletException;
435
public void destroy();
436
437
protected void doGet(HttpServletRequest request, HttpServletResponse response)
438
throws ServletException, IOException;
439
protected void doPost(HttpServletRequest request, HttpServletResponse response)
440
throws ServletException, IOException;
441
}
442
```
443
444
## Production Deployment Patterns
445
446
### Docker Deployment
447
448
```dockerfile
449
FROM openjdk:11-jre-slim
450
451
# Add H2 database jar
452
COPY h2-*.jar /app/h2.jar
453
454
# Create data directory
455
RUN mkdir -p /data
456
457
# Expose ports
458
EXPOSE 9092 8082 5435
459
460
# Start H2 servers
461
CMD ["java", "-cp", "/app/h2.jar", "org.h2.tools.Server", \
462
"-tcp", "-tcpAllowOthers", "-tcpPort", "9092", \
463
"-web", "-webAllowOthers", "-webPort", "8082", \
464
"-pg", "-pgAllowOthers", "-pgPort", "5435", \
465
"-baseDir", "/data"]
466
```
467
468
### Systemd Service
469
470
```ini
471
[Unit]
472
Description=H2 Database Server
473
After=network.target
474
475
[Service]
476
Type=simple
477
User=h2
478
Group=h2
479
ExecStart=/usr/bin/java -cp /opt/h2/h2.jar org.h2.tools.Server \
480
-tcp -tcpAllowOthers -tcpPort 9092 \
481
-web -webAllowOthers -webPort 8082 \
482
-baseDir /var/lib/h2
483
ExecStop=/bin/kill -TERM $MAINPID
484
Restart=on-failure
485
RestartSec=10
486
487
[Install]
488
WantedBy=multi-user.target
489
```
490
491
### Application Server Integration
492
493
```java
494
@Singleton
495
@Startup
496
public class H2ServerManager {
497
498
private Server tcpServer;
499
private Server webServer;
500
501
@PostConstruct
502
public void startServers() {
503
try {
504
// Start TCP server for application connections
505
tcpServer = Server.createTcpServer(
506
"-tcpPort", "9092",
507
"-tcpAllowOthers", "true",
508
"-baseDir", System.getProperty("h2.baseDir", "./data")
509
);
510
tcpServer.start();
511
512
// Start web console (development only)
513
if (isDevelopmentMode()) {
514
webServer = Server.createWebServer(
515
"-webPort", "8082",
516
"-webAllowOthers", "false"
517
);
518
webServer.start();
519
}
520
521
System.out.println("H2 servers started successfully");
522
523
} catch (SQLException e) {
524
throw new RuntimeException("Failed to start H2 servers", e);
525
}
526
}
527
528
@PreDestroy
529
public void stopServers() {
530
if (tcpServer != null) {
531
tcpServer.stop();
532
System.out.println("TCP server stopped");
533
}
534
if (webServer != null) {
535
webServer.stop();
536
System.out.println("Web server stopped");
537
}
538
}
539
540
private boolean isDevelopmentMode() {
541
return "development".equals(System.getProperty("app.profile"));
542
}
543
}
544
```
545
546
## Load Balancing and High Availability
547
548
### Connection Pooling with Multiple Servers
549
550
```java
551
public class LoadBalancedH2Pool {
552
private final List<String> serverUrls;
553
private final List<JdbcConnectionPool> pools;
554
private final AtomicInteger currentIndex = new AtomicInteger(0);
555
556
public LoadBalancedH2Pool(List<String> serverUrls, String user, String password) {
557
this.serverUrls = new ArrayList<>(serverUrls);
558
this.pools = serverUrls.stream()
559
.map(url -> JdbcConnectionPool.create(url, user, password))
560
.collect(Collectors.toList());
561
562
// Configure each pool
563
pools.forEach(pool -> {
564
pool.setMaxConnections(10);
565
pool.setTimeoutMs(5000);
566
});
567
}
568
569
public Connection getConnection() throws SQLException {
570
SQLException lastException = null;
571
572
// Try each server in round-robin fashion
573
for (int i = 0; i < pools.size(); i++) {
574
int index = currentIndex.getAndIncrement() % pools.size();
575
JdbcConnectionPool pool = pools.get(index);
576
577
try {
578
return pool.getConnection();
579
} catch (SQLException e) {
580
lastException = e;
581
System.err.println("Failed to connect to server: " + serverUrls.get(index));
582
}
583
}
584
585
throw new SQLException("All H2 servers unavailable", lastException);
586
}
587
588
public void shutdown() {
589
pools.forEach(JdbcConnectionPool::dispose);
590
}
591
}
592
```
593
594
## Monitoring and Management
595
596
### Server Status Monitoring
597
598
```java
599
public class H2ServerMonitor {
600
private final List<Service> services;
601
602
public H2ServerMonitor(List<Service> services) {
603
this.services = services;
604
}
605
606
public ServerStatus getOverallStatus() {
607
boolean allRunning = true;
608
StringBuilder statusReport = new StringBuilder();
609
610
for (Service service : services) {
611
boolean running = service.isRunning(false);
612
allRunning &= running;
613
614
statusReport.append(service.getClass().getSimpleName())
615
.append(" (port ").append(service.getPort()).append("): ")
616
.append(running ? "RUNNING" : "STOPPED")
617
.append("\n");
618
}
619
620
return new ServerStatus(allRunning, statusReport.toString());
621
}
622
623
public static class ServerStatus {
624
private final boolean allRunning;
625
private final String report;
626
627
public ServerStatus(boolean allRunning, String report) {
628
this.allRunning = allRunning;
629
this.report = report;
630
}
631
632
public boolean isAllRunning() { return allRunning; }
633
public String getReport() { return report; }
634
}
635
}
636
637
// Usage
638
List<Service> services = Arrays.asList(tcpServer, webServer, pgServer);
639
H2ServerMonitor monitor = new H2ServerMonitor(services);
640
641
// Periodic health check
642
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
643
scheduler.scheduleAtFixedRate(() -> {
644
ServerStatus status = monitor.getOverallStatus();
645
if (!status.isAllRunning()) {
646
System.err.println("Server health check failed:\n" + status.getReport());
647
// Send alert, restart services, etc.
648
}
649
}, 0, 30, TimeUnit.SECONDS);
650
```