Migration - Upgrades

How to Migrate ColdFusion Applications Without Downtime

Contents show

Why planning a Migration without downtime matters

Customers expect applications to be available at all hours. For ColdFusion-based systems that often power critical back-office processes, even short outages can translate to lost revenue, failed integrations, and support escalations. A no-downtime approach yields safer releases, smoother upgrades to newer Adobe ColdFusion or Lucee engines, and the ability to iterate faster. Techniques like blue-green deployments, canary releases, database expand-and-contract migrations, and shared session stores make it feasible to upgrade runtime, code, and Infrastructure while users continue working uninterrupted.


Prerequisites / Before You Start

  • Environment inventory and compatibility

    • List all ColdFusion servers, OS versions, web servers (IIS/Apache/Nginx), application servers (Tomcat), JVM build, CFML engine (Adobe ColdFusion 2016/2018/2021/2023 or Lucee).
    • Note installed ColdFusion modules/packages (using cfpm on CF2021/2023), hotfix levels, and third-party libraries (JDBC drivers, custom JARs in lib/ or classpath).
    • Document Scheduled tasks, cfthread usage, event gateways, ColdFusion Administrator settings, datasources, mail servers, mappings, and Security sandboxes.
  • Backups and Disaster recovery

    • Full database backups and tested point-in-time restore.
    • File storage backups (uploaded assets, generated reports, image transforms).
    • Export ColdFusion Administrator Configuration:
      • Adobe CF 2018+: PMT settings and Admin config.
      • Adobe CF 2021/2023: cfsetup export and cfpm package list.
    • Export web server/IIS/Apache/Nginx config and connector settings (wsconfig).
  • Environment parity

    • Provision a separate “green” environment mirroring production: same CPU/memory, JVM version and options, OS locales/timezone, SSL/TLS certificates, cipher suites, firewall openings, and load balancer/Health check behavior.
    • Network access to databases, Redis/Memcached, SMTP, S3/Blob storage, Message queues, SFTP.
  • Access and credentials

    • Secrets stored in a secure system (Vault/Key Vault/Secrets Manager) and injected via environment variables or per-environment config files. Avoid hard-coding in Application.cfc.
    • Administrative access for load balancer, DNS, and web server connector changes.
  • Tooling and Automation

    • CI/CD pipeline (Jenkins, GitHub Actions, GitLab CI, Azure DevOps) capable of building CFML artifacts, running tests, and promoting releases.
    • Observability stack: logs (ELK/Datadog/Splunk), metrics (Prometheus, CloudWatch), APM (FusionReactor, New Relic, AppDynamics), synthetic monitoring.
    • Feature flagging system (LaunchDarkly, Unleash, or a simple DB/config toggle).
  • Communication and change control

    • Stakeholder alignment, Maintenance window fallback plan, and rollback criteria.
    • Incident Playbook with clear on-call ownership.

Migration strategy Overview

Blue-green vs. canary vs. rolling

Strategy Downtime Complexity Typical Use
Blue-green None Medium Full-stack switch of runtime + code with instant rollback
Canary release None High Gradual traffic shift to new version for confidence building
Rolling restart Low/None Medium In-place upgrade across a cluster node by node
  • For most ColdFusion upgrades across runtime or OS, Blue-Green Deployment is the safest, with the option to add a canary phase to reduce risk.
See also  How to Test Performance Before and After Migration

Session strategy

  • Use sticky sessions at the load balancer, or better, move to a shared session store such as Redis to allow truly stateless app nodes.
  • ColdFusion built-in J2EE Session replication is possible but adds complexity and overhead.
  • Avoid storing large objects in session. Prefer a compact identifier that fetches state from a cache or DB.

Database migration approach

  • Adopt an expand-and-contract migration:
    • Expand phase: add new tables/columns/indices in a backward-compatible manner.
    • Update code to read/write both old and new structures (behind feature flags).
    • Contract phase: remove legacy columns/paths after confidence is achieved.
  • Keep schema and code backward compatible during the transition to enable instant rollback.

Step-by-Step Migration guide

1) Build a parallel “green” environment

  • Provision servers/containers that mirror production.
  • Clone the web tier, application tier, and configure a separate or shared database depending on your strategy (shared DB is common with backward-compatible changes).
  • Ensure TLS certificates and ciphers match production.

2) Install the ColdFusion engine and packages

  • Install Adobe ColdFusion (2021/2023) or Lucee in the green environment.
  • For Adobe CF 2021/2023, use cfpm to install required modules:

