Skip to content

Deployment

Production topology

Use Apache as the public edge, PHP as the authorization/application layer, Tomcat as a private report engine, PostgreSQL for application/Central/report data, and systemd for schedules. Bind Tomcat port 9099 to loopback or firewall it from untrusted clients; direct /report access bypasses the PHP report ACL proxy.

Apache

installer.sh creates aliases for /jasper-report-service and /jasper-report-services, enables .htaccess, and proxies /report plus /acugis_report_image to localhost:9099.

deploy/apache-central-jasper.conf.example instead demonstrates a same-host Central/Jasper proxy:

  • /login and /logout → Central at 127.0.0.1:8888
  • /jasper-report-services/ → a PHP upstream at 127.0.0.1:9080
  • forwarded host/protocol information for shared cookies

It is an example fragment, not a complete virtual host. Adjust paths, ports, cookie scope, modules, and access controls.

The root .htaccess disables indexes, sets index.php, and rewrites /reports/<key> to the viewer. Apache must allow overrides and have mod_rewrite.

Nginx and reverse proxies

No Nginx configuration is checked in. An Nginx deployment must reproduce these verified requirements:

  • serve or pass the PHP tree at /jasper-report-services/;
  • preserve the acugis_session cookie and original host;
  • set X-Forwarded-Proto correctly at the TLS edge;
  • route Central /login and /logout consistently with CENTRAL_LOGIN_URL;
  • keep Tomcat internal and send client report traffic through reports/execute_report.php and report_image.php;
  • deny direct access to report JSON, generated context, schedule state, logs, and debug files.

If a proxy strips or adds a path prefix, test every generated discovery/viewer/thumbnail URL: this service has no general base-path configuration and several URLs are hardcoded to /jasper-report-services.

Docker and Compose

The current Compose file:

  • uses stock tomcat:9-jdk11;
  • publishes 9099:8080;
  • mounts reports, context.xml, WAR, and PostgreSQL JDBC 42.7.3;
  • has no database, PHP, Apache, scheduler, mail, network policy, restart policy, healthcheck, resource limits, secret management, or persistent named volume.

Start it from docker/report-server:

docker compose config
docker compose up -d

The Dockerfile is a separate build path using Tomcat 9 JDK 11 Temurin and downloaded JDBC 42.7.4. Compose does not reference it. DOCKER.md describes a stale config-volume design inconsistent with Compose; use the executable Compose definition as the source of truth and reconcile paths before production.

Scheduler host setup

Current hardcoded scheduler behavior requires:

  • writable source unit directory /opt/qcarta-jasper-service/systemd;
  • load directory /etc/systemd/system unless JRS_JASPER_SYSTEMD_SYSTEM_DIR changes it;
  • PHP exec() enabled;
  • sudo -n permission for systemctl, ln, rm, and test operations used by the service;
  • PHP CLI and application files accessible to www-data;
  • writable schedules/, schedules/logs/, and schedules/output/.

Example preparation:

install -d -o www-data -g www-data -m 0775 \
  /opt/qcarta-jasper-service/systemd \
  /path/to/qcarta-jasper-service/schedules

Create a narrowly scoped sudoers policy after reviewing every generated command. JRS_JASPER_SYSTEMD_USE_SUDO and JRS_JASPER_SYSTEMD_UNIT_DIR cannot currently override their hardcoded values.

Generated units are oneshot services running as www-data, with Persistent=true timers. Interval timers use OnBootSec and OnUnitActiveSec; calendar timers use OnCalendar. One-time timers are not automatically removed after execution.

The repository does not provide a systemd unit for Apache/PHP or Tomcat itself; only generated per-schedule units are present. Use the operating system's Apache/PHP units and either Compose or a separately authored, reviewed Tomcat unit.

Filesystem and backup

Persist and back up:

  • reports/json/
  • docker/report-server/reports/
  • assets/reports/
  • email_tmpl/
  • schedules/ if execution artifacts/history files are required
  • application and Central PostgreSQL databases

Generated context.xml and schedule EnvironmentFiles contain sensitive operational data. Set restrictive ownership/modes and exclude them from public/static serving and backup exports that lack encryption.

No output retention or cleanup exists; monitor disk consumption and define an external retention job. Deleting a schedule sets execution schedule_id to null but does not remove prior output/history rows.

Email

When JRS_SMTP_HOST is empty, PHP mail() is used. Otherwise the built-in client opens a raw socket and optionally uses AUTH LOGIN; it has no STARTTLS implementation. Prefer a local secured relay. Confirm attachment size limits and avoid storing sensitive report output longer than required.

Logging

Source Destination
PHP auth/resource/systemd/action errors PHP/Apache error log
Schedule application log schedules/logs/schedule-<id>.log
Generated systemd unit stdout/stderr Same schedule log via StandardOutput/Error=append:
Tomcat/WAR Container stdout/Tomcat servlet log
Execution status jasper_schedule_execution

Logs can contain report URLs, parameter values, recipient addresses, paths, errors, and stack traces. Apply access controls and rotation externally; no rotation configuration is supplied.

TLS, Nginx, health, and monitoring

  • No Nginx configuration is present.
  • No automated TLS certificate provisioning, redirect policy, cipher configuration, or complete TLS virtual host is present. The Apache example only forwards X-Forwarded-Proto when SSL is already configured.
  • No application health/readiness endpoint exists. /api/resource-sync GET is authenticated/admin-oriented and is not a safe health check; Tomcat has no Compose healthcheck.
  • No metrics, dashboards, alerts, tracing, or monitoring agent integration exists.

Implement these at the platform layer and test failure modes for PostgreSQL, Central, Tomcat, filesystem capacity, timers, and mail delivery.

Scaling

The PHP web tier is request-oriented and can run behind multiple Apache/PHP workers, but state is shared through PostgreSQL and a writable filesystem. Horizontal replicas therefore require shared or replicated report JSON/JRXML/assets and consistent config.php/Central settings. Do not let multiple replicas independently manage the same systemd timer files.

Tomcat can be scaled only if every instance receives the same reports and JNDI configuration and the proxy provides appropriate routing. Scheduled jobs have no distributed lock or queue, so running the same timer on multiple hosts can duplicate outputs and email. The source provides no load-balancer config, clustering, object storage, worker coordination, or autoscaling policy.

Production checklist

  • Rotate all committed credentials and remove public debug endpoints.
  • Configure explicit Central auth; do not permit local-development auth fallback.
  • Restrict Tomcat to trusted callers.
  • Reconcile Compose/Dockerfile/JDBC/report paths and pin deploy artifacts.
  • Apply and verify the schema; resolve scheduler-column mismatch.
  • Configure least-privilege PostgreSQL/JNDI users and filesystem permissions.
  • Configure Apache/TLS, headers, request/upload limits, and log rotation.
  • Establish backups, output retention, health checks, monitoring, and alerting.
  • Manually test ACLs, rendering, schedules, email, restore, and rollback.