Skip to main content

CMS and PHP Platforms

CloudForge deploys PHP content management, e-commerce, forum, CRM, wiki, LMS, and social platforms with the cms-service topology. Each platform is a CmsSpec implementation annotated with @CmsPlugin in cloudforge-api/src/main/java/com/cloudforgeci/api/application/cms/.

Quick start​

{
"cfc": {
"topology": "cms-service",
"applicationId": "wordpress",
"runtime": "fargate",
"env": "prod",
"domain": "example.com",
"subdomain": "blog",
"enableSsl": true,
"authMode": "alb-oidc"
}
}

The cms-service topology (CmsServiceTopologyConfiguration) reads the platform's CmsSpec capabilities and provisions, in addition to the usual container service and load balancer:

CapabilityProvisions
supportsS3MediaStorage()S3 media bucket
supportsCdnIntegration() (with S3 media)CloudFront distribution and DNS records, created once the load balancer exists
supportsObjectCache() with preferredCacheBackend() == "redis"ElastiCache Redis cluster
databaseRequirement()RDS instance
hasScheduledTasks() / cronCommands()System cron entries

Connection settings reach the container through each spec's databaseEnvVars() and redisEnvVars(), so a new platform only overrides those methods.

Platforms​

Port is 80 for every platform except phpBB (8080). Size is Fargate CPU units / memory MiB, followed by the default EC2 instance type.

IDNameCategoryPHPDefault imageSize
wordpressWordPresscms8.2wordpress:php8.2-apache1024 / 2048, t3.small
drupalDrupalcms8.2drupal:10-php8.2-apache1024 / 2048, t3.small
joomlaJoomlacms8.2joomla:5-php8.2-apache1024 / 2048, t3.small
typo3TYPO3cms8.2martinhelmich/typo3:122048 / 4096, t3.medium
concrete-cmsConcrete CMScms8.2php:8.2-apache1024 / 2048, t3.small
october-cmsOctober CMScms8.2php:8.2-apache1024 / 2048, t3.small
woocommerceWooCommerceecommerce8.2wordpress:php8.2-apache2048 / 4096, t3.medium
magentoMagento 2 / Adobe Commerceecommerce8.2magento/magento-cloud-docker-php:8.2-fpm4096 / 8192, t3.xlarge
prestashopPrestaShopecommerce8.1prestashop/prestashop:8-8.1-apache2048 / 4096, t3.medium
opencartOpenCartecommerce8.1vimagick/opencart:latest1024 / 2048, t3.small
syliusSyliusecommerce8.3sylius/standard:latest2048 / 4096, t3.medium
bagistoBagistoecommerce8.2php:8.2-apache2048 / 4096, t3.medium
phpbbphpBBforum8.2php:8.2-apache1024 / 2048, t3.small
flarumFlarumforum8.2php:8.2-apache1024 / 2048, t3.small
mybbMyBBforum8.2php:8.2-apache1024 / 2048, t3.small
suitecrmSuiteCRMcrm8.2bitnami/suitecrm:82048 / 4096, t3.medium
mediawikiMediaWikiwiki8.2mediawiki:1.421024 / 2048, t3.small
moodleMoodlelms8.2moodlehq/moodle-php-apache:8.22048 / 4096, t3.medium
dolphin-unaUNA (Dolphin)social8.2php:8.2-apache2048 / 4096, t3.medium

Override the image with containerImage and the size with cpu, memory, or instanceType.

Capabilities, databases, and authentication​

Every platform supports the Redis object cache. The default database engine is MySQL (8.0, or 5.7 where noted); databaseEngine can select another supported engine.

IDS3 mediaMultisiteDatabasesauthMode valuesOIDC method
wordpressyesyesmysql, mariadbapplication-oidc, alb-oidc, noneOpenID Connect Generic plugin
drupalyesyesmysql, mariadb, postgresqlapplication-oidc, alb-oidc, noneOpenID Connect module
joomlayesnomysql, mariadb, postgresqlapplication-oidc, alb-oidc, noneminiOrange OIDC plugin
typo3yesyesmysql, mariadb, postgresql, sqlitealb-oidc, none—
concrete-cmsyesyesmysql (5.7), mariadbalb-oidc, noneOAuth add-on / ALB OIDC
october-cmsyesyesmysql (5.7), mariadb, postgresql, sqlitealb-oidc, noneLaravel Socialite / OAuth plugin
woocommerceyesnomysql, mariadbapplication-oidc, alb-oidc, noneOpenID Connect Generic plugin
magentoyesyesmysql, mariadbapplication-oidc, alb-oidc, noneminiOrange OIDC module
prestashopyesyesmysql, mariadbapplication-oidc, alb-oidc, noneOAuth admin API module
opencartyesyesmysql, mariadbalb-oidc, noneOAuth extension / ALB OIDC
syliusyesyesmysql, mariadb, postgresqlalb-oidc, noneSymfony Security / OAuth2
bagistoyesyesmysql, mariadbalb-oidc, noneLaravel Socialite / Passport
phpbbnonomysql (5.7), mariadb, postgresql, sqlitealb-oidc, noneOAuth extension / ALB OIDC
flarumyesnomysql (5.7), mariadbalb-oidc, noneFoF OAuth extension / ALB OIDC
mybbnonomysql (5.7), mariadb, postgresql, sqlitealb-oidc, noneOAuth plugin / ALB OIDC
suitecrmnonomysql, mariadbalb-oidc, noneOAuth2 / LDAP / ALB OIDC
mediawikiyesyesmysql (5.7), mariadb, postgresql, sqlitealb-oidc, noneOpenID Connect extension (PluggableAuth)
moodleyesnomysql, mariadb, postgresqlapplication-oidc, alb-oidc, noneMicrosoft OIDC plugin
dolphin-unayesnomysql (5.7), mariadbalb-oidc, noneOAuth Connect app / ALB OIDC