list modules

cfpm list

install needed packages

cfpm install pdfg charting orm aws s3 azuregcp

  • Apply the same hotfix level as tested in lower environments.
  • Verify JVM version and jvm.config settings (heap, GC, metaspace):

Example JVM options in jvm.config

-Xms4g
-Xmx4g
-XX:+UseG1GC
-Dfile.encoding=UTF-8
-Duser.timezone=UTC

3) Configure connectors and the web server

  • Use wsconfig to connect CF to IIS/Apache:

Windows (IIS)

wsconfig.exe -install -ws iis -siteid:1

Linux (Apache)

wsconfig.sh -install -ws Apache -dir /etc/httpd/conf -bin /usr/sbin/httpd

  • Validate AJP/HTTP proxy settings, request size limits, and secure headers.
  • Ensure identical rewrite rules between blue and green.

4) Migrate ColdFusion Administrator Configuration

  • Adobe CF 2021/2023: export from current and import to green with cfsetup:

On old environment

cfsetup export -o cfadmin-export.json

On green environment

cfsetup import -f cfadmin-export.json

  • Alternatively, use the ColdFusion Admin API to script DSNs, mappings, and mail settings.

cfm



adminObj = createObject(“component”,”cfide.adminapi.administrator”);
adminObj.login(“yourAdminPassword”);

ds = createObject(“component”,”cfide.adminapi.datasource”);
ds.setMSSQL(
name=”AppDSN”,
host=”db.prod.local”,
database=”appdb”,
port=”1433″,
username=”appuser”,
password=”securepass”,
sendStringParametersAsUnicode=true,
selectMethod=”direct”,
blobBuffer=2048
);

  • Confirm mail servers, sandboxes, Security settings, and Debugging are production-appropriate (disable debug output).

5) Sync application artifacts and dependencies

  • Deploy the CFML codebase (CFCs, CFMs, libraries).
  • Ensure third-party JARs are aligned with the target engine.
  • Verify Application.cfc settings, including sessionManagement, this.mappings, and this.datasource.

cfm
component {
this.name = “MyApp”;
this.sessionManagement = true;
this.sessionTimeout = createTimeSpan(0,0,30,0);
this.loginStorage = “session”;
this.javaSettings = { loadPaths = [“/opt/coldfusion/customlib”] };
}

6) Implement a shared session store or confirm sticky sessions

  • For shared sessions, integrate Redis/Memcached via a session manager (Tomcat valve or CF extension). Example Tomcat context snippet:



  • If using sticky sessions, confirm LB affinity cookie configuration and failover behavior.

7) Create health and readiness endpoints

cfm






SELECT 1 AS ok




ok


fail

  • Configure the load balancer to use readiness for routing and liveness for instance health.

8) Prepare the database: expand phase

  • Add new columns/tables with default-safe behavior, avoid destructive changes:

sql
ALTER TABLE orders ADD column ext_ref VARCHAR(64) NULL;
CREATE INDEX ix_orders_ext_ref ON orders (ext_ref);

— For type changes, add new column instead of altering in place:
ALTER TABLE users ADD column phone_e164 VARCHAR(20);

  • Deploy code that can handle both old and new schema. Use feature flags for toggling behavior:

cfm

<cfif useNewPhone AND structKeyExists(user, “phone_e164”)>

See also  How to Upgrade ColdFusion from Version 10 to 2023




  • Run data backfill as an idempotent job (queue-based or batched SQL). Throttle to avoid impacting production.

9) Warm up caches and Scheduled tasks

  • Precompile CFML templates if applicable.
  • Warm caches by exercising key routes or invoking services:

curl -s https://green.example.com/health.cfm
curl -s https://green.example.com/warmup/cache/topProducts

  • Disable scheduled tasks on blue or green to avoid duplication. Prefer an environment variable gate:

cfm
<cfif structKeyExists(server.system.environment, “RUN_SCHEDULED_TASKS”) AND
server.system.environment.RUN_SCHEDULED_TASKS EQ “true”>


10) Canary release via load balancer

  • Route a small percentage (1–5%) of production traffic to green.

Example HAProxy snippet:

backend app
balance roundrobin
server blue1 10.0.0.10:8500 check
server blue2 10.0.0.11:8500 check
server green1 10.0.1.10:8500 check weight 1
server green2 10.0.1.11:8500 check weight 1

  • Alternatively, use header-based routing for internal testers only:

