Update: 🍻 apnscp 3.0 beta has been released. Release notes.

apnscp 3.0 alpha has been released, which is the first public release. A public support forum has been launched as well, forums.apnscp.com, powered by Discourse; Discourse will be included in an interim update before 3.0 beta is released at the end of September.

Refer to pre-alpha TR announcement for installation + tutorial

A new public licensing server is available, which arms servers with a renewable 60-day license. License may be renewed an unlimited amount until 3.0 final launches in November. Likewise fully functional trial accounts may be run using the apnscp Bootstrap Utility:

curl https://raw.githubusercontent.com/apisnetworks/apnscp-bootstrapper/master/bootstrap.sh | bash
SHA2: cf2bf6521775f6ff0de1608b0e4d34c34a75385ee57442d7c13b66ebcdf9cc81

Domain/username/db prefix changes have been resumed in the panel as well (Account > Settings or EditDomain -c siteinfo,domain=XXX -c siteinfo,admin_user=YYY -c mysql,dbaseprefix=ZZZ). mysql/pgsql/users are now optional services too, as well as shell assignment, which can optionally be used to disallow logins, but still allow su by the account admin, by setting the shell to /bin/false.

Bootstrap 4.0.0 alpha -> 4.1 will take a considerable amount of work to verify transition. Until then, accept this interim theme which softens up colors:

Upgrade instructions

Upgrading from pre-alpha to alpha consists of three commands:

cd /usr/local/apnscp
upcp -a
./artisan migrate --force

Server integrity will be brought up to speed with alpha changes. A database migration is necessary to take advantage of platform migration support discussed later.

Scheduled changes alpha -> beta

  • ipset support for Rampart
  • AWS DNS provider - module info
  • Discourse web app
  • Bootstrap 4.0.0 alpha -> 4.0 official
  • Documentation
  • Unit tests

config driver

alpha introduces a new configuration module, aptly named config, which simplifies system configuration. For example, net.hostname changes the system hostname and reissues a Let's Encrypt certificate. system.timezone changes your active timezone.

A full list of supported directives can be found with config_list,

cpcmd config_list

Brotli compression

Brotli compression has been added to apnscp. Brotli can further compress files an additional 15-20% with minimal performance impact. It's still experimental, but based upon usage data is stable. You can enable Brotli with config_set,

cpcmd config_set apache.brotli 1

Audit support

An important paradigm in apnscp is that PHP always runs as a separate user, because security is good and hacked sites are bad. A variety of enforcement policies exist to enrich performance while minimizing exposed vectors. One of these is that PHP will never run as an established account user. Doing so ensures that in the event of a hack, much to the chagrin of the Panama Papers breach, your personal data - email, ssh keys, miscellaneous data - is safe.

Separating users also creates an interesting audit trail. Files created by a PHP application have a different UID than the account holder that cannot be changed except by the account admin (Files > File Manager, file_takeover_user(), or file_chown()). So long as the creator UID is retained, file_audit() is your new best friend. It's also available under Web > Web Apps.

Subordinate logins

Appliance Admin may login to individual accounts via Nexus and likewise Site Administrators may log into user accounts via User > Manage Users. Doing so will bypass any login alerts that are configured for the account.


Platform migrations

