This guide covers deploying OJP Server using Docker, including configuration options, JVM parameter customization, and production best practices.
- Quick Start
- Passing JVM Parameters
- Environment Variables
- Production Deployment
- Examples
- Troubleshooting
The fastest way to run OJP Server is using the pre-built Docker image:
docker run -d \
--name ojp-server \
-p 1059:1059 \
-p 9159:9159 \
rrobetti/ojp:0.4.0-betaThis starts the OJP Server with:
- Port 1059: gRPC server for database connections
- Port 9159: Prometheus metrics endpoint
- Included drivers: H2, PostgreSQL, MySQL, MariaDB
- UTC timezone: The image is built with
-Duser.timezone=UTCfor consistent date/time handling
The recommended way to pass JVM parameters (including system properties, heap settings, and GC options) to the OJP Server Docker container is using the JAVA_TOOL_OPTIONS environment variable.
The JVM automatically recognizes and applies any parameters set in JAVA_TOOL_OPTIONS at startup.
docker run -d \
--name ojp-server \
-p 1059:1059 \
-e JAVA_TOOL_OPTIONS="-Dfile.encoding=UTF-8 -Duser.timezone=UTC" \
rrobetti/ojp:0.4.0-betaConfigure heap size and other memory settings:
docker run -d \
--name ojp-server \
-p 1059:1059 \
-e JAVA_TOOL_OPTIONS="-Xmx2g -Xms1g -Duser.timezone=UTC" \
rrobetti/ojp:0.4.0-betaCombine multiple JVM parameters:
docker run -d \
--name ojp-server \
-p 1059:1059 \
-e JAVA_TOOL_OPTIONS="-Xmx4g -Xms2g -Dfile.encoding=UTF-8 -Duser.timezone=UTC -XX:+UseG1GC" \
rrobetti/ojp:0.4.0-beta| Parameter | Description | Example |
|---|---|---|
-Xmx |
Maximum heap size | -Xmx4g (4 GB) |
-Xms |
Initial heap size | -Xms2g (2 GB) |
-XX:MaxMetaspaceSize |
Maximum metaspace size | -XX:MaxMetaspaceSize=512m |
-XX:MetaspaceSize |
Initial metaspace size | -XX:MetaspaceSize=256m |
| Parameter | Description | Use Case |
|---|---|---|
-XX:+UseG1GC |
Use G1 garbage collector | Default for most workloads |
-XX:+UseZGC |
Use Z garbage collector | Low-latency requirements (Java 17+) |
-XX:MaxGCPauseMillis |
Target max GC pause time | -XX:MaxGCPauseMillis=200 |
-XX:G1HeapRegionSize |
G1 heap region size | -XX:G1HeapRegionSize=32m |
| Parameter | Description | Example |
|---|---|---|
-Dfile.encoding |
Character encoding | -Dfile.encoding=UTF-8 |
-Duser.timezone |
Default timezone | -Duser.timezone=UTC |
-Duser.language |
Default language | -Duser.language=en |
-Duser.country |
Default country | -Duser.country=US |
⚠️ Keep-Duser.timezone=UTC:
The OJP Docker image is built with-Duser.timezone=UTCbaked in. Always include this property when settingJAVA_TOOL_OPTIONSto ensure consistent date/time handling across all database types and client timezones.
| Parameter | Description | Example |
|---|---|---|
-agentlib:jdwp |
Enable remote debugging | -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005 |
-XX:+HeapDumpOnOutOfMemoryError |
Create heap dump on OOM | -XX:+HeapDumpOnOutOfMemoryError |
-XX:HeapDumpPath |
Heap dump file path | -XX:HeapDumpPath=/tmp/heapdump.hprof |
-verbose:gc |
Verbose GC logging | -verbose:gc |
In addition to JVM parameters, OJP Server supports configuration through environment variables:
docker run -d \
--name ojp-server \
-p 8080:8080 \
-p 9091:9091 \
-e OJP_SERVER_PORT=8080 \
-e OJP_PROMETHEUS_PORT=9091 \
-e OJP_SERVER_LOGLEVEL=DEBUG \
-e OJP_SERVER_THREADPOOLSIZE=300 \
rrobetti/ojp:0.4.0-betaSee ojp-server-configuration.md for a complete list of available configuration options.
You can use both approaches together:
docker run -d \
--name ojp-server \
-p 1059:1059 \
-e JAVA_TOOL_OPTIONS="-Xmx4g -Xms2g -Dfile.encoding=UTF-8 -Duser.timezone=UTC" \
-e OJP_SERVER_PORT=1059 \
-e OJP_SERVER_LOGLEVEL=INFO \
rrobetti/ojp:0.4.0-betaA production deployment example with appropriate JVM tuning:
docker run -d \
--name ojp-server \
--restart unless-stopped \
-p 1059:1059 \
-p 9159:9159 \
-v /var/log/ojp:/var/log/ojp \
-e JAVA_TOOL_OPTIONS="\
-Xmx4g \
-Xms2g \
-XX:+UseG1GC \
-XX:MaxGCPauseMillis=200 \
-XX:+HeapDumpOnOutOfMemoryError \
-XX:HeapDumpPath=/var/log/ojp/heapdump.hprof \
-Dfile.encoding=UTF-8 \
-Duser.timezone=UTC" \
-e OJP_SERVER_PORT=1059 \
-e OJP_PROMETHEUS_PORT=9159 \
-e OJP_SERVER_THREADPOOLSIZE=300 \
-e OJP_SERVER_LOGLEVEL=INFO \
-e OJP_SERVER_LOG_FILE=/var/log/ojp/server.log \
-e OJP_SERVER_LOG_MAXHISTORY=90 \
-e OJP_SERVER_ALLOWEDIPS="10.0.0.0/8" \
rrobetti/ojp:0.4.0-betaCreate a docker-compose.yml file:
version: '3.8'
services:
ojp-server:
image: rrobetti/ojp:0.4.0-beta
container_name: ojp-server
restart: unless-stopped
ports:
- "1059:1059"
- "9159:9159"
environment:
JAVA_TOOL_OPTIONS: >-
-Xmx4g
-Xms2g
-XX:+UseG1GC
-XX:MaxGCPauseMillis=200
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=/var/log/ojp/heapdump.hprof
-Dfile.encoding=UTF-8
-Duser.timezone=UTC
OJP_SERVER_PORT: 1059
OJP_PROMETHEUS_PORT: 9159
OJP_SERVER_THREADPOOLSIZE: 300
OJP_SERVER_LOGLEVEL: INFO
OJP_SERVER_LOG_FILE: /var/log/ojp/server.log
OJP_SERVER_LOG_MAXHISTORY: 90
OJP_SERVER_ALLOWEDIPS: "10.0.0.0/8"
volumes:
- ojp-logs:/var/log/ojp
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9159/metrics"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
volumes:
ojp-logs:
driver: localStart with:
docker-compose up -dMonitor container health:
# Check if container is running
docker ps | grep ojp-server
# View logs
docker logs ojp-server
# Check metrics endpoint
curl http://localhost:9159/metrics
# Follow logs in real-time
docker logs -f ojp-serverdocker run -d \
--name ojp-dev \
-p 1059:1059 \
-e JAVA_TOOL_OPTIONS="-Xmx1g -Xms512m -Duser.timezone=UTC" \
-e OJP_SERVER_LOGLEVEL=DEBUG \
rrobetti/ojp:0.4.0-betadocker run -d \
--name ojp-prod \
--restart unless-stopped \
-p 1059:1059 \
-p 9159:9159 \
-e JAVA_TOOL_OPTIONS="-Xmx16g -Xms8g -XX:+UseG1GC -Dfile.encoding=UTF-8 -Duser.timezone=America/New_York" \
-e OJP_SERVER_THREADPOOLSIZE=500 \
-e OJP_SERVER_LOGLEVEL=INFO \
-e OJP_SERVER_ALLOWEDIPS="10.0.0.0/8,172.16.0.0/12" \
rrobetti/ojp:0.4.0-betadocker run -d \
--name ojp-debug \
-p 1059:1059 \
-p 5005:5005 \
-e JAVA_TOOL_OPTIONS="-Duser.timezone=UTC -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005" \
-e OJP_SERVER_LOGLEVEL=DEBUG \
rrobetti/ojp:0.4.0-betaConnect your IDE debugger to localhost:5005.
For applications requiring low latency:
docker run -d \
--name ojp-lowlatency \
-p 1059:1059 \
-e JAVA_TOOL_OPTIONS="-Xmx8g -Xms8g -XX:+UseZGC -XX:+UnlockExperimentalVMOptions -Dfile.encoding=UTF-8 -Duser.timezone=UTC" \
-e OJP_SERVER_THREADPOOLSIZE=400 \
rrobetti/ojp:0.4.0-betaTo add proprietary JDBC drivers (Oracle, SQL Server, DB2), use a volume mount:
# Create libs directory and download open source drivers
mkdir -p ojp-libs
cd ojp-server
bash download-drivers.sh ../ojp-libs
cd ..
# Add proprietary drivers
cp ~/Downloads/ojdbc11.jar ojp-libs/
cp ~/Downloads/mssql-jdbc-12.jar ojp-libs/
# Run with volume mount
docker run -d \
--name ojp-custom \
-p 1059:1059 \
-v $(pwd)/ojp-libs:/opt/ojp/ojp-libs \
-e JAVA_TOOL_OPTIONS="-Xmx4g -Xms2g -Dfile.encoding=UTF-8 -Duser.timezone=UTC" \
rrobetti/ojp:0.4.0-betaCheck the container logs to confirm JVM parameters are picked up:
docker logs ojp-server 2>&1 | head -5You should see:
Picked up JAVA_TOOL_OPTIONS: -Xmx4g -Xms2g -Dfile.encoding=UTF-8 -Duser.timezone=UTC
# View memory usage
docker stats ojp-server
# Exec into container and check Java process
docker exec ojp-server ps aux | grep java- Check logs for errors:
docker logs ojp-server- Verify ports are available:
netstat -tuln | grep -E '1059|9159'- Test with minimal configuration:
docker run --rm rrobetti/ojp:0.4.0-betaIf you see OutOfMemoryError:
- Increase heap size:
-e JAVA_TOOL_OPTIONS="-Xmx8g -Xms4g"- Enable heap dumps for analysis:
-e JAVA_TOOL_OPTIONS="-Xmx4g -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp/heapdump.hprof"- Mount volume to preserve heap dump:
-v /host/path:/tmp- Enable GC logging:
-e JAVA_TOOL_OPTIONS="-Xmx4g -verbose:gc -Xlog:gc*:file=/var/log/ojp/gc.log"- Increase thread pool:
-e OJP_SERVER_THREADPOOLSIZE=500- Tune garbage collection:
-e JAVA_TOOL_OPTIONS="-Xmx4g -XX:+UseG1GC -XX:MaxGCPauseMillis=100"- OJP Server Configuration Guide - Complete configuration reference
- Kubernetes Deployment - Deploy to Kubernetes with Helm
- Driver Configuration - JDBC driver setup
- SSL/TLS Configuration - Certificate configuration
For issues or questions:
- GitHub Issues: https://github.com/Open-J-Proxy/ojp/issues
- Documentation: https://github.com/Open-J-Proxy/ojp/tree/main/documents