acl is_canary hdr(User-Agent) -m sub QA
use-server green1 if is_canary

  • Monitor error rates, latency, CPU, GC, and thread pools via FusionReactor/APM.

11) Blue-green switch

  • Increase green to 100% gradually or in one step, depending on confidence.
  • Keep blue running for fast rollback. Do not drop Backward compatibility yet.
  • Validate functional flows (login, checkout, APIs, file uploads) against green.

12) Contract phase and decommissioning

  • After a stable period, remove legacy DB columns, remove dual-write code paths, and simplify flags:

sql
ALTER TABLE users DROP COLUMN phone;

  • De-register blue from the load balancer, remove connectors, and archive logs/configs according to retention policy.

Risks, Common Issues, and How to Avoid Them

  • Connector mismatches

    • Risk: Incompatible web server connector (wsconfig) or outdated AJP configs cause 500/502 errors.
    • Mitigation: Rebuild connectors with the target ColdFusion; use the same connector version across nodes.
  • Datasource and JDBC driver differences

    • Risk: SQL behavior changes (e.g., null handling, date/time parsing) between old and new drivers.
    • Mitigation: Pin JDBC driver versions tested in staging; add Integration tests for queries; set connection string params consistently (e.g., sendStringParametersAsUnicode, time zone).
  • Character encoding and locale

    • Risk: Shift to UTF-8 or different default encodings breaks string comparisons or data imports.
    • Mitigation: Force UTF-8 in JVM and CF Admin; verify DB collations; test exports/imports.
  • Session loss

    • Risk: Users are logged out during cutover.
    • Mitigation: Use sticky sessions or shared session store; don’t rotate encryption keys or session cookie names mid-flight.
  • Long-running requests/jobs

    • Risk: In-flight report generation or bulk tasks are killed on switch-over.
    • Mitigation: Implement graceful drain. Disable new heavy jobs on blue; watch request queues and wait for completion.
  • Scheduled tasks duplication

    • Risk: Jobs run twice on blue and green.
    • Mitigation: Single-writer strategy via environment flag or distributed lock (e.g., Redis-based lock).
  • File storage inconsistency

    • Risk: User-uploaded files get split across nodes or environments.
    • Mitigation: Centralize to shared storage (NAS/S3) and ensure paths/ACLs are identical.
  • Licensing and activation

    • Risk: Adobe ColdFusion license activation issues when Scaling nodes.
    • Mitigation: Validate entitlements, keep license keys secure, pre-activate green nodes before canary.
  • TLS and cipher suite drift

    • Risk: Clients fail to connect due to stricter ciphers.
    • Mitigation: Mirror TLS configuration; test with SSL Labs and client integrations.
  • Time zone and scheduling differences

    • Risk: Jobs at midnight shift due to TZ differences or DST.
    • Mitigation: Standardize on UTC, make TZ explicit in JVM and database.

Post-Migration Checklist / Validation Steps

  • Application functionality

    • Login/auth flows including SSO/SAML/OAuth.
    • CRUD operations on key entities.
    • File uploads/downloads, image generation, PDF generation.
    • Email sending, SMS, and external API integrations.
    • Scheduled tasks running only on intended node(s).
  • Performance and stability

    • Compare p50/p95 latency and error rates to Pre-migration baselines.
    • Check JVM heap, GC pause times, thread pool utilization.
    • Verify connection pool metrics for each datasource.
  • Data integrity

    • Verify dual-write/dual-read behavior if used; spot-check migrated columns.
    • Reconcile counts between old and new tables/indices.
    • Confirm no duplicate jobs or records.
  • Sessions and Authentication

    • Track active sessions across cutover; confirm no spike in logouts.
    • Validate session cookie attributes (HttpOnly, Secure, SameSite).
  • Logging and monitoring

    • Ensure logs are flowing to central store with correct parsing.
    • APM traces show healthy throughput and no anomalous errors.
    • Synthetic checks passing from multiple regions.
  • Security and Compliance

    • Confirm HTTPS everywhere, HSTS, CSP, and secure headers are intact.
    • Validate firewall rules and WAF allowlists/denylists.
    • Confirm PII redaction and log sanitization still active.
  • Decommissioning and cleanup

    • Remove legacy feature flags once safe.
    • Archive blue environment configs and shut down resources to reduce cost.
See also  How to Migrate ColdFusion Code to CFScript Syntax

Practical configuration snippets