Laravel now supports lightweight platform migrations, which tie into the apnscp playbooks as a faster alternative to  Bootstrapper. You can still validate server integrity with upcp -b or upcp -a. upcp will now run artisan migrate, which migrates both database schema and platform playbooks.


  • REL: apnscp 3.0 alpha
  • NEW: admin settings
  • NEW: system.apnscp-restart command
  • NEW: platform migration support
  • NEW: secondary user login-as support (Users)
  • NEW: define subdomain owner (Subdomains)
  • NEW: assign shell, random password to user (Add User)
  • NEW: [auth] => retain_ui_password, store UI password for webmail SSO login (config)
  • NEW: Vultr DNS provider
  • NEW: improve module dependency tracking
  • NEW: Audit support (Web Apps)
  • NEW: ASN.1 parser (Opcenter\License)
  • NEW: automated license renewals (Opcenter\License)
  • NEW: Brotli compression support (Opcenter\Admin\Settings)
  • NEW: quoted()- value is represented in quotes. Allows proper usage of sysconfig files (Map)
  • NEW: -b|--bootstrap, run bootstrapper after panel update (upcp)
  • NEW: --all option, force a reconfiguration on all services (EditDomain)
  • NEW: array support (Nexus)
  • FIX: inheritence (Console\Commands\PlatformRollback)
  • FIX: force session as array (apnscpSession)
  • FIX: prefer cur/, but accept new/ on site creation (Module Skeleton)
  • FIX: sync preferences before impersonating user (ImpersonableTrait)
  • FIX: empty gecos translates incorrectly to "''" (Opcenter\Role\User)
  • FIX: namespace styling (Lararia)
  • FIX: path()- dangling forward slash (Lararia\Application)
  • FIX: failed event erroneously reports subsequent event as cause (Service\Validators)
  • FIX: ignore empty packages (Yum Synchronizer)
  • FIX: relocated GMail provider (DNS)
  • FIX: \b cannot match on start (Opcenter\Admin\Apache)
  • FIX: set()- removing multiple cache states fails (Opcenter\Settings\Apache)
  • FIX: bypass notification for admin if email not set (Login)
  • FIX: ServiceReconfiguration + ServiceInstall + AlwaysValidate case unreachable (Opcenter\ConfigurationContext)
  • FIX: popd leaves APNSCP_HOME early (upcp)
  • FIX: unintended leakage- requesting password reset as non-secondary user results in fatal() instead of non-descript success (login)
  • FIX: respect OPTIONS representation in /etc/sysconfig/httpd (Opcenter\Admin\Settings)
  • FIX: gracefully handle invalid option (Opcenter\Admin\Settings)
  • FIX: pending postback lost (Page Container)
  • FIX: ensure site_id removed before AddDomain completes if failed (Validators\Siteinfo)
  • FIX: always set dbaseadmin on creation (Validators\Mysql)
  • FIX: hasNew() always returns true (ConfigurationContext)
  • FIX: update email in siteinfo on siteinfo,email change (Opcenter\Service)
  • FIX: force octal (Cgroup\Permissions)
  • FIX: hasChange()- check old/new service value instead enabled service var (ServiceValidator)
  • FIX: template load fails if page explicitly requested with .php (Page Container)
  • FIX: strict typing (Lararia)
  • FIX: button rename (Nexus)
  • FIX: strict typing (Auth)
  • FIX: in headless mode don't reload frontend on certificate reissuance
  • CHG: check if zone exists before altering IP (Transfer)
  • CHG: automatically run migrate (upcp)
  • CHG: add release annotation (changelogparser)
  • CHG: snake case configuration vars (config)
  • CHG: validate zone exists before attempting DNS record modifications (dns)
  • CHG: common_set_timezone() for admin sets system timezone (common)
  • CHG: add release annotation (changelogparser)
  • CHG: intelligent session deserialization (apnscpSession)
  • CHG: horizon:terminate to kill (Lararia\JobDaemon)
  • CHG: clear dirty flag on sync. Add sync() to immediately update preferences (Preferences)
  • CHG: default web app ownership to docroot stat (Web Apps)
  • CHG: strict session id/Auth::profile() matching (Module Skeleton)
  • CHG: drop proclimit back to 25 (plans/skeleton)
  • CHG: update apnscp theme
  • CHG: rename app_path() to webapp_path(), conflict with app_path used by Artisan (helpers)
  • CHG: tolerate map check if map value matches (Service\Validators\GenericDomainMap)
  • CHG: support class property, string representation as AXFR line (Opcenter\Dns\Record)
  • CHG: [mail] => providers, [dns] => providers native type array (config.ini)
  • CHG: -a flag, refer to hierarchy instead of parent to determine whether Bootstrapper runs (upcp)
  • CHG: follow redirects, validate hostname contained in redirect. Use UUID instead of time. (letsencrypt)
  • CHG: reset Auth_Info_User/Auth_Info_Account on wakeup (Module Skeleton)
  • CHG: get_service_value() must query cur/ per documentation (Module Skeleton)
  • CHG: mirror()- skip mirror if uid matches (Opcenter\Role\User)
  • CHG: force all modules depend on siteinfo
  • CHG: secondary sort on path (Web Apps)
  • CHG: detect older versions of Magento (Webapps)
  • CHG: get_aliases()- strip trailing slash off domains (aliases)
  • CHG: unit semantic positioning (templates/plans)
  • CHG: update themes
  • CHG: early init Laravel cache in case boot() requires configuration before .env sourced (ApplicationWrapper)
  • CHG: stringent afi verification (Preferences)
  • CHG: unnecessary reconfiguration firing (Opcenter\Service\Diskquota, Dbaseadmin)
  • CHG: convert static validation marker to property. Never use getInstance() in backend. (Preferences)
  • CHG: additional assertion that reported path matches docroot configured for webapp path. Workaround for older relocatable webapps that left behind the previous path (Webapps)
  • CHG: serviceValueChanged()- expand test to service class (Opcenter\Service)
  • CHG: Web App enhancements. Show "installing" during installation. Allow refresh without form submission after installation (Web Apps)
  • CHG: add spare worker (httpd.conf)
  • CHG: include exception type (Error Reporter)
  • CHG: workaround for root controller which can report limit_in_bytes >= usage_in_bytes >= max_usage_in_bytes (Opcenter\System)
  • CHG: set success after authentication confirmed (Opcenter\Create)
  • CHG: move intellisense constants to compile-time (Util_Completion)
  • CHG: mproxy removed (constants)
  • CHG: constants compile time instead of runtime (constants)
  • CHG: ignore patch level when determining service compatibility (Service\Validators)
  • CHG: semantic versioning (config.ini)
  • CHG: recursive_ns as array (config.ini)
  • CHG: merge_buffer()- check if buffer is sensible (Error_Reporter)
  • CHG: @TODO context created before session initialized (apnscpd)
  • CHG: redirect to Nexus portal on addition (Nexus)
  • CHG: create session when SID generated (apnscpSession)
  • CHG: flush auth profile on id change (apnscpd)
  • CHG: enable fortification (laravel)
  • CHG: set default rc to failure (Opcenter\Account)
  • CHG: accept --force (Opcenter\Account\Delete)
  • CHG: call reconfigure/rollback on ServiceInstall validators if the value changed on edit is not 0 or 1, as with enabled  (ConfigurationContext)
  • CHG: lock /etc/site_id at shutdown (Opcenter\Validators\Siteinfo)
  • CHG: -a|--auto, automatically run bootstrapper if playbooks have changed (upcp)
  • CHG: use contextable interface to reset password (Login)
  • CHG: increase upper limit for qualified TLD to 16 chars (Regex)
  • CHG: cleanup password reset (Login)
  • CHG: Util_Process() workaround for -1 return code in SAPI (Login)
  • CHG: rename filter() to INI-appropriate section() (Opcenter\Map)
  • CHG: 404 soap URI, unlink WSDL if SOAP disabled (Auth::SOAP)
  • CHG: implement change domain support for v7.5+ platforms (Opcenter)
  • CHG: attempt to stop frontend
  • CHG: AlwaysValidate calls reconfigure on more frequently (Opcenter\ConfigurationContext)
  • CHG: add PTR support (Opcenter\Dns\Linode)
  • CHG: move Gmail to remote repo (Opcenter\Mail)
  • CHG: update Linode DNS provider
  • CHG: refactor provider location
  • CHG: render Record as array on var_dump/var_export (Opcenter\Dns)
  • CHG: fail-safe, apply php_value directives only when PHP module loaded (templates/apache)
  • CHG: composer path
  • CHG: dups fix (php.ini)
  • CHG: expand * cgroup controller to all available controllers, workaround for cgrules.conf that queries all known controllers when * is provided (cgroup)
  • CHG: forceValidation(), require revalidation of service regardless of AlwaysValidate presence (ServiceValidator)
  • CHG: treat '' as null (Nexus)
  • CHG: defer enumerating all processes for admin (Dashboard)
  • REM: fallthrough domains from Web Apps, SSL Certificates
  • REM: DB map type for older platforms. Default to APR (Apache\Map)
  • REM: reset_password helper scripts, superceded by contextables (Login)
  • REM: unnecessary warnings during account creation