With alb-oidc, only the paths returned by protectedPaths() require sign-in. For CMS platforms this defaults to cdnAdminPaths() (for example /wp-admin/* and /wp-login.php for WordPress, /administrator/* for Joomla), so the public site stays open.

CDN path routing​

CmsCdnConfiguration maps each platform's path groups to CloudFront behaviors:

MethodOriginCaching
cdnMediaPaths()S3 media bucket7-day default TTL
cdnStaticPaths()Load balancer1-day default TTL
cdnAdminPaths()Load balancer, all headers forwardedDisabled

Platform notes​

WordPress and WooCommerce​

  • WP-Cron is disabled (DISABLE_WP_CRON); a system cron entry requests wp-cron.php every 15 minutes.
  • CLI tool: WP-CLI (wp).
  • Multisite (WordPress only) defaults to subdirectory mode.
  • WooCommerce extends the WordPress spec with larger defaults.

Magento 2​

  • Defaults to a db.r6g.large RDS instance and t3.xlarge EC2 instances.
  • Requires OpenSearch or Elasticsearch for catalog search.
  • Declares system cron entries for its cron groups (index, consumers, ddg_automation). cronCommands() is keyed by schedule, so the default group, which shares the every-minute schedule with index, is not registered.
  • Uses separate Redis databases for cache, page cache, and sessions.

Drupal​

  • CLI tool: Drush.
  • /admin/*, /user/*, and /update.php bypass the CDN cache and are the alb-oidc protected paths.

Joomla​

  • /administrator/* bypasses the CDN cache and is the alb-oidc protected path.

Platforms that store or process payment data (WooCommerce, Magento, PrestaShop, and the other ecommerce platforms) should run with complianceFrameworks including pci-dss; see the PCI-DSS compliance guide.

Writing a CMS plugin​

cfc-testing/src/main/java/com/cloudforgeci/samples/plugins/cms/CraftCmsApplicationSpec.java is a complete external plugin (also published as cloudforge-sample). It shows a document root in a subdirectory (/var/www/html/web), a queue runner in cron, platform-specific environment variable names, and alb-oidc protection of /admin/* only.

A minimal plugin:

@CmsPlugin(
value = "my-cms",
category = "cms",
displayName = "My CMS",
description = "A custom CMS platform",
phpVersion = "8.2",
defaultCpu = 1024,
defaultMemory = 2048,
supportsOidc = true,
requiresDatabase = true,
supportsS3Media = true,
supportsObjectCache = true,
defaultImage = "my-org/my-cms:latest"
)
public class MyCmsApplicationSpec implements CmsSpec, DatabaseSpec {

@Override public String applicationId() { return "my-cms"; }
@Override public String defaultContainerImage() { return "my-org/my-cms:latest"; }
@Override public int applicationPort() { return 80; }
@Override public String containerDataPath() { return "/var/www/html"; }
@Override public String efsDataPath() { return "/my-cms"; }
@Override public String volumeName() { return "myCmsData"; }
@Override public String containerUser() { return "33:33"; }
@Override public String efsPermissions() { return "755"; }
@Override public String mediaUploadPath() { return "/var/www/html/uploads"; }
@Override public String phpVersion() { return "8.2"; }

@Override public List<String> cdnMediaPaths() { return List.of("/uploads/*"); }
@Override public List<String> cdnStaticPaths() { return List.of("/assets/*", "/themes/*"); }
@Override public List<String> cdnAdminPaths() { return List.of("/admin/*"); }

@Override
public Map<String, String> databaseEnvVars(String host, int port, String name, String user) {
return Map.of("DB_HOST", host, "DB_PORT", String.valueOf(port), "DB_NAME", name, "DB_USER", user);
}

@Override
public DatabaseRequirement databaseRequirement() {
return DatabaseRequirement.required("mysql", "8.0")
.withInstanceClass("db.t3.micro")
.withStorage(20)
.withDatabaseName("my_cms");
}
}

Register it in META-INF/services/com.cloudforge.core.interfaces.ApplicationSpec:

com.example.MyCmsApplicationSpec

and deploy with "topology": "cms-service", "applicationId": "my-cms".

Discovery API​

Map<String, CmsSpec> all = CmsLoader.discover();
List<CmsSpec> ecommerce = CmsLoader.discoverEcommerce();
List<CmsSpec> forums = CmsLoader.discoverForums();
List<CmsSpec> oidcReady = CmsLoader.discoverOidcEnabled();
List<CmsSpec> s3Ready = CmsLoader.discoverS3MediaSupported();
Optional<CmsSpec> wordpress = CmsLoader.findById("wordpress");
System.out.println(CmsLoader.printCatalog());

Compliance considerations​

Platform typeFrameworks to considerReason
E-commercepci-dss, soc2Payment data
CRM (SuiteCRM)gdpr, soc2Customer personal data
LMS (Moodle)gdprStudent records (FERPA also applies in the US but is not a built-in framework)
CMS, forum, wiki, socialsoc2, gdprUser accounts and content
{
"cfc": {
"securityProfile": "production",
"complianceFrameworks": "PCI-DSS,SOC2",
"complianceMode": "enforce"
}
}