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:
/loginand/logout→ Central at127.0.0.1:8888/jasper-report-services/→ a PHP upstream at127.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_sessioncookie and original host; - set
X-Forwarded-Protocorrectly at the TLS edge; - route Central
/loginand/logoutconsistently withCENTRAL_LOGIN_URL; - keep Tomcat internal and send client report traffic through
reports/execute_report.phpandreport_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 JDBC42.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:
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/systemunlessJRS_JASPER_SYSTEMD_SYSTEM_DIRchanges it; - PHP
exec()enabled; sudo -npermission forsystemctl,ln,rm, andtestoperations used by the service;- PHP CLI and application files accessible to
www-data; - writable
schedules/,schedules/logs/, andschedules/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-Protowhen SSL is already configured. - No application health/readiness endpoint exists.
/api/resource-syncGET 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.