Example Nginx blue-green switch

upstream app_pool {
server 10.0.0.10:8500 max_fails=3 fail_timeout=10s; # blue
server 10.0.1.10:8500 max_fails=3 fail_timeout=10s backup; # green
}

server {
listen 443 ssl http2;
server_name app.example.com;

location / {
proxy_pass http://app_pool;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto https;
proxy_read_timeout 120s;
proxy_connect_timeout 10s;
}

location /health.cfm {
proxy_pass http://10.0.1.10:8500; # test green health explicitly
}
}

Feature toggle stored in environment variable

cfm
<cfset application.flags = {
useNewPhoneField = (server.system.environment.USE_NEW_PHONE ?: “false”) == “true”
} />

Rolling back instantly

  • Set LB weights back to blue.
  • Keep DB expand changes in place; do not perform destructive contract steps until stability is proven.

Tips for special scenarios

Migrating to containers or Kubernetes

  • Bake CF runtime and app into images; externalize Admin config via cfsetup/cfpm at build or boot time.
  • Use readiness/liveness probes for rolling updates.
  • Mount secrets via KMS/Secrets Manager; mount shared storage for user files.

Migrating Adobe ColdFusion to Lucee

  • Audit CFML compatibility: some enterprise Features differ (PDFG, SAML, SOLR).
  • Replace proprietary tags/functions where needed, test ORM/Hibernate behavior and mail handling.
  • Revalidate Licensing and cost assumptions; Performance test thoroughly.

Upgrading with Legacy code

  • Put brittle areas behind strangler fig proxies and upgrade piece by piece.
  • Add automated Integration tests around the riskiest modules before migration.

Minimal runbook summary

  1. Build green identical to prod; install CF and packages.
  2. Import Admin settings; configure connectors.
  3. Configure sessions (sticky or shared).
  4. Expand DB schema; dual-read/write behind flags.
  5. Warm caches; set up health endpoints.
  6. Canary 1–5%; monitor.
  7. Switch 100% to green; keep blue ready to roll back.
  8. Contract DB and remove old code once stable.

FAQ

Puis-je migrer de ColdFusion 11/2016 vers 2023 directement sans étape intermédiaire ?

Yes, many teams perform a direct jump, but you must validate compatibility. Review removed/deprecated Features, test JDBC driver changes, and refit any CFML tags that changed semantics. Use a representative staging environment, run cfpm to align modules, and plan a blue-green cutover so rollback is instant if surprises appear.

Comment gérer les sessions utilisateurs lors d’un déploiement blue‑green ?

Either enable sticky sessions at the load balancer or move sessions to a shared store like Redis. Sticky sessions are simplest but limit failover. A shared session store enables true zero-downtime switchovers and rolling restarts. Avoid changing encryption keys or cookie names during the cutover.

Faut-il migrer vers Lucee au lieu d’Adobe ColdFusion pour réduire les coûts ?

It depends. Lucee can reduce licensing cost and performs well, but some enterprise features differ or require alternatives (e.g., PDF generation, SAML, SOLR, Admin APIs). Conduct a gap analysis, proof-of-concept, and performance tests. If parity is achievable and your team is comfortable with Community support, Lucee can be a good fit.

Quelle est la meilleure stratégie pour les migrations de base de données sans interruption ?

Use expand-and-contract: add new structures first, deploy code that reads/writes both versions under a feature flag, backfill data, then switch reads to the new structure. Only after confidence do you remove legacy columns. This supports instant rollback and avoids long blocking schema changes.

Comment tester la compatibilité des anciennes balises CFML et des composants CFC ?

Build automated tests that exercise critical tags/functions and CFC methods. Run them on both old and new engines. Pay attention to differences in date/time handling, query-of-queries, ORM, mail, and PDF operations. Use static analysis (cfparser/CommandBox tools) to flag deprecated constructs and run integration tests in a staging environment connected to production-like data.

About the author

Aaron Longnion

Aaron Longnion

Hey there! I'm Aaron Longnion — an Internet technologist, web software engineer, and ColdFusion expert with more than 24 years of experience. Over the years, I've had the privilege of working with some of the most exciting and fast-growing companies out there, including lynda.com, HomeAway, landsofamerica.com (CoStar Group), and Adobe.com.

I'm a full-stack developer at heart, but what really drives me is designing and building internet architectures that are highly scalable, cost-effective, and fault-tolerant — solutions built to handle rapid growth and stay ahead of the curve.