# Aptible

## Docs

- [Custom Certificate](https://aptible.com/docs/core-concepts/apps/connecting-to-apps/app-endpoints/custom-certificate)
- [Custom Domain](https://aptible.com/docs/core-concepts/apps/connecting-to-apps/app-endpoints/custom-domain): Learn about setting up endpoints with custom domains
- [Default Domain](https://aptible.com/docs/core-concepts/apps/connecting-to-apps/app-endpoints/default-domain)
- [gRPC Endpoints](https://aptible.com/docs/core-concepts/apps/connecting-to-apps/app-endpoints/grpc-endpoints)
- [ALB vs. ELB Endpoints](https://aptible.com/docs/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/alb-elb)
- [Endpoint Logs](https://aptible.com/docs/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/endpoint-logs)
- [Health Checks](https://aptible.com/docs/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/health-checks)
- [HTTP Request Headers](https://aptible.com/docs/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/http-request-headers)
- [HTTPS Protocols](https://aptible.com/docs/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/https-protocols)
- [HTTPS Redirect](https://aptible.com/docs/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/https-redirect)
- [Maintenance Page](https://aptible.com/docs/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/maintenance-page)
- [HTTP(S) Endpoints](https://aptible.com/docs/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/overview)
- [IP Filtering](https://aptible.com/docs/core-concepts/apps/connecting-to-apps/app-endpoints/ip-filtering)
- [Managed TLS](https://aptible.com/docs/core-concepts/apps/connecting-to-apps/app-endpoints/managed-tls)
- [App Endpoints](https://aptible.com/docs/core-concepts/apps/connecting-to-apps/app-endpoints/overview)
- [TCP Endpoints](https://aptible.com/docs/core-concepts/apps/connecting-to-apps/app-endpoints/tcp-endpoints)
- [TLS Endpoints](https://aptible.com/docs/core-concepts/apps/connecting-to-apps/app-endpoints/tls-endpoints)
- [Outbound IP Addresses](https://aptible.com/docs/core-concepts/apps/connecting-to-apps/outbound-ips): Learn about using outbound IP addresses to create an allowlist
- [Connecting to Apps](https://aptible.com/docs/core-concepts/apps/connecting-to-apps/overview): Learn how to connect to your Aptible Apps
- [Ephemeral SSH Sessions](https://aptible.com/docs/core-concepts/apps/connecting-to-apps/ssh-sessions): Learn about using Ephemeral SSH sessions on Aptible
- [Configuration](https://aptible.com/docs/core-concepts/apps/deploying-apps/configuration): Learn about how configuration variables provide persistent environment variables for your app's containers, simplifying settings management
- [Companion Git Repository](https://aptible.com/docs/core-concepts/apps/deploying-apps/image/deploying-with-docker-image/companion-git-repository)
- [Deploying with Docker Image](https://aptible.com/docs/core-concepts/apps/deploying-apps/image/deploying-with-docker-image/overview): Learn about the deployment method for the most control: deploying via Docker Image
- [Procfiles and  `.aptible.yml`](https://aptible.com/docs/core-concepts/apps/deploying-apps/image/deploying-with-docker-image/procfile-aptible-yml-direct-docker-deploy)
- [Docker Build](https://aptible.com/docs/core-concepts/apps/deploying-apps/image/deploying-with-git/build)
- [Deploying with Git](https://aptible.com/docs/core-concepts/apps/deploying-apps/image/deploying-with-git/overview): Learn about the easiest deployment method to get started: deploying via Git Push
- [Image](https://aptible.com/docs/core-concepts/apps/deploying-apps/image/overview): Learn about deploying Docker images on Aptible
- [Linking Apps to Sources](https://aptible.com/docs/core-concepts/apps/deploying-apps/linking-apps-to-sources)
- [Deploying Apps](https://aptible.com/docs/core-concepts/apps/deploying-apps/overview): Learn about the components involved in deploying an Aptible app in seconds: images, services, and configurations
- [.aptible.yml](https://aptible.com/docs/core-concepts/apps/deploying-apps/releases/aptible-yml)
- [Releases](https://aptible.com/docs/core-concepts/apps/deploying-apps/releases/overview)
- [Services](https://aptible.com/docs/core-concepts/apps/deploying-apps/services)
- [Managing Apps](https://aptible.com/docs/core-concepts/apps/managing-apps): Learn how to manage Aptible Apps
- [Apps - Overview](https://aptible.com/docs/core-concepts/apps/overview)
- [Container Recovery](https://aptible.com/docs/core-concepts/architecture/containers/container-recovery)
- [Containers](https://aptible.com/docs/core-concepts/architecture/containers/overview)
- [Environments](https://aptible.com/docs/core-concepts/architecture/environments): Learn about grouping resources with environments
- [Maintenance](https://aptible.com/docs/core-concepts/architecture/maintenance): Learn about how Aptible simplifies infrastructure maintenance
- [Operations](https://aptible.com/docs/core-concepts/architecture/operations): Learn more about operations work on Aptible - with minimal downtime and rollbacks
- [Architecture - Overview](https://aptible.com/docs/core-concepts/architecture/overview): Learn about the key components of the Aptible platform architecture and how they work together to help you deploy and manage your resources
- [Reliability Division of Responsibilities](https://aptible.com/docs/core-concepts/architecture/reliability-division)
- [Stacks](https://aptible.com/docs/core-concepts/architecture/stacks): Learn about using Stacks to deploy resources to various regions
- [Billing & Payments](https://aptible.com/docs/core-concepts/billing-payments): Learn how manage billing & payments within Aptible
- [Datadog Integration](https://aptible.com/docs/core-concepts/integrations/datadog): Learn about using the Datadog Integration for logging and monitoring
- [Entitle Integration](https://aptible.com/docs/core-concepts/integrations/entitle): Learn about using the Entitle integration for just-in-time access to Aptible resources
- [Mezmo Integration](https://aptible.com/docs/core-concepts/integrations/mezmo): Learn about sending Aptible logs to Mezmo
- [Network Integrations: VPC Peering & VPN Tunnels](https://aptible.com/docs/core-concepts/integrations/network-integrations)
- [All Integrations and Tools](https://aptible.com/docs/core-concepts/integrations/overview): Explore all integrations and tools used with Aptible
- [Sumo Logic Integration](https://aptible.com/docs/core-concepts/integrations/sumo-logic): Learn about sending Aptible logs to Sumo Logic
- [Twingate Integration](https://aptible.com/docs/core-concepts/integrations/twingate): Learn how to integrate Twingate with your Aptible account
- [Database Credentials](https://aptible.com/docs/core-concepts/managed-databases/connecting-databases/database-credentials)
- [Database Endpoints](https://aptible.com/docs/core-concepts/managed-databases/connecting-databases/database-endpoints)
- [Database Tunnels](https://aptible.com/docs/core-concepts/managed-databases/connecting-databases/database-tunnels)
- [Connecting to Databases](https://aptible.com/docs/core-concepts/managed-databases/connecting-databases/overview): Learn about the various ways to connect to your Database on Aptible
- [Database Backups](https://aptible.com/docs/core-concepts/managed-databases/managing-databases/database-backups): Learn more about Aptible's database backup solution with automatic backups, default encryption, with flexible customization
- [Application-Level Encryption](https://aptible.com/docs/core-concepts/managed-databases/managing-databases/database-encryption/application-level-encryption)
- [Custom Database Encryption](https://aptible.com/docs/core-concepts/managed-databases/managing-databases/database-encryption/custom-database-encryption)
- [Database Encryption at Rest](https://aptible.com/docs/core-concepts/managed-databases/managing-databases/database-encryption/database-encryption)
- [Database Encryption in Transit](https://aptible.com/docs/core-concepts/managed-databases/managing-databases/database-encryption/database-encryption-in-transit)
- [Database Encryption](https://aptible.com/docs/core-concepts/managed-databases/managing-databases/database-encryption/overview)
- [Database Performance Tuning](https://aptible.com/docs/core-concepts/managed-databases/managing-databases/database-tuning)
- [Database Upgrades](https://aptible.com/docs/core-concepts/managed-databases/managing-databases/database-upgrade-methods)
- [Managing Databases](https://aptible.com/docs/core-concepts/managed-databases/managing-databases/overview)
- [Database Replication and Clustering](https://aptible.com/docs/core-concepts/managed-databases/managing-databases/replication-clustering)
- [Managed Databases - Overview](https://aptible.com/docs/core-concepts/managed-databases/overview): Learn about Aptible Managed Databases that automate provisioning, maintenance, and scaling
- [Provisioning Databases](https://aptible.com/docs/core-concepts/managed-databases/provisioning-databases): Learn about provisioning Managed Databases on Aptible
- [CouchDB](https://aptible.com/docs/core-concepts/managed-databases/supported-databases/couchdb): Learn about running secure, Managed CouchDB Databases on Aptible
- [Elasticsearch](https://aptible.com/docs/core-concepts/managed-databases/supported-databases/elasticsearch): Learn about running secure, Managed Elasticsearch Databases on Aptible
- [InfluxDB](https://aptible.com/docs/core-concepts/managed-databases/supported-databases/influxdb): Learn about running secure, Managed InfluxDB Databases on Aptible
- [MongoDB](https://aptible.com/docs/core-concepts/managed-databases/supported-databases/mongodb): Learn about running secure, Managed MongoDB Databases on Aptible
- [MySQL](https://aptible.com/docs/core-concepts/managed-databases/supported-databases/mysql): Learn about running secure, Managed MySQL Databases on Aptible
- [PostgreSQL](https://aptible.com/docs/core-concepts/managed-databases/supported-databases/postgresql): Learn about running secure, Managed PostgreSQL Databases on Aptible
- [RabbitMQ](https://aptible.com/docs/core-concepts/managed-databases/supported-databases/rabbitmq)
- [Redis](https://aptible.com/docs/core-concepts/managed-databases/supported-databases/redis): Learn about running secure, Managed Redis Databases on Aptible
- [SFTP](https://aptible.com/docs/core-concepts/managed-databases/supported-databases/sftp)
- [Activity](https://aptible.com/docs/core-concepts/observability/activity): Learn about tracking changes to your resources with Activity
- [Elasticsearch Log Drains](https://aptible.com/docs/core-concepts/observability/logs/log-drains/elasticsearch-log-drains)
- [HTTPS Log Drains](https://aptible.com/docs/core-concepts/observability/logs/log-drains/https-log-drains)
- [Log Drains](https://aptible.com/docs/core-concepts/observability/logs/log-drains/overview): Learn about sending Logs to logging destinations
- [Syslog Log Drains](https://aptible.com/docs/core-concepts/observability/logs/log-drains/syslog-log-drains)
- [Logs](https://aptible.com/docs/core-concepts/observability/logs/overview): Learn about how to access and retain logs from your Aptible resources
- [Log Archiving to S3](https://aptible.com/docs/core-concepts/observability/logs/s3-log-archives)
- [InfluxDB Metric Drain](https://aptible.com/docs/core-concepts/observability/metrics/metrics-drains/influxdb-metric-drain): Learn about sending Aptible logs to an InfluxDB
- [Metrics Drains](https://aptible.com/docs/core-concepts/observability/metrics/metrics-drains/overview): Learn how to route metrics with Metric Drains
- [Metrics](https://aptible.com/docs/core-concepts/observability/metrics/overview): Learn about container metrics on Aptible
- [Observability - Overview](https://aptible.com/docs/core-concepts/observability/overview): Learn about observability features on Aptible to help you monitor, analyze and manange your Apps and Databases
- [Sources](https://aptible.com/docs/core-concepts/observability/sources)
- [App Scaling](https://aptible.com/docs/core-concepts/scaling/app-scaling): Learn about scaling Apps CPU, RAM, and containers - manually or automatically
- [Container Profiles](https://aptible.com/docs/core-concepts/scaling/container-profiles): Learn about using Container Profiles to optimize spend and performance
- [CPU Allocation](https://aptible.com/docs/core-concepts/scaling/cpu-isolation)
- [Database Scaling](https://aptible.com/docs/core-concepts/scaling/database-scaling): Learn about scaling Databases CPU, RAM, IOPS and throughput
- [Memory Management](https://aptible.com/docs/core-concepts/scaling/memory-limits): Learn how Aptible enforces memory limits to ensure predictable performance
- [Scaling - Overview](https://aptible.com/docs/core-concepts/scaling/overview): Learn more about scaling on-demand without worrying about any underlying configurations or capacity availability
- [Roles & Permissions](https://aptible.com/docs/core-concepts/security-compliance/access-permissions)
- [Password Authentication](https://aptible.com/docs/core-concepts/security-compliance/authentication/password-authentication)
- [Provisioning (SCIM)](https://aptible.com/docs/core-concepts/security-compliance/authentication/scim): Learn about configuring Cross-domain Identity Management (SCIM) on Aptible
- [SSH Keys](https://aptible.com/docs/core-concepts/security-compliance/authentication/ssh-keys): Learn about using SSH Keys to authenticate with Aptible
- [Single Sign-On (SSO)](https://aptible.com/docs/core-concepts/security-compliance/authentication/sso)
- [HIPAA](https://aptible.com/docs/core-concepts/security-compliance/compliance-frameworks/hipaa): Learn about achieving HIPAA compliance on Aptible
- [HITRUST](https://aptible.com/docs/core-concepts/security-compliance/compliance-frameworks/hitrust): Learn about achieving HITRUST compliance on Aptible
- [PCI DSS](https://aptible.com/docs/core-concepts/security-compliance/compliance-frameworks/pci): Learn about achieving PCI DSS compliance on Aptible
- [PIPEDA](https://aptible.com/docs/core-concepts/security-compliance/compliance-frameworks/pipeda): Learn about achieving PIPEDA compliance on Aptible
- [DDoS Protection](https://aptible.com/docs/core-concepts/security-compliance/ddos-pid-limits): Learn how Aptible automatically provides DDoS Protection
- [Managed Host Intrusion Detection (HIDS)](https://aptible.com/docs/core-concepts/security-compliance/hids)
- [Security & Compliance - Overview](https://aptible.com/docs/core-concepts/security-compliance/overview): Learn how Aptible enables dev teams to meet regulatory compliance requirements (HIPAA, HITRUST, SOC 2, PCI) and pass security audits
- [Compliance Readiness Scores](https://aptible.com/docs/core-concepts/security-compliance/security-compliance-dashboard/compliance-readiness-scores)
- [Control Performance](https://aptible.com/docs/core-concepts/security-compliance/security-compliance-dashboard/control-performance)
- [Security & Compliance Dashboard](https://aptible.com/docs/core-concepts/security-compliance/security-compliance-dashboard/overview)
- [Resources in Scope](https://aptible.com/docs/core-concepts/security-compliance/security-compliance-dashboard/resources-in-scope)
- [Shareable Compliance Posture Report](https://aptible.com/docs/core-concepts/security-compliance/security-compliance-dashboard/shareable-compliance-report)
- [Security Scans](https://aptible.com/docs/core-concepts/security-compliance/security-scans): Learn about application vulnerability scanning provided by Aptible
- [Deploy your custom code](https://aptible.com/docs/getting-started/deploy-custom-code): Learn how to deploy your custom code on Aptible
- [Node.js + Express - Starter Template](https://aptible.com/docs/getting-started/deploy-starter-template/node-js): Deploy a starter template Node.js app using the Express framework on Aptible
- [Deploy a starter template](https://aptible.com/docs/getting-started/deploy-starter-template/overview)
- [PHP + Laravel - Starter Template](https://aptible.com/docs/getting-started/deploy-starter-template/php-laravel): Deploy a starter template PHP app using the Laravel framework on Aptible
- [Python + Django - Starter Template](https://aptible.com/docs/getting-started/deploy-starter-template/python-django): Deploy a starter template Python app using the Django framework on Aptible
- [Python + Flask - Demo App](https://aptible.com/docs/getting-started/deploy-starter-template/python-flask): Deploy our Python demo app using the Flask framework with Managed PostgreSQL Database and Redis instance
- [Ruby on Rails - Starter Template](https://aptible.com/docs/getting-started/deploy-starter-template/ruby-on-rails): Deploy a starter template Ruby on Rails app on Aptible
- [Aptible Documentation](https://aptible.com/docs/getting-started/home): A Platform as a Service (PaaS) that gives startups everything developers need to launch and scale apps and databases that are secure, reliable, and compliant — no manual configuration required.
- [Introduction to Aptible](https://aptible.com/docs/getting-started/introduction): Learn what Aptible is and why scaling companies use it to host their apps and data in the cloud
- [How to access configuration variables during Docker build](https://aptible.com/docs/how-to-guides/app-guides/access-config-vars-during-docker-build)
- [How to define services](https://aptible.com/docs/how-to-guides/app-guides/define-services)
- [How to deploy via Docker Image](https://aptible.com/docs/how-to-guides/app-guides/deploy-docker-image): Learn how to deploy your code to Aptible from a Docker Image
- [How to deploy from Git](https://aptible.com/docs/how-to-guides/app-guides/deploy-from-git): Guide for deploying from Git using Dockerfile Deploy
- [Deploy Metric Drain with Terraform](https://aptible.com/docs/how-to-guides/app-guides/deploy-metric-drain-with-terraform)
- [How to migrate from deploying via Docker Image to deploying via Git](https://aptible.com/docs/how-to-guides/app-guides/deploying-docker-image-to-git): Guide for migrating from deploying via Docker Image to deploying via Git
- [How to establish client certificate authentication](https://aptible.com/docs/how-to-guides/app-guides/establish-client-certificiate-auth): Client certificate authentication, also known as two-way SSL authentication, is a form of mutual Transport Layer Security(TLS) authentication that involves both the server and the client in the authentication process. Users and the third party they are working with need to establish, own, and manage this type of authentication.
- [How to expose a web app to the Internet](https://aptible.com/docs/how-to-guides/app-guides/expose-web-app-to-internet)
- [How to generate certificate signing requests](https://aptible.com/docs/how-to-guides/app-guides/generate-certificate-signing-requests)
- [Getting Started with Docker](https://aptible.com/docs/how-to-guides/app-guides/getting-started-with-docker)
- [Horizontal Autoscaling Guide](https://aptible.com/docs/how-to-guides/app-guides/horizontal-autoscaling-guide)
- [How to create an app](https://aptible.com/docs/how-to-guides/app-guides/how-to-create-app)
- [How to deploy to Aptible with CI/CD](https://aptible.com/docs/how-to-guides/app-guides/how-to-deploy-aptible-ci-cd)
- [How to scale apps and services](https://aptible.com/docs/how-to-guides/app-guides/how-to-scale-apps-services)
- [Circle CI](https://aptible.com/docs/how-to-guides/app-guides/integrate-aptible-with-ci/circle-cl)
- [Codeship](https://aptible.com/docs/how-to-guides/app-guides/integrate-aptible-with-ci/codeship)
- [Jenkins](https://aptible.com/docs/how-to-guides/app-guides/integrate-aptible-with-ci/jenkins)
- [How to integrate Aptible with CI Platforms](https://aptible.com/docs/how-to-guides/app-guides/integrate-aptible-with-ci/overview)
- [Travis CI](https://aptible.com/docs/how-to-guides/app-guides/integrate-aptible-with-ci/travis-cl)
- [How to make Dockerfile Deploys faster](https://aptible.com/docs/how-to-guides/app-guides/make-docker-deploys-faster)
- [How to migrate from Dockerfile Deploy to Direct Docker Image Deploy](https://aptible.com/docs/how-to-guides/app-guides/migrate-dockerfile-to-direct-image-deploy)
- [How to migrate a NodeJS app from Heroku to Aptible](https://aptible.com/docs/how-to-guides/app-guides/migrate-nodjs-from-heroku-to-aptible): Guide for migrating a NodeJS app from Heroku to Aptible
- [All App Guides](https://aptible.com/docs/how-to-guides/app-guides/overview): Explore guides for deploying and managing Apps on Aptible
- [How to serve static assets](https://aptible.com/docs/how-to-guides/app-guides/serve-static-assets)
- [How to set and modify configuration variables](https://aptible.com/docs/how-to-guides/app-guides/set-modify-config-variables)
- [How to synchronize configuration and code changes](https://aptible.com/docs/how-to-guides/app-guides/synchronize-config-code-changes)
- [How to use cron to run scheduled tasks](https://aptible.com/docs/how-to-guides/app-guides/use-cron-to-run-scheduled-tasks): Learn how to use cron to run and automate scheduled tasks on Aptible
- [AWS Domain Apex Redirect](https://aptible.com/docs/how-to-guides/app-guides/use-domain-apex-with-endpoints/aws-domain-apex-redirect): This tutorial will guide you through the process of setting up an Apex redirect using AWS S3, AWS CloudFront, and AWS Certificate Manager.
- [Domain Apex ALIAS](https://aptible.com/docs/how-to-guides/app-guides/use-domain-apex-with-endpoints/domain-apex-alias)
- [Domain Apex Redirect](https://aptible.com/docs/how-to-guides/app-guides/use-domain-apex-with-endpoints/domain-apex-redirect)
- [How to use Domain Apex with Endpoints](https://aptible.com/docs/how-to-guides/app-guides/use-domain-apex-with-endpoints/overview)
- [How to use Nginx with Aptible Endpoints](https://aptible.com/docs/how-to-guides/app-guides/use-nginx-with-aptible-endpoints)
- [How to use S3 to accept file uploads](https://aptible.com/docs/how-to-guides/app-guides/use-s3-to-accept-file-uploads): Learn how to connect your app to S3 to accept file uploads
- [Automate Database migrations](https://aptible.com/docs/how-to-guides/database-guides/automate-database-migrations)
- [How to configure Aptible PostgreSQL Databases](https://aptible.com/docs/how-to-guides/database-guides/configure-aptible-postgresql-databases): Learn how to configure PostgreSQL Databases on Aptible
- [How to connect Fivetran with your Aptible databases](https://aptible.com/docs/how-to-guides/database-guides/connect-fivetran-with-aptible-db): Learn how to connect Fivetran with your Aptible Databases
- [Dump and restore MySQL](https://aptible.com/docs/how-to-guides/database-guides/dump-restore-mysql)
- [Dump and restore PostgreSQL](https://aptible.com/docs/how-to-guides/database-guides/dump-restore-postgresql)
- [How to scale databases](https://aptible.com/docs/how-to-guides/database-guides/how-to-scale-databases): Learn how to scale databases on Aptible
- [All Database Guides](https://aptible.com/docs/how-to-guides/database-guides/overview): Explore guides for deploying and managing databases on Aptible
- [Test a PostgreSQL Database's schema on a new version](https://aptible.com/docs/how-to-guides/database-guides/test-schema-new-version): The goal of this guide is to test the schema of an existing Database against another Database version in order to see if it's compatible with the desired version. The primary reason to do this is to ensure a Database's schema is compatible with a higher version before upgrading.
- [Use mysqldump to test for upgrade incompatibilities](https://aptible.com/docs/how-to-guides/database-guides/test-upgrade-incompatibiltiies)
- [Upgrade MongoDB](https://aptible.com/docs/how-to-guides/database-guides/upgrade-mongodb)
- [Upgrade PostgreSQL with logical replication](https://aptible.com/docs/how-to-guides/database-guides/upgrade-postgresql)
- [Upgrade Redis](https://aptible.com/docs/how-to-guides/database-guides/upgrade-redis)
- [Browse Guides](https://aptible.com/docs/how-to-guides/guides-overview): Explore guides for using the Aptible platform
- [How to access operation logs](https://aptible.com/docs/how-to-guides/observability-guides/access-operation-logs): For all operations performed, Aptible collects operation logs. These logs are retained only for active resources and can be viewed in the following ways.
- [How to deploy and use Grafana](https://aptible.com/docs/how-to-guides/observability-guides/deploy-use-grafana): Learn how to deploy and use Aptible-hosted analytics and monitoring with Grafana
- [How to set up Elasticsearch Log Rotation](https://aptible.com/docs/how-to-guides/observability-guides/elasticsearch-log-rotation)
- [How to set up a self-hosted Elasticsearch Log Drain with Logstash and Kibana (ELK)](https://aptible.com/docs/how-to-guides/observability-guides/elk): This guide will walk you through setting up a self-hosted Elasticsearch - Logstash - Kibana (ELK) stack on Aptible.
- [How to export Activity Reports](https://aptible.com/docs/how-to-guides/observability-guides/export-activity-reports): Learn how to export Activity Reports
- [How to set up a self-hosted HTTPS Log Drain](https://aptible.com/docs/how-to-guides/observability-guides/https-log-drain)
- [All Observability Guides](https://aptible.com/docs/how-to-guides/observability-guides/overview): Explore guides for enhancing observability on Aptible
- [How to set up a Papertrail Log Drain](https://aptible.com/docs/how-to-guides/observability-guides/papertrail-log-drain): Learn how to set up a PaperTrail Log Drain on Aptible
- [How to set up application performance monitoring](https://aptible.com/docs/how-to-guides/observability-guides/setup-application-performance-monitoring): Learn how to set up application performance monitoring
- [How to set up Datadog APM](https://aptible.com/docs/how-to-guides/observability-guides/setup-datadog-apm): Guide for setting up Datadog Application Performance Monitoring (APM) on your Aptible apps
- [How to set up Kibana on Aptible](https://aptible.com/docs/how-to-guides/observability-guides/setup-kibana)
- [Advanced Best Practices Guide](https://aptible.com/docs/how-to-guides/platform-guides/advanced-best-practices-guide): Learn how to take your infrastructure to the next level with advanced best practices
- [Best Practices Guide](https://aptible.com/docs/how-to-guides/platform-guides/best-practices-guide): Learn how to deploy your infrastructure with best practices for setting up your Aptible account
- [How to cancel my Aptible Account](https://aptible.com/docs/how-to-guides/platform-guides/cancel-aptible-account): To cancel your Deploy account and avoid any future charges, please follow these steps in order:
- [How to create and deprovison dedicated stacks](https://aptible.com/docs/how-to-guides/platform-guides/create-deprovision-dedicated-stacks): Learn how to create and deprovision dedicated stacks
- [How to create environments](https://aptible.com/docs/how-to-guides/platform-guides/create-environment)
- [How to delete environments](https://aptible.com/docs/how-to-guides/platform-guides/delete-environment)
- [How to deprovision resources](https://aptible.com/docs/how-to-guides/platform-guides/deprovision-resources)
- [How to handle vulnerabilities found in security scans](https://aptible.com/docs/how-to-guides/platform-guides/handle-vulnerabilities-security-scans)
- [How to achieve HIPAA compliance on Aptible](https://aptible.com/docs/how-to-guides/platform-guides/hipaa-compliance): Learn how to achieve HIPAA compliance on Aptible, the leading platform for hosting HIPAA-compliant apps & databases
- [MedStack to Aptible Migration Guide](https://aptible.com/docs/how-to-guides/platform-guides/medstack-migration): Learn how to migrate resources from MedStack to Aptible
- [How to migrate environments](https://aptible.com/docs/how-to-guides/platform-guides/migrate-environments): Learn how to migrate environments
- [Minimize Downtime Caused by AWS Outages](https://aptible.com/docs/how-to-guides/platform-guides/minimize-downtown-outages): Learn how to optimize your Aptible resource to reduce the potential downtime caused by AWS Outages
- [How to request HITRUST Inhertiance](https://aptible.com/docs/how-to-guides/platform-guides/navigate-hitrust): Learn how to request HITRUST Inhertiance from Aptible
- [How to navigate security questionnaires and audits](https://aptible.com/docs/how-to-guides/platform-guides/navigate-security-questionnaire-audits): Learn how to approach responding to security questionnaires and audits on Aptible
- [Platform Guides](https://aptible.com/docs/how-to-guides/platform-guides/overview): Explore guides for using the Aptible Platform
- [How to Re-invite Deleted Users](https://aptible.com/docs/how-to-guides/platform-guides/re-inviting-deleted-users)
- [How to reset my Aptible 2FA](https://aptible.com/docs/how-to-guides/platform-guides/reset-aptible-2fa)
- [How to restore resources](https://aptible.com/docs/how-to-guides/platform-guides/restore-resources)
- [Provisioning with Entra Identity (SCIM)](https://aptible.com/docs/how-to-guides/platform-guides/scim-entra-guide): Aptible supports SCIM 2.0 provisioning through Entra Identity using the Aptible SCIM integration. This setup enables you to automate user provisioning and de-provisioning for your organization.
- [Provisioning with Okta (SCIM)](https://aptible.com/docs/how-to-guides/platform-guides/scim-okta-guide): Aptible supports SCIM 2.0 provisioning through Okta using the Aptible SCIM integration. This setup enables you to automate user provisioning and de-provisioning for your organization.
- [How to set up Single Sign On (SSO)](https://aptible.com/docs/how-to-guides/platform-guides/setup-sso): To use SSO, you must configure both the SSO provider and Aptible with metadata related to the SAML protocol. This documentation covers the process in general terms applicable to any SSO provider. Then, it covers in detail the setup process in Okta.
- [How to Set Up Single Sign-On (SSO) for Auth0](https://aptible.com/docs/how-to-guides/platform-guides/setup-sso-auth0): This guide provides detailed instructions on how to set up a custom SAML application in Auth0 for integration with Aptible.
- [How to upgrade or downgrade my plan](https://aptible.com/docs/how-to-guides/platform-guides/upgrade-downgrade-plan): Learn how to upgrade and downgrade your Aptible plan
- [Aptible Support](https://aptible.com/docs/how-to-guides/troubleshooting/aptible-support)
- [App Processing Requests Slowly](https://aptible.com/docs/how-to-guides/troubleshooting/common-errors-issues/app-processing-requests-slowly)
- [Application is Currently Unavailable](https://aptible.com/docs/how-to-guides/troubleshooting/common-errors-issues/application-unavailable)
- [App Logs Not Being Received](https://aptible.com/docs/how-to-guides/troubleshooting/common-errors-issues/apps-logs-not-received)
- [aptible ssh Operation Timed Out](https://aptible.com/docs/how-to-guides/troubleshooting/common-errors-issues/aptible-ssh-operation-timed-out)
- [aptible ssh Permission Denied](https://aptible.com/docs/how-to-guides/troubleshooting/common-errors-issues/aptible-ssh-permission-denied)
- [before_release Commands Failed](https://aptible.com/docs/how-to-guides/troubleshooting/common-errors-issues/before-released-commands-fail)
- [Build Failed Error](https://aptible.com/docs/how-to-guides/troubleshooting/common-errors-issues/build-failed-error)
- [Connecting to MongoDB fails](https://aptible.com/docs/how-to-guides/troubleshooting/common-errors-issues/connecting-mongodb-fails)
- [Container Failed to Start Error](https://aptible.com/docs/how-to-guides/troubleshooting/common-errors-issues/container-failed-start-error)
- [Deploys Take Too long](https://aptible.com/docs/how-to-guides/troubleshooting/common-errors-issues/deploys-take-long)
- [Enabling HTTP Response Streaming](https://aptible.com/docs/how-to-guides/troubleshooting/common-errors-issues/enabling-http-response)
- [git Push "Everything up-to-date."](https://aptible.com/docs/how-to-guides/troubleshooting/common-errors-issues/git-push-everything-utd)
- [git Push Permission Denied](https://aptible.com/docs/how-to-guides/troubleshooting/common-errors-issues/git-push-permission-denied)
- [git Reference Error](https://aptible.com/docs/how-to-guides/troubleshooting/common-errors-issues/git-reference-error)
- [HTTP Health Checks Failed](https://aptible.com/docs/how-to-guides/troubleshooting/common-errors-issues/http-health-check-failed)
- [MySQL Access Denied](https://aptible.com/docs/how-to-guides/troubleshooting/common-errors-issues/mysql-access-denied)
- [No CMD or Procfile in Image](https://aptible.com/docs/how-to-guides/troubleshooting/common-errors-issues/no-cmd-procfile-image)
- [Operation Restricted to Availability Zone(s)](https://aptible.com/docs/how-to-guides/troubleshooting/common-errors-issues/operation-restricted-to-availability)
- [Common Errors and Issues](https://aptible.com/docs/how-to-guides/troubleshooting/common-errors-issues/overview)
- [PostgreSQL Incomplete Startup Packet](https://aptible.com/docs/how-to-guides/troubleshooting/common-errors-issues/postgresql-incomplete)
- [PostgreSQL Replica max_connections](https://aptible.com/docs/how-to-guides/troubleshooting/common-errors-issues/postgresql-replica)
- [PostgreSQL SSL Off](https://aptible.com/docs/how-to-guides/troubleshooting/common-errors-issues/postgresql-ssl-off)
- [Private Key Must Match Certificate](https://aptible.com/docs/how-to-guides/troubleshooting/common-errors-issues/private-key-match-certificate)
- [SSL error ERR_CERT_AUTHORITY_INVALID](https://aptible.com/docs/how-to-guides/troubleshooting/common-errors-issues/ssl-error-auth-invalid)
- [SSL error ERR_CERT_COMMON_NAME_INVALID](https://aptible.com/docs/how-to-guides/troubleshooting/common-errors-issues/ssl-error-common-name-invalid)
- [Unexpected Requests in App Logs](https://aptible.com/docs/how-to-guides/troubleshooting/common-errors-issues/unexpected-requests-app-logs)
- [aptible apps](https://aptible.com/docs/reference/aptible-cli/cli-commands/cli-apps)
- [aptible apps:create](https://aptible.com/docs/reference/aptible-cli/cli-commands/cli-apps-create)
- [aptible apps:deprovision](https://aptible.com/docs/reference/aptible-cli/cli-commands/cli-apps-deprovision)
- [aptible apps:rename](https://aptible.com/docs/reference/aptible-cli/cli-commands/cli-apps-rename)
- [aptible apps:scale](https://aptible.com/docs/reference/aptible-cli/cli-commands/cli-apps-scale)
- [aptible backup:list](https://aptible.com/docs/reference/aptible-cli/cli-commands/cli-backup-list)
- [aptible backup:orphaned](https://aptible.com/docs/reference/aptible-cli/cli-commands/cli-backup-orphaned)
- [aptible backup:purge](https://aptible.com/docs/reference/aptible-cli/cli-commands/cli-backup-purge)
- [aptible backup:restore](https://aptible.com/docs/reference/aptible-cli/cli-commands/cli-backup-restore)
- [aptible backup_retention_policy](https://aptible.com/docs/reference/aptible-cli/cli-commands/cli-backup-retention-policy)
- [aptible backup_retention_policy:set](https://aptible.com/docs/reference/aptible-cli/cli-commands/cli-backup-retention-policy-set)
- [aptible config](https://aptible.com/docs/reference/aptible-cli/cli-commands/cli-config)
- [aptible config:add](https://aptible.com/docs/reference/aptible-cli/cli-commands/cli-config-add)
- [aptible config:get](https://aptible.com/docs/reference/aptible-cli/cli-commands/cli-config-get)
- [aptible config:rm](https://aptible.com/docs/reference/aptible-cli/cli-commands/cli-config-rm)
- [aptible config:set](https://aptible.com/docs/reference/aptible-cli/cli-commands/cli-config-set)
- [aptible config:unset](https://aptible.com/docs/reference/aptible-cli/cli-commands/cli-config-unset)
- [aptible db:backup](https://aptible.com/docs/reference/aptible-cli/cli-commands/cli-db-backup)
- [aptible db:clone](https://aptible.com/docs/reference/aptible-cli/cli-commands/cli-db-clone)
- [aptible db:create](https://aptible.com/docs/reference/aptible-cli/cli-commands/cli-db-create)
- [aptible db:deprovision](https://aptible.com/docs/reference/aptible-cli/cli-commands/cli-db-deprovision)
- [aptible db:dump](https://aptible.com/docs/reference/aptible-cli/cli-commands/cli-db-dump)
- [aptible db:execute](https://aptible.com/docs/reference/aptible-cli/cli-commands/cli-db-execute)
- [aptible db:list](https://aptible.com/docs/reference/aptible-cli/cli-commands/cli-db-list)
- [aptible db:modify](https://aptible.com/docs/reference/aptible-cli/cli-commands/cli-db-modify)
- [aptible db:reload](https://aptible.com/docs/reference/aptible-cli/cli-commands/cli-db-reload)
- [aptible db:rename](https://aptible.com/docs/reference/aptible-cli/cli-commands/cli-db-rename)
- [aptible db:replicate](https://aptible.com/docs/reference/aptible-cli/cli-commands/cli-db-replicate)
- [aptible db:restart](https://aptible.com/docs/reference/aptible-cli/cli-commands/cli-db-restart)
- [aptible db:tunnel](https://aptible.com/docs/reference/aptible-cli/cli-commands/cli-db-tunnel)
- [aptible db:url](https://aptible.com/docs/reference/aptible-cli/cli-commands/cli-db-url)
- [aptible db:versions](https://aptible.com/docs/reference/aptible-cli/cli-commands/cli-db-versions)
- [aptible deploy](https://aptible.com/docs/reference/aptible-cli/cli-commands/cli-deploy)
- [aptible endpoints:database:create](https://aptible.com/docs/reference/aptible-cli/cli-commands/cli-endpoints-database-create)
- [aptible endpoints:database:modify](https://aptible.com/docs/reference/aptible-cli/cli-commands/cli-endpoints-database-modify)
- [aptible endpoints:deprovision](https://aptible.com/docs/reference/aptible-cli/cli-commands/cli-endpoints-deprovision)
- [aptible endpoints:grpc:create](https://aptible.com/docs/reference/aptible-cli/cli-commands/cli-endpoints-grpc-create)
- [aptible endpoints:grpc:modify](https://aptible.com/docs/reference/aptible-cli/cli-commands/cli-endpoints-grpc-modify)
- [aptible endpoints:https:create](https://aptible.com/docs/reference/aptible-cli/cli-commands/cli-endpoints-https-create)
- [aptible endpoints:https:modify](https://aptible.com/docs/reference/aptible-cli/cli-commands/cli-endpoints-https-modify)
- [aptible endpoints:list](https://aptible.com/docs/reference/aptible-cli/cli-commands/cli-endpoints-list)
- [aptible endpoints:renew](https://aptible.com/docs/reference/aptible-cli/cli-commands/cli-endpoints-renew)
- [aptible endpoints:tcp:create](https://aptible.com/docs/reference/aptible-cli/cli-commands/cli-endpoints-tcp-create)
- [aptible endpoints:tcp:modify](https://aptible.com/docs/reference/aptible-cli/cli-commands/cli-endpoints-tcp-modify)
- [aptible endpoints:tls:create](https://aptible.com/docs/reference/aptible-cli/cli-commands/cli-endpoints-tls-create)
- [aptible endpoints:tls:modify](https://aptible.com/docs/reference/aptible-cli/cli-commands/cli-endpoints-tls-modify)
- [aptible environment:ca_cert](https://aptible.com/docs/reference/aptible-cli/cli-commands/cli-environment-ca-cert)
- [aptible environment:list](https://aptible.com/docs/reference/aptible-cli/cli-commands/cli-environment-list)
- [aptible environment:rename](https://aptible.com/docs/reference/aptible-cli/cli-commands/cli-environment-rename)
- [aptible help](https://aptible.com/docs/reference/aptible-cli/cli-commands/cli-help)
- [aptible log_drain:create:datadog](https://aptible.com/docs/reference/aptible-cli/cli-commands/cli-log-drain-create-datadog)
- [aptible log_drain:create:elasticsearch](https://aptible.com/docs/reference/aptible-cli/cli-commands/cli-log-drain-create-elasticsearch)
- [aptible log_drain:create:https](https://aptible.com/docs/reference/aptible-cli/cli-commands/cli-log-drain-create-https)
- [aptible log_drain:create:logdna](https://aptible.com/docs/reference/aptible-cli/cli-commands/cli-log-drain-create-logdna)
- [aptible log_drain:create:papertrail](https://aptible.com/docs/reference/aptible-cli/cli-commands/cli-log-drain-create-papertrail)
- [aptible log_drain:create:sumologic](https://aptible.com/docs/reference/aptible-cli/cli-commands/cli-log-drain-create-sumologic)
- [aptible log_drain:create:syslog](https://aptible.com/docs/reference/aptible-cli/cli-commands/cli-log-drain-create-syslog)
- [aptible log_drain:deprovision](https://aptible.com/docs/reference/aptible-cli/cli-commands/cli-log-drain-deprovision)
- [aptible log_drain:list](https://aptible.com/docs/reference/aptible-cli/cli-commands/cli-log-drain-list)
- [aptible login](https://aptible.com/docs/reference/aptible-cli/cli-commands/cli-login)
- [aptible logs](https://aptible.com/docs/reference/aptible-cli/cli-commands/cli-logs)
- [aptible logs_from_archive](https://aptible.com/docs/reference/aptible-cli/cli-commands/cli-logs-from-archive)
- [aptible maintenance:apps](https://aptible.com/docs/reference/aptible-cli/cli-commands/cli-maintenance-apps)
- [aptible maintenance:dbs](https://aptible.com/docs/reference/aptible-cli/cli-commands/cli-maintenance-dbs)
- [aptible metric_drain:create:datadog](https://aptible.com/docs/reference/aptible-cli/cli-commands/cli-metric-drain-create-datadog)
- [aptible metric_drain:create:influxdb](https://aptible.com/docs/reference/aptible-cli/cli-commands/cli-metric-drain-create-influxdb)
- [aptible metric_drain:create:influxdb:custom](https://aptible.com/docs/reference/aptible-cli/cli-commands/cli-metric-drain-create-influxdb-custom)
- [aptible metric_drain:deprovision](https://aptible.com/docs/reference/aptible-cli/cli-commands/cli-metric-drain-deprovision)
- [aptible metric_drain:list](https://aptible.com/docs/reference/aptible-cli/cli-commands/cli-metric-drain-list)
- [aptible operation:cancel](https://aptible.com/docs/reference/aptible-cli/cli-commands/cli-operation-cancel)
- [aptible operation:follow](https://aptible.com/docs/reference/aptible-cli/cli-commands/cli-operation-follow)
- [aptible operation:logs](https://aptible.com/docs/reference/aptible-cli/cli-commands/cli-operation-logs)
- [aptible rebuild](https://aptible.com/docs/reference/aptible-cli/cli-commands/cli-rebuild)
- [aptible restart](https://aptible.com/docs/reference/aptible-cli/cli-commands/cli-restart)
- [aptible services](https://aptible.com/docs/reference/aptible-cli/cli-commands/cli-services)
- [aptible services:settings](https://aptible.com/docs/reference/aptible-cli/cli-commands/cli-services-settings)
- [aptible ssh](https://aptible.com/docs/reference/aptible-cli/cli-commands/cli-ssh)
- [aptible version](https://aptible.com/docs/reference/aptible-cli/cli-commands/cli-version)
- [CLI Configurations](https://aptible.com/docs/reference/aptible-cli/cli-configurations): The Aptible CLI provides configuration options such as MFA support, customizing output format, and overriding configuration location.
- [Aptible CLI - Overview](https://aptible.com/docs/reference/aptible-cli/overview): Learn more about using the Aptible CLI for managing resources
- [Aptible Metadata Variables](https://aptible.com/docs/reference/aptible-metadata-variables)
- [Dashboard](https://aptible.com/docs/reference/dashboard): Learn about navigating the Aptible Dashboard
- [Glossary](https://aptible.com/docs/reference/glossary)
- [Interface Feature Availability Matrix](https://aptible.com/docs/reference/interface-feature)
- [Pricing](https://aptible.com/docs/reference/pricing): Learn about Aptible's pricing
- [Terraform](https://aptible.com/docs/reference/terraform)


## Optional

- [Contact Support](https://app.aptible.com/support)
- [Changelog](https://www.aptible.com/changelog)
- [Trust Center](https://trust.aptible.com/)


# Custom Certificate



When an [Endpoint](/core-concepts/apps/connecting-to-apps/app-endpoints/overview) requires a Certificate to perform SSL / TLS termination on your behalf, you can opt to provide your own certificate and private key instead of Aptible managing them via [Managed TLS](/core-concepts/apps/connecting-to-apps/app-endpoints/managed-tls). Start by generating a [Certificate Signing Request](https://en.wikipedia.org/wiki/Certificate_signing_request)(CSR) using [these steps](/how-to-guides/app-guides/generate-certificate-signing-requests). With the certificate and private key in hand:

*   Select the appropriate App
*   Navigate to Endpoints
*   Add an endpoint
*   Under **Endpoint Type**, select the *Use a custom domain with a custom certificate* option.
*   Under **Certificate**, add a new certificate
*   Add the certificate and private key to the respective sections
*   Save Endpoint

> 📘 Aptible doesn't *require* that you use a valid certificate. If you want, you're free to use a self-signed certificate, but of course, your clients will receive errors when they connect.

# Format

The certificate should be a PEM-formatted certificate bundle, which means you should concatenate your certificate file along with the intermediate CA certificate files provided by your CA.

As for the private key, it should be unencrypted and PEM-formatted as well.

> ❗️ Don't forget to include intermediate certificates! Otherwise, your customers may receive a certificate error when they attempt to connect. However, you don't need to worry about the ordering of certificates in your bundle: Aptible will sort it properly for you.

# Hostname

When you use a Custom Certificate, it's your responsibility to ensure the [Custom Domain](/core-concepts/apps/connecting-to-apps/app-endpoints/custom-domain) you use and your certificate match.

If they don't, your users will see certificate errors.

# Supported Keys

Aptible supports the following types of keys for Custom Certificates:

*   RSA 1024
*   RSA 2048
*   RSA 4096
*   ECDSA prime256v1
*   ECDSA secp384r1
*   ECDSA secp521r1


# Custom Domain

Learn about setting up endpoints with custom domains

# Overview

Using a Custom Domain with an [Endpoint](/core-concepts/apps/connecting-to-apps/app-endpoints/overview), you can send traffic from your own domain to your [Apps](/core-concepts/apps/overview) running on Aptible.

# Endpoint Hostname

When you set up an Endpoint using a Custom Domain, Aptible will provide you with an Endpoint Hostname of the form `elb-XXX.aptible.in`.

<Tip> The following things are **not** Endpoint Hostnames:
`app.your-domain.io` is your Custom Domain and `app-123.on-aptible.com` is a [Default Domain](/core-concepts/apps/connecting-to-apps/app-endpoints/default-domain). In contrast, this is an Endpoint Hostname: `elb-foobar-123.aptible.in`. </Tip>

You should **not** send traffic directly to the Endpoint Hostname. Instead, to finish setting up your Endpoint, create a CNAME from your own domain to the Endpoint Hostname.

<Info> You can't create a CNAME for a domain apex (i.e. you **can** create a CNAME from `app.foo.com`, but you can't create one from `foo.com`). If you'd like to point your domain apex at an Aptible Endpoint, review the instructions here: [How do I use my domain apex with Aptible?](/how-to-guides/app-guides/use-domain-apex-with-endpoints/overview). </Info>

<Warning>Warning: Do **not** create a DNS A record mapping directly to the IP addresses for an Aptible Endpoint, or use the Endpoint IP addresses directly: those IP addresses change periodically, so your records and configuration would eventually go stale. </Warning>

# SSL / TLS Certificate

For Endpoints that require [SSL / TLS Certificates](/core-concepts/apps/connecting-to-apps/app-endpoints/overview#ssl--tls-certificates), you have two options:

*   Bring your own [Custom Certificate](/core-concepts/apps/connecting-to-apps/app-endpoints/custom-certificate): in this case, you're responsible for making sure the certificate you use is valid for the domain name you're using.
*   Use [Managed TLS](/core-concepts/apps/connecting-to-apps/app-endpoints/managed-tls): in this case, you'll have to provide Aptible with the domain name you plan to use, and Aptible will take care of certificate provisioning and renewal for you.


# Default Domain



> ❗️ Don't create a CNAME from your domain to an Endpoint using a Default Domain. These Endpoints use an Aptible-provided certificate that's valid for `*.on-aptible.com`, so using your own domain will result in a HTTPS error being shown to your users. If you'd like to use your own domain, set up an Endpoint with a [Custom Domain](/core-concepts/apps/connecting-to-apps/app-endpoints/custom-domain) instead.

When you create an [Endpoint](/core-concepts/apps/connecting-to-apps/app-endpoints/overview) with a Default Domain, Aptible will provide you with a hostname you can directly send traffic to, with the format `app-APP_ID.on-aptible.com`.

# Use Cases

Default Domains are ideal for internal and development apps, but if you need a branded hostname to send customers to, you should use a [Custom Domain](/core-concepts/apps/connecting-to-apps/app-endpoints/custom-domain) instead.

# SSL / TLS Certificate

For Endpoints that require [SSL / TLS Certificates](/core-concepts/apps/connecting-to-apps/app-endpoints/overview#ssl--tls-certificates), Aptible will automatically deploy a valid certificate when you use a Default Endpoint.

# One Default Endpoint per app

At most, one Default Endpoint can be used per app. If you need more than one Endpoint for an app, you'll need to use Endpoints with a [Custom Domain](/core-concepts/apps/connecting-to-apps/app-endpoints/custom-domain).

# Custom Default Domains

If you cannot use the on-aptible.com domain, or have concerns about the fact that external Endpoints using the on-aptible.com domain are discoverable via the App ID, we can replace `*.on-aptible.com` with your own domain. This option is only available for apps hosted on [Dedicated Stacks](/core-concepts/architecture/stacks#dedicated-stacks). Contact [Aptible Support](/how-to-guides/troubleshooting/aptible-support) for more information.


# gRPC Endpoints



![Image](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/ccfd24b-tls-endpoints.png)

gRPC Endpoints can be created using the [`aptible endpoints:grpc:create`](/reference/aptible-cli/cli-commands/cli-endpoints-grpc-create) command.

<Warning>Like TCP/TLS endpoints, gRPC endpoints do not support [Endpoint Logs](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/endpoint-logs)</Warning>

# Traffic

gRPC Endpoints terminate TLS traffic and transfer it as plain TCP to your app.

# Container Ports

gRPC Endpoints are configured similarly to [TLS Endpoints](/core-concepts/apps/connecting-to-apps/app-endpoints/tls-endpoints).

The Endpoint will listen for encrypted gRPC traffic on exposed ports and transfer it as plain gRPC traffic to your app over the same port. For example, if your [Image](/core-concepts/apps/deploying-apps/image/overview) exposes port `123`, the Endpoint will listen for gRPC traffic on port `123`, and forward it as plain gRPC traffic to your app [Containers](/core-concepts/architecture/containers/overview) on port `123`.

<Tip>Unlike [TLS Endpoints](/core-concepts/apps/connecting-to-apps/app-endpoints/tls-endpoints), gRPC Endpoints DO provide [Zero-Downtime Deployment](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/overview#zero-downtime-deployment).</Tip>

# Zero-Downtime Deployment / Health Checks

gRPC endpoints provide [Zero-Downtime Deployment](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/overview#zero-downtime-deployment) by leveraging [gRPC Health Checking](https://grpc.io/docs/guides/health-checking/).
Specifically, Aptible will use [health/v1](https://github.com/grpc/grpc-proto/blob/master/grpc/health/v1/health.proto)'s Health.Check call against your service, passing in an empty service name, and will only continue with the deploy if your application responds `SERVING`.

<Warning>When implementing the health service, please ensure you register your service with a blank name, as this is what Aptible looks for.</Warning>

# SSL / TLS Settings

Aptible offer a few ways to configure the protocols used by your endpoints for TLS termination through a set of [Configuration](/core-concepts/apps/deploying-apps/configuration) variables. These are the same variables as can be defined for [HTTP(S) Endpoints](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/overview). If set once on the application, they will apply to all gRPC, TLS, and HTTPS endpoints for that application.

# `SSL_PROTOCOLS_OVERRIDE`: Control SSL / TLS Protocols

The `SSL_PROTOCOLS_OVERRIDE` variable lets you customize the SSL Protocols allowed on your Endpoint. The format is that of Nginx's [ssl\_protocols directive](http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_protocols). Pay very close attention to the format, as a bad variable will prevent the proxies from starting.

# `SSL_CIPHERS_OVERRIDE`: Control ciphers

This variable lets you customize the SSL Ciphers used by your Endpoint.

The format is a string accepted by Nginx for its [ssl\_ciphers directive](http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_ciphers).

Pay very close attention to the required format, as here, again a bad variable will prevent the proxies from starting.

# `DISABLE_WEAK_CIPHER_SUITES`: an opinionated policy

Setting this variable to `true` (it has to be the exact string `true`) causes your Endpoint to stop accepting traffic over the `SSLv3` protocol or using the `RC4` cipher.

We strongly recommend setting this variable to `true` on all Endpoints nowadays.

# Examples

## Set `SSL_PROTOCOLS_OVERRIDE`

```shell
aptible config:set --app "$APP_HANDLE" \
        "SSL_PROTOCOLS_OVERRIDE=TLSv1.1 TLSv1.2"
```

## Set `DISABLE_WEAK_CIPHER_SUITES`

```shell
# Note: the value to enable DISABLE_WEAK_CIPHER_SUITES is the string "true"
# Setting it to e.g. "1" won't work.
aptible config:set --app "$APP_HANDLE" \
        DISABLE_WEAK_CIPHER_SUITES=true
```


# ALB vs. ELB Endpoints



[HTTP(S) Endpoints](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/overview) are available in two flavors:

*   [ALB Endpoints](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/alb-elb#alb-endpoints)
*   [Legacy ELB endpoints](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/alb-elb#legacy-elb-endpoints)

ALB Endpoints are next-generation endpoints on Aptible. All customers are encouraged to upgrade legacy ELB Endpoints to ALB Endpoints.

You can check whether an Endpoint is an ALB or ELB Endpoint in the Aptible dashboard by selecting your app, then choosing the "Endpoints" tab to view all endpoints associated with that app. ALB vs. ELB is listed under the "Platform" section.

# ALB Endpoints

ALB Endpoints are more robust than ELB Endpoints and provide additional features, including:

*   **Connection Draining:** Unlike ELB Endpoints, ALB Endpoints will drain connections to existing instances over 30 seconds when you redeploy your app, which ensures that even long-running requests aren't interrupted by a deploy.
*   **DNS-Level Failover:** via [Brickwall](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/maintenance-page#brickwall).
*   **HTTP/2 Client Support:** ALBs let you better utilize high-latency network connections via HTTP/2. Of course, HTTP/1 clients are still supported, and your app continues to receive traffic over HTTP/1.

<Info> Requests are balanced round-robin style. </Info>

# Legacy ELB endpoints

ELB Endpoints are deprecated for HTTPS services. Use ALBs instead. Review the upgrade checklist below to migrate to ALB Endpoints.

# Upgrading to ALB from ELB

When planning an upgrade from an ELB Endpoint to an ALB Endpoint, be aware of a few key differences between the platforms:

## Migration Checklist

### DNS Name

If you point your DNS records directly at the AWS DNS name for your ELB, DNS will break when you upgrade because the underlying AWS ELB will be deleted.

If you pointed your DNS records at the Aptible portable name (`elb-XXX-NNN.aptible.in`), you will not need to modify your DNS, as the Aptible record will automatically update. This means you will not need to change your DNS records if:

*   You created a `CNAME` record in your DNS provider from your domain name to this portable name, or
*   You are using DNSimple and created an ALIAS record to the Aptible portable name, or if you're using CloudFlare and are relying on CNAME flattening.

However, if you created a CNAME to the underlying ELB name (ending with `.elb.amazonaws.com`), or if you are using an `ALIAS` record in AWS Route 53, then you must update your DNS records to use the Aptible portable name before upgrading.

### HTTPS Protocols and Ciphers

The main difference between ELB and ALB Endpoints is that SSLv3 is supported (and enabled by default) on ELB Endpoints, whereas it is not available on ALB Endpoints. For an overwhelming majority of apps, not supporting SSLv3 is desirable.

For more information, review [HTTPS Protocols](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/https-protocols).

### `X-Forwarded-For` Header

Unlike ELB Endpoints, ALB Endpoints perform SSL/TLS termination at the load balancer level. Traffic is then re-encrypted, delivered to a reverse proxy on the same instance as your app container, and forwarded over HTTP to your app.

Both the ALB and the local reverse proxy will add an IP address to the `X-Forwarded-For` header. As a result, the X-Forwarded-For proxy will typically contain two IP addresses when using an ALB (whereas it would only contain one when using an ELB):

1.  The IP address of the client that connected to the ALB
2.  The IP address of the ALB itself

If you are using another proxy in front of your app (e.g., a CDN), there might be more IP addresses in the list. If your app contains logic that depends on this header (e.g., IP address filtering or matching header entries to proxies), you will want to account for the additional proxy.

## How to Upgrade

### Upgrade by Adding a New Endpoint

This option is recommended for **production apps**.

1.  Provision a new Endpoint, choosing ALB as the platform
2.  Once the new ALB Endpoint is provisioned, verify that your app is behaving properly when using the new ALB's Aptible portable name (`elb-XXX-NNN.aptible.in`)
3.  Update all DNS records pointing to the old ELB Endpoint to use the new ALB Endpoint instead
4.  Deprovision the old ELB Endpoint

### Upgrade in-place

<Tip>This option is recommended for **staging apps**.</Tip>

In the Aptible dashboard, locate the ELB Endpoint you want to upgrade. Select "Upgrade" under the "Platform" entry. Custom upgrade instructions for that specific endpoint will appear.


# Endpoint Logs



Logs from HTTP(S) Endpoints can be routed to [Log Drains](/core-concepts/observability/logs/log-drains/overview) (select this option when creating the Log Drain). These logs will contain all requests your Endpoint receives, as well as most errors pertaining to the inability of your App to serve a response, if applicable.

<Warning> The Log Drain that receives these logs cannot be pointed at an HTTPS endpoint in the same account. This would cause an infinite loop of logging, eventually crashing your Log Drain. Instead, you can host the target of the Log Drain in another account or use an external service.</Warning>

# Format

Logs are generated by Nginx in the following format, see the [Nginx documentation](http://nginx.org/en/docs/varindex.html) for definitions of specific fields:

```
$remote_addr:$remote_port $ssl_protocol/$ssl_cipher $host $remote_user [$time_local] "$request" $status $body_bytes_sent $request_time "$http_referer" "$http_user_agent" "$http_x_amzn_trace_id" "$http_x_forwarded_for";
```

<Warning> The `$remote_addr` field is not the client's real IP, it is the private network address associated with your Endpoint. To identify the IP Address the end-user connected to your App, you will need to refer to the `X-Forwarded-For` header. See [HTTP Request Headers](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/http-request-headers) for more information. </Warning>

<Tip> You should log the `X-Amzn-Trace-Id` header in your App, especially if you are proxying this request to another destination. This header will allow you to track requests as they are passed between services.</Tip>

# Metadata

For Log Drains that support embedding metadata in the payload ([HTTPS Log Drains](/core-concepts/observability/logs/log-drains/https-log-drains) and [Self-Hosted Elasticsearch Log Drains](/core-concepts/observability/logs/log-drains/elasticsearch-log-drains)), the following keys are included:

*   `endpoint_hostname`: The hostname of the specific Endpoint that serviced this request (eg elb-shared-us-east-1-doit-123456.aptible.in)
*   `endpoint_id`: The unique Endpoint ID

# Configuration Options

Aptible offer a few ways to customize what events get logged in your Endpoint Logs. These are set as [Configuration](/core-concepts/apps/deploying-apps/configuration) variables, so they are applied to all Endpoints for the given App.

## `SHOW_ELB_HEALTHCHECKS`

Endpoint Logs will always emit an error if your App container fails Runtime [Health Checks](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/health-checks), but by default, they do not log the health check request itself. These are not user requests, are typically very noisy, and are almost never useful since any errors for such requests are logged. See [Common Errors](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/endpoint-logs#common-errors) for further information about identifying Runtime Health Check errors.

Setting this variable to any value will show these requests.

# Common Errors

When your App does not respond to a request, the Endpoint will return an error response to the client. The client will be served a page that says *This application crashed*, and you will find a log of the corresponding request and error message in your Endpoint Logs. In these errors, "upstream" means your App.

<Note> If you have a [Custom Maintenance Page](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/maintenance-page#custom-maintenance-page) then you will see your maintenance page instead of *This application crashed*.</Note>

## 502

This response code is generally returned when your App generates a partial or otherwise incomplete response. The specific error logged is usually one of the following messages:

```
(104: Connection reset by peer) while reading response header from upstream
```

```
upstream prematurely closed connection while reading response header from upstream
```

These errors can be attributed to several possible causes:

*   Your Container exceeded the [Memory Limit](/core-concepts/scaling/memory-limits) for your Service while serving this request. You can tell if your Container has been restarted after exceeding its Memory Limit by looking for the message `container exceeded its memory allocation` in your [Log Drains](/core-concepts/observability/logs/log-drains/overview).
*   Your Container exited unexpectedly for some reason other than a deploy, restart, or exceeding its Memory Limit. This is typically caused by a bug in your App or one of its dependencies. If your Container unexpectedly exits, you will see `container has exited` in your logs.
*   A timeout was reached in your App that is shorter than the [Endpoint Timeout](/core-concepts/apps/connecting-to-apps/app-endpoints/overview#timeouts).
*   Your App encountered an unhandled exception.

## 504

This response code is generally returned when your App accepts a connection but does not respond at all or does not respond in a timely manner.

The following error message is logged along with the 504 response if the request reaches the idle timeout. See [Endpoint Timeouts](/core-concepts/apps/connecting-to-apps/app-endpoints/overview#timeouts) for more information.

```
(110: Operation timed out) while reading response header from upstream
```

The following error message is logged along with the 504 response if the Endpoint cannot establish a connection to your container at all:

```
(111: Connection refused) while connecting to upstream
```

A connection refused error can be attributed to several possible causes related to the service being unreachable:

*   Your Container is in the middle of restarting due to exceeding the [Memory Limit](/core-concepts/scaling/memory-limits) for your Service or because it exited unexpectedly for some reason other than a deploy, restart, or exceeding its Memory Limit.
*   The process inside your Container cannot accept any more connections.
*   The process inside your container has stopped responding or running entirely.

## Runtime Health Check Errors

Runtime Health Check Errors will be denoted by an error message like the ones documented above and will reference a request path of `/healthcheck`.

See [Runtime Health Checks](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/health-checks#runtime-health-checks) for more details about how these checks are performed.

# Uncommon Errors

## 499

This is not a response code that is returned to the client, but rather a 499 "response" in the Endpoint log indicates that the client closed the connection before the response was returned. This could be because the user closed their browser or otherwise did not wait for a response.

If you have any other proxy in front of this Endpoint, it may mean that this request reached the other proxy's idle timeout.

## "worker\_connections are not enough"

This error will occur when there are too many concurrent requests for the Endpoint to handle at this time. This can be caused either by an increase in the number of users accessing your system or indirectly by a performance bottleneck causing connections to remain open much longer than usual.

The total concurrent requests that can be opened at once can be increased by [Scaling](/core-concepts/scaling/overview) your App horizontally to add more Containers. However, if the root cause is poor performance of dependencies such as [Databases](/core-concepts/managed-databases/overview), this may only exacerbate the underlying issue.

If scaling your resources appropriately to the load does not resolve this issue, please contact [Aptible Support](/how-to-guides/troubleshooting/aptible-support).


# Health Checks



When you add [HTTP(S) Endpoints](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/overview), Aptible performs health checks on your App [Containers](/core-concepts/architecture/containers/overview) when deploying and throughout their lifecycle.

# Health Check Modes

Health checks on Aptible can operate in two modes:

## Default Health Checks

In this mode (the default), Aptible expects your App Containers to respond to health checks with any valid HTTP response, and does not care about the status code.

## Strict Health Checks

When Strict Health Checks are enabled, Aptible expects your App Containers to respond to health checks with a `200 OK` HTTP response. Any other response will be considered a [failure](/how-to-guides/troubleshooting/common-errors-issues/http-health-check-failed).

Strict Health Checks are useful if you're doing further checking in your App to validate that it's up and running.

To enable Strict Health Checks, set the `STRICT_HEALTH_CHECKS` [Configuration](/core-concepts/apps/deploying-apps/configuration) variable on your App to the value `true`. This  setting will apply to all Endpoints associated with your App.
<Note>The Endpoint has no notion of what hostname the App expects, so it sends health check requests to your application with `containers` as the [host](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Host). This is not a problem for most applications but for those that only allow the use of certain hosts, such as applications built with Django that use `ALLOWED_HOSTS`, this may result in non-200 responses. These applications will need to exempt hostname checking or add `containers` to the list of allowed hosts on `/healthcheck`.</Note>

<Warning> Redirections are not `200 OK` responses, so be careful with e.g. SSL redirections in your App that could cause your App to respond to the health check with a redirect, such as Rails' `config.force_ssl = true`. Overall, we strongly recommend verifying your logs first to check that you are indeed returning `200 OK` on `/healthcheck` before enabling Strict Health Checks.</Warning>

# Health Check Lifecycle

Aptible performs health checks at two stages:

*   [Release Health Checks](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/health-checks#release-health-checks) when releasing new App [Containers](/core-concepts/architecture/containers/overview).
*   [Runtime Health Checks](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/health-checks#runtime-health-checks) throughout the lifecycle of your App [Containers](/core-concepts/architecture/containers/overview).

## Release Health Checks

When deploying your App, Aptible ensures that new App Containers are receiving traffic before they're registered with load balancers.

When [Strict Health Checks](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/health-checks#strict-health-checks) are enabled, this request is performed on `/healthcheck`, otherwise, it is simply performed at `/`. In either case, the request is sent to the [Container Port](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/overview#container-port) for the Endpoint.

### Release Health Check Timeout

By default, Aptible waits for up to 3 minutes for your App to respond. If needed, you can increase that timeout by setting the `RELEASE_HEALTHCHECK_TIMEOUT` [Configuration](/core-concepts/apps/deploying-apps/configuration) variable on your App.

This variable must be set to your desired timeout in seconds. Any value from 0 to 900 (15 minutes) seconds is valid (we recommend that you avoid setting this to anything below 1 minute).

You can set this variable using the [`aptible config:set`](/reference/aptible-cli/cli-commands/cli-config-set) command:

```shell
aptible config:set --app "$APP_HANDLE" \
        RELEASE_HEALTHCHECK_TIMEOUT=600
```

## Runtime Health Checks

<Note>This health check is only executed if your [Service](/core-concepts/apps/deploying-apps/services) is scaled to 2 or more Containers.</Note>

When your App is live, Aptible periodically runs a health check to determine if your [Containers](/core-concepts/architecture/containers/overview) are healthy. Traffic will route to a healthy Container, except when:

*   No Containers are healthy. Requests will route to **all** Containers, regardless of health status, and will still be visible in your [Endpoint Logs](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/endpoint-logs).
*   Your Service is scaled to zero. Traffic will instead route to [Brickwall](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/maintenance-page#brickwall), our error page server.

The health check is an HTTP request sent to `/healthcheck`. A healthy Container must respond with `200 OK` HTTP response if [Strict Health Checks](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/health-checks#strict-health-checks) are enabled, or any status code otherwise. See [Endpoint Logs](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/endpoint-logs) for information about how Runtime Health Checks error logs can be viewed, and [Health Checks Failed](/how-to-guides/troubleshooting/common-errors-issues/http-health-check-failed) dealing with failures.

<Note> If needed, you can identify requests to `/healthcheck` coming from Aptible: they'll have the `X-Aptible-Health-Check` header set.</Note>


# HTTP Request Headers



[HTTP(S) Endpoints](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/overview) set standard HTTP headers to identify the original IP address of clients making requests to your Apps and the protocol they used:

<Note> Aptible Endpoints only allows headers composed of English letters, digits, hyphens, and underscores. If your App headers contain characters such as periods, you can allow this with `aptible config:set --app "$APP_HANDLE" "IGNORE_INVALID_HEADERS=off"`.</Note>

# `X-Forwarded-Proto`

This represents the protocol the end-user used to connect to your app. The value can be `http` or `https`.

# `X-Forwarded-For`

This represents the IP Address of the end-user connected to your App.

The `X-Forwarded-For` header is structured as a comma-separated list of IP addresses. It is generated by proxies that handle the request from an end-user to your app (each proxy appends the client IP they see to the header).

Here are a few examples:

## ALB Endpoint, users connect directly to the ALB

In this scenario, the request goes through two hops when it enters Aptible: the ALB, and an Nginx proxy. This means that the ALB will inject the client's IP address in the header, and Nginx will inject the ALB's IP address in the header.

In other words, the header will normally look like this: `$USER_IP,$ALB_IP`.

However, be mindful that end-users may themselves set the `X-Forwarded-For` in their request (typically if they're trying to spoof some IP address validation performed in your app). This means the header might look like this: `$SPOOFED_IP_A,$SPOOFED_IP_B,$SPOOFED_IP_C,$USER_IP,$ALB_IP`.

When processing the `X-Forwarded-For` header, it is important that you always start from the end and work you way back to the IP you're looking for. In this scenario, this means you should look at the second-to-last IP address in the `X-Forwarded-For` header.

## ALB Endpoint, users connect through a CDN

Assuming your CDN only has one hop (review your CDN's documentation for `X-Forwarded-For` if you're unsure), the `X-Forwarded-For` header will look like this: `$USER_IP,$CDN_IP,$ALB_IP`.

Similarly to the example above, keep in mind that the user can inject arbitrary IPs at the head of the list in the `X-Forwarded-For` header. For example, the header could look like this: `$SPOOFED_IP_A,$SPOOFED_IP_B,$USER_IP,$CDN_IP,$ALB_IP`.

So, in this case, you need to look at the third-to-last IP address in the `X-Forwarded-For` header.

## ELB Endpoint

ELB Endpoints have one less hop than ALB Endpoints. In this case, the client IP is the last IP in the `X-Forwarded-For` header.


# HTTPS Protocols



Aptible offer a few ways to configure the protocols used by your [HTTP(S) Endpoints](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/overview) for HTTPS termination through a set of [Configuration](/core-concepts/apps/deploying-apps/configuration) variables. These are the same variables as can be defined for [TLS Endpoints](/core-concepts/apps/connecting-to-apps/app-endpoints/tls-endpoints). If set once on the application, they will apply to all TLS and HTTPS endpoints for that application.

# `SSL_PROTOCOLS_OVERRIDE`: Control SSL / TLS Protocols

The `SSL_PROTOCOLS_OVERRIDE` variable lets you customize the SSL Protocols allowed on your Endpoint.

Available protocols depend on your Endpoint platform:

*   For [ALB Endpoints](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/alb-elb#alb-endpoints): you can choose from these 8 combinations:
    *   `TLSv1 TLSv1.1 TLSv1.2` (default)
    *   `TLSv1 TLSv1.1 TLSv1.2 PFS`
    *   `TLSv1.1 TLSv1.2`
    *   `TLSv1.1 TLSv1.2 PFS`
    *   `TLSv1.2`
    *   `TLSv1.2 PFS`
    *   `TLSv1.2 PFS TLSv1.3` (see note below comparing ciphers to `TLSv1.2 PFS`)
    *   `TLSv1.3`

<Note>
  `PFS` ensures your Endpoint's ciphersuites support perfect forward secrecy on TLSv1.2 or earlier. TLSv1.3 natively includes perfect forward secrecy.
  Note for `TLSv1.2 PFS TLSv1.3`, compared to ciphers for `TLSv1.2 PFS`, this adds `TLSv1.3` ciphers and omits the following:

  *   ECDHE-ECDSA-AES128-SHA
  *   ECDHE-RSA-AES128-SHA
  *   ECDHE-RSA-AES256-SHA
  *   ECDHE-ECDSA-AES256-SHA
</Note>

*   For [Legacy ELB endpoints](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/alb-elb#legacy-elb-endpoints): the format is Nginx's [ssl\_protocols directive](http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_protocols). Pay very close attention to the format! A bad variable will prevent the proxies from starting.

<Note> The format for ALBs and ELBs is effectively identical: the only difference is the supported protocols. This means that if you have both ELB Endpoints and ALB Endpoints on a given app, or if you're upgrading from ELB to ALB, things will work as expected as long as you use protocols supported by ALBs, which are stricter.</Note>

# `SSL_CIPHERS_OVERRIDE`: Control ciphers

<Note>This variable is only available on [Legacy ELB endpoints](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/alb-elb#legacy-elb-endpoints). On [ALB Endpoints](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/alb-elb#alb-endpoints), you normally don't need to customize the ciphers available.</Note>

This variable lets you customize the SSL Ciphers used by your Endpoint.

The format is a string accepted by Nginx for its [ssl\_ciphers directive](http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_ciphers).

Pay very close attention to the required format, as here again a bad variable will prevent the proxies from starting.

# `DISABLE_WEAK_CIPHER_SUITES`: an opinionated policy for ELBs

<Note> This variable is only available on [Legacy ELB endpoints](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/alb-elb#legacy-elb-endpoints). On [ALB Endpoints](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/alb-elb#alb-endpoints), weak ciphers are disabled by default, so that setting has no effect.</Note>

Setting this variable to `true` (it has to be the exact string `true`) causes your Endpoint to stop accepting traffic over the `SSLv3` protocol or using the `RC4` cipher.

We strongly recommend setting this variable to `true` on all ELB Endpoints nowadays. Or, better, yet, [upgrade to ALB Endpoints](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/alb-elb), where that's the default.

# Examples

## Set `SSL_PROTOCOLS_OVERRIDE`

```shell
aptible config:set --app "$APP_HANDLE" \
        "SSL_PROTOCOLS_OVERRIDE=TLSv1.1 TLSv1.2"
```

## Set `DISABLE_WEAK_CIPHER_SUITES`

```shell
# Note: the value to enable DISABLE_WEAK_CIPHER_SUITES is the string "true"
# Setting it to e.g. "1" won't work.
aptible config:set --app "$APP_HANDLE" \
        DISABLE_WEAK_CIPHER_SUITES=true
```


# HTTPS Redirect



<Tip> Your app can detect which protocol is being used by examining a request's `X-Forwarded-Proto` header. See [HTTP Request Headers](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/http-request-headers) for more information.</Tip>

By default, [HTTP(S) Endpoints](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/overview) accept traffic over both HTTP and HTTPS.

To disallow HTTP and redirect traffic to HTTPS at the Endpoint level, you can set the `FORCE_SSL` [Configuration](/core-concepts/apps/deploying-apps/configuration) variable to `true` (it must be set to the string `true`, not just any value).

# `FORCE_SSL` in detail

Setting `FORCE_SSL=true` on an app causes 2 things to happen:

*   Your HTTP(S) Endpoints will redirect all HTTP requests to HTTPS.
*   Your HTTP(S) Endpoints will set the `Strict-Transport-Security` header on responses with a max-age of 1 year.

Make sure you understand the implications of setting the `Strict-Transport-Security` header before using this feature.

In particular, by design, clients that connect to your site and receive this header will refuse to reconnect via HTTP for up to a year after they receive the `Strict-Transport-Security` header.

# Enabling `FORCE_SSL`

To set `FORCE_SSL`, you'll need to use the [`aptible config:set`](/reference/aptible-cli/cli-commands/cli-config-set) command.

The value must be set to the string `true` (e.g., setting to `1` won't work).

```shell
aptible config:set --app "$APP_HANDLE" \
        "FORCE_SSL=true"
```


# Maintenance Page



# Enable Maintenance Page

Maintenance pages are only available by request. Please get in touch with [Aptible Support](/how-to-guides/troubleshooting/aptible-support) to enable this feature. Maintenance pages are enabled stack-by-stack, so please confirm which stacks you would like to enable this feature when you contact Aptible Support.

# Custom Maintenance Page

You can configure your [App](/core-concepts/apps/overview) with a custom maintenance page.

This page will be served by your [HTTP(S) Endpoints](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/overview) when requests time out, or if your App is down. It will also be served if the Endpoint's underlying [Service](/core-concepts/apps/deploying-apps/services) is scaled to zero.

To configure one, set the `MAINTENANCE_PAGE_URL` [Configuration](/core-concepts/apps/deploying-apps/configuration) variable on your app:

```shell
aptible config:set --app "$APP_HANDLE" \
        MAINTENANCE_PAGE_URL=http://...
```

Aptible will download and cache the maintenance page when deploying your app. If it needs to be served, Aptible will serve the maintenance page directly to clients.

This means:

*   Make sure your maintenance page is publicly accessible so that Aptible can download it.
*   Don't use relative links in your maintenance page: the page won't be served from its original URL, so relative links will break.

If you don't set up a custom maintenance page, a generic Aptible maintenance page will be served instead.

# Brickwall

If your Service is scaled to zero, Aptible instead will route your traffic to an error page server: *Brickwall*.

Brickwall will serve your `Custom Maintenance Page` if you set one up, and fallback to a generic Aptible error page if you did not.

You usually shouldn't need to, but you can identify responses coming from Brickwall through their `Server` header, which will be set to `brickwall`. Brickwall returns a `502` error code which is not configurable.

If your Service is scaled up, but all app [Containers](/core-concepts/architecture/containers/overview) appear down, Aptible will route your traffic to *all* containers.


# HTTP(S) Endpoints



![Image](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/d869927-https-endpoints.png)

HTTP(S) Endpoints can be created in the following ways:

*   Using the [`aptible endpoints:https:create`](/reference/aptible-cli/cli-commands/cli-endpoints-https-create) command,
*   Using the Aptible Dashboard by:
    *   Navigating to the respective Environment
    *   Selecting the **Apps** tab
    *   Selecting the respective App
    *   Selecting **Create Endpoint**
    *   Selecting Use a custom domain with Managed HTTPS

Like all Endpoints, HTTP(S) Endpoints can be modified using the [`aptible endpoints:https:modify`](/reference/aptible-cli/cli-commands/cli-endpoints-https-modify) command.

# Traffic

HTTP(S) Endpoints are ideal for web apps. They handle HTTPS termination (and optionally redirect HTTP traffic to HTTPS), and pass it on as HTTP traffic to your app [Containers](/core-concepts/architecture/containers/overview).

<Note> HTTP(S) Endpoints can receive client connections from HTTP/1 and HTTP/2, but it is forced down to HTTP/1 through our proxy before it reaches the app.</Note>

# Container Port

When creating an HTTP Endpoint, you can specify the container port the traffic should be sent to. Different [Endpoints](/core-concepts/apps/connecting-to-apps/app-endpoints/overview) can use different ports, even if they're associated with the same [Service](/core-concepts/apps/deploying-apps/services).

If you don't specify a port, Aptible will pick a default port for you. The default port Aptible picks is the lexicographically lowest port exposed by your [Image](/core-concepts/apps/deploying-apps/image/overview). For example, if your Dockerfile contains `EXPOSE 80 443`, then the default port would be `443`.

It's important to make sure your app is listening on the port the Endpoint will route traffic to, or clients won't be able to access your app.

# Zero-Downtime Deployment

HTTP(S) Endpoints provide zero-downtime deployment: whenever you deploy or restart your [App](/core-concepts/apps/overview), Aptible will ensure that new containers are accepting traffic before terminating old containers. For more information on Aptible's deployment process, see [Releases](/core-concepts/apps/deploying-apps/releases/overview).

***

**Keep reading:**

*   [ALB vs. ELB Endpoints](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/alb-elb)
*   [Health Checks](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/health-checks)
*   [HTTP Request Headers](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/http-request-headers)
*   [HTTPS Protocols](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/https-protocols)
*   [HTTPS Redirect](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/https-redirect)
*   [Maintenance Page](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/maintenance-page)
*   [Endpoint Logs](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/endpoint-logs)


# IP Filtering



[Endpoints](/core-concepts/apps/connecting-to-apps/app-endpoints/overview) support IP filtering. This lets you restrict access to Apps hosted on Aptible to a set of whitelisted IP addresses or networks and block other incoming traffic.

The maximum amount of IP sources (aka IPv4 addresses and CIDRs) per Endpoint available for IP filtering is 50. IPv6 is not currently supported.

# Use Cases

While IP filtering is no substitute for strong authentication, it is useful to:

*   Further lock down access to sensitive apps and interfaces, such as admin dashboards or third-party apps you're hosting on Aptible for internal use only (For example: Kibana, Sentry).
*   Restrict access to your Apps and APIs to a set of trusted customers or data partners.

If you’re hosting development Apps on Aptible, IP filtering can also help you make sure no one outside your company can view your latest and greatest before you're ready to release it to the world.

Note that IP filtering only applies to [Endpoints](/core-concepts/apps/connecting-to-apps/app-endpoints/overview), not to [`aptible ssh`](/reference/aptible-cli/cli-commands/cli-ssh), [`aptible logs`](/reference/aptible-cli/cli-commands/cli-logs), and other backend access functionality provided by the [Aptible CLI](/reference/aptible-cli/cli-commands/overview) (this access is covered by strong mutual authentication, see our [Q1 2017 Webinar](https://www.aptible.com/resources/january-2017-updates-webinar/) for more detail).

# Enabling IP Filtering

IP filtering is configured via the Aptible Dashboard on a per-Endpoint basis:

*   Edit an existing Endpoint or Add a new Endpoint
*   Under the **IP Filtering** section, click to enable IP filtering.
*   Add the list of IPs in the input area that appears
*   Add more sources (IPv4 addresses and CIDRs) by separating them with spaces or newlines
*   You must allow traffic from at least one source to enable IP filtering.


# Managed TLS



When an [Endpoint](/core-concepts/apps/connecting-to-apps/app-endpoints/overview) requires a Certificate to perform SSL / TLS termination on your behalf, you can opt to let Aptible provision and renew certificates on your behalf. To do so, enable Managed HTTPS when creating your Endpoint. You'll need to provide Aptible with the [Custom Domain](/core-concepts/apps/connecting-to-apps/app-endpoints/custom-domain) name you intend to use so Aptible knows what certificate to provision. Aptible-provisioned certificates are valid for 90 days and are renewed automatically by Aptible.

Alternatively, you can provide your own with a [Custom Certificate](/core-concepts/apps/connecting-to-apps/app-endpoints/custom-certificate).

# Managed HTTPS Validation Records

Managed HTTPS uses [Let's Encrypt](https://letsencrypt.org) under the hood. There are two mechanisms Aptible can use to authorize your domain with Let's Encrypt, and provision certificates on your behalf:

For either of these to work, you'll need to create some CNAMEs in the DNS provider you use for your Custom Domain. The CNAMEs you need to create are listed in the Dashboard.

## http-01

> 📘  http-01 verification only works for Endpoints with [External Placement](/core-concepts/apps/connecting-to-apps/app-endpoints/overview#endpoint-placement) that do **not** use [IP Filtering](/core-concepts/apps/connecting-to-apps/app-endpoints/ip-filtering). Wildcard domains are not supported either.

HTTP verification relies on Let's Encrypt sending an HTTP request to your app and receiving a specific response (presenting that the response is handled by Aptible).

For this to work, you must have a setup a CNAME from your [Custom Domain](/core-concepts/apps/connecting-to-apps/app-endpoints/custom-domain) to the [Endpoint Hostname](/core-concepts/apps/connecting-to-apps/app-endpoints/custom-domain#endpoint-hostname) provided by Aptible.

## dns-01

> 📘 Unlike http-01 verification, dns-01 verification works with all Endpoints.

DNS verification relies on Let's Encrypt checking for the existence of a DNS TXT record with specific contents under your domain.

For this to work, you must have created a CNAME from `_acme-challenge.$DOMAIN` (where `$DOMAIN` is your [Custom Domain](/core-concepts/apps/connecting-to-apps/app-endpoints/custom-domain)) to an Aptible-provided validation name. This name is provided in the Dashboard (it's the `acme` subdomain of the [Endpoint's Hostname](/core-concepts/apps/connecting-to-apps/app-endpoints/custom-domain#endpoint-hostname)). The `acme` subdomain has the TXT record containing the challenge token that Let's Encrypt is looking for.

> ❗️ If you have a TXT record defined for `_acme-challenge.$DOMAIN` then Let's Encrypt will use this value instead of the value on the `acme` subdomain and it will not issue a certificate.

> 📘 If you are using a wildcard domain, then `$DOMAIN` above should be your domain name, but without the leading `*.` portion.

# Wildcard Domains

Managed TLS supports wildcard domains, which you'll have to verify using [dns-01](/core-concepts/apps/connecting-to-apps/app-endpoints/managed-tls#dns-01).

Aptible automatically creates a SAN certificate for the wildcard and its apex when using a wildcard domain. In other words, if you use `*.$DOMAIN`, then your certificate will be valid for any subdomain of `$DOMAIN`, as well as for `$DOMAIN` itself.

> ❗️ A single wildcard domain can only be used by one Endpoint at a time. This is due to the fact that the dns-01 validation record for all Endpoints using the domain will have the same `_acme-challenge` hostname but each requires different data to in the record. Therefore, only the Endpoint with the matching record will be able to renew its certificate. If you would like to use the same wildcard certificate with multiple Enpdoints you should acquire the certificate from a trusted certificate authority and use it as a [Custom Certificate](/core-concepts/apps/connecting-to-apps/app-endpoints/custom-certificate) on all of the Endpoints.

# Rate Limits

Let's Encrypt enforces a number of rate limits on certificate generation. In particular, Let's Encrypt limits the number of certificates you can provision per domain every week. See the [Let's Encrypt Rate Limits](https://letsencrypt.org/docs/rate-limits) documentation for details.

> ❗️ When you enable Managed TLS on an Endpoint, Aptible will provision an individual certificate for this Endpoint. If you create an Endpoint, provision a certificate for it via Managed TLS, then deprovision the Endpoint, this certificate will count against your weekly Let's Encrypt weekly rate limit.

# Creating CAA Records

If you want to set up a [CAA record](https://en.wikipedia.org/wiki/DNS_Certification_Authority_Authorization) for your domain, please add Let's Encrypt to the list of allowed certificate authorities. Aptible uses Let's Encrypt to provision certificates for your custom domain.


# App Endpoints



![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/7-app-ui.png)

# Overview

App Endpoints (also referred to as Endpoints) let you expose your Apps on Aptible to clients over the public internet or your [Stack](/core-concepts/architecture/stacks)'s internal network.

An App Endpoint is always associated with a given [Service](/core-concepts/apps/deploying-apps/services): traffic received by the App Endpoint will be load-balanced across all the [Containers](/core-concepts/architecture/containers/overview) for the service, which allows for highly available and horizontally scalable architectures.

> 📘 When provisioning a new App Endpoint, make sure the Service is scaled to at least one container. Attempts to create an endpoint on a Service scaled to zero will fail.

# Types of App Endpoints

The Endpoint type determines the type of traffic the Endpoint accepts (and on which ports it does so) and how that traffic is passed on to your App [Containers](/core-concepts/architecture/containers/overview). Aptible supports four types of App Endpoints:

*   [HTTP(S) Endpoints](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/overview) accept HTTP and HTTPS traffic and forward plain HTTP traffic to your containers. They handle HTTPS termination for you.
*   [gRPC Endpoints](/core-concepts/apps/connecting-to-apps/app-endpoints/grpc-endpoints) accept encrypted gRPC traffic and forward plain gRPC traffic to your containers. They handle TLS termination for you.
*   [TLS Endpoints](/core-concepts/apps/connecting-to-apps/app-endpoints/tls-endpoints) accept TLS traffic and forward it as TCP to your containers. Here again, TLS termination is handled by the Endpoint.
*   [TCP Endpoints](/core-concepts/apps/connecting-to-apps/app-endpoints/tcp-endpoints) accept TCP traffic and forward TCP traffic to your containers.

# Endpoint Placement

App Endpoints can be exposed to the public internet, called **External Placement**, or exposed only to other Apps deployed in the same [Stack, ](/core-concepts/architecture/stacks)called **Internal Placement**.

Regardless of placement, [IP Filtering](/core-concepts/apps/connecting-to-apps/app-endpoints/ip-filtering) allows users to limit which clients are allowed to connect to Endpoints.

> ❗️ Do not use internal endpoints as an exclusive security measure. Always authenticate requests to Apps, even Apps that are only exposed over internal Endpoints.

> 📘 Review [Using Nginx with Aptible Endpoints](/how-to-guides/app-guides/use-nginx-with-aptible-endpoints)  for details on using Nginx as a reverse proxy to route traffic to Internal Endpoints.

# Domain Name

App Endpoints let you bring your own [Custom Domain](/core-concepts/apps/connecting-to-apps/app-endpoints/custom-domain).

If you don't have or don't want to use a Custom Domain, you can use an Aptible-provided [Default Domain](/core-concepts/apps/connecting-to-apps/app-endpoints/default-domain).

# SSL / TLS Certificates

[HTTP(S) Endpoints](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/overview) and [TLS Endpoints](/core-concepts/apps/connecting-to-apps/app-endpoints/tls-endpoints) perform TLS termination for you, so if you are using either of those, Aptible will need a certificate valid for the hostname you plan to access the Endpoint from.

There are two cases here:

*   If you are using a [Default Domain](/core-concepts/apps/connecting-to-apps/app-endpoints/default-domain), Aptible controls the hostname and will provide an SSL/TLS Certificate as well.
*   However, if you are using a [Custom Domain](/core-concepts/apps/connecting-to-apps/app-endpoints/custom-domain), you will need to provide Aptible with a [Custom Certificate](/core-concepts/apps/connecting-to-apps/app-endpoints/custom-certificate), or enable [Managed TLS](/core-concepts/apps/connecting-to-apps/app-endpoints/managed-tls) and let Aptible provision the certificate for you.

# Timeouts

App Endpoints enforce idle timeouts on traffic, so clients will be disconnected after a configurable inactivity timeout.

By default, the inactivity timeout is 60 seconds. You can set the IDLE\_TIMEOUT [Configuration](/core-concepts/apps/deploying-apps/configuration) variable on Apps to a value in seconds in order to use a different timeout. The timeout can be set to any value from 30 to 2400 seconds.

For example:

```shell
aptible config: set--app "$APP_HANDLE" IDLE_TIMEOUT = 1200
```

# Inbound IP Addresses

App Endpoints use dynamic IP addresses, so no static IP addresses are available.

> 🧠 Each Endpoint uses an AWS Elastic Load Balancer, which uses dynamic IP addresses to seamlessly scale based on request growth and provides seamless maintenance (of the ALB itself by AWS). As such, AWS may change the set of IP addresses at any time.


# TCP Endpoints



![Image](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/15715dc-tcp-endpoints.png)

TCP Endpoints can be created using the [`aptible endpoints:tcp:create`](/reference/aptible-cli/cli-commands/cli-endpoints-tcp-create) command.

# Traffic

TCP Endpoints pass the TCP traffic they receive directly to your app.

# Container Ports

When creating a TCP Endpoint, you can specify the container ports the Endpoint should listen on. If you don't specify a port, Aptible will use all the ports exposed by your [Image](/core-concepts/apps/deploying-apps/image/overview).

The TCP Endpoint will listen for traffic on the ports you expose and transfer that traffic to your app [Containers](/core-concepts/architecture/containers/overview) on the same port.

For example, if you expose ports `123` and `456`, the Endpoint will listen on those two ports. Traffic received by the Endpoint on port `123` will be sent to your app containers on port `123`, and traffic received by the Endpoint on port `456` will be sent to your app containers on port `456`.

You may expose at most 10 ports. Note that this means that if your image exposes more than 10 ports, you will need to specify which ones should be exposed to provision TCP Endpoints.

> ❗️ Unlike [HTTP(S) Endpoints](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/overview), TCP Endpoints currently do not provide [Zero-Downtime Deployment](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/overview#zero-downtime-deployment). If you require Zero-Downtime Deployment for a TCP app, you'd need to architect it yourself, e.g. at the DNS level.


# TLS Endpoints



![Image](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/ccfd24b-tls-endpoints.png)

TLS Endpoints can be created using the [`aptible endpoints:tls:create`](/reference/aptible-cli/cli-commands/cli-endpoints-tls-create) command.

# Traffic

TLS Endpoints terminate TLS traffic and transfer it as plain TCP to your app.

# Container Ports

TLS Endpoints are configured similarly to [TCP Endpoints](/core-concepts/apps/connecting-to-apps/app-endpoints/tcp-endpoints).

The Endpoint will listen for TLS traffic on exposed ports and transfer it as TCP traffic to your app over the same port. For example, if your [Image](/core-concepts/apps/deploying-apps/image/overview) exposes port `123`, the Endpoint will listen for TLS traffic on port `123`, and forward it as TCP traffic to your app [Containers](/core-concepts/architecture/containers/overview) on port `123`.

> ❗️ Unlike [HTTP(S) Endpoints](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/overview), TLS Endpoints currently do not provide [Zero-Downtime Deployment](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/overview#zero-downtime-deployment). If you require Zero-Downtime Deployments for a TLS app, you'd need to architect it yourself, e.g. at the DNS level.

# SSL / TLS Settings

Aptible offer a few ways to configure the protocols used by your endpoints for TLS termination through a set of [Configuration](/core-concepts/apps/deploying-apps/configuration) variables. These are the same variables as can be defined for [HTTP(S) Endpoints](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/overview). If set once on the application, they will apply to all TLS and HTTPS endpoints for that application.

# `SSL_PROTOCOLS_OVERRIDE`: Control SSL / TLS Protocols

The `SSL_PROTOCOLS_OVERRIDE` variable lets you customize the SSL Protocols allowed on your Endpoint. The format is that of Nginx's [ssl\_protocols directive](http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_protocols). Pay very close attention to the format, as a bad variable will prevent the proxies from starting.

# `SSL_CIPHERS_OVERRIDE`: Control ciphers

This variable lets you customize the SSL Ciphers used by your Endpoint.

The format is a string accepted by Nginx for its [ssl\_ciphers directive](http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_ciphers).

Pay very close attention to the required format, as here, again a bad variable will prevent the proxies from starting.

# `DISABLE_WEAK_CIPHER_SUITES`: an opinionated policy

Setting this variable to `true` (it has to be the exact string `true`) causes your Endpoint to stop accepting traffic over the `SSLv3` protocol or using the `RC4` cipher.

We strongly recommend setting this variable to `true` on all TLS Endpoints nowadays.

# Examples

## Set `SSL_PROTOCOLS_OVERRIDE`

```shell
aptible config:set --app "$APP_HANDLE" \
        "SSL_PROTOCOLS_OVERRIDE=TLSv1.2 TLSv1.3"
```

## Set `DISABLE_WEAK_CIPHER_SUITES`

```shell
# Note: the value to enable DISABLE_WEAK_CIPHER_SUITES is the string "true"
# Setting it to e.g. "1" won't work.
aptible config:set --app "$APP_HANDLE" \
        DISABLE_WEAK_CIPHER_SUITES=true
```


# Outbound IP Addresses

Learn about using outbound IP addresses to create an allowlist

# Overview

You can share an app's outbound IP address pool with partners or vendors that use an allowlist.

<Note> [Stacks](/core-concepts/architecture/stacks) have a single NAT gateway, and all requests originating from an app use the outbound IP addresses associated with that NAT gateway's IP address.</Note>

These IP addresses are *different* from the IP addresses associated with an app's [Endpoints](/core-concepts/apps/connecting-to-apps/app-endpoints/overview), which are used for *inbound* requests.

The outbound IP addresses for an app *may* change for the following reasons:

1.  Aptible migrates the [Environment](/core-concepts/architecture/environments) the app is deployed on to a new [stack](/core-concepts/architecture/stacks)
2.  Failure of the underlying NAT instance
3.  Failover to minimize downtime during maintenance

In either case, Aptible selects the new IP address from a pool of pre-defined IP addresses associated with the NAT gateway. This set pool will not change without notification from Aptible.

<Warning> For this reason, when sharing IP addresses with vendors or partners for whitelisting, ensure all of the provided outbound IP addresses are whitelisted. </Warning>

# Determining Outbound IP Address Pool

Your outbound IP address pool can be identified by navigating to the [Stack](/core-concepts/architecture/stacks) with the Aptible Dashboard.


# Connecting to Apps

Learn how to connect to your Aptible Apps

# App Endpoints (Load Balancers)

Expose your apps to the internet via Endpoints. All traffic received by the Endpoint will be load-balanced across all the Containers for the service. IP Filtering locks down which clients are allowed to connect to your Endpoint.

<Card title="Learn more aobut App Endpoints (Load Balancers)" icon="book" iconType="duotone" href="https://www.aptible.com/docs/endpoints" />

# Ephemeral SSH Sessions

Create an ephemeral SSH Session configured identically to your App Containers. These Ephemeral SSH Sessions are great for debugging, one-off scripts, and running ad-hoc jobs.

<Card title="Learn more about Ephemeral SSH Sessions" icon="book" iconType="duotone" href="https://www.aptible.com/docs/ssh-sessions" />

# Outbound IP Addresses

Share an App's outbound IP address with partners or vendors that use an allowlist

<Card title="Learn more about Outbound IP Addresses" icon="book" iconType="duotone" href="https://www.aptible.com/docs/outbound-ips" />


# Ephemeral SSH Sessions

Learn about using Ephemeral SSH sessions on Aptible

# Overview

Aptible offers Ephemeral SSH Sessions for accessing containers that are configured identically to App containers, making them ideal for managing consoles and running ad-hoc jobs.

Unlike regular containers, ephemeral containers won't be restarted when they crash. If your connection to Aptible drops, the remote Container will be terminated.

## Creating Ephemeral SSH Sessions

Ephemeral SSH Sessions can be created using the [`aptible ssh`](/reference/aptible-cli/cli-commands/cli-ssh) command.

<Note> Ephemeral containers are not the same size as your App Container. By default, ephemeral containers are scaled to 1024 MB. </Note>

# Terminating Ephemeral SSH Sessions

### Manually Terminating

You can terminate your SSH sessions by closing the terminal session you spawned it in or exiting the container.

<Tip> It may take a bit of time for our API to acknowledge that the SSH session is shut down. If you're running into Plan Limits trying to create another one, wait a few minutes and try again.</Tip>

### Expiration

SSH sessions will automatically terminate upon expiration. By default, SSH sessions will expire after seven days. Contact [Aptible Support](/how-to-guides/troubleshooting/aptible-support) to reduce the default SSH session duration for Dedicated [Stacks](/core-concepts/architecture/stacks). Please note that this setting takes effect regardless of whether the session is active or idle.

<Note> When you create a SSH session using [`aptible ssh`](/reference/aptible-cli/cli-commands/cli-ssh), you're logging in to an **ephemeral** container. You are **not** logging to one of your running app containers. This means that running commands like `ps` won't reflect what's actually running in your App containers, and that files that exist in your App containers will not be present in the ephemeral session. </Note>

# Logging

<Warning> **If you process PHI or  sensitive information in your app or database:** it's very likely that PHI will at some point leak in your SSH session logs. To ensure compliance, make sure you have the appropriate agreements in place with your logging provider before sending your SSH logs there. For PHI, you'll need a BAA. </Warning>

Logs from Ephemeral SSH Sessions can be routed to [Log Drains](/core-concepts/observability/logs/log-drains/overview).

Note that for interactive sessions, Aptible allocates a TTY for your container, so your Log Drain will receive exactly what the end user is seeing. This has two benefits:

*   You see the user's input as well.
*   If you’re prompting the user for a password using a safe password prompt that does not write back anything, nothing will be sent to the Log Drain either. That prevents you from leaking your passwords to your logging provider.

## Metadata

For Log Drains that support embedding metadata in the payload ([HTTPS Log Drains](/core-concepts/observability/logs/log-drains/https-log-drains) and [Self-Hosted Elasticsearch Log Drains](/core-concepts/observability/logs/log-drains/elasticsearch-log-drains)), the following keys are included:

*   `operation_id`: The ID of the Operation that resulted in the creation of this Ephemeral Session.
*   `operation_user_name`: The name of the user that created the Operation.
*   `operation_user_email`: The email of the user that created the Operation.
*   `APTIBLE_USER_DOCUMENT`: An expired JWT object with user information.

For Log Drains that don't support embedding metadata (i.e., [Syslog Log Drains](/core-concepts/observability/logs/log-drains/syslog-log-drains)), the ID of the Operation that created the session is included in the logs.


# Configuration

Learn about how configuration variables provide persistent environment variables for your app's containers, simplifying settings management

# Overview

Configuration variables contain a collection of keys and values, which will be made available to your app's containers as environment variables. Configurable variables persist once set, eliminating the need to repeatedly set the variables upon deploys. These variables will remain available in your app containers until modified or unset.

You can use the following configuration variables:

*   `FORCE_SSL` (See [HTTPS Redirect](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/https-redirect))
*   `STRICT_HEALTH_CHECKS` (See [Strict Health Checks](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/health-checks#strict-health-checks))
*   `IDLE_TIMEOUT` (See [Endpoint Timeouts](/core-concepts/apps/connecting-to-apps/app-endpoints/overview#timeouts))
*   `SSL_PROTOCOLS_OVERRIDE` (See [HTTPS Protocols](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/https-protocols))
*   `SSL_CIPHERS_OVERRIDE` (See [HTTPS Protocols](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/https-protocols))
*   `DISABLE_WEAK_CIPHER_SUITE` (See [HTTPS Protocols](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/https-protocols))
*   `SHOW_ELB_HEALTHCHECKS` (See [Endpoint configuration variables](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/endpoint-logs#configuration-options))
*   `RELEASE_HEALTHCHECK_TIMEOUT` (See [Release Health Checks](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/health-checks#release-health-checks))
*   `MAINTENANCE_PAGE_URL` (See [Maintenance Page](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/maintenance-page))
*   `APTIBLE_PRIVATE_REGISTRY_USERNAME` (See [Private Registry Authentication](/how-to-guides/app-guides/migrate-dockerfile-to-direct-image-deploy#private-registry-authentication))
*   `APTIBLE_PRIVATE_REGISTRY_PASSWORD` (See [Private Registry Authentication](/how-to-guides/app-guides/migrate-dockerfile-to-direct-image-deploy#private-registry-authentication))
*   `APTIBLE_DO_NOT_WIPE` (See [Disabling filesystem wipes](/core-concepts/architecture/containers/container-recovery#disabling-filesystem-wipes))

# FAQ

<AccordionGroup>
  <Accordion title="How do I set or modify configuration variables?">
    See related guide:

    <Card title="How to set or modify configuration variables" icon="book-open-reader" iconType="duotone" href="https://www.aptible.com/docs/set-configuration-variables" />
  </Accordion>

  <Accordion title="How do I synchronize configuration and code change?">
    See related guide:

    <Card title="How to synchronize configuration and code changes" icon="book-open-reader" iconType="duotone" href="https://www.aptible.com/docs/synchronized-deploys" />
  </Accordion>
</AccordionGroup>


# Companion Git Repository



<Warning> **Companion Git Repositories are a legacy mechanism!** There is now an easier way to provide [Procfiles](/how-to-guides/app-guides/define-services) and [`.aptible.yml`](/core-concepts/apps/deploying-apps/releases/aptible-yml) when deploying from Docker Image. In practice, this means you should not need to use a companion git repository anymore. For more information, review [Procfiles and `.aptible.yml` with Direct Docker Image Deploy](/core-concepts/apps/deploying-apps/image/deploying-with-docker-image/procfile-aptible-yml-direct-docker-deploy). </Warning>

# Using a Companion Git Repository

Some features supported by Aptible don't map perfectly to Docker Images.

Specifically:

*   [Explicit Services (Procfiles)](/how-to-guides/app-guides/define-services#explicit-services-procfiles)
*   [`.aptible.yml`](/core-concepts/apps/deploying-apps/releases/aptible-yml)

You can however use those along with [Direct Docker Image Deploy](/how-to-guides/app-guides/migrate-dockerfile-to-direct-image-deploy) by adding a Companion Git Repository.

# Providing a Procfile

When you deploy directly from a Docker image, Aptible uses your image's `CMD` to know which service command to run, you can create a separate [App](/core-concepts/apps/overview), or add a [Procfile](/how-to-guides/app-guides/define-services) via a companion git repository.

To do so, create a new empty git repository containing a Procfile, and include all your services in the Procfile.

For example:

```yaml
web: some-command
background: some-other-command
```

Then, push this git repository to your App's Git Remote. Make sure to push to the `master` branch to trigger a deploy:

```shell
git push aptible master
```

When you do this, Aptible will use your Docker Image, but with the services defined in the Procfile.

# Providing .aptible.yml

When you deploy directly from a Docker Image, you don't normally use a git repository associated with your app. This means you don't have a [`.aptible.yml`](/core-concepts/apps/deploying-apps/releases/aptible-yml) file.

Generally, we recommend architecting your app to avoid the need for a .aptible.yml file when using Direct Docker Image deploy, but if you'd like to use one nonetheless, you can.

To do so, create new empty git repository containing a .aptible.yml file, and include your desired configuration in it.

For example:

```yaml
before_release:
  - do some task
  - do other task
```

Then, push this git repository to your App's Git Remote. Make sure to push to the `master` branch to trigger a deploy:

```shell
git push aptible master
```

When you do this, Aptible will use your Docker Image, and run respect the instructions from your .aptible.yml file, e.g. by running `before_release` commands;

# Synchronizing git and Docker image deploys

If you are using a companion git repository to complement your Direct Docker Image deploy with a Procfile and/or a .aptible.yml file, you can synchronize their deploys.

To do so, push the updated Procfile and/or .aptible.yml files to a branch on Aptible that is *not* master. For example:

```shell
git push aptible master:update-the-Procfile
```

Pushing to a non-master will *not* trigger a deploy. Once that's done, deploy normally using `aptible deploy`, but add the `--git-commitish` argument, like so:

```shell
aptible deploy \
  --app "$APP_HANDLE" \
  --docker-image "$DOCKER_IMAGE" \
  --git-commitish "$BRANCH"
```

This will trigger a new deployment using the image you provided, using the services from your Procfile and/or the instructions from your .aptible.yml file.

In the example above, `$BRANCH` represents the remote branch you pushed your updated files to. In the `git push` example above, that's `update-the-Procfile`.

# Disabling Companion Git Repositories

Companion Git Repositories can be disabled on dedicated stacks by request to [Aptible Support](/how-to-guides/troubleshooting/aptible-support). Once disabled, deploying using a companion git repository will result in a failed operation without any warning.

When Companion Git Repositories are disabled, your deploys must use either deploy with Git or Docker Image. Attempts to perform mixed-mode deployment using Companion Git Repositories will raise an error.

## How-to

If you'd like to go down this route, first make sure that you are not using Companion Git Repositories in your deployments. There is a "Deploying with a Companion Git Repository is deprecated" warning when you deploy that will inform you if this is the case. If you find an app currently using a Companion Git Repository, you'll need to get rid of it. To do so, follow the instructions in [Migrating from Dockerfile Deploy](/how-to-guides/app-guides/migrate-dockerfile-to-direct-image-deploy). Once all your apps have been migrated, contact [Aptible Support](/how-to-guides/troubleshooting/aptible-support) to disable the Companion Git Repositories.


# Deploying with Docker Image

Learn about the deployment method for the most control: deploying via Docker Image

![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/Direct-Docker-Image-Deploy.png)

# Overview

If you need absolute control over your Docker image's build, Aptible lets you deploy directly from a Docker image. Additionally, [Aptible's Terraform Provider](/reference/terraform) currently only supports Direct Docker Image Deployment - so this is a benefit to using this deployment method.

The workflow for Direct Docker Image Deploy is as follows:

1.  You build your Docker image locally or in a CI platform
2.  You push the image to a Docker registry
3.  You use the [`aptible deploy`](/reference/aptible-cli/cli-commands/cli-deploy) command to initiate a deployment on Aptible from the image stored in your registry.

# Private Registry Authentication

You may need to provide Aptible with private registry credentials to pull images on your behalf. To do this, use the `APTIBLE_PRIVATE_REGISTRY_USERNAME` and `APTIBLE_PRIVATE_REGISTRY_PASSWORD` [Configuration](/core-concepts/apps/deploying-apps/configuration) variables.

<Note> If you set those Configuration variables, Aptible will use them regardless of whether the image you are attempting to pull is public or private. If needed, you can unset those Configuration variables by setting them to an empty string (""). </Note>

## Long term credentials

Most Docker image registries provide long-term credentials, which you only need to provide once to Aptible.

With Direct Docker Image Deploy, you only need to provide the registry credentials the first time you deploy.

```javascript
aptible deploy \
--app "$APP_HANDLE" \
--docker-image "$DOCKER_IMAGE" \
--private-registry-username "$USERNAME" \
--private-registry-password "$PASSWORD"
```

## Short term credentials

Some registries, like AWS Elastic Container Registry (ECR), only provide short-term credentials. In these cases, you will likely need to update your registry credentials every time you deploy.

With Direct Docker Image Deploy, you need to provide updated credentials whenever you deploy, as if it were the first time you deployed:

```javascript
aptible deploy \
--app "$APP_HANDLE" \
--docker-image "$DOCKER_IMAGE" \
--private-registry-username "$USERNAME" \
--private-registry-password "$PASSWORD"
```

# FAQ

<AccordionGroup>
  <Accordion title="How do I deploy from Docker Image?">
    See related guide:

    <Card title="How to deploy via Docker Image" icon="book-open-reader" iconType="duotone" href="https://www.aptible.com/docs/direct-docker-image-deploy-example" />
  </Accordion>

  <Accordion title="How do I switch from deploying with Git to deploying from Docker Image?">
    See related guide:

    <Card title="How to migrate from deploying via Docker Image to deploying via Git" icon="book-open-reader" iconType="duotone" href="https://www.aptible.com/docs/migrating-from-dockerfile-deploy" />
  </Accordion>

  <Accordion title="How do I synchronize configuration and code change?">
    See related guide:

    <Card title="How to synchronize configuration and code changes" icon="book-open-reader" iconType="duotone" href="https://www.aptible.com/docs/synchronized-deploys" />
  </Accordion>
</AccordionGroup>


# Procfiles and  `.aptible.yml`



To provide a [Procfile](/how-to-guides/app-guides/define-services) or a [`.aptible.yml`](/core-concepts/apps/deploying-apps/releases/aptible-yml) when using [Direct Docker Image Deploy](/how-to-guides/app-guides/migrate-dockerfile-to-direct-image-deploy), you need to include these files in your Docker image at a pre-defined location:

*   The `Procfile` must be located at `/.aptible/Procfile`.
*   The `.aptible.yml` must be located at `/.aptible/.aptible.yml`.

Both of these files are optional.

# Creating a suitable Docker Image

Here is how you can create those files in your Dockerfile, assuming you have files named `Procfile` and `.aptible.yml` at the root of your Docker build context:

```dockerfile
RUN mkdir /.aptible/
ADD Procfile /.aptible/Procfile
ADD .aptible.yml /.aptible/.aptible.yml
```

Note that if you are using `docker build .` to build your image, then the build context is the current directory.

# Alternatives

Aptible also supports providing these files through a [Companion Git Repository](/core-concepts/apps/deploying-apps/image/deploying-with-docker-image/companion-git-repository).

However, this approach is much less convenient, so we strongly recommend including the files in the Docker image instead.


# Docker Build



# Build context

When Aptible builds your Docker image using [Dockerfile Deploy](/how-to-guides/app-guides/deploy-from-git), the build context contains the git repository you pushed and a [`.aptible.env`](/how-to-guides/app-guides/access-config-vars-during-docker-build#aptible-env) file injected by Aptible at the root of your repository.

Here are a few caveats you should be mindful of:

*   **Git clone is a shallow clone**
    *   When Aptible ships your git repository to a build instance, it uses a git shallow clone.
    *   This has no impact on the code being cloned, but you should be mindful that using e.g. `git log` within your container will yield a single commit: the one you deployed from.
*   **File timestamps are all set to January 1st, 2000**
    *   Git does not preserve timestamps on files. This means that when Aptible clones a git repository, the timestamps on your files represent when the files were cloned, as opposed to when you last modified them.
    *   However, Docker caching relies on timestamps (i.e., a different timestamp will break the Docker build cache), so timestamps that reflect the clone time would break Docker caching.
    *   To optimize your build times, Aptible sets all the timestamps on all files in your repository to an arbitrary timestamp: January 1st, 2000, at 00:00 UTC.
*   **`.dockerignore` is not used**
    *   The `.dockerignore` file is read by the Docker CLI client, not by the Docker server.
    *   However, Aptible does not use the Docker CLI client and does not currently use the `.dockerignore` file.

# Multi-stage builds

Although Aptible supports [multi-stage builds](https://docs.docker.com/build/building/multi-stage/), there are a few points to keep in mind:

*   You cannot specify a target stage to be built within Aptible. This means the final stage is always used as the target.
*   Aptible always builds all stages regardless of dependencies or lack thereof in the final stage.


# Deploying with Git

Learn about the easiest deployment method to get started: deploying via Git Push

![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/Dockerfile-deploy.png)

# Overview

Deploying via [Git](https://git-scm.com/) (formerly known as Dockerfile Deploy) is the easiest deployment method to get up and running on Aptible - if you're migrating over from another Platform-as-a-Service or your team isn't using Docker yet.

The deployment process is as follows:

1.  You add a [Dockerfile](/how-to-guides/app-guides/deploy-from-git#dockerfile) at the root of your code repository and commit it.
2.  You use `git push` to push your code repository to a [Git Remote](/how-to-guides/app-guides/deploy-from-git#git-remote) provided by Aptible.
3.  Aptible builds a new [image](/core-concepts/apps/deploying-apps/image/overview) from your Dockerfile and deploys it to new [app](/core-concepts/apps/overview) containers

# Get Started

If you are just getting started [deploy a starter template](/getting-started/deploy-starter-template/overview) or [review guides for deploying with Git](/how-to-guides/app-guides/deploy-from-git#featured-guide).

# Dockerfile

The Dockerfile is a series of instructions that indicate how Docker should build an image for your app when you [deploy via Git](/how-to-guides/app-guides/deploy-from-git).

To build your Dockerfile on Aptible, the file must be named Dockerfile, and located at the root of your repository.

If it takes Aptible longer than 30 minutes to build your image from the Dockerfile, the deploy [Operation](/core-concepts/architecture/operations) will time out. If your image takes long to build, consider [deploying via Docker Image](/how-to-guides/app-guides/migrate-dockerfile-to-direct-image-deploy).

<Tip>New to Docker? Check out our [guide for Getting Started with Docker.](/how-to-guides/app-guides/getting-started-with-docker)</Tip>

# Git Remote

A Git Remote is a reference to a repository stored on a remote server. When you provision an Aptible app, the platform creates a unique Git Remote. For example:

```javascript
git @beta.aptible.com: $ENVIRONMENT_HANDLE / $APP_HANDLE.git
```

When deploying via Git, you push your code repository to the unique Git Remote for your app. To do this, you must:

*   Register an [SSH Public Key](/core-concepts/security-compliance/authentication/ssh-keys) with Aptible
*   Push your code to the master or main branch of the Aptible Git Remote

<Warning> If [SSO is required for accessing](/core-concepts/security-compliance/authentication/sso#require-sso-for-access) your Aptible organization, attempts to use the Git Remote will return an App not found or not accessible error. Users will need to be added to the [SSO Allow List](/core-concepts/security-compliance/authentication/sso#exempt-users-from-sso-requirement) to access your organization's resources via Git. </Warning>

## Branches and refs

There are three branches that take action on push.

*   `master` and `main` attempt to deploy the incoming code before accepting the changes.
*   `aptible-scan` checks that the repo is deployable, usually by verifying the dockerfile can be built.

If you push to a different branch, you can manually deploy the branch using the `aptible deploy --git-commitish $BRANCH_NAME` [CLI command](/reference/aptible-cli/cli-commands/cli-deploy). This can also be used to [synchronize code and configuration changes](/how-to-guides/app-guides/synchronize-config-code-changes).

When pushing multiple refs, each is processed individually. This means, for example you could check the deployability of your repo and push to an alternate branch using `git push $APTIBLE_REMOTE $BRANCH_NAME:aptible-scan $BRANCH_NAME`.

### Aptible's Git Server's SSH Key Fingerprints

For an additional security check, public key fingerprints can be used to validate the connection to Aptible's Git server. These are Aptible's public key fingerprints for the Git server (beta.aptible.com):

*   SHA256:tA38HY1KedlJ2GRnr5iDB8bgJe9OoFOHK+Le1vJC9b0 (RSA)
*   SHA256:FsLUs5U/cZ0nGgvy/OorvGSaLzvLRSAo4+xk6+jNg8k (ECDSA)

# Private Registry Authentication

You may need to provide Aptible with private registry credentials to pull images on your behalf. To do this, use the following [configuration](/core-concepts/apps/deploying-apps/configuration) variables.

*   `APTIBLE_PRIVATE_REGISTRY_USERNAME` 
*   `APTIBLE_PRIVATE_REGISTRY_PASSWORD` 

<Note> Aptible will use configuration varibles when the image is attempting to be pulled is public or private. Configuration variables can be unset by setting them to an empty string ("").</Note>

## Long term credentials

Most Docker image registries provide long-term credentials, which you only need to provide once to Aptible.

It's recommended to set the credentials before updating your `FROM` declaration to depend on a private image and push your Dockerfile to Aptible. Credentials can be set in the following ways:

*   From the Aptible Dashboard by
    *   Navigating to the App
    *   Selecting the \*\*Configuration \*\*tab
*   Using the [`aptible config:set`](/reference/aptible-cli/cli-commands/cli-config-set) CLI command:

```javascript
aptible config: set \
--app "$APP_HANDLE" \
"APTIBLE_PRIVATE_REGISTRY_USERNAME=$USERNAME"
"APTIBLE_PRIVATE_REGISTRY_PASSWORD=$PASSWORD"
```

## Short term credentials

Some registries, like AWS Elastic Container Registry (ECR), only provide short-term credentials. In these cases, you will likely need to update your registry credentials every time you deploy.

Since Docker credentials are provided as [configuration](/core-concepts/apps/deploying-apps/configuration) variables, you'll need to use the CLI in addition to `git push` to deploy. There are two solutions to this problem.

1.  **Recommended**:
    [Synchronize configuration and code changes](/how-to-guides/app-guides/synchronize-config-code-changes). This approach is the fastest.
2.  Update the variables using [`aptible config:set`](/reference/aptible-cli/cli-commands/cli-config-set), deploy using `git push aptible master`, and restart your app to apply to apply the configuration change before the deploy can start. This approach is slower.

# FAQ

<AccordionGroup>
  <Accordion title="How do I deploy with Git Push?">
    See related guide:

    <Card title="How to deploy from Git" icon="book-open-reader" iconType="duotone" href="https://www.aptible.com/docs/dockerfile-deploy-example" />
  </Accordion>

  <Accordion title="How do I switch from deploying via Docker Image to deploying via Git?">
    See related guide:

    <Card title="How to migrate from deploying via Docker Image to deploying via Git" icon="book-open-reader" iconType="duotone" href="https://www.aptible.com/docs/migrating-from-direct-docker-image-deploy" />
  </Accordion>

  <Accordion title="How do I access configuration variables during Docker build?">
    See related guide:

    <Card title="How to access configuration variables during Docker build" icon="book-open-reader" iconType="duotone" href="https://www.aptible.com/docs/docker-build-configuration" />
  </Accordion>

  <Accordion title="How do I synchronize configuration and code change?">
    See related guide:

    <Card title="How to synchronize configuration and code changes" icon="book-open-reader" iconType="duotone" href="https://www.aptible.com/docs/synchronized-deploys" />
  </Accordion>
</AccordionGroup>


# Image

Learn about deploying Docker images on Aptible

# Overview

On Aptible, a [Docker image](https://docs.docker.com/get-started/overview/#images) is used to deploy app containers.

# Deploying with Git

Deploy with Git (formerly known as Dockerfile Deploy) where you push source code (including a Dockerfile) via Git repository to Aptible, and the platform creates a Docker image on your behalf.

<Card title="Learn more about deploying with Git" icon="book" iconType="duotone" href="https://www.aptible.com/docs/dockerfile-deploy" />

# Deploy from Docker Image

Deploy from Docker Image (formerly known as Direct Docker Image Deploy) where you deploy a Docker image that you have built yourself (e.g., in a CI environment), push it to a registry, and tell Aptible to fetch it from there.

<Card title="Learn more about deploying from Docker Image" icon="book" iconType="duotone" href="https://www.aptible.com/docs/direct-docker-image-deploy" />


# Linking Apps to Sources



# Overview

Apps can be connected to their [Sources](/core-concepts/observability/sources) to enable the Aptible dashboard to provide details about the code that is deployed in your infrastructure, enabling your team to answer the question "*what's deployed where?*".

When an App is connected to its Source, you'll see details about the currently-deployed revision (the git ref, SHA, commit message, and other information) in the header of the App Details page, as well as a running history of revision information on the Deployments tab.

# Sending Deployment Metadata to Aptible

To get started, you'll need to configure your deployment pipeline to send Source information when your App is deployed.

## Using the Aptible Deploy GitHub Action

> 📘 If you're using **version `v4` or later** of the official [Aptible Deploy GitHub Action](https://github.com/aptible/aptible-deploy-action), Source information is retrieved and sent automatically. No further configuration is required.

To set up a new Source for an App, visit the [Source Setup page](https://app.aptible.com/sources/setup) and follow the instructions. You will be presented with a GitHub Workflow that you can add to your repository.

## Using Another Deployment Strategy

The Sources feature is powered by [App configuration](/core-concepts/apps/deploying-apps/configuration), so if you're using Terraform or your own custom scripts to deploy your app, you'll just need to send the following variables along with your deployment (note that **all of these variables are optional**):

*   `APTIBLE_GIT_REPOSITORY_URL`, the browser-accessible URL of the git repository associated with the App.
    *   Example: `https://github.com/example-org/example`.
*   `APTIBLE_GIT_REF`, the branch name or tag of the revision being deployed.
    *   Example: `release-branch-2024-01-01` or `v1.0.1`.
*   `APTIBLE_GIT_COMMIT_SHA`, the 40-character git commit SHA.
    *   Example: `2fa8cf206417ac18179f36a64b31e6d0556ff20684c1ad8d866569912bbf7235`.
*   `APTIBLE_GIT_COMMIT_URL`, the browser-accessible URL of the commit.
    *   Example: `https://github.com/example-org/example/commit/2fa8cf`.
*   `APTIBLE_GIT_COMMIT_TIMESTAMP`, the ISO8601 timestamp of the git commit.
    *   Example: `2024-01-01T12:00:00-04:00`.
*   `APTIBLE_GIT_COMMIT_MESSAGE`, the full git commit message.
*   (If deploying a Docker image) `APTIBLE_DOCKER_REPOSITORY_URL`, the browser-accessible URL of the Docker registry for the image being deployed.
    *   Example: `https://hub.docker.com/repository/docker/example-org/example`

For example, if you're using the Aptible CLI to deploy your app, you might use a command like this:

```shell
$ aptible deploy --app your-app \
    --docker-image=example-org/example:v1.0.1 \
    APTIBLE_GIT_REPOSITORY_URL="https://github.com/example/example" \
    APTIBLE_GIT_REF="$(git symbolic-ref --short -q HEAD || git describe --tags --exact-match 2> /dev/null)" \
    APTIBLE_GIT_COMMIT_SHA="$(git rev-parse HEAD)" \
    APTIBLE_GIT_COMMIT_URL="https://github.com/example/repo/commit/$(git rev-parse HEAD)" \
    APTIBLE_GIT_COMMIT_MESSAGE="$(git log -1 --pretty=%B)" \
    APTIBLE_GIT_COMMIT_TIMESTAMP="$(git log -1 --pretty=%cI)"
```


# Deploying Apps

Learn about the components involved in deploying an Aptible app in seconds: images, services, and configurations

# Overview

On Aptible, developers can deploy code, and in seconds, the platform will transform their code into app containers with zero-downtime — completely abstracting the complexities of the underlying infrastructure.

Apps are made up of three components:

*   **[An Image:](/core-concepts/apps/deploying-apps/image/overview)** Deploy directly from a Docker image, or push your code to Aptible with `git push` and the platform will build a Docker image for you.
*   **[Services:](/core-concepts/apps/deploying-apps/services)** Services define how many containers Aptible will start for your app, what command they will run, and their Memory and CPU Limits.
*   **[Configuration (optional):](/core-concepts/apps/deploying-apps/configuration)** The configuration is a set of keys and values securely passed to the containers as environment variables. For example - secrets are passed as configurations.

# Get Started

If you are just getting started, [deploy a starter template.](/getting-started/deploy-starter-template/overview)

# Integrating with CI/CD

Aptible integrates with several continuous integration services to make it easier to deploy on Aptible—whether migrating from another platform or deploying for the first time.

<CardGroup cols={2}>
  <Card title="Browse CI/CD integrations" icon="arrow-up-right" iconType="duotone" href="https://aptible.mintlify.app/core-concepts/integrations/overview#developer-tools" />

  <Card title="How to deploy to Aptible from CI/CD" icon="book-open-reader" iconType="duotone" href="https://www.aptible.com/docs/continuous-integration-provider-deployment" />
</CardGroup>


# .aptible.yml



In addition to [Configuration variables read by Aptible](/core-concepts/apps/deploying-apps/configuration), Aptible also lets you configure your [Apps](/core-concepts/apps/overview) through a `.aptible.yml` file.

# Location

If you are using [Dockerfile Deploy](/how-to-guides/app-guides/deploy-from-git), this file must be named `.aptible.yml` and located at the root of your repository.

If you are using [Direct Docker Image Deploy](/how-to-guides/app-guides/migrate-dockerfile-to-direct-image-deploy), it must be located at `/.aptible/.aptible.yml` in your Docker image. See [Procfiles and `.aptible.yml` with Direct Docker Image Deploy](/core-concepts/apps/deploying-apps/image/deploying-with-docker-image/procfile-aptible-yml-direct-docker-deploy) for more information.

# Structure

This file should be a `yaml` file containing any of the following configuration keys:

## `before_release`

<Warning>For now, this is an alias to `before_deploy`, but should be considered deprecated. If you're still using this key, please update!</Warning>

## `before_deploy`

`before_deploy` should be set to a list, e.g.:

```yaml
before_deploy:
  - command1
  - command2
```

<Warning>If your Docker image has an `ENTRYPOINT`, Aptible will not use a shell to interpret your commands. Instead, the command is split according to shell rules, then simply passed to your Container's ENTRYPOINT as a series of arguments. In this case, using the form `sh -c 'command1 && command2'` or making use of a single wrapper script is required. See [How to define services](/how-to-guides/app-guides/define-services#images-with-an-entrypoint) for additional details.</Warning>

The commands listed under `before_deploy` will run when you deploy your app, either via a `git push` (for [Dockerfile Deploy](/how-to-guides/app-guides/deploy-from-git)) or using [`aptible deploy`](/reference/aptible-cli/cli-commands/cli-deploy) (for [Direct Docker Image Deploy](/how-to-guides/app-guides/migrate-dockerfile-to-direct-image-deploy)). However, they will *not* run when you execute [`aptible config:set`](/reference/aptible-cli/cli-commands/cli-config-set), [`aptible restart`](/reference/aptible-cli/cli-commands/cli-restart), etc.

`before_deploy` commands are executed in an isolated ephemeral [Container](/core-concepts/architecture/containers/overview), before new [Release](/core-concepts/apps/deploying-apps/releases/overview) Containers are launched. The commands are executed sequentially in the order that they are listed in the file.

If any of the `before_deploy` commands fail, Release Containers will not be launched and the operation will be rolled back.

This has several key implications:

*   Any side effects of your `before_deploy` commands (such as database migrations) are guaranteed to have been completed before new Containers are launched for your app.
*   Any changes made to the container filesystem by a `before_deploy` command (such as installing dependencies or pre-compiling assets) will **not** be reflected in the Release Containers. You should usually include such commands in your [Dockerfile](/core-concepts/apps/deploying-apps/image/deploying-with-git/overview) instead.

As such, `before_deploy` commands are ideal for use cases such as:

*   Automating database migrations
*   Notifying an error tracking system that a new release is being deployed.

<Warning>There is a 30-minute timeout on `before_deploy` tasks. If you need to run something that takes longer, consider using [Ephemeral SSH Sessions](/core-concepts/apps/connecting-to-apps/ssh-sessions).</Warning>

## After Success/Failure Hooks

Aptible provides multiple hook points for you to run custom code when certain operations succeed or fail.

Like `before_deploy`, commands are executed in an isolated ephemeral [Container](/core-concepts/architecture/containers/overview). These commands are executed sequentially in the order that they are listed in the file.

**Success hooks** run after your Release Containers are launched and confirmed to be in good health. **Failure hooks** run if the operation needs to be rolled back.

<Note>Unlike `before_deploy`, command failures in these hooks do not result in the operation being rolled back.</Note>

<Warning>There is a 30-minute timeout on all hooks.</Warning>

The available hooks are:

*   `after_deploy_success`
*   `after_restart_success`
*   `after_configure_success`
*   `after_scale_success`
*   `after_deploy_failure`
*   `after_restart_failure`
*   `after_configure_failure`
*   `after_scale_failure`

As their names suggest, these hooks run during `deploy`, `restart`, `configure`, and `scale` operations.

In order to update your hooks, you must initiate a deploy with the new hooks added to your .aptible.yml.

Please note that due to their nature, **Failure hooks** are only updated after a successful deploy. This means, for example, that if you currently have an `after_deploy_failure` hook A, and are updating it to B, it will only take effect after the deploy operation completes. If the deploy operation were to fail, then the `after_deploy_failure` hook A would run, not B. In a similar vein, Failure hooks use your **previous** image to run commands, not the current image being deployed. As such, it would not have any new code available to it.


# Releases



Whenever you deploy, restart, configure, scale, etc. your App, a new set of [Containers](/core-concepts/architecture/containers/overview) will be launched to replace the existing ones for each of your App's [Services](/core-concepts/apps/deploying-apps/services).

This set of Containers is referred to as a Release. The Containers themselves are referred to as Release Containers, as opposed to the ephemeral containers created by e.g. [`before_release`](/core-concepts/apps/deploying-apps/releases/aptible-yml#before-release) commands or [Ephemeral SSH Sessions](/core-concepts/apps/connecting-to-apps/ssh-sessions).

> 📘 Each one of your App's Services gets a new Release when you deploy, etc. In other words, Releases are Scoped to Services, not Apps. This isn't very important, but it'll help you better understand how certain [Aptible Metadata](/core-concepts/architecture/containers/overview#aptible-metadata) variables work.

# Lifecycle

Aptible will adopt a deployment strategy on a Service-by-Service basis.

The exact deployment strategy Aptible chooses for a given Service depends on whether the Service has any [Endpoints](/core-concepts/apps/connecting-to-apps/app-endpoints/overview) associated with it:

> 📘 In any cases, new Containers are always launched *after* [`before_release`](/core-concepts/apps/deploying-apps/releases/aptible-yml#before-release) commands have completed.

## Services without Endpoints

Services without Endpoints (also known as *Background Services*) are deployed with **zero overlap**: the existing Containers are stopped before new Containers are launched.

Alternatively, you can force **zero downtime** deploys either in the UI in the Service Settings area, [aptible-cli services:settings](/reference/aptible-cli/cli-commands/cli-services-settings), or via our [Terraform Provider](https://registry.terraform.io/providers/aptible/aptible/latest/docs).
When this is enabled, we rely on [Docker Healthchecks](https://docs.docker.com/reference/dockerfile/#healthcheck) to ensure your containers are healthy before cutting over.
If you do not wish to use docker healthchecks, you may enable **simple healthchecks** for your service, which will instead ensure the container can remain up for 30 seconds before cutting over.
<Warning>Please read [Concurrent Releases](#concurrent-releases) for caveats to this deployment strategy</Warning>

### Docker Healthchecks

Since Docker Healthchecks affect your entire image and not just a single service, you MUST write a healthcheck script similar to the following:

```bash
#!/bin/bash

case $APTIBLE_PROCESS_TYPE in
  "web" | "ui" )
      exit 0 # We do not use docker healthchecks for services with endpoints
      ;;
  "sidekiq-long-jobs" )
      # healthcheck-for-this-service
      ;;
  "cmd" )
      # yet another healthcheck
      ;;
  * )
    # So you don't ever accidentally enable zero-downtime on a service without defining a health check
    echo "Unexpected process type $APTIBLE_PROCESS_TYPE"
    exit 1
      ;;
esac
```

![Service Settings UI](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/service-settings-1.png)

## Services with Endpoints

Services with Endpoints (also known as *Foreground Services*) are deployed with **minimal** (for [TLS Endpoints](/core-concepts/apps/connecting-to-apps/app-endpoints/tls-endpoints) and [TCP Endpoints](/core-concepts/apps/connecting-to-apps/app-endpoints/tcp-endpoints)) or **zero downtime** (for [HTTP(S) Endpoints](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/overview)): new Containers are launched and start accepting traffic before the existing Containers are shut down.

Specifically, the process is:

1.  Launch new Containers.
2.  Wait for the new Containers to pass [Health Checks](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/health-checks) (only for [HTTP(S) Endpoints](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/overview)).
3.  Register the new Containers with the Endpoint's load balancer. Wait for registration to complete.
4.  Deregister the old Containers from the Endpoint's load balancer. Wait for deregistration to complete (in-flight requests are given 15 seconds to complete).
5.  Shutdown the old Containers.

### Concurrent Releases

> ❗️ An important implication of zero-downtime deployments is that you'll have Containers from two different releases accepting traffic at the same time, so make sure you design your apps accordingly!

> For example, if you are running database migrations as part of your deploy, you need to design your migrations so that your existing Containers will be able to continue working with the database structure that results from running migrations.

> Often, this means you might need to apply complex migrations in multiple steps.


# Services



![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/services-screenshot.png)

# Overview

Services determine the number of Containers of your App and the memory and CPU limits for your app. An app can have multiple services.

Services are defined one of two ways:

*   **Single Implicit Service:** By default, the platform will create a single implicit cmd service defined by your image’s `cmd` or `ENTRYPOINT`.
*   **Explicit Services:** Alternatively, you can define one or more explicit services using a Procfile. This allows you to specify a command for each service. Each service is scaled independently.

# FAQ

<AccordionGroup>
  <Accordion title="How do I define Services">
    See related guide

    <Card title="How to define Services" icon="book-open-reader" iconType="duotone" href="https://aptible.mintlify.dev/docs/how-to-guides/app-guides/define-services" />
  </Accordion>

  <Accordion title="Can Services be scaled indepedently?">
    Yes, all App Services are scaled independently
  </Accordion>
</AccordionGroup>


# Managing Apps

Learn how to manage Aptible Apps

# Overview

Aptible makes managing your application simple. Whether you're using the Aptible Dashboard, CLI, or Terraform, you have full control over your App’s lifecycle without needing to worry about the underlying infrastructure.

# Learn More

<AccordionGroup>
  <Accordion title="Manually Scaling Apps">
    <Frame>
      ![scaling](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/app-scaling2.gif)
    </Frame>

    Apps can be manually scaled both horizontially (number of containers) and vertically (RAM/CPU) can be scaled on-demand with zero downtime deployments. Refer to [App Scaling](/core-concepts/scaling/app-scaling) for more information.
  </Accordion>

  <Accordion title="Autoscaling Apps">
    Aptible is currently offering Vertical Autoscaling for Apps in limited release. Contact Aptible Support to request early access.
  </Accordion>

  <Accordion title="Restarting Apps">
    Apps can be restarted the following ways:

    *   Using the [aptible restart](/reference/aptible-cli/cli-commands/cli-restart) command
    *   Within the Aptible Dashboard, by:

        *   Navigating to the app
        *   Selecting the Settings tab
        *   Selecting Restart

        Like all [Releases](/core-concepts/apps/deploying-apps/releases/overview), when Apps are restarted, a new set of [Containers](/core-concepts/architecture/containers/overview) will be launched to replace the existing ones for each of your App's [Services](/core-concepts/apps/deploying-apps/services).
  </Accordion>

  <Accordion title="Achieving High Availability">
    <Note> High Availability Apps are only available on [Production and Enterprise](https://www.aptible.com/pricing)[ plans.](https://www.aptible.com/pricing)</Note>

    Apps scaled to 2 or more Containers are automatically deployed in a high-availability configuration, with Containers deployed in separate [AWS Availability Zones](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-regions-availability-zones.html).
  </Accordion>

  <Accordion title="Renaming Apps">
    An App can be renamed in the following ways:

    *   Using the [`aptible apps:rename`](/reference/aptible-cli/cli-commands/cli-apps-rename) command
    *   Using the Aptible [Terraform Provider](https://registry.terraform.io/providers/aptible/aptible/latest/docs)

    For the change to take effect, the App must be restarted.

    <Warning>Apps handles cannot start with "internal-" because applications with that prefix cannot have [Endpoints](/core-concepts/apps/connecting-to-apps/app-endpoints/overview) allocated due to an AWS limitation. </Warning>
  </Accordion>

  <Accordion title="Deprovisioning an App">
    Apps can be deleted/deprovisioned using one of these three methods:

    *   Within the Aptible Dashboard:
        *   Selecting the Environment in which the App lives
        *   Selecting the **Apps** tab
        *   Selecting the given App
        *   Selecting the **Deprovision** tab
    *   Using the [`aptible apps:deprovision`](/reference/aptible-cli/cli-commands/cli-apps-deprovision) command
    *   Using the Aptible [Terraform Provider](https://registry.terraform.io/providers/aptible/aptible/latest/docs)
  </Accordion>
</AccordionGroup>


# Apps - Overview



<Frame>
  ![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/apps.png)
</Frame>

## Overview

Aptible is a platform that simplifies the deployment and management of applications, abstracting away the complexities of the underlying infrastructure for development teams. Here are the key features and capabilities that Aptible provides to achieve this:

1.  **Simplified and Flexible Deployment:** You can deploy your code to app containers in seconds using Aptible. You have the option to [deploy via Git](https://www.aptible.com/docs/dockerfile-deploy) or [deploy via Docker Image](https://www.aptible.com/docs/direct-docker-image-deploy). Define your [services](https://www.aptible.com/docs/services) and [configurations](https://www.aptible.com/docs/configuration), and let the platform handle the deployment process and provisioning of the underlying infrastructure.
2.  **Easy Connectivity:** Aptible offers multiple methods for connecting to your deployed applications. Users can access their apps through public URLs, ephemeral sessions, or outbound IP addresses.
3.  **Scalability Options:** Easily [scale an App](https://www.aptible.com/docs/app-scaling) to add more containers to your application to handle the increased load, or vertically to allocate additional resources like RAM and CPU to meet performance requirements. Aptible offers various [container profiles](https://www.aptible.com/docs/container-profiles), allowing you to fine-tune resource allocation for optimal performance.
4.  **High Availability:** Apps hosted on Aptible are designed to maintain high availability. Apps are deployed with zero downtime, and when scaled to two or more containers, the platform automatically distributes them across multiple availability zones.

## Learn more using Apps on Aptible

<CardGroup cols={3}>
  <Card title="Deploying Apps" icon="book" iconType="duotone" href="https://www.aptible.com/docs/core-concepts/apps/deploying-apps/overview">
    Learn to deploy your code into Apps with an image, Services, and Configuration
  </Card>

  <Card title="Connecting to Apps" icon="book" iconType="duotone" href="https://www.aptible.com/docs/core-concepts/apps/connecting-to-apps/overview">
    Learn to expose your App to the internet with Endpoints and connect with ephemeral SSH sessions
  </Card>

  <Card title="Managing Apps" icon="book" iconType="duotone" href="https://www.aptible.com/docs/core-concepts/apps/managing-apps">
    Learn to scale, restart, rename, restart, and delete your Apps
  </Card>
</CardGroup>

## Explore Starter Templates

<CardGroup cols={3}>
  <Card title="Custom Code" icon="globe" href="https://www.aptible.com/docs/custom-code-quickstart">
    Explore compatibility and deploy custom code
  </Card>

  <Card
    title="Ruby "
    href="https://www.aptible.com/docs/ruby-quickstart"
    icon={
    <svg width="30" height="30" viewBox="0 0 256 255" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMinYMin meet"><defs><linearGradient x1="84.75%" y1="111.399%" x2="58.254%" y2="64.584%" id="a"><stop stop-color="#FB7655" offset="0%"/><stop stop-color="#FB7655" offset="0%"/><stop stop-color="#E42B1E" offset="41%"/><stop stop-color="#900" offset="99%"/><stop stop-color="#900" offset="100%"/></linearGradient><linearGradient x1="116.651%" y1="60.89%" x2="1.746%" y2="19.288%" id="b"><stop stop-color="#871101" offset="0%"/><stop stop-color="#871101" offset="0%"/><stop stop-color="#911209" offset="99%"/><stop stop-color="#911209" offset="100%"/></linearGradient><linearGradient x1="75.774%" y1="219.327%" x2="38.978%" y2="7.829%" id="c"><stop stop-color="#871101" offset="0%"/><stop stop-color="#871101" offset="0%"/><stop stop-color="#911209" offset="99%"/><stop stop-color="#911209" offset="100%"/></linearGradient><linearGradient x1="50.012%" y1="7.234%" x2="66.483%" y2="79.135%" id="d"><stop stop-color="#FFF" offset="0%"/><stop stop-color="#FFF" offset="0%"/><stop stop-color="#E57252" offset="23%"/><stop stop-color="#DE3B20" offset="46%"/><stop stop-color="#A60003" offset="99%"/><stop stop-color="#A60003" offset="100%"/></linearGradient><linearGradient x1="46.174%" y1="16.348%" x2="49.932%" y2="83.047%" id="e"><stop stop-color="#FFF" offset="0%"/><stop stop-color="#FFF" offset="0%"/><stop stop-color="#E4714E" offset="23%"/><stop stop-color="#BE1A0D" offset="56%"/><stop stop-color="#A80D00" offset="99%"/><stop stop-color="#A80D00" offset="100%"/></linearGradient><linearGradient x1="36.965%" y1="15.594%" x2="49.528%" y2="92.478%" id="f"><stop stop-color="#FFF" offset="0%"/><stop stop-color="#FFF" offset="0%"/><stop stop-color="#E46342" offset="18%"/><stop stop-color="#C82410" offset="40%"/><stop stop-color="#A80D00" offset="99%"/><stop stop-color="#A80D00" offset="100%"/></linearGradient><linearGradient x1="13.609%" y1="58.346%" x2="85.764%" y2="-46.717%" id="g"><stop stop-color="#FFF" offset="0%"/><stop stop-color="#FFF" offset="0%"/><stop stop-color="#C81F11" offset="54%"/><stop stop-color="#BF0905" offset="99%"/><stop stop-color="#BF0905" offset="100%"/></linearGradient><linearGradient x1="27.624%" y1="21.135%" x2="50.745%" y2="79.056%" id="h"><stop stop-color="#FFF" offset="0%"/><stop stop-color="#FFF" offset="0%"/><stop stop-color="#DE4024" offset="31%"/><stop stop-color="#BF190B" offset="99%"/><stop stop-color="#BF190B" offset="100%"/></linearGradient><linearGradient x1="-20.667%" y1="122.282%" x2="104.242%" y2="-6.342%" id="i"><stop stop-color="#BD0012" offset="0%"/><stop stop-color="#BD0012" offset="0%"/><stop stop-color="#FFF" offset="7%"/><stop stop-color="#FFF" offset="17%"/><stop stop-color="#C82F1C" offset="27%"/><stop stop-color="#820C01" offset="33%"/><stop stop-color="#A31601" offset="46%"/><stop stop-color="#B31301" offset="72%"/><stop stop-color="#E82609" offset="99%"/><stop stop-color="#E82609" offset="100%"/></linearGradient><linearGradient x1="58.792%" y1="65.205%" x2="11.964%" y2="50.128%" id="j"><stop stop-color="#8C0C01" offset="0%"/><stop stop-color="#8C0C01" offset="0%"/><stop stop-color="#990C00" offset="54%"/><stop stop-color="#A80D0E" offset="99%"/><stop stop-color="#A80D0E" offset="100%"/></linearGradient><linearGradient x1="79.319%" y1="62.754%" x2="23.088%" y2="17.888%" id="k"><stop stop-color="#7E110B" offset="0%"/><stop stop-color="#7E110B" offset="0%"/><stop stop-color="#9E0C00" offset="99%"/><stop stop-color="#9E0C00" offset="100%"/></linearGradient><linearGradient x1="92.88%" y1="74.122%" x2="59.841%" y2="39.704%" id="l"><stop stop-color="#79130D" offset="0%"/><stop stop-color="#79130D" offset="0%"/><stop stop-color="#9E120B" offset="99%"/><stop stop-color="#9E120B" offset="100%"/></linearGradient><radialGradient cx="32.001%" cy="40.21%" fx="32.001%" fy="40.21%" r="69.573%" id="m"><stop stop-color="#A80D00" offset="0%"/><stop stop-color="#A80D00" offset="0%"/><stop stop-color="#7E0E08" offset="99%"/><stop stop-color="#7E0E08" offset="100%"/></radialGradient><radialGradient cx="13.549%" cy="40.86%" fx="13.549%" fy="40.86%" r="88.386%" id="n"><stop stop-color="#A30C00" offset="0%"/><stop stop-color="#A30C00" offset="0%"/><stop stop-color="#800E08" offset="99%"/><stop stop-color="#800E08" offset="100%"/></radialGradient><linearGradient x1="56.57%" y1="101.717%" x2="3.105%" y2="11.993%" id="o"><stop stop-color="#8B2114" offset="0%"/><stop stop-color="#8B2114" offset="0%"/><stop stop-color="#9E100A" offset="43%"/><stop stop-color="#B3100C" offset="99%"/><stop stop-color="#B3100C" offset="100%"/></linearGradient><linearGradient x1="30.87%" y1="35.599%" x2="92.471%" y2="100.694%" id="p"><stop stop-color="#B31000" offset="0%"/><stop stop-color="#B31000" offset="0%"/><stop stop-color="#910F08" offset="44%"/><stop stop-color="#791C12" offset="99%"/><stop stop-color="#791C12" offset="100%"/></linearGradient></defs><path d="M197.467 167.764l-145.52 86.41 188.422-12.787L254.88 51.393l-57.414 116.37z" fill="url(#a)"/><path d="M240.677 241.257L224.482 129.48l-44.113 58.25 60.308 53.528z" fill="url(#b)"/><path d="M240.896 241.257l-118.646-9.313-69.674 21.986 188.32-12.673z" fill="url(#c)"/><path d="M52.744 253.955l29.64-97.1L17.16 170.8l35.583 83.154z" fill="url(#d)"/><path d="M180.358 188.05L153.085 81.226l-78.047 73.16 105.32 33.666z" fill="url(#e)"/><path d="M248.693 82.73l-73.777-60.256-20.544 66.418 94.321-6.162z" fill="url(#f)"/><path d="M214.191.99L170.8 24.97 143.424.669l70.767.322z" fill="url(#g)"/><path d="M0 203.372l18.177-33.151-14.704-39.494L0 203.372z" fill="url(#h)"/><path d="M2.496 129.48l14.794 41.963 64.283-14.422 73.39-68.207 20.712-65.787L143.063 0 87.618 20.75c-17.469 16.248-51.366 48.396-52.588 49-1.21.618-22.384 40.639-32.534 59.73z" fill="#FFF"/><path d="M54.442 54.094c37.86-37.538 86.667-59.716 105.397-40.818 18.72 18.898-1.132 64.823-38.992 102.349-37.86 37.525-86.062 60.925-104.78 42.027-18.73-18.885.515-66.032 38.375-103.558z" fill="url(#i)"/><path d="M52.744 253.916l29.408-97.409 97.665 31.376c-35.312 33.113-74.587 61.106-127.073 66.033z" fill="url(#j)"/><path d="M155.092 88.622l25.073 99.313c29.498-31.016 55.972-64.36 68.938-105.603l-94.01 6.29z" fill="url(#k)"/><path d="M248.847 82.833c10.035-30.282 12.35-73.725-34.966-81.791l-38.825 21.445 73.791 60.346z" fill="url(#l)"/><path d="M0 202.935c1.39 49.979 37.448 50.724 52.808 51.162l-35.48-82.86L0 202.935z" fill="#9E1209"/><path d="M155.232 88.777c22.667 13.932 68.35 41.912 69.276 42.426 1.44.81 19.695-30.784 23.838-48.64l-93.114 6.214z" fill="url(#m)"/><path d="M82.113 156.507l39.313 75.848c23.246-12.607 41.45-27.967 58.121-44.42l-97.434-31.428z" fill="url(#n)"/><path d="M17.174 171.34l-5.57 66.328c10.51 14.357 24.97 15.605 40.136 14.486-10.973-27.311-32.894-81.92-34.566-80.814z" fill="url(#o)"/><path d="M174.826 22.654l78.1 10.96c-4.169-17.662-16.969-29.06-38.787-32.623l-39.313 21.663z" fill="url(#p)"/></svg>
    }
  >
    Deploy using a Ruby on Rails template
  </Card>

  <Card
    title="NodeJS"
    href="https://www.aptible.com/docs/node-js-quickstart"
    icon={
    <svg xmlns="http://www.w3.org/2000/svg" width="30" height="30" viewBox="0 0 58 64" fill="none">
    <path d="M26.3201 0.681001C27.9201 -0.224999 29.9601 -0.228999 31.5201 0.681001L55.4081 14.147C56.9021 14.987 57.9021 16.653 57.8881 18.375V45.375C57.8981 47.169 56.8001 48.871 55.2241 49.695L31.4641 63.099C30.6514 63.5481 29.7333 63.7714 28.8052 63.7457C27.877 63.7201 26.9727 63.4463 26.1861 62.953L19.0561 58.833C18.5701 58.543 18.0241 58.313 17.6801 57.843C17.9841 57.435 18.5241 57.383 18.9641 57.203C19.9561 56.887 20.8641 56.403 21.7761 55.891C22.0061 55.731 22.2881 55.791 22.5081 55.935L28.5881 59.451C29.0221 59.701 29.4621 59.371 29.8341 59.161L53.1641 45.995C53.4521 45.855 53.6121 45.551 53.5881 45.235V18.495C53.6201 18.135 53.4141 17.807 53.0881 17.661L29.3881 4.315C29.2515 4.22054 29.0894 4.16976 28.9234 4.16941C28.7573 4.16905 28.5951 4.21912 28.4581 4.313L4.79207 17.687C4.47207 17.833 4.25207 18.157 4.29207 18.517V45.257C4.26407 45.573 4.43207 45.871 4.72207 46.007L11.0461 49.577C12.2341 50.217 13.6921 50.577 15.0001 50.107C15.5725 49.8913 16.0652 49.5058 16.4123 49.0021C16.7594 48.4984 16.9443 47.9007 16.9421 47.289L16.9481 20.709C16.9201 20.315 17.2921 19.989 17.6741 20.029H20.7141C21.1141 20.019 21.4281 20.443 21.3741 20.839L21.3681 47.587C21.3701 49.963 20.3941 52.547 18.1961 53.713C15.4881 55.113 12.1401 54.819 9.46407 53.473L2.66407 49.713C1.06407 48.913 -0.00993076 47.185 6.9243e-05 45.393V18.393C0.0067219 17.5155 0.247969 16.6557 0.698803 15.9027C1.14964 15.1498 1.79365 14.5312 2.56407 14.111L26.3201 0.681001ZM33.2081 19.397C36.6621 19.197 40.3601 19.265 43.4681 20.967C45.8741 22.271 47.2081 25.007 47.2521 27.683C47.1841 28.043 46.8081 28.243 46.4641 28.217C45.4641 28.215 44.4601 28.231 43.4561 28.211C43.0301 28.227 42.7841 27.835 42.7301 27.459C42.4421 26.179 41.7441 24.913 40.5401 24.295C38.6921 23.369 36.5481 23.415 34.5321 23.435C33.0601 23.515 31.4781 23.641 30.2321 24.505C29.2721 25.161 28.9841 26.505 29.3261 27.549C29.6461 28.315 30.5321 28.561 31.2541 28.789C35.4181 29.877 39.8281 29.789 43.9141 31.203C45.6041 31.787 47.2581 32.923 47.8381 34.693C48.5941 37.065 48.2641 39.901 46.5781 41.805C45.2101 43.373 43.2181 44.205 41.2281 44.689C38.5821 45.279 35.8381 45.293 33.1521 45.029C30.6261 44.741 27.9981 44.077 26.0481 42.357C24.3801 40.909 23.5681 38.653 23.6481 36.477C23.6681 36.109 24.0341 35.853 24.3881 35.883H27.3881C27.7921 35.855 28.0881 36.203 28.1081 36.583C28.2941 37.783 28.7521 39.083 29.8161 39.783C31.8681 41.107 34.4421 41.015 36.7901 41.053C38.7361 40.967 40.9201 40.941 42.5101 39.653C43.3501 38.919 43.5961 37.693 43.3701 36.637C43.1241 35.745 42.1701 35.331 41.3701 35.037C37.2601 33.737 32.8001 34.209 28.7301 32.737C27.0781 32.153 25.4801 31.049 24.8461 29.351C23.9601 26.951 24.3661 23.977 26.2321 22.137C28.0321 20.307 30.6721 19.601 33.1721 19.349L33.2081 19.397Z" fill="#8CC84B"/></svg>
    }
  >
    Deploy using a Node.js + Express template
  </Card>

  <Card
    title="Django"
    href="https://www.aptible.com/docs/python-quickstart"
    icon={
    <svg width="30" height="30" viewBox="0 0 256 326" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMinYMin meet"><g fill="#2BA977"><path d="M114.784 0h53.278v244.191c-27.29 5.162-47.38 7.193-69.117 7.193C33.873 251.316 0 222.245 0 166.412c0-53.795 35.93-88.708 91.608-88.708 8.64 0 15.222.68 23.176 2.717V0zm1.867 124.427c-6.24-2.038-11.382-2.717-17.965-2.717-26.947 0-42.512 16.437-42.512 45.243 0 28.046 14.88 43.532 42.17 43.532 5.896 0 10.696-.332 18.307-1.351v-84.707z"/><path d="M255.187 84.26v122.263c0 42.105-3.154 62.353-12.411 79.81-8.64 16.783-20.022 27.366-43.541 39.055l-49.438-23.297c23.519-10.93 34.901-20.588 42.17-35.327 7.61-15.072 10.01-32.529 10.01-78.445V84.261h53.21zM196.608 0h53.278v54.135h-53.278V0z"/></g></svg>
    }
  >
    Deploy using a Python + Django template.
  </Card>

  <Card
    title="Laravel"
    href="https://www.aptible.com/docs/php-quickstart"
    icon={
    <svg height="30" viewBox="0 -.11376601 49.74245785 51.31690859" width="30" xmlns="http://www.w3.org/2000/svg"><path d="m49.626 11.564a.809.809 0 0 1 .028.209v10.972a.8.8 0 0 1 -.402.694l-9.209 5.302v10.509c0 .286-.152.55-.4.694l-19.223 11.066c-.044.025-.092.041-.14.058-.018.006-.035.017-.054.022a.805.805 0 0 1 -.41 0c-.022-.006-.042-.018-.063-.026-.044-.016-.09-.03-.132-.054l-19.219-11.066a.801.801 0 0 1 -.402-.694v-32.916c0-.072.01-.142.028-.21.006-.023.02-.044.028-.067.015-.042.029-.085.051-.124.015-.026.037-.047.055-.071.023-.032.044-.065.071-.093.023-.023.053-.04.079-.06.029-.024.055-.05.088-.069h.001l9.61-5.533a.802.802 0 0 1 .8 0l9.61 5.533h.002c.032.02.059.045.088.068.026.02.055.038.078.06.028.029.048.062.072.094.017.024.04.045.054.071.023.04.036.082.052.124.008.023.022.044.028.068a.809.809 0 0 1 .028.209v20.559l8.008-4.611v-10.51c0-.07.01-.141.028-.208.007-.024.02-.045.028-.068.016-.042.03-.085.052-.124.015-.026.037-.047.054-.071.024-.032.044-.065.072-.093.023-.023.052-.04.078-.06.03-.024.056-.05.088-.069h.001l9.611-5.533a.801.801 0 0 1 .8 0l9.61 5.533c.034.02.06.045.09.068.025.02.054.038.077.06.028.029.048.062.072.094.018.024.04.045.054.071.023.039.036.082.052.124.009.023.022.044.028.068zm-1.574 10.718v-9.124l-3.363 1.936-4.646 2.675v9.124l8.01-4.611zm-9.61 16.505v-9.13l-4.57 2.61-13.05 7.448v9.216zm-36.84-31.068v31.068l17.618 10.143v-9.214l-9.204-5.209-.003-.002-.004-.002c-.031-.018-.057-.044-.086-.066-.025-.02-.054-.036-.076-.058l-.002-.003c-.026-.025-.044-.056-.066-.084-.02-.027-.044-.05-.06-.078l-.001-.003c-.018-.03-.029-.066-.042-.1-.013-.03-.03-.058-.038-.09v-.001c-.01-.038-.012-.078-.016-.117-.004-.03-.012-.06-.012-.09v-21.483l-4.645-2.676-3.363-1.934zm8.81-5.994-8.007 4.609 8.005 4.609 8.006-4.61-8.006-4.608zm4.164 28.764 4.645-2.674v-20.096l-3.363 1.936-4.646 2.675v20.096zm24.667-23.325-8.006 4.609 8.006 4.609 8.005-4.61zm-.801 10.605-4.646-2.675-3.363-1.936v9.124l4.645 2.674 3.364 1.937zm-18.422 20.561 11.743-6.704 5.87-3.35-8-4.606-9.211 5.303-8.395 4.833z" fill="#ff2d20"/></svg>
    }
  >
    Deploy using a PHP + Laravel template
  </Card>

  <Card
    title="Python"
    href="https://www.aptible.com/docs/deploy-demo-app"
    icon={
    <svg width="30" height="30" viewBox="0 0 256 255" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMinYMin meet"><defs><linearGradient x1="12.959%" y1="12.039%" x2="79.639%" y2="78.201%" id="a"><stop stop-color="#387EB8" offset="0%"/><stop stop-color="#366994" offset="100%"/></linearGradient><linearGradient x1="19.128%" y1="20.579%" x2="90.742%" y2="88.429%" id="b"><stop stop-color="#FFE052" offset="0%"/><stop stop-color="#FFC331" offset="100%"/></linearGradient></defs><path d="M126.916.072c-64.832 0-60.784 28.115-60.784 28.115l.072 29.128h61.868v8.745H41.631S.145 61.355.145 126.77c0 65.417 36.21 63.097 36.21 63.097h21.61v-30.356s-1.165-36.21 35.632-36.21h61.362s34.475.557 34.475-33.319V33.97S194.67.072 126.916.072zM92.802 19.66a11.12 11.12 0 0 1 11.13 11.13 11.12 11.12 0 0 1-11.13 11.13 11.12 11.12 0 0 1-11.13-11.13 11.12 11.12 0 0 1 11.13-11.13z" fill="url(#a)"/><path d="M128.757 254.126c64.832 0 60.784-28.115 60.784-28.115l-.072-29.127H127.6v-8.745h86.441s41.486 4.705 41.486-60.712c0-65.416-36.21-63.096-36.21-63.096h-21.61v30.355s1.165 36.21-35.632 36.21h-61.362s-34.475-.557-34.475 33.32v56.013s-5.235 33.897 62.518 33.897zm34.114-19.586a11.12 11.12 0 0 1-11.13-11.13 11.12 11.12 0 0 1 11.13-11.131 11.12 11.12 0 0 1 11.13 11.13 11.12 11.12 0 0 1-11.13 11.13z" fill="url(#b)"/></svg>
    }
  >
    Deploy Python + Flask Demo app
  </Card>
</CardGroup>


# Container Recovery



When [Containers](/core-concepts/architecture/containers/overview) on Aptible exit unexpectedly (i.e., Aptible did not terminate them as part of a deploy or restart), they are automatically restarted. This feature is called Container Recovery. For most apps, Aptible will automatically restart containers in the event of a crash without requiring user action.

# Overview

When Containers exit, Aptible automatically restarts them from a pristine state. As a result, any changes to the filesystem will be undone (e.g., PID files will be deleted, etc.). As a user, the implication is that if a Container starts properly, Aptible can automatically recover it. To modify this behavior, see [Disabling filesystem wipes](#disabling-filesystem-wipes) below.

Whenever a Container exits and Container Recovery is initiated, Aptible logs the following messages and forwards them to your Log Drains. Note that these logs may not be contiguous; there may be additional log lines between them.

```
container has exited
container recovery initiated
container has started
```

If you wish to set up a log-based alert whenever a Container crashes, we recommend doing so based on the string `container recovery initiated`. This is because the lines `container has started` and `container has exited` will be logged during the normal, healthy [Release Lifecycle](/core-concepts/apps/deploying-apps/releases/overview).

If an App is continuously restarting, Aptible will throttle recovery to a rate of one attempt every 2 minutes.

# Cases where Container Recovery will not work

Container Recovery restarts *Containers* that exit, so if an app crashes but the Container does not exit, then Container Recovery can't help.

Here's an example [Procfile](/how-to-guides/app-guides/define-services) demonstrating this issue:

```yaml
app: (my-app &) && tail -F log/my-app.log
```

In this case, since `my-app` is running in the background, the Container will not exit when `my-app` exits. Instead, it would exit if `tail` exited.

To ensure Container Recovery effectively keeps an App up, make sure that:

*   Each Container is only running one App.
*   The one App each Container is supposed to run is running in the foreground.

For example, rewrite the above Procfile like so:

```yaml
app: (tail -F log/my-app.log &) && my-app
```

Use a dedicated process manager in a Container, such as [Forever](https://github.com/foreverjs/forever) or [Supervisord](http://supervisord.org/), if multiple processes need to run in a Container or something else needs to run in the foreground.

Contact [Aptible Support](/how-to-guides/troubleshooting/aptible-support) when in doubt.

# Disabling filesystem wipes

Container Recovery automatically restarting containers with a pristine filesystem maximizes the odds of a Container coming back up when recovered and mimics what happens when restarting an App using [`aptible restart`](/reference/aptible-cli/cli-commands/cli-restart).

Set the `APTIBLE_DO_NOT_WIPE` [Configuration](/core-concepts/apps/deploying-apps/configuration) variable on an App to any non-null value (e.g., set it to `1`) to prevent the filesystem from being wiped (assuming it is designed to handle being restarted properly).


# Containers



Aptible deploys all resources in Containers.

# Container Command

Containers run the command specified by the [Service](/core-concepts/apps/deploying-apps/services) they belong to:

*   If the service is an [Implicit Service](/how-to-guides/app-guides/define-services#implicit-service-cmd), then that command is the [Image](/core-concepts/apps/deploying-apps/image/overview)'s `CMD`.
*   If the service is an [Explicit Service](/how-to-guides/app-guides/define-services#explicit-services-procfiles), then that command is defined by the [Procfile](/how-to-guides/app-guides/define-services).

# Container Environment

Containers run with three types of environment variables and if there is a name collision, [Aptible Metadata](/reference/aptible-metadata-variables) takes precedence over App Configuration, which takes precedence over Docker Image Variables:

## Docker Image Variables

Docker [Images](/core-concepts/apps/deploying-apps/image/overview) define these variables via the `ENV` directive. They are present when your Containers start:

```dockerfile
ENV FOO=BAR
```

## App Configuration

Aptible injects an App's [Configuration](/core-concepts/apps/deploying-apps/configuration) as environment variables. For example, for the keys `FOO` and `BAR`:

```shell
aptible config:set --app "$APP_HANDLE" \
  FOO=SOME BAR=OTHER
```

Aptible runs containers with the environment variables `FOO` and `BAR` set respectively to `SOME` and `OTHER`.

## Aptible Metadata

Finally, Aptible injects a set of [metadata keys](/reference/aptible-metadata-variables) as environment variables.

These environment variables are accessible through the facilities exposed by the language, such as `ENV` in Ruby, `process.env` in Node, or `os.environ` in Python.

# Container Hostname

Aptible (and Docker in general) sets the hostname for your Containers to the 12 first characters of the Container's ID and uses it in [Logging](/core-concepts/observability/logs/overview) and [Metrics](/core-concepts/observability/metrics/overview).

# Container Isolation

Containers on Aptible are isolated. Use one of the following options to allow multiple Containers to communicate:

*   For web APIs or microservices, set up an [Endpoint](/core-concepts/apps/connecting-to-apps/app-endpoints/overview) and direct your requests to the Endpoint.
*   For background workers, use a [Database](/core-concepts/managed-databases/overview) as a message queue. Aptible supports [Redis](/core-concepts/managed-databases/supported-databases/redis) and [RabbitMQ](/core-concepts/managed-databases/supported-databases/rabbitmq), which are well-suited for this use case.

# Container Lifecycle

Containers on Aptible are frequently recycled during Operations - meaning new Containers are created during an Operation, and the old ones are terminated. This happens within the following Operations:

*   Redeploying an App
*   Restarting an App or Database
*   Scaling an App or Database

# Filesystem Implications

With the notable exception of [Database](/core-concepts/managed-databases/overview) data, the filesystem for your [Containers](/core-concepts/architecture/containers/overview) is ephemeral. As a result, any data stored on the filesystem will be gone every time containers are recycled.

Never use the filesystem to retain long-term data. Instead, store this data in a Database or a third-party storage solution, such as AWS S3 (see [How do I accept file uploads when using Aptible?](/how-to-guides/app-guides/use-s3-to-accept-file-uploads) for more information).

<DocsTableOfContents />


# Environments

Learn about grouping resources with environments

![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/2-app-ui.png)

# Overview

Environments live within [Stacks](/core-concepts/architecture/stacks) and provide logical isolation of resources. Environments on the same Stack share networks and underlying hosts.

[User Permissions](/core-concepts/security-compliance/access-permissions), [Activity Reports](/core-concepts/architecture/operations#activity-reports), and [Database Backup Retention Policies](/core-concepts/managed-databases/managing-databases/database-backups) are also managed on the Environment level.

<Tip> You may want to consider having your production Environments in separate Stacks from staging, testing, and development Environments to ensure network-level isolation. </Tip>

# FAQ

<AccordionGroup>
  <Accordion title="Is there a limit to how many Environments I can have in a given stack?">
    No, there is no limit to the number of Environments you can have.
  </Accordion>

  <Accordion title="How do I create Environments?">
    ### Read more

    <Card title="How to create environments" icon="book-open-reader" iconType="duotone" href="https://www.aptible.com/docs/create-environments" />
  </Accordion>

  <Accordion title="How do I delete Environments?">
    ### Read more

    <Card title="How to delete environments" icon="book-open-reader" iconType="duotone" href="https://www.aptible.com/delete-environments" />
  </Accordion>

  <Accordion title="How do I rename Environments?">
    Environments can be renamed from the Aptible Dashboard within the Environment's Settings.
  </Accordion>

  <Accordion title="How do I migrate Environments?">
    ### Read more

    <Card title="How to migrate environments" icon="book-open-reader" iconType="duotone" href="https://www.aptible.com/docs/migrate-environments" />
  </Accordion>
</AccordionGroup>


# Maintenance

Learn about how Aptible simplifies infrastructure maintenance

# Overview

At Aptible, we are committed to providing a managed infrastructure solution that empowers you to focus on your applications while we handle the essential maintenance tasks, ensuring the continued reliability and security of your services.

To this extent, Aptible may schedule maintenance on your resources for several reasons, including but not limited to:

*   **EC2 Hardware**: Aptible hardware is hosted on AWS EC2 (See: [Architecture](/core-concepts/architecture/overview)). Hardware can occasionally fail or require replacement. Aptible ensures that these issues are promptly addressed without disrupting your services.
*   **Platform Security Upgrades**: Security is a top priority. Aptible handles security upgrades to protect your infrastructure from vulnerabilities and threats.
*   **Platform Feature Upgrades**: Aptible continuously improves the platform to provide enhanced features and capabilities. Some upgrades may result in scheduled maintenance on various resources.
*   **Database-Specific Security Upgrades**: Critical patches and security updates for supported database types are essential to keep your data secure. Aptible ensures that these updates are applied promptly.

Aptible will notify you of upcoming maintenance ahead of time, including the maintenance window, expectations for automated maintenance, and instructions for self-serve maintenance (if applicable).

# Maintenance Notifications

Our commitment to transparency ensures that you are always aware of scheduled maintenance windows and the reasons behind each maintenance type.

To notify you of upcoming maintenance, we will update our [status page](https://status.aptible.com/) and/or use your Ops Alert contact settings on your organization to notify you, providing you with the information you need to manage your resources effectively.

# Performing Maintenance

Scheduled maintenance can be handled in one of two ways

*   **Automated Maintenance:** Aptible will automatically execute maintenance during scheduled windows, eliminating the need for manual intervention. You can trust us to manage these tasks efficiently and be monitored by our SRE team. During this time, Aptible will perform a restart operation on all impacted resources, as identified in the maintenance notifications.
*   **Self-Service Maintenance (if applicable):** For maintenance impacting apps and databases, Aptible may provide a self-service option for performing the maintenance yourself. This allows you to perform the maintenance during the best window for you.

## Self-service Maintenance

Aptible may provide instructions for self-service maintenance for apps and databases. When available, you can perform maintenance by restarting the affected app or database before the scheduled window. Many operations, such as deploying an app, scaling a database, or creating a new [Release](/core-concepts/apps/deploying-apps/releases/overview), will also complete scheduled maintenance.

To identify which apps or databases require maintenance and view the scheduled maintenance window for each resource, you can use the following Aptible CLI commands:

*   [`aptible maintenance:apps`](/reference/aptible-cli/cli-commands/cli-maintenance-apps)
*   [`aptible maintenance:dbs`](/reference/aptible-cli/cli-commands/cli-maintenance-dbs)

<Info> Please note that you need at least "read" permissions to see the apps and databases requiring a restart. To ensure you are viewing information for all environments, its best this is reviewed by an Account Owner, Aptible Deploy Owner, or any user with privileges to all environments. </Info>


# Operations

Learn more about operations work on Aptible - with minimal downtime and rollbacks

# Overview

An operation is performed and recorded for all changes made to resources, environments, and stacks. As operations are performed, operation logs are outputted and stored within Aptible. Operations are designed with reliability in mind - with minimal downtime and automatic rollbacks.

A collective record of operations is referred to as [activity](/core-concepts/observability/activity).

# Type of Operations

*   `backup`: Creates a [database backup](/core-concepts/managed-databases/managing-databases/database-backups)
*   `configure`: Sets the [configuration](/core-concepts/apps/deploying-apps/configuration) for an app
*   `copy`: Creates a cross-region copy [database backup](/core-concepts/managed-databases/managing-databases/database-backups#cross-region-copy-backups)
*   `deploy`: [Deploys a Docker image](/how-to-guides/app-guides/migrate-dockerfile-to-direct-image-deploy) for an app
*   `deprovision`: Stops all running [containers](/core-concepts/architecture/containers/overview) and deletes the resources
*   `execute`: Creates an [ephemeral SSH session](/core-concepts/apps/connecting-to-apps/ssh-sessions) for an app
*   `logs`: Streams [logs](/core-concepts/observability/logs/overview) to CLI
*   `modify`: Modifies a [database](/core-concepts/managed-databases/overview) volume type (gp3, gp2, standard) or provisioned IOPS (if gp3)
*   `provision`: Provisions a new [database](/core-concepts/managed-databases/overview), [log drain](/core-concepts/observability/logs/log-drains/overview), or [metric drain](/core-concepts/observability/metrics/metrics-drains/overview)
*   `purge`: Deletes a [database backup](/core-concepts/managed-databases/managing-databases/database-backups)
*   `rebuild`: Rebuilds the Docker [image](/core-concepts/apps/deploying-apps/image/overview) for an app and deploys the app with the newly built image
*   `reload`: Restarts the [database](/core-concepts/managed-databases/overview) in place (does not alter size)
*   `replicate`: Creates a [replica](/core-concepts/managed-databases/managing-databases/replication-clustering) for databases that support replication.
*   `renew`: Renews a certificate for an [app endpoint using Managed HTTPS](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/overview).
*   `restart`: Restarts an [app](/core-concepts/apps/overview) or [database](/core-concepts/managed-databases/overview)
*   `restore`: Restores a [database backup](/core-concepts/managed-databases/managing-databases/database-backups) into a new database
*   `scale`: Scales a [service](/core-concepts/apps/deploying-apps/services) for an app
*   `scan`: Generates a [security scan](/core-concepts/security-compliance/security-scans) for an app

# Operation Logs

For all operations performed, Aptible collects operation logs. These logs are retained only for active resources.

# Activity Dashboard

![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/5-app-ui.png)

The Activity dashboard provides a real-time view of operations for active resources in the last seven days. Through the Activity page, you can:

*   View operations for resources you have access to
*   Search operations by resource name, operation type, and user
*   View operation logs for debugging purposes

<Tip> Troubleshooting with our team? Link the Aptible Support team to the logs for the operation you are having trouble with. </Tip>

# Activity Reports

Activity Reports provide historical data of all operations in a given environment, including operations executed on resources that were later deleted. These reports are generated on a weekly basis for each environment, and they can be accessed for the duration of the environment's existence. All Activity Reports for an Environment are accessible for the lifetime of the Environment.

# Minimal downtime operations

To further mitigate the impact of failures, Aptible Operations are designed to be interruptible at any stage whenever possible.

In particular, when deploying a web application, Aptible performs [Zero-Downtime Deployment](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/overview#zero-downtime-deployment). This ensures that if the Operation is interrupted at any time and for any reason, it still won't take your application down.

When downtime is inevitable (such as when resizing a Database volume or redeploying a Database to a bigger instance), Aptible optimizes for minimal downtime.

For example, when redeploying a Database to another instance, Aptible must perform the following steps:

*   Shut down the old Database [Container](/core-concepts/architecture/containers/overview).
*   Unmount and then detach the Database volume from the instance the Database was originally scheduled on.
*   Attach then remount the Database volume on the instance the Database is being re-scheduled on.
*   Start the new Database Container.

When performing this Operation, Aptible will minimize downtime by ensuring that all preconditions are in place to start the new Database Container on the new instance before shutting down the old Database Container. In particular, Aptible will ensure the new instance is available and has pre-pulled the Docker image for your Database.

# Operation Rollbacks

Aptible was designed with reliability in mind. To this extent, Aptible provides automatic rollbacks for failed operations. Users can also manually rollback an operation should they need to.

### Automatic Rollbacks

All Aptible operations are designed to support automatic rollbacks in the event of a failure (with the exception of a handful of trivial operations with no side effects (such as launching [Ephemeral SSH Sessions](/core-concepts/apps/connecting-to-apps/ssh-sessions)).

When a failure occurs, and an automatic rollback is initiated, a message will be displayed within the operation logs. The logs will indicate whether the rollback succeeded (i.e., everything was restored back to the way it was before the Operation) or failed (some changes could not be undone).

<Warning> Some side-effects of deployments cannot be rolled back by Aptible. In particular, database migrations performed in [`before_release`](/core-concepts/apps/deploying-apps/releases/aptible-yml#before-release) commands cannot be rolled back (unless you design your migrations to roll back on failure, of course!). We strongly recommend designing your database migrations so that they are backwards compatible across at least one release. This is a very good idea in general (not just on Aptible), and a best practice for zero-downtime deployments (see [Concurrent Releases](/core-concepts/apps/deploying-apps/releases/overview#concurrent-releases) for more information). </Warning>

### Manual Rollbacks

A rollback can be manually initiated within the Aptible CLI by using the [`aptible operation:cancel`](/reference/aptible-cli/cli-commands/cli-operation-cancel) command.

# FAQ

<AccordionGroup>
  <Accordion title="How do I access Operation Logs?">
    Operation Logs can be accessed in the following ways:

    *   Within the Aptible Dashboard:
        *   Within the resource summary by:
            *   Navigating to the respective resource
            *   Selecting the Activity tab
                ![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/Downloading-operation-logs-2.png)
        *   Within the Activity dashboard by:
            *   Navigating to the Activity page
            *   Selecting the Logs button for the respective operation
                *   Note: This page only shows operations performed in the last 7 days.
    *   Within the Aptible CLI by using the [`aptible operation:logs`](/reference/aptible-cli/cli-commands/cli-operation-logs) command
        *   Note: This command only shows operations performed in the last 90 days.
  </Accordion>

  <Accordion title="How do I access Activity Reports?">
    Activity Reports can be downloaded in CSV format within the Aptible Dashboard by:

    *   Selecting the respective Environment
    *   Selecting the **Activity Reports** tab

    ![Activity reports](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/App_UI_Activity_Reports.png)
  </Accordion>

  <Accordion title="Why do Operation Failures happen?">
    Reliability is a top priority at Aptible in general and for Aptible in particular. That said, occasional failures during Operations are inevitable and may be caused by the following:

    *   Failing third-party services: Aptible strives to minimize dependencies on the critical path to deploying an [App](/core-concepts/apps/overview) or restarting a [Database](/core-concepts/managed-databases/managing-databases/overview), but Aptible nonetheless depends on a number of third-party services. Notably, Aptible depends on AWS EC2, AWS S3, AWS ELB, and the Docker Hub (with a failover or Quay.io and vice-versa). These can occasionally fail and when they do, they may cause Aptible Operations to fail.

    *   Crashing instances: Aptible is built on a fleet of Linux instances running Docker. Like any other software, Linux and Docker have bugs and may occasionally crash. Here again, when they do, Aptible operations may fail
  </Accordion>
</AccordionGroup>


# Architecture - Overview

Learn about the key components of the Aptible platform architecture and how they work together to help you deploy and manage your resources

# Overview

Aptible is an AWS-based container orchestration platform designed for deploying highly available and secure applications and databases to cloud environments. It is compromised of several key components:

*   **Stacks:** [Stacks](/core-concepts/architecture/stacks) are fundamental to the network-level isolation of your resources. The underlying virtualized infrastructure (EC2 instances, private network, etc.), provides network-level isolation of resources. Each stack is hosted in a specific region and is comprised of environments. Aptible offers shared stacks (non-isolated) and dedicated stacks (isolated). Dedicated stacks automatically come with a [suite of security features](https://www.aptible.com/secured-by-aptible), including encryption, DDoS protection, host hardening, [intrusion detection](/core-concepts/security-compliance/hids), and [vulnerability scanning ](/core-concepts/security-compliance/security-scans)— alleviating the need to worry about security best practices.
*   **Environments:** [Environments](/core-concepts/architecture/environments) determine the logical isolation of your resources. Environments help you maintain a clear separation between development, testing, and production resources, ensuring that changes in one environment do not affect others.
*   **Containers:** [Containers](/core-concepts/architecture/containers/overview) are at the heart of how your resources, such as [apps](/core-concepts/apps/overview) and [databases](/core-concepts/managed-databases/overview), are deployed on the Aptible platform. Containers can be easily scaled up or down to meet the needs of your application, making it simple to manage resource allocation.
*   **Endpoints (Load Balancers)** allow you to expose your resources to the internet and are responsible for distributing incoming traffic across your containers. They act as load balancers to ensure high availability and reliability for your applications. See [App Endpoints](/core-concepts/apps/connecting-to-apps/app-endpoints/overview) and [Database Endpoints](/core-concepts/managed-databases/connecting-databases/database-endpoints) for more information.

<Tip> Need a visual? Check our our [Aptible Architecture Diagram](https://www.aptible.com/assets/deploy-reference-architecture.pdf)</Tip>

# FAQ

<Accordion title="How does the Aptible platform/architecture compare to Kubernetes?">
  Aptible is a custom-built container orchestration solution designed to streamline deploying, managing, and scaling infrastructure scaling, much like Kubernetes. However, Aptible distinguishes itself by being developed in-house with a strong focus on [security, compliance, and reliability.](/getting-started/introduction) This focus stemmed from our original mission to automate HIPAA compliance. As a result, Aptible has evolved into a platform for engineering teams of all sizes, ensuring private, fully secure, and compliant deployments - without the added complexities of Kubernetes.

  <Note> Check out this related blog post "[Kubernetes Challenges: Container Orchestration and Scaling](https://www.aptible.com/blog/kubernetes-challenges-container-orchestration-and-scaling)"</Note>

  Moreover, Aptible goes beyond basic orchestration functionalities by providing additional features such as Managed Databases, a 99.95% uptime guarantee, and enterprise-level support for engineering teams of all sizes.
</Accordion>

<Accordion title="What kinds of isolation can Aptible provide?">
  Multitenancy is a key property of most cloud computing service models, which makes isolation a critical component of most cloud computing security models.

  Aptible customers often need to explain to their own customers what kinds of isolation they provide, and what kinds of isolation are possible on the Aptible platform.

  The [Reference Architecture Diagram](https://www.aptible.com/assets/deploy-reference-architecture.pdf) helps illustrate some of the following concepts.

  ### Infrastructure

  All Aptible resources are deployed using Amazon Web Services. AWS operates and secures the physical data centers that produce the underlying compute, storage, and networking functionality needed to run your [Apps](https://www.aptible.com/docs/core-concepts/apps/overview) and [Databases](https://www.aptible.com/docs/core-concepts/managed-databases/overview).

  ### Network/Stack

  Each [Aptible Stack](https://www.aptible.com/docs/core-concepts/architecture/stacks) is an AWS Virtual Private Cloud provisioned with EC2, ELB, and EBS assets and Aptible platform software.

  When you provision a [Dedicated Stack](https://www.aptible.com/docs/core-concepts/architecture/stacks#dedicated-stacks-isolated) on Aptible, you receive your own VPC, meaning you receive your own private and public subnets, isolated from other Aptible customers…

  You can provide further network level isolation between your own Apps and Databases by provisioning Additional Dedicated Stacks.

  ### Host

  The Aptible layers where your Apps and Databases run are backed by AWS EC2 instances, or hosts.

  Each host is deployed in a single VPC. On a Dedicated Stack, this means you are the only Aptible customer using those EC2 virtual servers.

  In a Dedicated Stack, these EC2 instances are AWS Dedicated Instances, meaning Aptible is the sole tenant of the underlying hardware. The AWS hypervisor enforces isolation between EC2 hosts running on the same underlying hardware.

  Within a Stack, the EC2 hosts are organized into Aptible services layers. Each EC2 instance belongs to only one layer, isolating against failures in other layers:

  App Layer: Runs your app containers, terminates SSL.
  Database Layer: Runs your database containers.
  Bastion Layer: Provides backend SSH access to your Stack, builds your Docker images.
  Because Aptible may occasionally need to rotate or deprovision hosts in your Stack to avoid disruptions in service, we do not expose the ability for you to select which specific hosts in your Stack will perform a given workload.

  ### Environment

  [Aptible Environments](https://www.aptible.com/docs/core-concepts/architecture/environments) are used for access control.

  Each environment runs on a specific Stack. Each Stack can support multiple Environments. Note that when you use Environments to separate Apps or Databases, those resources will share networks and underlying hosts if they are on the same Stack.

  You can use separate Environments to isolate access to specific Apps or Databases to specific members of your organization.

  ### Container

  Aptible uses Docker to build and run your App and Database [Containers](https://www.aptible.com/docs/core-concepts/architecture/containers/overview).

  Each container is a lightweight virtual machine that isolates Linux processes running on the same underlying host. Containers are generally isolated from each other, but are the weakest level of isolation.

  You can provide container-level isolation between your own customers by provisioning their resources as separate Apps and Databases.
</Accordion>


# Reliability Division of Responsibilities



## Overview

Aptible is a Platform as a Service that simplifies infrastructure management for developers. However, it's important to note that users have certain responsibilities as well.

This document builds on the [Divisions of Responsibility](https://www.aptible.com/assets/deploy-division-of-responsibilities.pdf) between Aptible and users, focusing on use cases related to Reliability and Disaster Recovery. The goal is to provide users with a clear understanding of the monitoring and processes that Aptible manages on their behalf, as well as areas that are not covered.

While this document covers essential aspects, it's important to remember that it doesn't include all responsibilities in detail. Nevertheless, it's a valuable resource to help users navigate their infrastructure responsibilities effectively within the Aptible ecosystem.

## Uptime

Uptime refers to the percentage of time that the Aptible platform is operational and available for use. Aptible provides a 99.95% uptime SLA guarantee for dedicated stacks and on the Enterprise Plan.

Aptible

*   Aptible will send notifications of availability incidents for all dedicated environments and corresponding resources, including but not limited to stacks and databases.

    *   For service-wide availability incidents, Aptible will notify users of the incident within the Aptible Dashboard and our [Status Page](https://status.aptible.com/). For all other availability incidents on dedicated stacks, Aptible will notify the Ops Alert contact.
*   Aptible will issue a credit for SLA breaches as defined by our SLA guarantee for dedicated stacks and organizations on the Enterprise Plan.

Users

*   To receive Aptible’s 99.95% uptime SLA, Enterprise users are responsible for ensuring their critical resources, such as production environments, are provisioned on dedicated stacks.

*   To receive email notifications of availability incidents impacting the Aptible platform, users are responsible for subscribing to email notifications on our [Status Page](https://status.aptible.com/).

*   Users are responsible for providing a valid Ops Alert Contact. Ops Alert Contact should be reachable by [support@aptible.com](mailto:support@aptible.com)

## Maintenance

Maintenance can occur at any time, causing unavailability of Aptible resources (including but not limited to stacks, databases, VPNs, and log drains). Scheduled maintenance typically occurs between 9 pm and 9 am ET on weekdays, or between 6 pm and 10 am ET on weekends. Unscheduled maintenance may occur in situations like critical security patching.

Aptible

*   Aptible will notify the Ops Alert contact of scheduled maintenance for dedicated stacks or service-wide with at least two weeks out whenever possible. However, there may be cases where Aptible provides less notice, such as AWS instance retirement, or no prior notice, such as critical security patching.

Users

*   Users are responsible for providing a valid Ops Alert Contact.

## Hosts

Aptible

*   Aptible is solely responsible for the host and the host's health. If a host becomes unhealthy, impacted containers will be moved to a healthy host. This extends to AWS-scheduled hardware maintenance.

## Databases

Aptible

*   While Aptible avoids unnecessary database restarts, Aptible may restart your database at any time for the purposes of security or availability. This may include but is not limited to restarts which:

    *   Resolve existing availability issue

    *   Avoid an imminent, unavoidable availability issue that would have a greater impact than a restart

    *   Resolve critical and/or urgent security incident

*   Aptible restarts database containers that have exited (see: [Container Recovery](/core-concepts/architecture/containers/container-recovery)).

*   Aptible restarts database containers that have run out of memory (see: [Memory Management](/core-concepts/scaling/memory-limits)).

*   Aptible monitors database containers stuck in restart loops and will take action to resolve the root cause of the restart loop.

    *   Common cases include the database running out of disk space, memory, or incorrect/invalid settings. The on-call Aptible engineer will contact the Ops Alert contact with information about the root cause and action taken.

*   Aptible's SRE team receives a list of databases using more than 98% of disk space roughly once a day. Any action taken is on a "best effort" basis, and at the discretion of the responding SRE. Typically, the responding SRE will scale the database and notify the Ops Alert contact, but depending on usage patterns and growth rates, they may instead contact the Ops Alert contact before taking action.

    *   Aptible is considering automating this process as part of our roadmap. With this automation, any Database that exceeds 99% disk utilization will be scaled up, and the Ops Alert contact will be notified.

*   Aptible ensures that database replicas are distributed across availability zones.

    *   There are times when this may not be possible. For example, when recovering a primary or replica after an outage, the fastest path to recovery may be temporarily running both a primary and replica in the same availability zone. In these cases, the Aptible SRE team is notified and will reach out to schedule a time to migrate the database to a new availability zone.

*   Aptible automatically takes backups of databases once a day and monitors for failed backups. Backups are created via point-in-time snapshots of the database's disk. As a result, taking a backup causes no performance degradation. The resulting backup is not stored on the primary volume.

*   If enabled as part of the retention policy, Aptible copies database backups to another region as long as another geographically appropriate region is available.

Users

*   Users are responsible for monitoring performance, resource consumption, latency, network connectivity, or any other metrics for databases other than the metrics explicitly outlined above.

*   Users are responsible for monitoring database replica health or replication lag.

*   To achieve cross-region replication, users are responsible for enabling cross-region replication.

## Apps

Aptible

*   While Aptible avoids unnecessary restarts, Aptible may restart your app at any time. This may include but is not limited to restarts which:

    *   Resolve existing availability issue

    *   Avoid an imminent, unavoidable availability issue that would have a greater impact than a restart

    *   Resolve critical and/or urgent security incident

*   Aptible automatically restarts containers that have exited (see: [Container Recovery](/core-concepts/architecture/containers/container-recovery)).

*   Aptible restarts containers that have run out of memory (see: [Memory Management](/core-concepts/scaling/memory-limits)).

*   Aptible monitors App host disk utilization. When Apps that are writing to the ephemeral file system cause utilization issues, we may restart the Apps to reset the container filesystem back to a clean state.

Users

*   Users are responsible for ensuring your container correctly exits (see: "Cases where Container Recovery will not work" in [Container Recovery](/core-concepts/architecture/containers/container-recovery)). If a container is not correctly designed to exit on failure, Aptible does not restart it and has no monitoring that will catch that failure condition.

*   Users are responsible for monitoring app containers stuck in restart loops.

*   Aptible does not proactively run your apps in another region, nor do we retain a copy of your code or Docker Images required to fail your Apps over to another region. In the event of a regional outage, users are responsible for coordinating with Aptible to restore apps in a new region.

*   Users are responsible for monitoring performance, resource consumption, latency, network connectivity, or any other metrics for apps other than the metrics explicitly outlined above.

## VPNs

Aptible

*   Aptible provides connectivity between resource(s) in an Aptible customer's [Dedicated Stack](/core-concepts/architecture/stacks) and resource(s) in a customer-specified peer network. Aptible is responsible for the configuration and setup of the Aptible VPN peer. (See [Site-to-site VPN Tunnels](/core-concepts/integrations/network-integrations#site-to-site-vpn-tunnels))

Users

*   Users are responsible for coordinating the configuration of the non-Aptible peer.

*   Users are responsible for monitoring the connectivity between resources across the VPN Tunnel (this is the responsibility of the customer and/or their partner network operator).


# Stacks

Learn about using Stacks to deploy resources to various regions

<Frame>
  ![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/1-app-ui.png)
</Frame>

# Overview

Stacks are fundamental to the network-level isolation of your resources. Each Stack is hosted in a specific region and is comprised of [environments](/core-concepts/architecture/environments). Aptible offers two types of Stacks: [Shared Stacks](/core-concepts/architecture/stacks#shared-stacks) (non-isolated) and [Dedicated Stacks](/core-concepts/architecture/stacks#dedicated-stacks) (isolated).

Resources in different Stacks can only connect with each other with a [network integration.](/core-concepts/integrations/network-integrations) For example: Databases and Internal Endpoints deployed in a given Stack are not accessible from Apps deployed in other Stacks.

<Note> The underlying virtualized infrastructure (EC2 instances, private network, etc.), which provides network-level isolation of resources.</Note>

# Shared Stacks (Non-Isolated)

Stacks shared across many customers are called Shared Stacks. Use Shared Stacks for development, testing, and staging [Environments](/core-concepts/architecture/environments).

<Warning> You can not host sensitive or regulated data with shared stacks.</Warning>

# Dedicated Stacks (Isolated)

<Info> Dedicated Stacks are only available on [Production and Enterprise plans.](https://www.aptible.com/pricing)</Info>

Dedicated stacks are built for production [environments](/core-concepts/architecture/environments), are dedicated to a single customer, and provide four significant benefits:

*   **Tenancy** - Dedicated stacks are isolated from other Aptible customers, and you can also use multiple Dedicated Stacks to architect the [isolation](https://www.aptible.com/core-concepts/architecture/overview#what-kinds-of-isolation-can-aptible-provide) you require within your organization.
*   **Availability** - Aptible's [Service Level Agreement](https://www.aptible.com/legal/service-level-agreement/) applies only to Environments hosted on a Dedicated stack.
*   **Regulatory** - Aptible will sign a HIPAA Business Associate Agreement (BAA) to cover information processing in Environments hosted on a Dedicated stack.
*   **Connectivity** - [Integrations](/core-concepts/integrations/network-integrations), such as VPN and VPC Peering connections, are available only to Dedicated stacks.
*   **Security** - Dedicated stacks automatically come with a [suite of security features](https://www.aptible.com/secured-by-aptible), including encryption, DDoS protection, host hardening, [intrusion detection](/core-concepts/security-compliance/hids), and [vulnerability scanning ](/core-concepts/security-compliance/security-scans)— alleviating the need to worry about security best practices.

## Supported Regions

<Frame>
  ![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/regions.png)
</Frame>

| Region                                    | Available on Shared Stacks | Available on Dedicated Stacks |
| ----------------------------------------- | -------------------------- | ----------------------------- |
| us-east-1 / US East (N. Virginia)         | ✔️                         | ✔️                            |
| us-east-2 / US East (Ohio)                |                            | ✔️                            |
| us-west-1 / US West (N. California)       | ✔️                         | ✔️                            |
| us-west-2 / US West (Oregon)              |                            | ✔️                            |
| eu-central-1 / Europe (Frankfurt)         | ✔️                         | ✔️                            |
| sa-east-1 / South America (São Paulo)     |                            | ✔️                            |
| eu-west-1 / Europe (Ireland)              |                            | ✔️                            |
| eu-west-2 / Europe (London)               |                            | ✔️                            |
| eu-west-3 / Europe (Paris)                |                            | ✔️                            |
| ca-central-1 / Canada (Central)           | ✔️                         | ✔️                            |
| ap-south-1 / Asia Pacific (Mumbai)        | ✔️                         | ✔️                            |
| ap-southeast-2 / Asia Pacific (Sydney)    | ✔️                         | ✔️                            |
| ap-northeast-1 / Asia Pacific (Tokyo)     |                            | ✔️                            |
| ap-southeast-1 / Asia Pacific (Singapore) |                            | ✔️                            |

<Tip> A Stack's Region will affect the latency of customer connections based on proximity. For [VPC Peering](/core-concepts/integrations/network-integrations), deploy the Aptible Stack in the same region as the AWS VPC for both latency and DNS concerns.</Tip>

# FAQ

<AccordionGroup>
  <Accordion title="How do I create or deprovision a dedicated stack?">
    ### Read the guide

    <Card title="How to create and deprovison dedicated stacks" icon="book-open-reader" iconType="duotone" href="https://www.aptible.com/docs/create-dedicated-stack" />
  </Accordion>

  <Accordion title="Does Aptible support multi-region setups for business continuity?">
    Yes, this is touched on in our [Business Continuity Guide](https://www.aptible.com/docs/business-continuity). For more information about setup, contact Aptible Support.
  </Accordion>

  <Accordion title="How much do Dedicated Stacks cost?">
    See our pricing page for more information: [https://www.aptible.com/pricing](https://www.aptible.com/pricing)
  </Accordion>

  <Accordion title="Can Dedicated Stacks be renamed?">
    Dedicated Stacks cannot be renamed once created. To update the name of a Dedicated Stack, you create a new Dedicated Stack and migrate your resources to this new Stack. Please note: this does incur downtime.
  </Accordion>

  <Accordion title="Can my resources be migrated from a Shared Stack to a Dedicated Stack">
    Yes, contact Aptible Support to request resources be migrated.
  </Accordion>
</AccordionGroup>


# Billing & Payments

Learn how manage billing & payments within Aptible

# Overview

To review or modify your billing information, navigate to your account settings within the Aptible Dashboard and select the appropriate option from the Billing section of the navigation.

# Navigating Billing

<Tip> Most billing actions are restricted to *Account Owners*. Billing contacts must request that an *Account Owner* make necessary changes.</Tip>

<Frame>
  ![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/billing1.png)
</Frame>

The following information and settings are available under each section:

*   Plans: View and manage your plan.
*   Contracts: View a list of your billing contracts, if any.
*   Invoices & Projections: View historical invoices and your projected future invoices based on current usage patterns.
*   Payment Methods: Add or update a payment method.
*   Credits: View credits applied to your account.
*   Contacts: Manage billing contacts who receive a copy of your invoices by email.
*   Billing Address: Set your billing address.

<Info> Aptible uses billing address information to determine your sales tax withholding per your local (state, county, city) tax rates. </Info>

# FAQ

<AccordionGroup>
  <Accordion title="How do I upgrade my plan?">
    Follow these steps to upgrade your account to the Production plan:

    *   In the Aptible Dashboard, select **Settings**
    *   Select **Plans**

    ![Viewing your Plan in the Aptible Dashboard](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/billing2.png)

    To upgrade to Enterprise, [contact Aptible Support.](https://app.aptible.com/support)
  </Accordion>

  <Accordion title="How to downgrade my plan?">
    Follow these steps to downgrade your account to the Development or Production plan:

    *   In the Aptible dashboard, select your name at the top right
    *   Select Billing Settings in the dropdown that appears
    *   On the left, select Plan
    *   Choose the plan you would like to downgrade to

    Please note that your active resources must match the limits of the plan you select for the downgrade to succeed. For example: if you downgrade to a plan that only includes up to 3GB RAM - you must scale your resources below 3GB RAM before you can successfully downgrade.
  </Accordion>

  <Accordion title="What payment methods are supported?">
    *   All plans: Credit Card and ACH Debit
    *   Enterprise plan: Credit Card, ACH Credit, ACH Debit, Wire, Bill.com, Custom Arrangement
  </Accordion>

  <Accordion title="How do I update my payment method?">
    *   Credit Card and ACH Debit: In the Aptible dashboard, select your name at the top right > select Billing Settings in the dropdown that appears > select Payment Methods on the left.

    *   Enterprise plan only: ACH Credit, Wire, Bill.com, Custom Arrangement: Please contact [Aptible Support](/how-to-guides/troubleshooting/aptible-support) to make necessary updates.
  </Accordion>

  <Accordion title="What's happens when invoices are unpaid/overdue?">
    Invoices can become overdue for several reasons:

    *   A card is expired
    *   Payment was declined
    *   There is no payment method on file

    Aptible suspends accounts with invoices overdue for more than 14 days. If an invoice is unpaid for over 30 days, Aptible will shut down your account.
  </Accordion>

  <Accordion title="How do I see the costs per service or Environment?">
    [Contact Aptible Support](/how-to-guides/troubleshooting/aptible-support) to request a "Detailed Invoice Breakdown Report."
  </Accordion>

  <Accordion title="Can I pay annually?">
    Yes, we offer volume discounts for paying upfront annually. [Contact Aptible Support](/how-to-guides/troubleshooting/aptible-support) to request volume pricing.
  </Accordion>

  <Accordion title="How do I cancel my Aptible account?">
    Please refer to [Cancel my account](/how-to-guides/platform-guides/cancel-aptible-account) for more information.
  </Accordion>

  <Accordion title="How can I get copies of invoices?">
    Billing contacts receive copies of monthly invoices in their email. Only [Account Owners](/core-concepts/security-compliance/access-permissions#account-owners) can add billing contacts. Add billing contacts using these steps:

    *   In the Aptible dashboard, select your name at the top right
    *   Select Billing Settings in the dropdown that appears
    *   On the left, select Contacts
  </Accordion>
</AccordionGroup>


# Datadog Integration

Learn about using the Datadog Integration for logging and monitoring

# Overview

Aptible integrates with [Datadog](https://www.datadoghq.com/), allowing you to send information about your Aptible resources directly to your Datadog account for monitoring and analysis. You can send the following data directly to your Datadog account:

*   **Logs:** Send logs to Datadog’s [log management](https://docs.datadoghq.com/logs/) using a log drains
*   **Container Metrics:** Send app and database container metrics to Datadog’s [container monitoring](https://www.datadoghq.com/product/container-monitoring/) using a metric drain
*   **In-Process Instrumentation Data (APM):** Send instrumentation data to [Datadog’s APM](https://www.datadoghq.com/product/apm/) by deploying a single Datadog Agent app

> Please note, Datadog's documentation defaults to v2. Please use v1 Datadog documentation with Aptible.

## Datadog Log Integration

On Aptible, you can set up a Datadog [log drain](/core-concepts/observability/logs/log-drains/overview) within an environment to send logs for apps, databases, SSH sessions and endpoints directly to your Datadog account for [log management and analytics](https://www.datadoghq.com/product/log-management/).

<Info> On other platforms, you might configure this by installing the Datadog Agent and setting `DD_LOGS_ENABLED`.</Info>

<Accordion title="Creating a Datadog Log Drain">
  A Datadog Log Drain can be created in three ways on Aptible:

  *   Within the Aptible Dashboard by:
      *   Navigating to an Environment
      *   Selecting the **Log Drains** tab
      *   Selecting **Create Log Drain**
      *   Selecting **Datadog**
  *   Using the [`aptible log_drain:create:datadog`](/reference/aptible-cli/cli-commands/cli-log-drain-create-datadog) CLI command
</Accordion>

## Datadog Container Monitoring Integration

On Aptible, you can set up a Datadog [metric drain](/core-concepts/observability/metrics/metrics-drains/overview) within an environment to send metrics directly to your Datadog account. This enables you to use Datadog’s [container monitoring](https://www.datadoghq.com/product/container-monitoring/) for apps and databases. Please note that not all features of container monitoring are supported (including but not limited to Docker integrations and auto-discovery).

<Info>On other platforms, you might configure this by installing the Datadog Agent and setting `DD_PROCESS_AGENT_ENABLED`.</Info>

<Accordion title="Creating a Datadog Metric Drain">
  A Datadog Log Drain can be created in three ways on Aptible:
  A Datadog Metric Drain can be provisioned in three ways on Aptible:

  *   Within the Aptible Dashboard by:
      *   Navigating to an Environment:
      *   Selecting the **Metric Drains** tab
      *   Selecting **Create Metric Drain**
  *   Using the [`aptible metric_drain:create:datadog`](/reference/aptible-cli/cli-commands/cli-metric-drain-create-datadog) CLI command
  *   Using the Aptible [Terraform Provider](https://registry.terraform.io/providers/aptible/aptible/latest/docs)
</Accordion>

### Datadog Metrics Structure

Aptible metrics are reported as [Custom Metrics](https://docs.datadoghq.com/developers/metrics/custom_metrics/) in Datadog. The following metrics are reported (all these metrics are reported as `gauge` in Datadog, approximately every 30 seconds):

*   `enclave.running`: a boolean indicating whether the Container was running when this point was sampled.
*   `enclave.milli_cpu_usage`: the Container's average CPU usage (in milli CPUs) over the reporting period.
*   `enclave.milli_cpu_limit`: the maximum CPU accessible to the container.
*   `enclave.memory_total_mb`: the Container's total memory usage. See [Understanding Memory Utilization](/core-concepts/scaling/memory-limits#understanding-memory-utilization) for more information on memory usage.
*   `enclave.memory_rss_mb`: the Container's RSS memory usage. This memory is typically not reclaimable. If this exceeds the `memory_limit_mb`, the container will be restarted.
    <Note> Review [Understanding Memory Utilization](/core-concepts/scaling/memory-limits#understanding-memory-utilization) for more information on the meaning of the `enclave.memory_total_mb` and `enclave.memory_rss_mb` values. </Note>
*   `enclave.memory_limit_mb`: the Container's [Memory Limit](/core-concepts/scaling/memory-limits).
*   `enclave.disk_read_kbps`: the Container's average disk read bandwidth over the reporting period.
*   `enclave.disk_write_kbps`: the Container's average disk write bandwidth over the reporting period.
*   `enclave.disk_read_iops`: the Container's average disk read IOPS over the reporting period.
*   `enclave.disk_write_iops`: the Container's average disk write IOPS over the reporting period.
    <Note> Review [I/O Performance](/core-concepts/scaling/database-scaling#i-o-performance) for more information on the meaning of the `enclave.disk_read_iops` and `enclave.disk_write_iops` values. </Note>
*   `enclave.disk_usage_mb`: the Database's Disk usage (Database metrics only).
*   `enclave.disk_limit_mb`: the Database's Disk size (Database metrics only).
*   `enclave.pids_current`: the current number of tasks in the Container (see [Other Limits](/core-concepts/security-compliance/ddos-pid-limits)).
*   `enclave.pids_limit`: the maximum number of tasks for the Container (see [Other Limits](/core-concepts/security-compliance/ddos-pid-limits)).

All metrics published in Datadog are enriched with the following tags:

*   `environment`: Environment handle
*   `app`: App handle (App metrics only)
*   `database`: Database handle (Database metrics only)
*   `service`: Service name
*   `container`: Container ID

Finally, Aptible also sets the `host_name` tag on these metrics to the [Container Hostname (Short Container ID).](/core-concepts/architecture/containers/overview#container-hostname)

## Datadog APM

On Aptible, you can configure in-process instrumentation Data (APM) to be sent to [Datadog’s APM](https://www.datadoghq.com/product/apm/) by deploying a single Datadog Agent app and configuring each of your apps to:

*   Enable Datadog in-process instrumentation and
*   Forward those data through the Datadog Agent app separately hosted on Aptible

<Card title="How to set up Datadog APM" icon="book-open-reader" iconType="duotone" iconType="duotone" href="https://www.aptible.com/docs/datadog-apm" />


# Entitle Integration

Learn about using the Entitle integration for just-in-time access to Aptible resources

# Overview

[Entitle](https://www.entitle.io/) is how cloud-forward companies provide employees with temporary, granular, and just-in-time access within their cloud infrastructure and SaaS applications. Entitle easily integrates with your stack, offering self-serve access requests, instant visibility into your cloud entitlements, and making user access reviews a breeze.

# Setup

[Learn more about integration Entitle with Aptible here.](https://www.entitle.io/integrations/aptible)


# Mezmo Integration

Learn about sending Aptible logs to Mezmo

## Overview

Mezmo, formerly known as LogDNA, is a cloud-based platform for log management and analytics. With Aptible's integration, you can send logs directly to Mezmo for analysis and storage.

## Set up

<Info> Prerequisites: A Mezmo account</Info>

<Steps>
  <Step title="Configure your Mezmo account for Aptible Log Ingestion">
    Refer to the [Mezmo documentation for setting up Aptible Log Ingestion on Mezmo.](https://docs.mezmo.com/docs/aptible-logs)

    Note: Like all Aptible Log Drain providers, Mezmo also offers Business Associate Agreements (BAAs). To ensure HIPAA compliance, please contact them to execute a BAA.
  </Step>

  <Step title="Configure your Log Drain">
    You can send your Aptible logs directly to Mezmo with a [log drain](https://www.aptible.com/docs/log-drains). A Mezmo/LogDNA Log Drain can be created in the following ways on Aptible:

    *   Within the Aptible Dashboard by:
        *   Navigating to an Environment
        *   Selecting the **Log Drains** tab
        *   Selecting **Create Log Drain**
        *   Selecting **Mezmo**
        *   Entering your Mezmo URL
    *   Using the [`aptible log_drain:create:logdna`](/reference/aptible-cli/cli-commands/cli-log-drain-create-logdna) command
  </Step>
</Steps>


# Network Integrations: VPC Peering & VPN Tunnels



# VPC Peering

<Info> VPC Peering is only available on [Production and Enterprise plans.](https://www.aptible.com/pricing)</Info>

Aptible offers VPC Peering to connect a user’s existing network to their Aptible dedicated VPC. This lets users access internal Aptible resources such as [Internal Endpoints](/core-concepts/apps/connecting-to-apps/app-endpoints/overview) and [Databases](/core-concepts/managed-databases/managing-databases/overview) from their network.

## Setup

VPC Peering connections can only be set up by contacting [Aptible Support](/how-to-guides/troubleshooting/aptible-support).

## Managing VPC Peering

VPC Peering connections can only be managed by the Aptible Support Team. This includes deprovisioning VPC Peering connections.

The details and status of VPC Peering connections can be viewed within the Aptible Dashboard by:

*   Navigating to the respective Dedicated Stack
*   Selecting the "VPC Peering" tab

# VPN Tunnels

<Info> VPN Tunnels are only available on [Production and Enterprise plans.](https://www.aptible.com/pricing) </Info>

Aptible supports site-to-site VPN Tunnels to connect external networks to your Aptible resources. VPN Tunnels are only available on dedicated stacks.

The default protocol for all new VPN Tunnels is IKEv2.

## Setup

VPN Tunnels can only be set up by contacting Aptible Support.

Please provide the following information when you contact [Aptible Support](/how-to-guides/troubleshooting/aptible-support) with your tunnel setup request:

*   What resources on the Aptible Stack must be exposed over the tunnel? Aptible can expose:
    *   Individual resources. Please share the hostname of the Internal [Endpoints](/core-concepts/apps/connecting-to-apps/app-endpoints/overview) (elb-xxxxx.aptible.in) and the names of the [Databases](/core-concepts/managed-databases/overview) that need to be made accessible over the tunnel.
    *   The entire Stack - only recommended if users own the network Aptible is integrating.
    *   No resources - or users who need to access resources on the other end of the tunnel without exposing Aptible-side resources.
*   Is outbound access from the Stack to the resources exposed on the other end of the tunnel required?

Aptible Support will follow up with a VPN Implementation Worksheet that can be shared with the tunnel partner.

> ❗️Road-warrior VPNs are **not** supported on Aptible. To provide road-warrior users with VPN access to Aptible resources, set up a VPN gateway on a user-owned network and have users connect there, then create a site-to-site VPN tunnel between the user-owned network and the Aptible Dedicated Stack.

## Managing VPN Tunnels

VPN Tunnels can only be managed by the Aptible Support Team. This includes deprovisioning VPN Tunnels.

The details and status of VPN Tunnels can be viewed within the Aptible Dashboard by:

*   Navigating to the respective Dedicated Stack
*   Selecting the "VPN Tunnels" tab

There are four statuses that you might see in this view:

*   `Up`: The connection is fully up
*   `Down`: The connection is fully down - consider contacting your partner or Aptible Support
*   `Partial`: The connection is in a mixed up/down state, usually because your tunnel is configured as a "connect when there is activity" tunnel, and some connections are not being used
*   `Unknown`: Something has gone wrong with the status check; please check again later or reach out to Aptible Support if you are having problems


# All Integrations and Tools

Explore all integrations and tools used with Aptible

## Cloud Hosting

Deploy apps and databases to **Aptible's secure cloud** or **integrate with existing cloud** providers to standardize infrastructure.

<CardGroup cols={2}>
  <Card title="Host in Aptible's cloud">
    ![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/stack02.png)

    <CardGroup cols={2}>
      <Card title="Get Started→" href="https://app.aptible.com/signup" />

      <Card title="Learn more→" href="https://www.aptible.com/docs/reference/pricing#aptible-hosted-pricing" />
    </CardGroup>
  </Card>

  <Card title="Host in your own AWS">
    ![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/stack01.png)

    <CardGroup cols={2}>
      <Card title="Request Access→" href="https://app.aptible.com/signup?cta=early-access" />

      <Card title="Learn more→" href="https://www.aptible.com/docs/reference/pricing#self-hosted-pricing" />
    </CardGroup>
  </Card>
</CardGroup>

## Managed Databases

Aptible offers a robust selection of fully [Managed Databases](https://www.aptible.com/docs/databases) automate provisioning, maintenance, and scaling.

<CardGroup cols={4}>
  <Card title="Elasticsearch" href="https://www.aptible.com/docs/elasticsearch" img="https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/Elasticsearch.png" />

  <Card title="InfluxDB" href="https://www.aptible.com/docs/influxdb" img="https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/InfluxDB.png" />

  <Card title="MongoDB" href="https://www.aptible.com/docs/mongodb" img="https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/MongoDB.png" />

  <Card title="MySQL" href="https://www.aptible.com/docs/mysql" img="https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/MySQL.png" />

  <Card title="PostgreSQL" href="https://www.aptible.com/docs/postgresql" img="https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/PostgreSQL.png" />

  <Card title="RabbitMQ" href="https://www.aptible.com/docs/rabbitmq" img="https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/RabbitMQ.png" />

  <Card title="Redis" href="https://www.aptible.com/docs/redis" img="https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/Redis.png" />

  <Card title="SFTP" href="https://www.aptible.com/docs/sftp" img="https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/SFTP.png" />
</CardGroup>

## Observability

### Logging

<CardGroup cols={4}>
  <Card title="Amazon S3" href="https://www.aptible.com/docs/s3-log-archives" img="https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/AmazonS3.png">
    Archive Aptible logs to S3 for historical retention
  </Card>

  <Card title="Datadog" href="https://www.aptible.com/docs/datadog" img="https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/Datadog.png">
    Send Aptible logs to Datadog
  </Card>

  <Card title="Custom - HTTPS" href="https://www.aptible.com/docs/https-log-drains" img="https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/HTTPS.png">
    Send Aptible logs to any destination of your choice via HTTPS
  </Card>

  <Card title="Custom - Syslog" href="https://www.aptible.com/docs/syslog-log-drains" img="https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/Syslog.png">
    Send Aptible logs to any destination of your choice with Syslog
  </Card>

  <Card title="Elasticsearch" href="https://www.aptible.com/docs/elasticsearch-log-drains" img="https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/Elasticsearch.png">
    Send logs to Elasticsearch on Aptible or in the cloud
  </Card>

  <Card title="Fivetran" href="https://www.aptible.com/docs/connect-to-fivetran" img="https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/Fivetran.png">
    Send Aptible database logs to Fivetran
  </Card>

  <Card title="Logentries" img="https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/Logentries.png">
    Send Aptible logs to Logentries
  </Card>

  <Card title="Mezmo" href="https://www.aptible.com/docs/mezmo" img="https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/Mezmo.png">
    Send Aptible logs to Mezmo (Formerly LogDNA)
  </Card>

  <Card title="Logstash" img="https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/Logstash.png">
    Send Aptible logs to Logstash
  </Card>

  <Card title="Papertrail" href="https://www.aptible.com/docs/papertrail" img="https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/Papertrail.png">
    Send Aptible logs to Papertrail
  </Card>

  <Card title="Sumo Logic" href="https://www.aptible.com/docs/sumo-logic" img="https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/Sumologic.png">
    Send Aptible logs to Sumo Logic
  </Card>

  <Card title="Request new integration" icon="plus" href="https://portal.productboard.com/aptible/2-aptible-roadmap-portal/tabs/5-ideas/submit-idea" />
</CardGroup>

### Metrics

<CardGroup cols={4}>
  <Card title="Datadog" href="https://www.aptible.com/docs/datadog" img="https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/Datadog.png">
    Send Aptible container metrics to Datadog or setup Datadog APM
  </Card>

  <Card title="InfluxDB" href="https://www.aptible.com/docs/core-concepts/observability/metrics/metrics-drains/influxdb-metric-drain" img="https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/InfluxDB.png">
    Send Aptible container metrics to an InfluxDB
  </Card>

  <Card title="Request new integration" icon="plus" href="https://portal.productboard.com/aptible/2-aptible-roadmap-portal/tabs/5-ideas/submit-idea" />
</CardGroup>

## Developer Tools

<CardGroup cols={4}>
  <Card title="Aptible CLI" href="https://www.aptible.com/docs/cli" img="https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/Aptible.png">
    Manage your Aptible resources via the Aptible CLI
  </Card>

  <Card title="Custom CI/CD" img="https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/Custom%20CI_CD.png">
    Deploy to Aptible using a CI/CD tool of your choice
  </Card>

  <Card title="Circle CI" img="https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/CircleCI.png">
    Deploy to Aptible using Circle CI.
  </Card>

  <Card title="GitHub Actions" img="https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/GitHub%20Actions.png">
    Deploy to Aptible using GitHub Actions.
  </Card>

  <Card title="Terraform" href="https://www.aptible.com/docs/terraform" img="https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/Terraform.png">
    Manage your Aptible resources programmatically via Terraform
  </Card>

  <Card title="Request new integration" icon="plus" href="https://portal.productboard.com/aptible/2-aptible-roadmap-portal/tabs/5-ideas/submit-idea" />
</CardGroup>

## Network & Security

<CardGroup cols={4}>
  <Card title="Entitle" href="https://www.aptible.com/docs/entitle" img="https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/Entitle.png">
    Automate just-in-time access to Aptible resources
  </Card>

  <Card title="Google SSO" href="https://www.aptible.com/docs/core-concepts/security-compliance/authentication/sso" img="https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/Google%20SSO.png">
    Configure SSO with Okta
  </Card>

  <Card title="Okta" href="https://www.aptible.com/docs/core-concepts/security-compliance/authentication/sso" img="https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/Okta.png">
    Configure SSO with Okta
  </Card>

  <Card title="Single Sign-On (SAML)" href="https://www.aptible.com/docs/core-concepts/security-compliance/authentication/sso" img="https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/SSO_SCIM.png">
    Configure SSO with Popular Identity Providers
  </Card>

  <Card title="SCIM (Provisioning)" href="https://www.aptible.com/docs/core-concepts/security-compliance/authentication/scim" img="https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/SSO_SCIM.png">
    Configure SCIM with Popular Identity Providers
  </Card>

  <Card title="Site-to-site VPNs " href="https://www.aptible.com/docs/network-integrations" img="https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/VPNs.png">
    Connect to your Aptible resources with site-to-site VPNs
  </Card>

  <Card title="Twingate" href="https://www.aptible.com/docs/twingate" img="https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/Twingate.png">
    Connect to your Aptible resources with a VPN alternative
  </Card>

  <Card title="VPC Peering" href="https://www.aptible.com/docs/network-integrations" img="https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/VPC%20Peering.png">
    Connect your external resources to Aptible resources with VPC Peering.
  </Card>

  <Card title="Request new integration" icon="plus" href="https://portal.productboard.com/aptible/2-aptible-roadmap-portal/tabs/5-ideas/submit-idea" />
</CardGroup>


# Sumo Logic Integration

Learn about sending Aptible logs to Sumo Logic

# Overview

[Sumo Logic](https://www.sumologic.com/) is a cloud-based log management and analytics platform. Aptible integrates with Sumo Logic, allowing logs to be sent directly to Sumo Logic for analysis and storage.

Sumo Logic signs BAAs and thus is a reliable log drain option for HIPAA compliance.

# Set up

<Info>  Prerequisites: A [Sumo Logic account](https://service.sumologic.com/ui/) </Info>

You can send your Aptible logs directly to Sumo Logic with a [log drain](/core-concepts/observability/logs/log-drains/overview). A Sumo Logic log drain can be created in the following ways on Aptible:

*   Within the Aptible Dashboard by:
    *   Navigating to an Environment
    *   Selecting the **Log Drains** tab
    *   Selecting **Create Log Drain**
    *   Selecting **Sumo Logic**
    *   Filling the URL by creating a new [Hosted Collector](https://help.sumologic.com/docs/send-data/hosted-collectors/) in Sumologic using an HTTP source
*   Using the [`aptible log_drain:create:sumologic`](/reference/aptible-cli/cli-commands/cli-log-drain-create-sumologic) command


# Twingate Integration

Learn how to integrate Twingate with your Aptible account

# Overview

[Twingate](https://www.twingate.com/) is a VPN-alterative solution. Integrate Twingate with your Aptible account to provide Aptible users with secure and controlled access to Aptible resources -- without needing a VPN.

# Set up

[Learn more about integrating with Twingate here.](https://www.twingate.com/docs/aptible/)


# Database Credentials



# Overview

When you provision a [Database](/core-concepts/managed-databases/overview) on Aptible, you'll be provided with a set of Database Credentials.

<Warning> The password in Database Credentials should be protected for security. </Warning>

Database Credentials are presented as connection URLs. Many libraries can use those directly, but you can always break down the URL into components.  The structure is:

![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/dbcredspath.png)

<Accordion title="Accessing Database Credentials">
  Database Credentials can be accessed from the Aptible Dashboard by selecting the respective Database > selecting "Reveal" under "Credentials"

  ![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/App_UI_Database_Credentials.png)
</Accordion>

# Connecting to a Database using Database Credentials

There are three ways to connect to a Database using Database Credentials:

*   **Direct Access:** This set of credentials is usable with [Network Integrations](/core-concepts/integrations/network-integrations). This is also how [Apps](/core-concepts/apps/overview), other [Databases](/core-concepts/managed-databases/overview), and [Ephemeral SSH Sessions](/core-concepts/apps/connecting-to-apps/ssh-sessions) within the [Stack](/core-concepts/architecture/stacks) can contact the Database. Direct Access can be achieved by running the `aptible db:url` command and accessing the Database Credentials from the Aptible Dashboard.
*   **Database Endpoint:** [Database Endpoints](/core-concepts/managed-databases/connecting-databases/database-endpoints) allow users to expose Aptible Databases on the public internet. When another Database Endpoint is created, a separate set of Database Credentials is provided. Database Endpoints are useful if, for example, a third party needs to be granted access to the Aptible Database. This set of Database Credentials can be found in the Dashboard.
*   **Database Tunnels:** The `aptible db:tunnel` CLI command allows users to create a [Database Tunnel](/core-concepts/managed-databases/connecting-databases/database-tunnels), which provides a convenient, ad-hoc method for users to connect to Aptible Databases from a local workstation. Database Credentials are exposed in the terminal when you successfully tunnel and are only valid while the `db:tunnel` is up. Database Tunnels persist until the connection is closed or for a maximum of 24 hours.

<Tip> The Database Credentials provides credentials for the `aptible` user, but you can also create your own users for database types that support multiple users such as PostgreSQL and MySQL. Refer to the database's own documentation for detailed instructions. If setting up a restricted user, review our [Setting Up Restriced User documentation](https://www.aptible.com/docs/core-concepts/managed-databases/connecting-databases/database-credentials#setting-up-a-restricted-user) for extra considerations.</Tip>

Note that certain [Supported Databases](/core-concepts/managed-databases/supported-databases/overview) provide multiple credentials. Refer to the respective Database documentation for more information.

# Rotating Database Credentials

The only way to rotate Database Credentials without any downtime is to create separate Database users and update Apps to use the newly created user's credentials. Additionally, these separate users limit the impact of security vulnerabilities because applications are not granted more permissions than they need.

While using the built-in `aptible` user may be convenient for Databases that support it (MySQL, PostgreSQL, MongoDB, Elasticsearch 7). Aptible recommends creating a separate user that is granted only the minimum permissions required by the application.

The `aptible` user credentials can only be rotated by contacting [Aptible Support](https://contact.aptible.com). Please note that rotating the `aptible` user's credentials will involve an interruption to the app's availability.

# Setting Up a Restricted User

Aptible role management for the Environment is limited to what the Aptible user can do through the CLI or Dashboard; Database user management is separate.

You can create other database users on the Database with CREATE USER . However, this can lead to exposing the Database so that it can be accessed by this individual without giving them access to the aptible database user’s credentials. Traditionally, you use aptible db:tunnel to access the Database locally but this command prints the tunnel URL with the aptible user credentials. This can lead to two main scenarios:

### If you don’t mind giving this individual access to the aptible credentials

Then you can give them Manage access to the Database’s Environment so they can tunnel into the database, and use the read-only user and password to log in via the tunnel. This is relatively easy to implement and can help prevent accidental writes but doesn’t ensure that this individual doesn’t login as aptible . The user would also have to remember not to copy/paste the aptible user credentials printed every time they tunnel.

### If this individual cannot have access to the aptible credentials

Then this user cannot have Manage access to the Database which removes db:tunnel as an option.

*   If the user only needs CLI access, you can create an App with a tool like psql installed on a different Environment on the same Stack. The user can aptible ssh into the App and use psql to access the Database using the read-only credentials. The Aptible user would require Manage access to this second Environment, but would not need any access to the Database’s Environment for this to work.

*   If the user needs access from their private system, then you’ll have to create a Database Endpoint to expose the Database over the internet. We strongly recommend using [IP Filtering](https://www.aptible.com/docs/core-concepts/apps/connecting-to-apps/app-endpoints/ip-filtering#ip-filtering) to restrict access to the IP addresses or address ranges that they’ll be accessing the Database from so that the Database isn’t exposed to the entire internet for anyone to attempt to connect to.


# Database Endpoints



![Image](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/5eac51b-database-endpoints-basic.png)

Database Endpoints let you expose a [Database](/core-concepts/managed-databases/overview) to the public internet. <Info> The underlying AWS hardware that backs Database Endpoints has an idle connection timeout of 60 minutes. If clients need the connection to remain open longer they can work around this by periodically sending data over the connection (i.e., a "heartbeat") in order to keep it active.</Info>

<Accordion title="Creating a Database Endpoint">
  A Database Endpoint can be created in the following ways:

  1.  Within the Aptible Dashboard by navigating to the respective Environment >selecting the respective Database > selecting the "Endpoints" tab > selecting "Create Endpoint"
  2.  Using the [`aptible endpoints:database:create`](/reference/aptible-cli/cli-commands/cli-endpoints-database-create) command
  3.  Using the [Aptible Terraform Provider](/reference/terraform)
</Accordion>

# IP Filtering

![Image](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/964e12a-database-endpoints-ip-filtering.png)

<Warning> To keep your data safe, it's high recommended to enable IP filtering on Database Endpoints. If you do not enable filtering, your Database will be left open to the entire public internet, and it may be subject to potentially malicious traffic. </Warning>

Like [App Endpoints](/core-concepts/apps/connecting-to-apps/app-endpoints/overview), Database Endpoints support [IP Filtering](/core-concepts/apps/connecting-to-apps/app-endpoints/ip-filtering) to restrict connections to your Database to a set of pre-approved IP addresses.

<Accordion title="Configuring IP Filtering">
  IP Filtering can be configured in the following ways:

  *   Via the Aptible Dashboard when creating an Endpoint
  *   By navigating to the Aptible Dashboard > selecting the respective Database > selecting the "Endpoints" tab > selecting "Edit"
</Accordion>

# Certificate Validation

<Warning> Not all Database clients will validate a Database server certificate by default. </Warning>

To ensure that you connect to the Database you intend to, you should ensure that your client performs full verification of the server certificate. Doing so will prevent Man-in-the-middle attacks of various types, such as address hijacking or DNS poisoning. You should consult the documentation for your client library to understand how to ensure it is properly configured to validate the certificate chain and the hostname.

For MySQL and PostgreSQL, you will need to retrieve a CA certificate using the [`aptible environment:ca_cert`](/reference/aptible-cli/cli-commands/cli-environment-ca-cert) command in order to perform validation. After the Endpoint has been provisioned, the Database will also need to be restarted in order to update the Database's certificate to include the Endpoint's hostname. See the [Database Encryption in Transit](/core-concepts/managed-databases/managing-databases/database-encryption/database-encryption-in-transit) page for more details.

If the remote service is not able to validate your database certificate, please [contact support](https://aptible.zendesk.com/hc/en-us/requests/new) for assistance.

# Least Privileged Access

<Warning> The provided [Database Credential](/core-concepts/managed-databases/connecting-databases/database-credentials) has the full set of privileges needed to administer your Database, and we recommend that you *do not* provide this user/password to any external services. </Warning>

Create Database Users with the least privileges needed to use for integrations. For example, granting only "read" privileges to specific tables, such as those that do not contain your user's hashed passwords, is recommended when integrating a business intelligence reporting tool.

Please refer to database-specific documentation for guidance on user and permission management.
<Tip> Create a unique user for each external integration. Not only will this making auditing access easier, it will also allow you to rotate just the affected user's password in the unfortunate event of credentials being leaked by a third party</Tip>


# Database Tunnels



# Overview

Database Tunnels are ephemeral connections between your local workstation and a [Database](/core-concepts/managed-databases/overview) running on Aptible. Database Tunnels are the most convenient way to get ad-hoc access to your Database. However, tunnels time out after 24 hours, so they're not ideal for long-term access or integrations. For those, you'll be better suited by [Database Endpoints](/core-concepts/managed-databases/connecting-databases/database-endpoints).

<Warning> A Database Tunnel listens on `localhost`, and instructs you to connect via the host name `localhost.aptible.in`. Be aware that some software may make assumptions about this database based on the host name or IP, with possible consequences such as bypassing safeguards for running against a remote (production) database.</Warning>

# Getting Started

<Accordion title="Creating Database Tunnels">
  Database Tunnels can be created using the [`aptible db:tunnel`](/reference/aptible-cli/cli-commands/cli-db-tunnel) command.
</Accordion>


# Connecting to Databases

Learn about the various ways to connect to your Database on Aptible

# Read more

<CardGroup cols={4}>
  <Card title="Database Credentials" icon="book" iconType="duotone" href="https://www.aptible.com/docs/database-credentials">
    Connect your Database to other resources deployed on the same Stack
  </Card>

  <Card title="Database Tunnels" icon="book" iconType="duotone" href="https://www.aptible.com/docs/database-tunnels">
    Connect to your Database for ad-hoc access
  </Card>

  <Card title="Database Endpoints" icon="book" iconType="duotone" href="https://www.aptible.com/docs/database-endpoints">
    Connect your Database to the internet
  </Card>

  <Card title="Network Integrations" icon="book" iconType="duotone" href="">
    Connect your Database using network integrations such as VPC Peering and site-to-site VPN tunnels
  </Card>
</CardGroup>


# Database Backups

Learn more about Aptible's database backup solution with automatic backups, default encryption, with flexible customization

# Overview

Database Backups are essential because they provide a way to recover important data in case of disasters or data loss. They also provide a historical record of changes to data, which can be required for auditing and compliance purposes.

Aptible provides Automatic Backups of your Databases every 24 hours, along with a range of other backup options. All Backups are compressed and encrypted for maximum security and efficiency. Additionally, all Backups are automatically stored across multiple Availability Zones for high-availability.

# Automatic Backups

By default, Aptible provides automatic backups of all Databases. The retention period for Automated Backups is determined by the Backup Retention Policy for the Environment in which the Database resides. The configuration options are as follows:

*   `DAILY BACKUPS RETAINED` - Number of daily backups retained

*   `MONTHLY BACKUPS RETAINED` - Number of monthly backups retained (the last backup of each month)

*   `YEARLY BACKUPS RETAINED` - Number of yearly backups retained (the last backup of each year)

*   `COPY BACKUPS TO ANOTHER REGION: TRUE/FALSE` - When enabled, Aptible will copy all the backups within that Environment to another region. See: Cross-region Copy Backups

*   `KEEP FINAL BACKUP: TRUE/FALSE` - When enabled, Aptible will retain the last backup of a Database after your deprovision it. See: Final Backups

<Tip>
  **Recommended Backup Retention Policies**

  **Production environments:** Daily: 14-30, Monthly: 12, Yearly: 5, Copy backups to another region: TRUE (depending on DR needs), Keep final backups: TRUE

  **Non-production environments:** Daily: 1-14, Monthly: 0, Yearly: 0, Copy backups to another region: FALSE, Keep final backups: FALSE
</Tip>

# Manual Backups

Manual Backups can be created anytime and are retained indefinitely (even after the Database is deprovisioned).

# Cross-region Copy Backups

When `COPY BACKUPS TO ANOTHER REGION` is enabled on an Environment, Aptible will copy all the backups within that Environment to another region. For example, if your Stack is in the US East Coast, then Backups will be copied to the US West Coast.

<Tip> Cross-region Copy Backups are useful for creating redundancy for disaster recovery purposes. To further improve your recovery time objective (RTO), it’s recommended to have a secondary Stack in the region of your Cross-region Copy Backups to enable quick restoration in the event of a regional outage. </Tip>

The exact mapping of Cross-region Copy Backups is as follows:

| Originating region | Destination region(s)          |
| ------------------ | ------------------------------ |
| us-east-1          | us-west-1, us-west-2           |
| us-east-2          | us-west-1, us-west-2           |
| us-west-1          | us-east-1                      |
| us-west-2          | us-east-1                      |
| sa-east-1          | us-east-2                      |
| ca-central-1       | us-east-2                      |
| eu-west-1          | eu-central-1                   |
| eu-west-2          | eu-central-1                   |
| eu-west-3          | eu-central-1                   |
| eu-central-1       | eu-west-1                      |
| ap-northeast-1     | ap-northeast-2                 |
| ap-northeast-2     | ap-northeast-1                 |
| ap-southeast-1     | ap-northeast-2, ap-southeast-2 |
| ap-southeast-2     | ap-southeast-1                 |
| ap-south-1         | ap-southeast-2                 |

<Note> Aptible guarantees that data processing and storage occur only within the US for US Stacks and EU for EU Stacks.</Note>

# Final Backups

When `KEEP FINAL BACKUP` is enabled on an Environment, Aptible will retain the last backup of a Database after your deprovision it. Final Backups are kept indefinitely as long as the Environment has this setting enabled.

<Tip>We highly recommend enabling this setting for production Environments. </Tip>

# Managing Backup Retention Policy

The retention period for Automated Backups is determined by the Backup Retention Policy for the Environment in which the Database resides.

The default Backup Retention Policy for an Environment is 30 Automatic Daily Backups, 12 Monthly Backups, 6 Yearly Backups, Keep Final Backup: Enabled, Cross-region Copy Backup: Disabled.

Backup Retention Policies can be modified using one of these methods:

*   Within the Aptible Dashboard:

    *   Select the desired Environment

    *   Select the **Backups** tab

*   Using the [`aptible backup_retention_policy:set` CLI command](/reference/aptible-cli/cli-commands/cli-backup-retention-policy-set).

*   Using the Aptible [Terraform Provider](https://registry.terraform.io/providers/aptible/aptible/latest/docs)

<Warning> Reducing the number of retained backups, including disabling copies or final backups, will automatically delete existing, automated backups that do not match the new policy. This may result in the permanent loss of backup data and could violate your organization's internal compliance controls. </Warning>

<Tip> **Cost Optimization Tip:** [See this related blog for more recommendations for balancing continuity and costs](https://www.aptible.com/blog/backup-strategies-on-aptible-balancing-continuity-and-costs) </Tip>

### Excluding a Database from new Automatic Backups

<Frame>
  ![Disabling Backups](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/DisablingDatabaseBackups.gif)
</Frame>

A Database can be excluded from the backup retention policy preventing new Automatic Backups from being taken. This can only be done within the Aptible Dashboard from the Database Settings.

Once this is selected, there will be no new automatic backups taken of this database, but please note: this does not automatically delete previously taken backups. Purging the previously taken backups can be achieved in the following ways:

*   Using the [`aptible backup:list DB_HANDLE`](/reference/aptible-cli/cli-commands/cli-backup-list) to provide input into the [`aptible backup:purge BACKUP_ID`](/reference/aptible-cli/cli-commands/cli-backup-purge) command

*   Setting the output format to JSON, like so:

```jsx
APTIBLE_OUTPUT_FORMAT=json aptible backup:list DB_HANDLE 
```

# Purging Backups

Automatic Backups are automatically and permanently deleted when the associated database is deprovisioned. Final Backups and Cross-region Copy Backups that do not match the Backup Retention Policy are also automatically and permanently deleted. This purging process can take up to 1 hour.

All Backups can be manually and individually deleted.

# Restoring from a Backup

Restoring a Backup creates a new Database from the backed-up data. It does not replace or modify the Database the Backup was initially created from. All new Databases are created with General Purpose Container Profile, which is the [default Container Profile.](/core-concepts/scaling/container-profiles#default-container-profile)

<Info> Deep dive: Databases Backups are stored as volume EBS Snapshots. As such, Databases restored from a Backup will initially have degraded disk performance, as described in the ["Restoring from an Amazon EBS snapshot" documentation](https://docs.aws.amazon.com/prescriptive-guidance/latest/backup-recovery/restore.html).
If you are using a restored Database for performance testing, the performance test should be run twice: once to ensure all of the required data has been synced to disk and the second time to get an accurate result.
Disk initialization time can be minimized by restoring the backup in the same region the Database is being restored to. Generally, this means the original Backup should be restored, not a copy.</Info>

<Tip>If you have special retention needs (such as for a litigation hold), please contact [Aptible Support.](/how-to-guides/troubleshooting/aptible-support)</Tip>

# Encryption

Aptible provides built-in, automatic [Database Encryption](/core-concepts/managed-databases/managing-databases/database-encryption/overview). The encryption key and algorithm used for Database Encryption are automatically applied to all Backups of a given Database.

# FAQ

<AccordionGroup>
  <Accordion title="How do I modify an Environments Backup Retention Policy?">
    Backup Retention Policies can be modified using one of these methods:

    *   Within the Aptible Dashboard:

        *   Select the desired Environment

        *   Select the **Backups** tab

    *   Using the [`aptible backup_retention_policy:set` CLI command](/reference/aptible-cli/cli-commands/cli-backup-retention-policy-set).

    *   Using the Aptible [Terraform Provider](https://registry.terraform.io/providers/aptible/aptible/latest/docs)

    ![Reviewing Backup Retention Policy in Aptible Dashboard](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/backups.png "Backup Management tab in the Aptible Dashboard")
  </Accordion>

  <Accordion title="How do I view/manage Automatic Backups?">
    Automatic Backups can be viewed in two ways:

    *   Using the [`aptible backup:list`](/reference/aptible-cli/cli-commands/cli-backup-list) command

    *   Within the Aptible Dashboard, by navigating to the Database > Backup tab
  </Accordion>

  <Accordion title="How do I view/manage Final Backups?">
    Final Backups can be viewed in two ways:

    *   Using the `aptible backup:orphaned` command

    *   Within the Aptible Dashboard by navigating to the respective Environment > “Backup Management” tab > “Retained Backups of Deleted Databases”
  </Accordion>

  <Accordion title="How do I create Manual Backups?">
    Users can create Manual Backups in two ways:

    *   Using the [`aptible db:backup`](/reference/aptible-cli/cli-commands/cli-db-backup)) command

    *   Within the Aptible Dashboard by navigating to the Database > “Backup Management” tab > “Create Backup”
  </Accordion>

  <Accordion title="How do I delete a Backup?">
    All Backups can be manually and individually deleted in the following ways:

    *   Using the [`aptible backup:purge`](/reference/aptible-cli/cli-commands/cli-backup-purge) command

    *   For Active Databases - Within the Aptible Dashboard by:

        *   Navigating to the respective Environment in which your Database lives in

        *   Selecting the respective Database

        *   Selecting the **Backups** tab

        *   Selecting **Permanently remove this backup** for the respective Backup

    *   For deprovisioned Databases - Within the Aptible Dashboard by:

        *   Navigating to the respective Environment in which your Database Backup lives in

        *   Selecting the **Backup Management** tab

        *   Selecting Delete for the respective Backup

    ![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/App_UI_Purging_Backups.png "Purging a Backup from the Aptible Dashboard")
  </Accordion>

  <Accordion title="How can I exclude a Database from Automatic Backups?">
    *   Navigating to the respective Database

    *   Selecting the **Settings** tab

    *   Select **Disabled: No new backups allowed** within **Database Backups**
  </Accordion>

  <Accordion title="How do I restore a Backup?">
    You can restore from a Backup in the following ways:

    *   Using the `aptible backup:restore` command

    *   For Active Databases - Within the Aptible Dashboard by:

        *   Navigating to the respective Environment in which your Database lives in

        *   Selecting the respective Database

        *   Selecting the **Backups** tab

        *   Selecting **Restore to a New Database** from the respective Backup

    *   For deprovisioned Databases - Within the Aptible Dashboard by:

        *   Navigating to the respective Environment in which your Database Backup lives in

        *   Selecting the **Backup Management** tab

        *   Selecting **Restore to a New Database** for the respective Backup

    ![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/App_UI_Restoring_Backups.png "Restoring a Database from the Aptible Dashboard")
  </Accordion>
</AccordionGroup>


# Application-Level Encryption



Aptible's built-in [Database Encryption](/core-concepts/managed-databases/managing-databases/database-encryption/overview) is sufficient to comply with most data regulations, including HIPAA Technical Safeguards \[[45 C.F.R. § 164.312](https://www.aptible.com/hipaa/regulations/164-312-technical-safeguards/) (e)(2)(ii)], but we strongly recommend also implementing application-level encryption in your App to further protect sensitive data.

The idea behind application-level encryption is simple: rather than store plaintext in your database, store encrypted data, then decrypt it on the fly in your app when fetching it from the database.

Using application-level encryption ensures that should an attacker get access to your database (e.g. through a SQL injection vulnerability in your app), they won't be able to extract data you encrypted unless they **also** compromise the keys you use to encrypt data at the application level.

The main downside of application-level encryption is that you cannot easily implement indices to search for this data. This is usually an acceptable tradeoff as long as you don't attempt to use application-level encryption on **everything**. There are, however, techniques that allow you to potentially work around this problem, such as [Homomorphic Encryption](https://en.wikipedia.org/wiki/Homomorphic_encryption).

> 📘 Don't roll your own encryption. There are a number of libraries for most application frameworks that can be used to implement application-level encryption.

# Key Rotation

Application-level encryption provides two main benefits over Aptible's built-in [Database Encryption](/core-concepts/managed-databases/managing-databases/database-encryption/overview) and [Custom Database Encryption](/core-concepts/managed-databases/managing-databases/database-encryption/custom-database-encryption) regarding rotating encryption keys.

## Key rotations are faster

Odds are, not all data is sensitive in your database.

If you are using application-level encryption, you only need to re-encrypt sensitive data when rotating the key, as opposed to having to re-encrypt **everything in your Database**.

This can be orders of magnitude faster than re-encrypting the disk. Indeed, consider that your Database stores a lot of things on disk which isn't strictly speaking data, such as indices, etc., which will inevitably be re-encrypted if you don't use application-level encryption.

## Zero-downtime key rotations are possible

Use the following approach to perform zero-downtime key rotations:

*   Update your app so that it can **read** data encrypted with 2 different keys (the *old key*, and the *new key*). At this time, all your data remains encrypted with the *old key*.
*   Update your app so that all new **writes** are encrypted using the *new key*.
*   In the background, re-encrypt all your data with the *new key*. Once complete, all your data is now encrypted with the *new key*.
*   Remove the *old key* from your app. At this stage, your app can no longer need any data encrypted with the *old key*, but that's OK because you just re-encrypted everything.
*   Make sure to retain a copy of the *old key* so you can access data in backups that were performed before the key rotation


# Custom Database Encryption



This section covers encryption using AWS Key Management Service. For more information about Aptible's default managed encryption, see [Database Encryption at rest](/core-concepts/managed-databases/managing-databases/database-encryption/overview).

Aptible supports providing your own encryption key for [Database](/core-concepts/managed-databases/overview) volumes using [AWS Key Management Service (KMS) customer-managed customer master keys (CMK)](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#customer-cmk). This layer of encryption is applied in addition to Aptible’s existing Database Encryption. Encryption using AWS KMS CMKs is ideal for those who want to retain absolute control over when their data is destroyed or for those who need to rotate their database encryption keys regularly.

> ❗️ CMKs are completely managed outside of Aptible. As a result, if there is an issue accessing a CMK, Aptible will be unable to decrypt the data. **If a CMK is deleted, Aptible will be unable to recover the data.**

# Creating a New CMK

CMKs used by Aptible must be symmetric and must not use imported key material. The CMK must be created in the same region as the Database that will be using the key. Aptible can support all other CMK options.

After creating a CMK, the key must be shared with Aptible's AWS account. When creating the CMK in the AWS console, you can specify that you would like to share the CMK with the AWS account ID `916150859591`. Alternatively, you can include the following statements in the policy for the key:

```json
{
    "Sid": "Allow use of the key",
    "Effect": "Allow",
    "Principal": {
        "AWS": "arn:aws:iam::916150859591:root"
    },
    "Action": [
        "kms:Encrypt",
        "kms:Decrypt",
        "kms:ReEncrypt*",
        "kms:GenerateDataKey*",
        "kms:DescribeKey"
    ],
    "Resource": "*"
},
{
    "Sid": "Allow attachment of persistent resources",
    "Effect": "Allow",
    "Principal": {
        "AWS": "arn:aws:iam::916150859591:root"
    },
    "Action": [
        "kms:CreateGrant",
        "kms:ListGrants",
        "kms:RevokeGrant"
    ],
    "Resource": "*",
    "Condition": {
        "Bool": {
            "kms:GrantIsForAWSResource": "true"
        }
    }
}
```

# Creating a new Database encrypted with a CMK

New databases encrypted with a CMK can be created via the Aptible CLI using the [`aptible db:create`](/reference/aptible-cli/cli-commands/cli-db-create) command. The CMK should be passed in using the `--key-arn` flag, for example:

```shell
aptible db:create $HANDLE --type $TYPE --key-arn arn:aws:kms:us-east-1:111111111111:key/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee
```

# Key Rotation

Custom encryption keys can be rotated through AWS. However, this method does not re-encrypt the existing data as described in the [CMK key rotation](https://docs.aws.amazon.com/kms/latest/developerguide/rotate-keys.html) documentation. In order to do this, the key must be manually rotated by updating the CMK in Aptible.

# Updating CMKs

CMKs can be added or rotated by creating a backup and restoring from the backup via the Aptible CLI command [`aptible backup:restore`](/reference/aptible-cli/cli-commands/cli-backup-restore)

```shell
aptible backup:restore $BACKUP_ID --key-arn arn:aws:kms:us-east-1:111111111111:key/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee
```

Rotating keys this way will inevitably cause downtime while the backup is restored. Therefore, if you need to conform to a strict key rotation schedule that requires all data to be re-encrypted, you may want to consider implementing [Application-Level Encryption](/core-concepts/managed-databases/managing-databases/database-encryption/application-level-encryption) to reduce or possibly even mitigate downtime when rotating.

# Invalid CMKs

There are a number of reasons that a CMK might be invalid, including being created in the wrong region and failure to share the CMK with Aptible's AWS account.

When the CMK is unavailable, you will hit one of the following errors:

```
ERROR -- : SUMMARY: Execution failed because of:
ERROR -- : - FAILED: Create 10 GB database volume
WARN -- :
ERROR -- : There was an error creating the volume. If you are using a custom encryption key, this may be because you have not shared the key with Aptible.
```

```
ERROR -- : SUMMARY: Execution failed because of:
ERROR -- : - FAILED: Attach volume
```

To resolve this, you will need to ensure that the key has been correctly created and shared with Aptible.


# Database Encryption at Rest



This section covers Aptible's default managed encryption. For more information about encryption using AWS Key Management Service, see [Custom Database Encryption](/core-concepts/managed-databases/managing-databases/database-encryption/custom-database-encryption).

Aptible automatically and transparently encrypts data at rest.

[Database](/core-concepts/managed-databases/overview) encryption uses eCryptfs, and the algorithm used is either AES-192 or AES-256.

> 📘 You can determine whether your Database uses AES-192 or AES-256 for disk encryption through the Dashboard. New Databases will automatically use AES-256.

# Key Rotation

Aptible encrypts your data at the disk level. This means that to rotate the key used to encrypt your data, all data needs to be rewritten on disk using a new key. If you're not using [Custom Database Encryption](/core-concepts/managed-databases/managing-databases/database-encryption/custom-database-encryption), you can do so by dumping the data from your database, then writing it to a new database, which will use a different key.

However, rotating keys this way will inevitably cause downtime while you dump and restore your data. This may take a long time if you have a lot of data.

Therefore, if you must conform to a strict key rotation schedule, we recommend implementing [Application-Level Encryption](/core-concepts/managed-databases/managing-databases/database-encryption/application-level-encryption).


# Database Encryption in Transit



Aptible [Databases](/core-concepts/managed-databases/overview) are configured to allow connecting with SSL. Where possible, they are also configured to require SSL to ensure data is encrypted in transit. See the documentation for your [supported Database type](/core-concepts/managed-databases/supported-databases/overview) for details on how it's configured.

# Trusted Certificates

Most supported database types use our wildcard `*.aptible.in` certificate for SSL / TLS termination and most clients should be able to use the local trust store to verify the validity of this certificate without issue. Depending on your client, you may still need to enable an option for force verification. Please see your client documentation for further details.

# Aptible CA Signed Certificates

While most Database types leverage the `*.aptible.in` certificate as above, other types (MySQL and PostgreSQL) have ways of revealing the private key as the provided default `aptible` user's permission set, so they cannot use this certificate without creating a security risk. In these cases, Deploy uses a Certificate Authority unique to each environment in order to a generate a server certificate for each of your databases.

The documentation for your [supported Database type](/core-concepts/managed-databases/supported-databases/overview) will specify if it uses such a certificate: currently this applies to MySQL and PostgreSQL databases only.

In order to perform certificate verification for these databases, you will need to provide the CA certificate to your client. To retrieve the CA certificate required to verify the server certificate for your database, use the [`aptible environment:ca_cert`](/reference/aptible-cli/cli-commands/cli-environment-ca-cert) command to retrieve the CA certificate for you environment(s).

# Self Signed Certificates

MySQL and PostgreSQL Databases that have been running since prior to January 15th, 2021 do not have a certificate generated by the Aptible CA as outlined above, but instead have a self-signed certificate installed. If this is the case for your database, all you need to do to move to an Aptible CA signed certificate is restart your database.

# Other Certificate Requirements

Contact [Aptible Support](/how-to-guides/troubleshooting/aptible-support) if you have unique database server certificate constraints - we can accommodate installing a certificate that you provide if required.


# Database Encryption



Aptible has built-in [Database Encryption](/core-concepts/managed-databases/managing-databases/database-encryption/overview) that applies to all Aptible [Databases](/core-concepts/managed-databases/overview) as well as the option to configure additional [Custom Database Encryption](/core-concepts/managed-databases/managing-databases/database-encryption/custom-database-encryption). [Application-Level Encryption](/core-concepts/managed-databases/managing-databases/database-encryption/application-level-encryption) may also be used, but this form of encryption is built into and used by your applications rather than being configured through Aptible.

# Backup Encryption

[Database Backups](/core-concepts/managed-databases/managing-databases/database-backups) are taken as volume snapshots, so all forms of encryption used by the Database are applied automatically in backups.

***

**Keep reading:**

*   [Database Encryption at Rest](/core-concepts/managed-databases/managing-databases/database-encryption/database-encryption)
*   [Custom Database Encryption](/core-concepts/managed-databases/managing-databases/database-encryption/custom-database-encryption)
*   [Application-Level Encryption](/core-concepts/managed-databases/managing-databases/database-encryption/application-level-encryption)
*   [Database Encryption in Transit](/core-concepts/managed-databases/managing-databases/database-encryption/database-encryption-in-transit)


# Database Performance Tuning



# Database IOPS Performance

Database IOPS (Input/Output Operations Per Second) refer to the number of read/write [Operations](/core-concepts/architecture/operations) that a Database can perform within a second.

**Baseline IOPS:**

*   **gp3 Volume:** Aptible provisions new Databases with AWS gp3 volumes, which provide a minimum baseline IOPS performance of 3,000 IOPS no matter how small your volume is. The maximum IOPS is 16,000, but you must meet a minimum ratio of 1 GB disk size per 500 IOPS. For example, to reach 16,000 IOPS, you must have at least a 32 GB or larger disk.
*   **gp2 Volume:** Older Databases may be using gp2 volumes, which provide a baseline IOPS performance of 3 IOPS / GB of disk, with a minimum allocation of 100 IOPS. In addition to the baseline performance, gp2 volumes also offer burst IOPS capacity up to 3,000 IOPS, which lets you exceed the baseline performance for a period of time. You should not rely on the volume's burst capacity during normal activity. Doing so will likely cause your performance to drop once you exhaust the volume's burst capacity, which will likely cause your app to go down.

Disk IO performance can be determined by viewing [Dashboard Metrics](/core-concepts/observability/metrics/overview#dashboard-metrics) or monitoring [Metric Drains](/core-concepts/observability/metrics/metrics-drains/overview) (`disk_read_iops` and `disk_write_iops` metrics).

IOPS can also be scaled on-demand to meet performance needs. For more information on scaling IOPS, refer to [Database Scaling.](/core-concepts/scaling/database-scaling#iops-scaling)

# Database Throughput Performance

Database throughput performance refers to the amount of data that a database system can process in a given time period.

**Baseline Throughput:**

*   **gp3 Volume:** gp3 volumes have a default throughput performance of 125MiB/s, and can be scaled up to 1,000MiB/s by contacting [Aptible Support](/how-to-guides/troubleshooting/aptible-support).
*   **gp2 Volume:** gp2 volumes have a maximum throughput performance of between 128MiB/s and 250MiB/s, depending on volume size. Volumes smaller or equal to 170 GB in size are allocated 128MiB/s of throughput. The throughput scales up until you reach a volume size of 334 GB. At 334 GB in size or larger, you have the full 250MiB/s performance possible with a GP2 volume. If you need more throughput, you may upgrade to a GP3 volume at any time by using the [`aptible db:modify`](/reference/aptible-cli/cli-commands/cli-db-modify) command.

Database Throughput can be monitored within [Metric Drains](/core-concepts/observability/metrics/metrics-drains/overview) (`disk_read_kbps` and `disk_write_kbps` metrics).

Database Throughput can be scaled by the Aptible Support Team only. For more information on scaling Throughput, refer to [Database Scaling.](/core-concepts/scaling/database-scaling#throughput-performance)


# Database Upgrades



There are three supported methods for upgrading [Databases](/core-concepts/managed-databases/overview):

*   Dump and Restore
*   Logical Replication
*   Upgrading In-Place

<Tip> To review the available Database versions, use the [`aptible db:versions`](/reference/aptible-cli/cli-commands/cli-db-versions) command.</Tip>

# Dump and Restore

Dump and Restore works by dumping the data from the existing Database and restoring it to a target Database, running the desired version. This method tends to require the most downtime to complete.

**Supported Databases:**

*   All Database types support this upgrade method.

<Tip> This upgrade method is relatively simple and reliable and often allows upgrades across multiple major versions at once.</Tip>

## Process

1.  Create a new target Database running the desired version.
2.  Scale [Services](/core-concepts/apps/deploying-apps/services) that use the existing Database down to zero containers. While this step is not strictly required, it ensures that the containers don't write to the Database during the upgrade.
3.  Dump the data from the existing Database to the local filesystem.
4.  Restore the data to the target Database from the local filesystem.
5.  Update all of the Services that use the original Database to use the target Database.
6.  Scale Services back up to their original container counts.

**Guides & Examples:**

*   [How to dump and restore PostgreSQL](/how-to-guides/database-guides/dump-restore-postgresql)

# Logical Replication

Logical replication works by creating an upgrade replica of the existing Database and updating all Services that currently use the existing Database to use the replica.

**Supported Databases:** [PostgreSQL](/core-concepts/managed-databases/supported-databases/postgresql) Databases are currently the only ones that support this upgrade method.

<Tip> Upgrading using logical replication is a little more complex than the dump and restore method but only requires a fix amount of downtime regardless of the Database's size. This makes it is a good option for large, production [Databases](/core-concepts/managed-databases/overview) that cannot tolerate much downtime. </Tip>

**Guides & Examples:**

*   [How to upgrade PostgreSQL with logical replication](/how-to-guides/database-guides/upgrade-postgresql)

# Upgrading In-Place

Upgrading Databases in-place works similarly to a "traditional" upgrade where, rather than replacing an existing Database instance with a new one, the existing instance is upgraded itself. This means that Services don't have to be updated to use the new instance, but it also makes it difficult or, in some cases, impossible to roll back if you find that a Service isn't compatible with the new version after upgrading.

Additionally, in-place upgrades generally don't work across multiple major versions, so the Database must be upgraded multiple times in situations like this.

Downtime for in-place upgrades varies.

In-place upgrades must be performed by [Aptible Support.](/how-to-guides/troubleshooting/aptible-support)

**Supported Databases:**

*   [MongoDB](/core-concepts/managed-databases/supported-databases/mongodb) and [Redis](/core-concepts/managed-databases/supported-databases/redis) have good support for in-place upgrades and, as such, can be upgraded fairly quickly and easily using this method.
*   [ElasticSearch](/core-concepts/managed-databases/supported-databases/elasticsearch) can generally be upgraded in-place but there are some exceptions:
    *   ES 6.X and below can be upgraded up to ES 6.8
    *   ES 7.X can be upgraded up to ES 7.10
        *   ES 7 introduced breaking changes to the way the Database is hosted on Aptible so ES 6.X and below cannot be upgraded to ES 7.X in-place.
*   [PostgreSQL](/core-concepts/managed-databases/supported-databases/postgresql) supports in-place upgrades but the process is much more involved. As such, in-place upgrades for PostgreSQL Databases are reserved for when none of the other upgrade methods are viable.
    *   Aptible will not offer in-place upgrades crossing from pre-15 PostgreSQL versions to PostgreSQL 15+ because of a [dependent change in glibc on the underlying Debian operating system](https://wiki.postgresql.org/wiki/Locale_data_changes). Instead, the following options are available to migrate existing pre-15 PostgreSQL databases to PostgreSQL 15+:
        *   [Dump and restore PostgreSQL](/how-to-guides/database-guides/dump-restore-postgresql)
        *   [Upgrade PostgreSQL with logical replication](/how-to-guides/database-guides/upgrade-postgresql)

**Guides & Examples:**

*   [How to upgrade Redis](/how-to-guides/database-guides/upgrade-redis)
*   [How to upgrade MongoDB](/how-to-guides/database-guides/upgrade-mongodb)


# Managing Databases



# Overview

Aptible makes database management effortless by fully managing and monitoring your Aptible Databases 24/7. From scaling to backups, Aptible automatically ensures that your Databases are secure, optimized, and always available. Aptible handles the heavy lifting and provides additional controls and options, giving you the flexibility to manage aspects of your Databases when need.

# Learn More

<AccordionGroup>
  <Accordion title="Scaling Databases">
    RAM/CPU, Disk, IOPS, and throughput can be scaled on-demand with minimal downtime (typically less than 1 minute) at any time via the Aptible Dashboard, CLI, or Terraform provider.

    Refer to [Database Scaling ](/core-concepts/scaling/database-scaling)for more information.
  </Accordion>

  <Accordion title="Upgrading Databases">
    Aptible supports various methods for upgrading Databases - such as dump and restore, logical replication, and in-place upgrades.

    Refer to [Database Upgrades](/core-concepts/managed-databases/managing-databases/database-upgrade-methods) for more information.
  </Accordion>

  <Accordion title="Backing up Databases">
    Aptible performs automatic daily backups of your databases every 24 hours. The default retention policy optimized for production environments, but this policy is fully customizable at the environment level, allowing you to configure daily, monthly, and yearly backups based on your requirements.

    In addition to automatic backups, you have the option to enable cross-region backups for disaster recovery and retain final backups of deprovisioned databases. Manual backups can be initiated at any time to provide additional flexibility and control over your data.

    Refer to [Database Backups](/core-concepts/managed-databases/managing-databases/database-backups) for more information.
  </Accordion>

  <Accordion title="Replicating Databases">
    Aptible simplifies Database replication (PostgreSQL, MySQL, Redis) and clustering (MongoDB) databases in high-availability setups by automatically deploying the Database Containers across different Availability Zones (AZ).

    Refer to [Database Replication and Clustering](/core-concepts/managed-databases/managing-databases/replication-clustering) for more information.
  </Accordion>

  <Accordion title="Encrypting Databases">
    Aptible has built-in Database Encryption that applies to all Databases as well as the option to configure additional [Custom Database Encryption](/core-concepts/managed-databases/managing-databases/database-encryption/custom-database-encryption). [Application-Level Encryption](/core-concepts/managed-databases/managing-databases/database-encryption/application-level-encryption) may also be used.

    Refer to [Database Encryption](/core-concepts/managed-databases/managing-databases/database-encryption/overview) for more information.
  </Accordion>

  <Accordion title="Restarting Databases">
    Databases can be restarted in the following ways:

    *   Using the [`aptible db:restart`](/reference/aptible-cli/cli-commands/cli-db-restart) command if you are also resizing the Database

    *   Using the [`aptible db:reload`](/reference/aptible-cli/cli-commands/cli-db-reload) command if you are not resizing the Database

        *   Note: this command is faster to execute than aptible db:restart

    *   Within the Aptible Dashboard, by:

        *   Navigating to the database

        *   Selecting the **Settings** tab

        *   Selecting **Restart**
  </Accordion>

  <Accordion title="Renaming Databases">
    A Database can be renamed in the following ways:

    *   Using the [`aptible db:rename`](/reference/aptible-cli/cli-commands/cli-db-rename) command

    *   Using the Aptible [Terraform Provider](https://registry.terraform.io/providers/aptible/aptible/latest/docs)

    For the change to take effect, the Database must be restarted.
  </Accordion>

  <Accordion title="Deprovisioning Databases">
    A Database can be deprovisioned in the following ways:

    *   Using the [`aptible db:deprovision`](/reference/aptible-cli/cli-commands/cli-db-deprovision) command

    *   Using the Aptible [Terraform Provider](https://registry.terraform.io/providers/aptible/aptible/latest/docs)

    When a Database is deprovisioned, its [Database Backups](/core-concepts/managed-databases/managing-databases/database-backups) are automatically deleted per the Environment's [Backup Retention Policy.](/core-concepts/managed-databases/managing-databases/database-backups#backup-retention-policy-for-automated-backups)
  </Accordion>

  <Accordion title="Restoring Databases">
    A deprovisioned Database can be [restored from a Backup](/core-concepts/managed-databases/managing-databases/database-backups#restoring-from-a-backup) as a new Database. The resulting Database will have the same data, username, and password as the original when the Backup was taken. Any [Database Endpoints](/core-concepts/managed-databases/connecting-databases/database-endpoints) or [Replicas](/core-concepts/managed-databases/managing-databases/replication-clustering) will have to be recreated.
  </Accordion>
</AccordionGroup>


# Database Replication and Clustering



<Info> Database Replication and Clustering is only available on [Production and Enterprise](https://www.aptible.com/pricing)[ plans.](https://www.aptible.com/pricing)</Info>

Aptible simplifies Database replication (PostgreSQL, MySQL, Redis) and clustering (MongoDB) databases in high-availability setups by automatically deploying the Database Containers across different Availability Zones (AZ).

# Support by Database Type

Aptible supports replication or clustering for a number of [Databases](/core-concepts/managed-databases/overview):

*   [Redis:](/core-concepts/managed-databases/supported-databases/redis) Aptible supports creating read-only replicas for Redis.
*   [PostgreSQL:](/core-concepts/managed-databases/supported-databases/postgresql) Aptible supports read-only hot standby replicas for PostgreSQL databases. PostgreSQL replicas utilize a [replication slot](https://www.postgresql.org/docs/current/warm-standby.html#STREAMING-REPLICATION-SLOTS) on the primary database which may increase WAL file retention on the primary. We recommend using a [Metric Drain](/core-concepts/observability/metrics/metrics-drains/overview) to monitor disk usage on the primary Database. PostgreSQL Databases support [Logical Replication](/how-to-guides/database-guides/upgrade-postgresql) using the [`aptible db:replicate`](/reference/aptible-cli/cli-commands/cli-db-replicate) CLI command with the `--logical` flag for the purpose of upgrading the Database with minimal downtime.
*   [MySQL:](/core-concepts/managed-databases/supported-databases/mysql) Aptible supports creating replicas for MySQL Databases. While these replicas do not prevent writes from occurring, Aptible does not support writing to MySQL replicas. Any data written directly to a MySQL replica (and not the primary) may be lost.
*   [MongoDB:](/core-concepts/managed-databases/supported-databases/mongodb) Aptible supports creating MongoDB replica sets. To ensure that your replica is fault-tolerant, you should follow the [MongoDB recommendations for a number of instances in a replica set](https://docs.mongodb.com/manual/core/replica-set-architectures/#consider-fault-tolerance) when creating a replica set. We also recommend that you review the [readConcern](https://docs.mongodb.com/manual/reference/read-concern/), [writeConcern](https://docs.mongodb.com/manual/reference/write-concern/) and [connection url](https://docs.mongodb.com/manual/reference/connection-string/#replica-set-option) documentation to ensure that you are taking advantage of useful features offered by running a MongoDB replica set.

# Creating Replicas

Replicas can be created for supported databases using the [`aptible db:replicate`](/reference/aptible-cli/cli-commands/cli-db-replicate) command. All new Replicas are created with General Purpose Container Profile, which is the [default Container Profile.](/core-concepts/scaling/container-profiles#default-container-profile)

<Warning> Creating a replica on Aptible has a 6 hour timeout. While most Databases can be replicated in under 6 hours, some very large databases may take longer than 6 hours to create a replica. If your attempt to create a replica fails after hitting the 6 hour timeout, reach out to [Aptible Support](/how-to-guides/troubleshooting/aptible-support). </Warning>


# Managed Databases - Overview

Learn about Aptible Managed Databases that automate provisioning, maintenance, and scaling

<Frame>
  ![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/databases.png)
</Frame>

# Overview

Aptible Databases provide data persistence and are automatically configured and managed by Aptible — including scaling, in-place upgrades, backups, database replication, network isolation, encryption, and more.

## Learn more about using Databases on Aptible

<CardGroup cols={3}>
  <Card title="Provisioning Databases" icon="book" iconType="duotone" href="https://www.aptible.com/docs/provisioning-databases">
    Learn how to provision secure, fully Managed Databases
  </Card>

  <Card title="Connecting to Database" icon="book" iconType="duotone" href="https://www.aptible.com/docs/connecting-to-databases">
    Learn how to connect to your Apps, your team, or the internet to your Databases
  </Card>

  <Card title="Managing Databases" icon="book" iconType="duotone" href="https://www.aptible.com/docs/managing-databases">
    Learn how to scale, upgrade, backup, restore, or replicate your Databases
  </Card>
</CardGroup>

## Explore supported Database types

<Info>Custom Databases are not supported.</Info>

<CardGroup cols={4}>
  <Card title="Elasticsearch" href="https://www.aptible.com/docs/elasticsearch" img="https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/Elasticsearch.png" />

  <Card title="InfluxDB" href="https://www.aptible.com/docs/influxdb" img="https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/InfluxDB.png" />

  <Card title="MongoDB" href="https://www.aptible.com/docs/mongodb" img="https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/MongoDB.png" />

  <Card title="MySQL" href="https://www.aptible.com/docs/mysql" img="https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/MySQL.png" />

  <Card title="PostgreSQL" href="https://www.aptible.com/docs/postgresql" img="https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/PostgreSQL.png" />

  <Card title="RabbitMQ" href="https://www.aptible.com/docs/rabbitmq" img="https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/RabbitMQ.png" />

  <Card title="Redis" href="https://www.aptible.com/docs/redis" img="https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/Redis.png" />

  <Card title="SFTP" href="https://www.aptible.com/docs/sftp" img="https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/SFTP.png" />
</CardGroup>


# Provisioning Databases

Learn about provisioning Managed Databases on Aptible

# Overview

Aptible provides a platform to provision secure, reliable, Managed Databases in a single click.

# Explore Supported Databases

<CardGroup cols={4}>
  <Card title="Elasticsearch" href="https://www.aptible.com/docs/elasticsearch" img="https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/Elasticsearch.png" />

  <Card title="InfluxDB" href="https://www.aptible.com/docs/influxdb" img="https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/InfluxDB.png" />

  <Card title="MongoDB" href="https://www.aptible.com/docs/mongodb" img="https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/MongoDB.png" />

  <Card title="MySQL" href="https://www.aptible.com/docs/mysql" img="https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/MySQL.png" />

  <Card title="PostgreSQL" href="https://www.aptible.com/docs/postgresql" img="https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/PostgreSQL.png" />

  <Card title="RabbitMQ" href="https://www.aptible.com/docs/rabbitmq" img="https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/RabbitMQ.png" />

  <Card title="Redis" href="https://www.aptible.com/docs/redis" img="https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/Redis.png" />

  <Card title="SFTP" href="https://www.aptible.com/docs/sftp" img="https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/SFTP.png" />
</CardGroup>

# FAQ

<Accordion title="How do I provision a Database?">
  A Database can be provisioned in three ways on Aptible:

  *   Within the Aptible Dashboard by
      *   Selecting an existing [Environment](/core-concepts/architecture/environments)
      *   Selecting the **Databases** tab
      *   Selecting **Create Database**
          *   Note: STFP Databases cannot be provisioned via the Aptible Dashboard
          <Frame>
            ![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/App_UI_Create_Database.png)
          </Frame>
  *   Using the [`aptible db:create`](/reference/aptible-cli/cli-commands/cli-db-create) command
  *   Using the Aptible [Terraform Provider](https://registry.terraform.io/providers/aptible/aptible/latest/docs)
</Accordion>


# CouchDB

Learn about running secure, Managed CouchDB Databases on Aptible

# Available Versions

<Warning> As of October 31, 2024, CouchDB is no longer be offered on Aptible. </Warning>

# Logging in to the CouchDB interface (Fauxton)

To maximize security, Aptible enables authentication in CouchDB, and requires valid users. While this is unquestionably a security best practice, a side effect of requiring authentication in CouchDB is that you can't access the management interface.

Indeed, if you navigate to the management interface on a CouchDB Database where authentication is enabled, you won't be served login form... because any request, including one for the login form, requires authentication! (more on the [CouchDB Blog](https://blog.couchdb.org/2018/02/03/couchdb-authentication-without-server-side-code/)).

That said, you can easily work around this. Here's how. When you access your CouchDB Database (either through a [Database Endpoint](/core-concepts/managed-databases/connecting-databases/database-endpoints) or through a [Database Tunnel](/core-concepts/managed-databases/connecting-databases/database-tunnels)), open your browser's console, and run the following code. Make sure to replace `USERNAME` and `PASSWORD` on the last line with the actual username and password from your [Database Credentials](/core-concepts/managed-databases/connecting-databases/database-credentials).

This code will log you in, then redirect you to Fauxton, the CouchDB management interface.

```javascript
(function (name, password) {
  // Don't use a relative URL in fetch: if the user accessed the page by
  // setting a username and password in the URL, that would fail (in fact, it
  // will break Fauxton as well).
  var rootUrl = window.location.href.split("/").slice(0, 3).join("/");
  var basic = btoa(`${name}:${password}`);

  window
    .fetch(rootUrl + "/_session", {
      method: "POST",
      credentials: "include",
      headers: {
        "Content-Type": "application/json",
        Authorization: `Basic ${basic}`,
      },
      body: JSON.stringify({ name, password }),
    })
    .then((r) => {
      if (r.status === 200) {
        return (window.location.href = rootUrl + "/_utils/");
      }
      return r.text().then((t) => {
        throw new Error(t);
      });
    })
    .catch((e) => {
      console.log(`login failed: ${e}`);
    });
})("USERNAME", "PASSWORD");
```

# Configuration

CouchDB Databases can be configured with the [CouchDB HTTP API](http://docs.couchdb.org/en/stable/config/intro.html#setting-parameters-via-the-http-api). Changes made this way will persist across Database restarts.

# Connection Security

Aptible CouchDB Databases support connections via the following protocol:

*   For CouchDB version 2.1: `TLSv1.2`


# Elasticsearch

Learn about running secure, Managed Elasticsearch Databases on Aptible

# Available Versions

<Warning> Due to Elastic licensing changes, newer versions of Elasticsearch will not be available on Aptible. 7.10 will be the final version offered, with no deprecation date. </Warning>

The following versions of [Elasticsearch](https://www.elastic.co/elasticsearch) are currently available:

| Version |   Status  | End-Of-Life Date | Deprecation Date |
| :-----: | :-------: | :--------------: | :--------------: |
|   7.10  | Available |        N/A       |        N/A       |

<Note>For databases on EOL versions, Aptible will prevent new databases from being provisioned and mark existing database as `DEPRECATED` on the deprecation date listed above. While existing databases will not be affected, we recommend end-of-life databases to be [upgraded](https://www.aptible.com/docs/core-concepts/managed-databases/managing-databases/database-upgrade-methods#database-upgrades). The latest version offered on Aptible will always be available for provisioning, regardless of end-of-life date.</Note>

# Connecting to Elasticsearch

**For Elasticsearch 6.8 or earlier:**
Elasticsearch is accessible over HTTPS, with HTTPS basic authentication.

**For Elasticsearch 7.0 or later:**
Elasticsearch is accessible over HTTPS, with Elasticsearch's native authentication mechanism.

The `aptible` user provided by the [Database Credentials](/core-concepts/managed-databases/connecting-databases/database-credentials) is the only user available by default and is configured with the [Elasticsearch Role](https://www.elastic.co/guide/en/elasticsearch/reference/current/built-in-roles.html) of `superuser`. You may [manage the password](https://www.elastic.co/guide/en/elasticsearch/reference/7.8/security-api-change-password.html) of any [Elasticsearch Built-in user](https://www.elastic.co/guide/en/elasticsearch/reference/current/built-in-users.html) if you wish and otherwise manage all aspects of user creation and permissions, with the exception of the `aptible` user.

<Info>Elasticsearch Databases deployed on Aptible use a valid certificate for their host, so you're encouraged to verify the certificate when connecting.</Info>

## Subscription Features

For Elasticsearch 7.0 or later:
Formerly referred to as X-pack features, your [Elastic Stack subscription](https://www.elastic.co/subscriptions) will determine the features available in your Deploy Elasticsearch Database. By default, you will have the "Basic" features. If you purchase a license from Elastic, you may [update your license](https://www.elastic.co/guide/en/kibana/current/managing-licenses.html#update-license) at any time.

# Plugins

Some Elasticsearch plugins may be installed by request. Contact [Aptible Support](/how-to-guides/troubleshooting/aptible-support) if you need a particular plugin.

# Configuration

Elasticsearch Databases can be configured with Elasticsearch's [Cluster Update Settings API](https://www.elastic.co/guide/en/elasticsearch/reference/current/cluster-update-settings.html). Changes made to persistent settings will persist across Database restarts.

Deploy will automatically set the JVM heap size to 50% of the container's memory allocation, per [Elastic's recommendation](https://www.elastic.co/guide/en/elasticsearch/reference/current/heap-size.html#heap-size).

## Kibana

For Elasticsearch 7.0 or later, you can easily deploy [Elastic's official Kibana image](https://hub.docker.com/_/kibana) as an App on Aptible.

<Card title="How to set up Kibana on Aptible" icon="book-open-reader" iconType="duotone" horizontal href="https://www.aptible.com/docs/running-kibana">
  Read the guide
</Card>

## Log Rotation

For Elasticsearch 7.0 or later: if you're using Elasticsearch to hold log data, you may need to periodically create new log indexes. By default, Logstash and our [Log Drains](/core-concepts/observability/logs/log-drains/overview) will create new indexes daily. As the indexes accumulate, they will require more disk space and more RAM. Elasticsearch allocates RAM on a per-index basis, and letting your logs retention grow unchecked will likely lead to fatal issues when the Database runs out of RAM or disk space.

To avoid this, we recommend using a combination of Elasticsearch's native features to ensure you don't accumulate too many open indexes:

*   [Index Lifecycle Management](https://www.elastic.co/guide/en/elasticsearch/reference/current/index-lifecycle-management.html) can be configured to delete indexes over a certain age
*   [Snapshot Lifecycle Management](https://www.elastic.co/guide/en/elasticsearch/reference/current/snapshot-lifecycle-management.html) can be configured to back up indexes on a schedule, for example, to S3
*   The Elasticsearch [S3 Repository Plugin](https://www.elastic.co/guide/en/elasticsearch/plugins/current/repository-s3.html), which is installed by default

<Card title="How to set up Elasticsearch Log Rotation" icon="book-open-reader" iconType="duotone" href="https://www.aptible.com/docs/elasticsearch-log-rotation" horizontal>
  Read the guide
</Card>

# Connection Security

Aptible Elasticsearch Databases support connections via the following protocols:

*   For all Elasticsearch versions 6.8 and earlier: `SSLv3`, `TLSv1.0`, `TLSv1.1`, `TLSv1.2`
*   For all Elasticsearch versions 7.0 and later: `TLSv1.1` , `TLSv1.2`


# InfluxDB

Learn about running secure, Managed InfluxDB Databases on Aptible

# Available Versions

The following versions of [InfluxDB](https://www.influxdata.com/) are currently available:

| Version |   Status  |  End-Of-Life Date | Deprecation Date |
| :-----: | :-------: | :---------------: | :--------------: |
|   1.8   | Available | December 31, 2021 |        N/A       |
|   2.7   | Available |        N/A        |        N/A       |

<Note> For databases on EOL versions, Aptible will prevent new databases from being provisioned and mark existing database as `DEPRECATED` on the deprecation date listed above. While existing databases will not be affected, we recommend end-of-life databases to be [upgraded](https://www.aptible.com/docs/core-concepts/managed-databases/managing-databases/database-upgrade-methods#database-upgrades). The latest minor version of each InfluxDB major version offered on Aptible will always be available for provisioning, regardless of end-of-life date.</Note>

# Accessing data in InfluxDB using Grafana

[Grafana](https://grafana.com) is a great visualization and monitoring tool to use with InfluxDB. For detailed instructions on deploying Grafana to Aptible, follow this tutorial: [Deploying Grafana on Aptible](/how-to-guides/observability-guides/deploy-use-grafana).

# Configuration

Contact [Aptible Support](/how-to-guides/troubleshooting/aptible-support) if you need to change the configuration of an InfluxDB database on Aptible.

# Connection Security

Aptible InfluxDB Databases support connections via the following protocols:

*   For InfluxDB version 1.4, 1.7, and 1.8: `TLSv1.0`, `TLSv1.1`, `TLSv1.2`

# Clustering

Clustering is not available for InfluxDB databases since this feature is not available in InfluxDB's open-source offering.


# MongoDB

Learn about running secure, Managed MongoDB Databases on Aptible

## Available Versions

<Warning> Due to MongoDB licensing changes, newer versions of MongoDB will no longer be available on Aptible. </Warning>

The following versions of [MongoDB](https://www.mongodb.com/) are currently available:

| Version |   Status  | End-Of-Life Date | Deprecation Date |
| :-----: | :-------: | :--------------: | :--------------: |
|   4.0   | Available |        N/A       |        N/A       |

<Note>For databases on EOL versions, Aptible will prevent new databases from being provisioned and mark existing database as `DEPRECATED` on the deprecation date listed above. While existing databases will not be affected, we recommend end-of-life databases to be [upgraded](https://www.aptible.com/docs/core-concepts/managed-databases/managing-databases/database-upgrade-methods#database-upgrades). The latest version offered on Aptible will always be available for provisioning, regardless of end-of-life date.</Note>

# Connecting to MongoDB

Aptible MongoDB [Databases](/core-concepts/managed-databases/overview) require authentication and SSL to connect.

<Tip> MongoDB databases use a valid certificate for their host, so you're encouraged to verify the certificate when connecting.</Tip>

## Connecting to the `admin` database

There are two MongoDB databases you might want to connect to:

*   The `admin` database.
*   The `db` database created by Aptible automatically.

The username (`aptible`) and password for both databases are the same. However, the users in MongoDB are different (i.e. there is a `aptible` user in the `admin` database, and a separate `aptible` user in the `db` database, which simply happens to have the same password).

This means that if you'd like to connect to the `admin` database, you need to make sure to select that one as your authentication database when connecting: connecting to `db` and running `use admin` will **not** work.

# Clustering

Replica set [clustering](/core-concepts/managed-databases/managing-databases/replication-clustering) is available for MongoDB. Replicas can be created using the [`aptible db:replicate`](/reference/aptible-cli/cli-commands/cli-db-replicate) command.

## Failover

MongoDB replica sets will automatically failover between members. In order to do so effectively, MongoDB recommends replica sets have a minimum of [three members](https://docs.mongodb.com/v4.2/core/replica-set-members/). This can be done by creating two Aptible replicas of the same primary Database.

The [connection URI](https://docs.mongodb.com/v4.2/reference/connection-string/) you provide your Apps with must contain the hostnames and ports of all members in the replica set. MongoDB clients will attempt each host until it's able to reach the replica set. With a single host, if that host is unavailable, the App will not be able to reach the replica set. The hostname and port of each member can be found in the [Database's Credentials](/core-concepts/managed-databases/connecting-databases/database-credentials), and the combined connection URI will look something like this for a three-member replica set:

```
mongodb://username:password@host1.aptible.in:27017,host2.aptible.in:27018,host3.aptible.in:27019/db
```

# Data Integrity and Durability

On Aptible, MongoDB is configured with default settings for journaling. For MongoDB 3.x instances, this means [journaling](https://docs.mongodb.com/manual/core/journaling/) is enabled. If you use the appropriate write concern (`j=1`) when writing to MongoDB, you are guaranteed that committed transactions were written to disk.

# Configuration

Configuration of MongoDB command line options is not supported on Aptible.

MongoDB Databases on Aptible autotune their Wired Tiger cache size based on the size of their Container, based upon [Mongo's recommendation](https://docs.mongodb.com/manual/faq/storage/#to-what-size-should-i-set-the-wiredtiger-internal-cache-).

# Connection Security

Aptible MongoDB Databases support connections via the following protocols:

*   For Mongo versions 2.6, 3.4, and 3.6: `TLSv1.0`, `TLSv1.1`, `TLSv1.2`
*   For Mongo version 4.0: `TLSv1.1`, `TLSv1.2`


# MySQL

Learn about running secure, Managed MySQL Databases on Aptible

# Available Versions

The following versions of [MySQL](https://www.mysql.com/) are currently available:

| Version |   Status  | End-Of-Life Date | Deprecation Date |
| :-----: | :-------: | :--------------: | :--------------: |
|   8.0   | Available |    April 2026    |    August 2026   |

MySQL releases LTS versions on a biyearly cadence and fully end-of-lifes (EOL) major versions after 8 years of extended support.

<Note> For databases on EOL versions, Aptible will prevent new databases from being provisioned and mark existing database as `DEPRECATED` on the deprecation date listed above. While existing databases will not be affected, we recommend end-of-life databases to be [upgraded](https://www.aptible.com/docs/core-concepts/managed-databases/managing-databases/database-upgrade-methods#database-upgrades). The latest version offered on Aptible will always be available for provisioning, regardless of end-of-life date.</Note>

## Connecting with SSL

If you get the following error, you're probably not connecting over SSL:

```
ERROR 1045 (28000): Access denied for user 'aptible'@'ip-[IP_ADDRESS].ec2.internal' (using password: YES)
```

Some tools may require additional configuration to connect with SSL to MySQL:

*   When connecting via the `mysql` command line client, add this option: `--ssl-cipher=DHE-RSA-AES256-SHA`.
*   When connecting via JetBrains DataGrip (through [`aptible db:tunnel`](/reference/aptible-cli/cli-commands/cli-db-tunnel)), you'll need to set `useSSL` to `true` and `verifyServerCertificate` to `false` in the *Advanced* settings tab for the data source.

Most MySQL clients will *not* attempt verification of the server certificate by default; please consult your client's documentation to enable `verify-identity`, or your client's equivalent option. The relevant documentation for the MySQL command line utility is [here](https://dev.mysql.com/doc/refman/8.0/en/using-encrypted-connections.html#using-encrypted-connections-client-side-configuration).

By default, MySQL Databases on Aptible use a server certificate signed by Aptible for SSL / TLS termination. Databases that have been running since prior to Jan 15th, 2021, will only have a self-signed certificate. See [Database Encryption in Transit](/core-concepts/managed-databases/managing-databases/database-encryption/database-encryption-in-transit#self-signed-certificates) for more details.

## Connecting without SSL

<Warning>Never transmit sensitive or regulated information without SSL. Connecting without SSL should only be done for troubleshooting or debugging.</Warning>

For debugging purposes, you can connect to MySQL without SSL using the `aptible-nossl` user. As the name implies, this user does not require SSL to connect.

## Connecting as `root`

If needed, you can connect as `root` to your MySQL database. The password for `root` is the same as that of the `aptible` user.

# Creating More Databases

Aptible provides you with full access to a MySQL instance. If you'd like to add more databases, you can do so by [Connecting as `root`](/core-concepts/managed-databases/supported-databases/mysql#connecting-as-root), then using SQL to create the database:

```sql
/* Substitute NAME for the actual name you'd like to use */
CREATE DATABASE NAME;
GRANT ALL ON NAME.* to 'aptible'@'%';
```

# Replication

Source-replica [replication](/core-concepts/managed-databases/managing-databases/replication-clustering) is available for MySQL. Replicas can be created using the [`aptible db:replicate`](/reference/aptible-cli/cli-commands/cli-db-replicate) command.

## Failover

MySQL replicas can accept writes without being promoted. However, it should still be promoted to stop following the source Database so that it doesn't encounter issues when the source Database becomes available again. To do so, run the following commands on the Database:

1.  `STOP REPLICA IO_THREAD`
2.  Run `SHOW PROCESSLIST` until you see `Has read all relay log` in the output.
3.  `STOP REPLICA`
4.  `RESET MASTER`

After the replica has been promoted, you should update your [Apps](/core-concepts/apps/overview) to use the promoted replica as the primary Database. Once you start using the replica, you should not go back to using the original primary Database. Instead, continue using the promoted replica and create a new replica off it it.

Aptible maintains a link between replicas and their source Database to ensure the source Database cannot be deleted before the replica. To deprovision the source Database after you've failed over to a promoted replica, users with the appropriate [roles and permissions](/core-concepts/security-compliance/access-permissions#full-permission-type-matrix) can unlink the replica from the source Database. Navigate to the replica's settings page to complete the unlinking process. See the [Deprovisioning a Database documentation ](/core-concepts/managed-databases/managing-databases/overview#deprovisioning-databases)for considerations when deprovisioning a Database.

# Data Integrity and Durability

On Aptible, [binary logging](https://dev.mysql.com/doc/refman/5.7/en/binary-log.html) is enabled (i.e., MySQL is configured with `sync-binlog = 1`). Committed transactions are therefore guaranteed to be written to disk.

# Configuration

We strongly recommend against relying only on `SET GLOBAL` with Aptible MySQL Databases.

Any configuration parameters added using `SET GLOBAL` will be discarded if your Database is restarted (e.g. as a result of exceeding [Memory Limits](/core-concepts/scaling/memory-limits), the underlying hardware crashing, or simply as a result of a [Database Scaling](/core-concepts/scaling/database-scaling) operation). In this scenario, unless your App automatically detects this condition and uses `SET GLOBAL` again, your custom configuration will no longer be present.

However, Aptible Support can accommodate reasonable configuration changes so that they can be persisted across restarts (by adding them to a configuration file). If you're contemplating using `SET GLOBAL`, please get in touch with [Aptible Support](/how-to-guides/troubleshooting/aptible-support) to apply the setting persistently.

MySQL Databases on Aptible autotune their buffer pool and chunk size based on the size of their container to improve performance. The `innodb_buffer_pool_size` setting will be set to half of the container memory, and `innodb_buffer_pool_chunk_size` and `innodb_buffer_pool_instances` will be set to approriate values.  You can view all buffer pool settings, including these autotuned values, with the following query: `SHOW VARIABLES LIKE 'innodb_buffer_pool_%'`.

# Connection Security

Aptible MySQL Databases support connections via the following protocols:

*   For MySQL version 5.6 and 5.7: `TLSv1.0`, `TLSv1.1`, `TLSv1.2`
*   For MySQL version 8.0: TLSv1.2, TLSv1.3


# PostgreSQL

Learn about running secure, Managed PostgreSQL Databases on Aptible

# Available Versions

The following versions of [PostgreSQL](https://www.postgresql.org/) are currently available:

| Version |   Status  | End-Of-Life Date | Deprecation Date |
| :-----: | :-------: | :--------------: | :--------------: |
|    12   | Available |   November 2024  |   February 2025  |
|    13   | Available |   November 2025  |   February 2026  |
|    14   | Available |   November 2026  |   February 2027  |
|    15   | Available |   November 2027  |   February 2028  |
|    16   | Available |   November 2028  |   February 2029  |
|    17   | Available |   November 2029  |   February 2030  |

<Info>PostgreSQL releases new major versions annually, and supports major versions for 5 years before it is considered end-of-life and no longer maintained.</Info>

<Note> For databases on EOL versions, Aptible will prevent new databases from being provisioned and mark existing database as `DEPRECATED` on the deprecation date listed above. While existing databases will not be affected, we recommend end-of-life databases to be [upgraded](https://www.aptible.com/docs/core-concepts/managed-databases/managing-databases/database-upgrade-methods#database-upgrades). The latest version offered on Aptible will always be available for provisioning, regardless of end-of-life date. </Note>

# Connecting to PostgreSQL

Aptible PostgreSQL [Databases](/core-concepts/managed-databases/overview) require authentication and SSL to connect.

## Connecting with SSL

Most PostgreSQL clients will attempt connection over SSL by default. If yours doesn't, try appending `?ssl=true` to your connection URL, or review your client's documentation.

Most PostgreSQL clients will *not* attempt verification of the server certificate by default, please consult your client's documentation to enable `verify-full`, or your client's equivalent option. The relevant documentation for libpq is [here](https://www.postgresql.org/docs/current/libpq-ssl.html#LIBQ-SSL-CERTIFICATES).

By default, PostgreSQL Databases on Aptible use a server certificate signed by Aptible for SSL / TLS termination. Databases that have been running since prior to Jan 15th, 2021 will only have a self-signed certificate. See [Database Encryption in Transit](/core-concepts/managed-databases/managing-databases/database-encryption/database-encryption-in-transit#self-signed-certificates) for more details.

# Extensions

Aptible supports two families of images for Postgres: default and contrib.

*   The default images have a minimal number of extensions installed, but do include PostGIS.
*   The alternative contrib images have a larger number of useful extensions installed. The list of available extensions is visible below.
*   In PostgreSQL versions 14 and newer, there is no sperate contrib image: the listed extension are avaiable in the default image.

| Extension     | Avaiable in versions |
| ------------- | -------------------- |
| plpythonu     | 9.5 - 11             |
| plpython2u    | 9.5 - 11             |
| plpython3u    | 9.5 - 12             |
| plperl        | 9.5 - 12             |
| plperlu       | 9.5 - 12             |
| mysql\_fdw    | 9.5 - 11             |
| PLV8          | 9.5 - 10             |
| multicorn     | 9.5 - 10             |
| wal2json      | 9.5 - 16             |
| pg-safeupdate | 9.5 - 11             |
| pg\_repack    | 9.5 - 16             |
| pgagent       | 9.5 - 13             |
| pgaudit       | 9.5 - 13             |
| pgcron        | 10                   |
| pgvector      | 15-16                |

If you require a particular PostgreSQL plugin, contact [Aptible Support](/how-to-guides/troubleshooting/aptible-support) to identify whether a contrib image is a good fit. Alternatively, you can launch a new PostgreSQL database using a contrib image with the [`aptible db:create`](/reference/aptible-cli/cli-commands/cli-db-create) command.

# Replication

Primary-standby [replication](/core-concepts/managed-databases/managing-databases/replication-clustering) is available for PostgreSQL. Replicas can be created using the [`aptible db:replicate`](/reference/aptible-cli/cli-commands/cli-db-replicate) command.

## Failover

PostgreSQL replicas can be manually promoted to stop following the primary and start accepting writes. To do so, run one of the following commands depending on your Database's version:

PostgreSQL 12 and higher

```
SELECT pg_promote();
```

PostgreSQL 11 and lower

```
COPY (SELECT 'fast') TO '/var/db/pgsql.trigger';
```

After the replica has been promoted, you should update your [Apps](/core-concepts/apps/overview) to use the promoted replica as the primary Database. Once you start using the replica, you should not go back to using the original primary Database. Instead, continue using the promoted replica and create a new replica off of it.

Aptible maintains a link between replicas and their source Database to ensure the source Database cannot be deleted before the replica. To deprovision the source Database after you've failed over to a promoted replica, users with the appropriate [roles and permissions](/core-concepts/security-compliance/access-permissions#full-permission-type-matrix) can unlink the replica from the source Database. Navigate to the replica's settings page to complete the unlinking process. See the [Deprovisioning a Database](/how-to-guides/platform-guides/deprovision-resources) documentation for considerations when deprovisioning a Database.

# Data Integrity and Durability

On Aptible, PostgreSQL is configured with default settings for [write-ahead logging](https://www.postgresql.org/docs/current/static/wal-intro.html). Committed transactions are therefore guaranteed to be written to disk.

# Configuration

A PostgreSQL database's [`pg_settings`](https://www.postgresql.org/docs/current/view-pg-settings.html) can be changed with [`ALTER SYSTEM`](https://www.postgresql.org/docs/current/sql-altersystem.html). Changes made this way are written to disk and will persist across database restarts.

PostgreSQL databases on Aptible autotune the size of their caches and working memory based on the size of their container in order to improve performance. See the image's [public git repo](https://github.com/aptible/docker-postgresql/blob/master/bin/autotune) for details.

The following settings are autotuned:

*   `shared_buffers`
*   `effective_cache_size`
*   `work_mem`
*   `maintenance_work_mem`
*   `checkpoint_completion_target`
*   `default_statistics_target`

Modifying these settings is not recommended as the setting will no longer scale with the size of the database's container.

# Connection Security

Aptible PostgreSQL Databases support connections via the following protocols:

*   For PostgreSQL versions 9.6, 10, 11, and 12: `TLSv1.0`, `TLSv1.1`, `TLSv1.2`
*   For PostgreSQL versions 13 and 14: `TLSv1.2`
*   For PostgreSQL versions 15 and 16: `TLSv1.2`, `TLSv1.3`


# RabbitMQ



# Available Versions

The following versions of RabbitMQ are currently available:

| Version |   Status  | End-Of-Life Date | Deprecation Date |
| :-----: | :-------: | :--------------: | :--------------: |
|   3.12  | Available |   December 2024  |        N/A       |

For databases on EOL versions, Aptible will prevent new databases from being provisioned and mark existing database as `DEPRECATED` on the deprecation date listed above. While existing databases will not be affected, we recommend end-of-life databases to be [upgraded](https://www.aptible.com/docs/core-concepts/managed-databases/managing-databases/database-upgrade-methods#database-upgrades). The latest version offered on Aptible will always be available for provisioning, regardless of end-of-life date.

# Connecting to RabbitMQ

Aptible RabbitMQ [Databases](/core-concepts/managed-databases/overview) require authentication and SSL to connect.

<Tip>RabbitMQ Databases use a valid certificate for their host, so you’re encouraged to verify the certificate when connecting.</Tip>

# Connecting to the RabbitMQ Management Interface

Aptible RabbitMQ [Databases](/core-concepts/managed-databases/overview) provide access to the management interface.

Typically, you should access the management interface via a [Database Tunnel](/core-concepts/managed-databases/connecting-databases/database-tunnels). For example:

```shell
aptible db:tunnel "$DB_HANDLE" --type management
```

# Modifying RabbitMQ Parameters & Policies

RabbitMQ [parameters](https://www.rabbitmq.com/parameters.html) can be updated via the management API and changes will persist across Database restarts.

The [log level](https://www.rabbitmq.com/logging.html#log-levels) of a RabbitMQ Database can be changed by contacting [Aptible Support](/how-to-guides/troubleshooting/aptible-support), but other [configuration file](https://www.rabbitmq.com/configure.html#configuration-files) values cannot be changed at this time.

# Connection Security

Aptible RabbitMQ Databases support connections via the following protocols:

*   For RabbitMQ 3.5, 3.7, 3.9: `TLSv1.0`, `TLSv1.1`, `TLSv1.2`
*   For RabbitMQ version 3.12: `TLSv1.2`, `TLSv1.3`


# Redis

Learn about running secure, Managed Redis Databases on Aptible

## Available Versions

The following versions of [Redis](https://redis.io/) are currently available:

| Version |   Status  | End-Of-Life Date | Deprecation Date |
| :-----: | :-------: | :--------------: | :--------------: |
|   6.2   | Available |   November 2027  |        N/A       |
|   7.0   | Available |   November 2028  |        N/A       |

<Info>Redis typically releases new major versions annually with a minor version release 6 months after. The latest major version is fully maintained and supported by Redis, while the previous major version and minor version receive security fixes only. All other versions are considered end-of-life.</Info>

<Note>For databases on EOL versions, Aptible will prevent new databases from being provisioned and mark existing database as `DEPRECATED` on the deprecation date listed above. While existing databases will not be affected, we recommend end-of-life databases to be [upgraded](https://www.aptible.com/docs/core-concepts/managed-databases/managing-databases/database-upgrade-methods#database-upgrades). Follow [this guide](https://www.aptible.com/docs/how-to-guides/database-guides/upgrade-redis) to upgrade your redis databases. The latest version offered on Aptible will always be available for provisioning, regardless of end-of-life date.</Note>

# Connecting to Redis

Aptible Redis [Databases](/core-concepts/managed-databases/overview) expose two [Database Credentials](/core-concepts/managed-databases/connecting-databases/database-credentials):

*   A `redis` credential. This is for plaintext connections, so you shouldn't use it for sensitive or regulated information.
*   A `redis+ssl` credential. This accepts connections over TLS, and it's the one you should use for regulated or sensitive information.

<Tip> The SSL port uses a valid certificate for its host, so you’re encouraged to verify the certificate when connecting.</Tip>

# Replication

Master-replica [replication](/core-concepts/managed-databases/managing-databases/replication-clustering) is available for Redis. Replicas can be created using the [`aptible db:replicate`](/reference/aptible-cli/cli-commands/cli-db-replicate) command.

## Failover

Redis replicas can be manually promoted to stop following the primary and start accepting writes. To do so, run the following command on the Database:

```
REPLICAOF NO ONE
```

After the replica has been promoted, you should update your [Apps](/core-concepts/apps/overview) to use the promoted replica as the primary Database. Once you start using the replica, you should not go back to using the original primary Database. Instead, continue using the promoted replica and create a new replica off of it.

The effects of `REPLICAOF NO ONE` are not persisted to the Database's filesystem, so the next time the Database starts, it will attempt to replicate the source Database again. In order to persist this change, contact [Aptible Support](/how-to-guides/troubleshooting/aptible-support) with the name of the Database and request that it be permanently promoted.

Aptible maintains a link between replicas and their source Database to ensure the source Database cannot be deleted before the replica. To deprovision the source Database after you've failed over to a promoted replica, users with the appropriate [roles and permissions](/core-concepts/security-compliance/access-permissions#full-permission-type-matrix) can unlink the replica from the source database. Navigate to the replica's settings page to complete the unlinking process. See the [Deprovisioning a Database](/how-to-guides/platform-guides/deprovision-resources) documentation for considerations when deprovisioning a Database.

# Data Integrity and Durability

On Aptible, Redis is by default configured to use both Append-only file and RDB backups. This means your data is stored in two formats on disk. Redis on Aptible uses the every-second fsync policy for AOF, and the following configuration for RDB backups:

```
save 900 1
save 300 10
save 60 10000
```

This configuration means Redis performs an RDB backup every 900 seconds at most, every 300 seconds if 10 keys are changed, and every 60 seconds if 10000 keys are changed. Additionally, each time a write operation is performed, it is immediately written to the append-only file and flushed from the kernel to the disk (using fsync) one time every second.

Broadly speaking, Redis is not designed to be a durable data store. We do not recommend using Redis in cases where durability is required.

## RDB-only flavors

If you'd like to use Redis with AOF disabled and RDB persistence enabled, we provide Redis images in this configuration that you can elect to use.

One of the benefits of RDB-only persistence is the fact that for a given database size, the number of I/O operations is bound by the above configuration, whatever the activity on the database is. However, if Redis crashes or runs out of memory between RDB backups, data might be lost.

Note that an RDB backup means Redis is writing data to disk and is not the same thing as an Aptible [Database Backups](/core-concepts/managed-databases/managing-databases/database-backups). Aptible Database Backups are daily snapshots of your Database's disk. In other words: Redis periodically commits data to disk (according to the above schedule), and Aptible periodically makes a snapshot of the disk (which includes the data).

These database types are displayed as `RDB-Only Persistence` on the Dashboard.

## Memory-only flavors

If you'd like to use Redis as a memory-only store (i.e., without any persistence), we provide Redis images with AOF and RDB persistence disabled.

If you use one of those (they aren't the default), make sure you understand that\*\* all data in Redis will be lost upon restarting or resizing your memory-only instance or upon your memory-only instance running out of memory.\*\*

If you'd like to use a memory-only flavor, provision it using the [`aptible db:create`](/reference/aptible-cli/cli-commands/cli-db-create) command (substitute `$HANDLE` with your desired handle for this Database). Since the disk will only be used to store configuration files, use the minimum size (with the `--disk-size` parameter as listed below):

```shell
aptible db:create \
        --type redis \
        --version 4.0-nordb \
        --disk-size 1 \
        "$HANDLE"
```

These database types are displayed as `NO PERSISTENCE` on the Dashboard.

## Specifying a flavor

When creating a Redis database from the Aptible Dashboard, you only have the option of version with both AOF and RDB enabled.

To list available Redis flavors that can be passed to [`aptible db:create`](/reference/aptible-cli/cli-commands/cli-db-create) via the `--version` option, use the [`aptible db:versions`](/reference/aptible-cli/cli-commands/cli-db-versions) command:

*   `..-aof` are the AOF + RDB ones.
*   `..-nordb` are the memory-only ones.
*   The unadorned versions are RDB-Only.

# Configuration

Contact [Aptible Support](/how-to-guides/troubleshooting/aptible-support) if you have a need to change the configuration of a Redis database on Aptible.

# Connection Security

Aptible Redis databases support connections via the following protocols:

*   For Redis versions 2.8, 3.0, 3.2, 4.0, and 5.0: `TLSv1.0`, `TLSv1.1`, `TLSv1.2`
*   For Redis versions 6.0, 6.2, and 7.0: `TLSv1.2`


# SFTP



# Provisioning an SFTP Database

SFTP Databases cannot be provisioned via the Dashboard. STFP Databases can be provisioned in the following ways:

*   Using the [`aptible db:create`](/reference/aptible-cli/cli-commands/cli-db-create) command
    *   For example: `aptible db:create "$DB_HANDLE" --type sftp`
*   Using the [Aptible Terraform Provider](/reference/terraform)

# Usage

The service is designed to run with an initial, password-protected admin user. The credentials for this user can be viewed in the [Database Credentials](/core-concepts/managed-databases/connecting-databases/database-credentials) section of the database page. Additional users can be provisioned anytime by calling add-sftp-user with a username and SSH public key.

<Warning> By default, this SFTP service defaults files to be stored in the given users home directory (in the `/home/%u` format). Files in the `/home/%u` directory structure are located on a persistent volume that will be reliably persisted between any reload/restart/scale/maintenance activity of the SFTP instance. However, the initial `aptible` user is a privileged user which can store files elsewhere in the file system, in areas which are on an ephemeral volume which will be lost during any reload/restart/scale/maintenance activity. Please only store SFTP files in the users' home directory structure!</Warning>

## Connecting and Adding Users

*   Run a db:tunnel in one terminal window: `aptible db:tunnel $DB_HANDLE`
*   This will give output of a URL containing the host/password/port
*   In another terminal window: `ssh -p PORT aptible@localhost.aptible.in` (where PORT is copied from the port provided in the previous step)
*   Use the password provided in the previous step
*   Once in the shell, you can use the `add-sftp-user` utility to add additional users to the SFTP instance. Please note that additional users added with this utility must use [ssh key authentication](/core-concepts/security-compliance/authentication/ssh-keys), and the public key is provided as an argument to the command.

```
sudo add-sftp-user regular-user "SSH_PUBLIC_KEY"
```

where `SSH_PUBLIC_KEY` would be the ssh public key for the user. To provide a fictional public key (truncated for readability) as an example:

```
sudo add-sftp-user regular-user "ssh-rsa AAAAB3NzaC1yc2EBAQClKswlTG2MO7YO9wENmf user@example.com"
```


# Activity

Learn about tracking changes to your resources with Activity

![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/Activity-overview.png)

# Overview

A collective record of [operations](/core-concepts/architecture/operations) is referred to as Activity. You can access and review Activity through the following methods:

1.  **Activity Dashboard:** To view recent operations executed across your entire organization, you can explore the [Activity dashboard](/core-concepts/observability/activity#activity-dashboard)
2.  **Resource-specific activity:** To focus on a particular resource, you can locate all associated operations within that resource's dedicated Activity tab.
3.  **Activity reports**: You can export comprehensive [Activity Reports](/core-concepts/observability/activity#activity-reports) for all past operations.

Users can only view activity for environments to which they have access.

# Activity Dashboard

![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/5-app-ui-1.png)

The Activity dashboard provides a real-time view of operations for active resources in the last seven days. Through the Activity page, you can:

*   View operations for resources you have access to
*   Search operations by resource name, operation type, and user
*   View operation logs for debugging purposes

> 📘 Tip: Troubleshooting with our team? Link the Aptible Support team to the logs for the operation you are having trouble with.

# Activity Reports

![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/Activity-Reports-4.png)

Activity Reports provide historical data of all operations in a given environment, including operations executed on resources that were later deleted. These reports are generated on a weekly basis for each environment, and they can be accessed for the duration of the environment's existence.


# Elasticsearch Log Drains



# Overview

Aptible can deliver your logs to an [Elasticsearch](/core-concepts/managed-databases/supported-databases/elasticsearch) database hosted in the same Aptible [Environment](/core-concepts/architecture/environments).

# Ingest Pipelines

Elasticsearch Ingest Pipelines are supported on Aptible but not currently exposed in the UI. To set up an Ingest Pipeline, please contact [Aptible Support](/how-to-guides/troubleshooting/aptible-support).

# Get Started

<Card title="Setting up a ELK stack on Aptible" icon="books" iconType="duotone" href="https://www.aptible.com/docs/elk-stack">
  Step-by-step instructions on setting up logging to an Elasticsearch database on Aptible
</Card>


# HTTPS Log Drains



# Overview

Aptible can deliver your logs via HTTPS.

The logs are delivered via HTTPS POST, using a JSON `Content-Type`.

# Payload

The payload is structured as follows. New keys may be added over time, and logs from [Ephemeral SSH Sessions](/core-concepts/apps/connecting-to-apps/ssh-sessions) include additional keys.

```json
{
  "@timestamp": "2017-01-11T11:11:11.111111111Z",
  "log": "some log line from your app",
  "stream": "stdout",
  "time": "2017-01-11T11:11:11.111111111Z",
  "@version": "1",
  "type": "json",
  "file": "/tmp/dockerlogs/containerId/containerId-json.log",
  "host": "containerId",
  "offset": "123",
  "layer": "app",
  "service": "app-web",
  "app": "app",
  "app_id": "456",
  "source": "app",
  "container": "containerId"
}
```

# Specific Metadata

Both [Ephemeral SSH Sessions](/core-concepts/apps/connecting-to-apps/ssh-sessions) and [Endpoint Logs](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/endpoint-logs) contain additional metadata; see the appropriate documentation for further details.

# Get Started

<Card title="Setting up a HTTP Log Drain on Aptible" icon="books" iconType="duotone" href="https://www.aptible.com/docs/self-hosted-https-log-drain">
  Step-by-step instructions on setting up logging to an HTTP Log Drain on Aptible
</Card>


# Log Drains

Learn about sending Logs to logging destinations

![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/log-drain-overview.png)

Log Drains let you route Logs to logging destinations for reviewing, searching, and alerting. Log Drains support capturing logs for Apps, Databases, SSH sessions, and Endpoints.

# Explore Log Drains

<CardGroup cols={3}>
  <Card title="Datadog" icon="book" iconType="duotone" href="https://www.aptible.com/docs/datadog" />

  <Card title="Custom - HTTPS" icon="book" iconType="duotone" href="https://www.aptible.com/docs/https-log-drains" />

  <Card title="Custom - Syslog" icon="book" iconType="duotone" href="https://www.aptible.com/docs/syslog-log-drains" />

  <Card title="Elasticsearch" icon="book" iconType="duotone" href="https://www.aptible.com/docs/elasticsearch-log-drains" />

  <Card title="Logentries" icon="book" iconType="duotone" href="https://www.aptible.com/docs/syslog-log-drains" />

  <Card title="Mezmo" icon="book" iconType="duotone" href="https://www.aptible.com/docs/mezmo" />

  <Card title="Papertrail" icon="book" iconType="duotone" href="https://www.aptible.com/docs/papertrail" />

  <Card title="Sumo Logic" icon="book" iconType="duotone" href="https://www.aptible.com/docs/sumo-logic" />
</CardGroup>


# Syslog Log Drains



# Overview

Aptible can deliver your logs via Syslog to a destination of your choice. This option makes it easy to use third-party providers such as [Logentries](https://logentries.com/) or [Papertrail](https://papertrailapp.com/) with Aptible.

> ❗️ When sending logs to a third-party provider, make sure your logs don't include sensitive or regulated information, or that you have the proper agreement in place with your provider.

# TCP-TLS-Only

Syslog [Log Drains](/core-concepts/observability/logs/log-drains/overview) exclusively support TCP + TLS as the transport. This means you cannot deliver your logs over unencrypted and insecure channels, such as UDP or plaintext TCP.

# Logging Tokens

Syslog [Log Drains](/core-concepts/observability/logs/log-drains/overview) lets you inject a prefix in all your log lines. This is useful with providers such as Logentries, which require a logging token to associate the logs you send with your account.

# Get Started

<Card title="Setting up a logging to Papertrail" icon="books" iconType="duotone" href="https://www.aptible.com/docs/papertrail">
  Step-by-step instructions on setting up logging to Papertrail
</Card>


# Logs

Learn about how to access and retain logs from your Aptible resources

# Overview

With each operation, the output of your [Containers](/core-concepts/architecture/containers/overview) is collected as Logs. This includes changes to your resources such as scaling, deploying, updating environment variables, creating backups, etc.

<Note> Strictly speaking, `stdout` and `stderr` are captured. If you are using Docker locally, this is what you'd see when you run `docker logs ...`. Most importantly, this means **logs sent to files are not captured by Aptible logging**, so when you deploy your [Apps](/core-concepts/apps/overview) on Aptible, you should ensure you are logging to `stdout` or `stderr`, and not to log files.</Note>

# Quick Access Logs

Aptible stores recent Logs for quick access. For long term retention of logs, you will need to set up a [Log Drain](/core-concepts/observability/logs/log-drains/overview).

<Tabs>
  <Tab title="Using the CLI">
    App and Database logs can be accessed in real-time from the [CLI](/reference/aptible-cli/overview) using the [`aptible logs`](/reference/aptible-cli/cli-commands/cli-logs) command. Upon executing this command, only the logs generated from that moment onward will be displayed.

    Example:

    ```
    aptible logs --app "$APP_HANDLE"
    aptible logs --database "$DATABASE_HANDLE"
    ```
  </Tab>

  <Tab title="Using the the Aptible Dashboard">
    ![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/Logs-overview.png)
    Within the Aptible Dashboard, logs for recent operations can be acccessed by viewing recent [Activity](/core-concepts/observability/activity).
  </Tab>
</Tabs>

# Log Integrations

## Log Drains

Log Drains let you route Logs to logging destinations for reviewing, searching, and alerting. Log Drains support capturing logs for Apps, Databases, SSH sessions, and Endpoints.

<Card title="Learn more about Log Drains" icon="book" href="https://www.aptible.com/docs/log-drains" />

## Log Archiving

Log Archiving lets you route Logs to S3 for business continuity and compliance. Log Archiving supports capturing logs for Apps, Databases, SSH sessions, and Endpoints.

<Card title="Learn more about Log Archiving" icon="book" href="https://www.aptible.com/docs/s3-log-archives" />


# Log Archiving to S3



<Info> S3 Log Archiving is currently in limited beta release and is only available on the [Enterprise plan](https://www.aptible.com/pricing). Please note that this feature is subject to limited availability while in the beta release stage. </Info>

Once you have configured [Log Drains](/core-concepts/observability/logs/log-drains/overview) for daily access to your logs (e.g., for searching and alerting purposes), you should also configure backup log delivery to Amazon S3. Having this backup method will help ensure that, in the event, your primary logging provider experiences delivery or availability issues, your ability to retain logs for compliance purposes will not be impacted.

Aptible provides this disaster-recovery option by uploading archives of your container logs to an S3 bucket owned by you, where you can define any retention policies as needed.

# Setup

## Prerequisites

To begin sending log archives to an S3 bucket, you must have your own AWS account and an S3 bucket configured for this purpose.

This must be the sole purpose of your S3 bucket (that is, do not add other content to this bucket), your S3 bucket **must** have versioning enabled, and your S3 bucket **must** be in the same region as your Stack. To enable [S3 bucket versioning](https://docs.aws.amazon.com/AmazonS3/latest/userguide/Versioning.html) via the AWS Console, visit the Properties tab of your S3 bucket, click Edit under Bucket Versioning, choose Enable, and then Save Changes.

## Process

Once you have created a bucket and enabled versioning, apply the following policy to the bucket in order to allow Aptible to replicate objects to it.

<Warning> You need to replace `YOUR_BUCKET_NAME` in both "Resource" sections with the name of your bucket. </Warning>

```json
{
  "Version": "2012-10-17",
  "Id": "Aptible log sync",
  "Statement": [
    {
      "Sid": "dest_objects",
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::916150859591:role/s3-stack-log-replication"
      },
      "Action": [
        "s3:ReplicateObject",
        "s3:ReplicateDelete",
        "s3:ObjectOwnerOverrideToBucketOwner"
      ],
      "Resource": "arn:aws:s3:::YOUR_BUCKET_NAME/*"
    },
    {
      "Sid": "dest_bucket",
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::916150859591:role/s3-stack-log-replication"
      },
      "Action": [
        "s3:List*",
        "s3:GetBucketVersioning",
        "s3:PutBucketVersioning"
      ],
      "Resource": "arn:aws:s3:::YOUR_BUCKET_NAME"
    }
  ]
}
```

Contact [Aptible Support](/how-to-guides/troubleshooting/aptible-support) to request access to this limited beta. We will need to know:

*   Your AWS Account ID.
*   The name of your S3 bucket to use for archiving.

# Delivery

To ensure you only need to read or process each file once, we do not upload any files which are actively being written to. This means we will only upload a log archive file when either of two conditions is met:

*   After the container has exited, the log file will be eligible for upload.
*   If the container log exceeds 500 MB, we will rotate the log, and the rotated file will be eligible for upload.

Aptible will upload log files at the bottom of every hour (1:30, 2:30, etc.).

If you have long-running containers that generate a low volume of logs, you may need to restart the App or Database periodically to flush the log archives to S3. As such, this feature is only intended to be used as a disaster archive for compliance purposes, not for the troubleshooting of running services, data processing pipelines, or any usage that mandates near-realtime access.

# Retrieval

You should not need access the log files from your S3 bucket directly, as Aptible has provided a command in our [CLI](/reference/aptible-cli/cli-commands/overview) that provides you the ability to search, download and decrypt your container logs: [`aptible logs_from_archive`](/reference/aptible-cli/cli-commands/cli-logs-from-archive).

This utility has no reliance on Aptible's services, and since the S3 bucket is under your ownership, you may use it to access your Log Archive even if you are no longer a customer of Aptible.

# File Format

## Encryption

Files stored in your S3 bucket are encrypted with an AES-GCM 256-bit key, protecting your data in transit and at rest in your S3 bucket. Decryption is handled automatically upon retrieval via the Aptible CLI.

## Compression

The files are stored and downloaded in gzip format to minimize storage and transfer costs.

## JSON Format

Once uncompressed, the logs will be in the [JSON format as emitted by Docker](https://docs.docker.com/config/containers/logging/json-file/). For example:

```json
{"log":"Log line is here\n","stream":"stdout","time":"2022-01-01T12:23:45.5678Z"}
{"log":"An error may be here\n","stream":"stderr","time":"2022-01-01T12:23:45.5678Z"}
```


# InfluxDB Metric Drain

Learn about sending Aptible logs to an InfluxDB

Aptible can deliver your [Metrics](/core-concepts/observability/metrics/overview) to any InfluxDB Database (hosted on Aptible or not). There are two types of InfluxDB Metric Drains on Aptible:

*   Aptible-hosted: This method allows you to route metrics to an InfluxDB Database hosted on Aptible. This Database must live in the same Environment as the Metrics you are retrieving. Additionally, the [Aptible Metrics Terraform Module](https://registry.terraform.io/modules/aptible/metrics/aptible/latest) uses this method to deploy prebuilt Grafana dashboards with alerts for monitoring RAM & CPU usage for your Apps & Databases - so you can instantly start monitoring your Aptible resources.
*   Hosted anywhere: This method allows you to route Metrics to any InfluxDB. This might be useful if you are leveraging InfluxData's [hosted InfluxDB offering](https://www.influxdata.com/).

# InfluxDB Metrics Structure

Aptible InfluxDB Metric Drains publish metrics in a series named `metrics`.

The following values are published (approximately every 30 seconds):

*   `running`: a boolean indicating whether the Container was running when this point was sampled.
*   `milli_cpu_usage`: the Container's average CPU usage (in milli CPUs) over the reporting period.
*   `milli_cpu_limit`: the maximum CPU accessible to the container.
*   `memory_total_mb`: the Container's total memory usage.
*   `memory_rss_mb`: the Container's RSS memory usage. This memory is typically not reclaimable. If this exceeds the `memory_limit_mb`, the container will be restarted.
*   `memory_limit_mb`: the Container's [Memory Limit](/core-concepts/scaling/memory-limits).
*   `disk_read_kbps`: the Container's average disk read bandwidth over the reporting period.
*   `disk_write_kbps`: the Container's average disk write bandwidth over the reporting period.
*   `disk_read_iops`: the Container's average disk read IOPS over the reporting period.
*   `disk_write_iops`: the Container's average disk write IOPS over the reporting period.
*   `disk_usage_mb`: the Database's Disk usage (Database metrics only).
*   `disk_limit_mb`: the Database's Disk size (Database metrics only).
*   `pids_current`: the current number of tasks in the Container (see [Other Limits](/core-concepts/security-compliance/ddos-pid-limits)).
*   `pids_limit`: the maximum number of tasks for the Container (see [Other Limits](/core-concepts/security-compliance/ddos-pid-limits)).

> 📘 Review [Understanding Memory Utilization](/core-concepts/scaling/memory-limits#understanding-memory-utilization) for more information on the meaning of the `memory_total_mb` and `memory_rss_mb` values.

> 📘 Review [I/O Performance](/core-concepts/scaling/database-scaling#i-o-performance) for more information on the meaning of the `disk_read_iops` and `disk_write_iops` values.

All points are enriched with the following tags:

*   `environment`: Environment handle
*   `app`: App handle (App metrics only)
*   `database`: Database handle (Database metrics only)
*   `service`: Service name
*   `host_name`: [Container Hostname (Short Container ID)](/core-concepts/architecture/containers/overview#container-hostname)
*   `container`: full Container ID

# Getting Started

<AccordionGroup>
  <Accordion title="Creating a Influx Metric Drain">
    You can set up an InfluxDB Metric Drain in the following ways:

    *   (Aptible-hosted only) Using [Aptible Metrics Terraform Module](https://registry.terraform.io/modules/aptible/metrics/aptible/latest). This provision an Influx Metric Drain with pre-built Grafana dashboards and alerts for monitoring RAM & CPU usage for your Apps & Databases. This simplifies the setup of Metric Drains so you can start monitoring your Aptible resources immediately, all hosted within your Aptible account.
    *   Within the Aptible Dashboard by navigating to the respective Environment > selecting the "Metrics Drain" tab > selecting "Create Metric Drain" > selecting "InfluxDB (This Environment)" or "InfluxDB (Anywhere)"
        ![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/App_UI_InfluxDB-self.png)
    *   Using the [`aptible metric_drain:create:influxdb`](/reference/aptible-cli/cli-commands/cli-metric-drain-create-influxdb) command
  </Accordion>

  <Accordion title="Accessing Metrics in DB">
    The best approach to accessing metrics from InfluxDB is to deploy [Grafana](https://grafana.com). Grafana is easy to deploy on Aptible.

    *   **Recommended:** [Using Aptible Metrics Terraform Module](https://registry.terraform.io/modules/aptible/metrics/aptible/latest). This provisions Metric Drains with pre-built Grafana dashboards and alerts for monitoring RAM & CPU usage for your Apps & Databases. This simplifies the setup of Metric Drains so you can start monitoring your Aptible resources immediately, all hosted within your Aptible account.
    *   You can also follow this tutorial [Deploying Grafana on Aptible](https://www.aptible.com/docs/deploying-grafana-on-deploy), which includes suggested queries to set up within Grafana.
  </Accordion>
</AccordionGroup>


# Metrics Drains

Learn how to route metrics with Metric Drains

![](https://assets.tina.io/0cc6fba2-0b87-4a6a-9953-a83971f2e3fa/App_UI_Create_Metric_Drain.png)

# Overview

Metric Drains lets you route metrics for [Apps](/core-concepts/apps/overview) and [Databases](/core-concepts/managed-databases/managing-databases/overview) to the destination of your choice. Metrics Drains are typically useful to:

*   Persist metrics for the long term

*   Alert when metrics cross thresholds of your choice

*   Troubleshoot performance problems

# Explore Metric Drains

<CardGroup cols={2}>
  <Card title="Datadog" icon="book" iconType="duotone" href="https://www.aptible.com/docs/datadog" />

  <Card title="InfluxDB" icon="book" iconType="duotone" href="https://www.aptible.com/docs/influxdb-metric-drain" />
</CardGroup>


# Metrics

Learn about container metrics on Aptible

## Overview

![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/Metrics-overview.png)

Aptible provides key metrics for your app and database containers, such as memory, CPU, and disk usage, and provides them in two forms:

*   **In-app metrics:** Metric visualizations within the Aptible Dashboard, enabling real-time monitoring

*   **Metric Drains:** Send to a destination of your choice for monitoring, alerting, and long-term retention

Aptible provides in-app metrics conveniently within the Aptible Dashboard. This feature offers real-time monitoring with visualizations for quick insights.

The following metrics are available within the Aptible Dashboard

*   Apps/Services:

    *   Memory Usage

    *   CPU Usage

    *   Load Average
*   Databases:

    *   Memory Usage

    *   CPU Usage

    *   Load Average

    *   Disk IO

    *   Disk Usage

### Accessing in-app metrics

Metrics can be accessed within the Aptible Dashboard by:

*   Selecting the respective app or database

*   Selecting the **Metrics** tab

## Metric Drains

Metric Drains provide a powerful option for routing your metrics data to a destination of your choice for comprehensive monitoring, alerting, and long-term data retention.

<CardGroup cols={2}>
  <Card title="Datadog" icon="book" iconType="duotone" href="https://www.aptible.com/docs/datadog" />

  <Card title="InfluxDB" icon="book" iconType="duotone" href="https://www.aptible.com/docs/influxdb-metric-drain" />
</CardGroup>


# Observability - Overview

Learn about observability features on Aptible to help you monitor, analyze and manange your Apps and Databases

# Overview

Aptible’s observability tools are designed to provide a holistic view of your resources, enabling you to effectively monitor, analyze, and manage your Apps and Databases. This includes monitoring activity tracking for changes made to your resources, logs for real-time data or historical retention, and metrics for monitoring usage and performance.

# Activity

![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/Activity-overview.png)

Aptible keeps track of all changes made to your resources as operations and records this as activity. You can explore this activity in the dashboard or share it with Activity Reports.

<Card title="Learn more about Activity" icon="book" iconType="duotone" href="https://www.aptible.com/docs/activity" />

# Logs

![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/Logs-overview.png)

Aptible's log features ensure you have access to critical information generated by your containers. Logs come in three forms: CLI Logs (for quick access), Log Drains (for search and alerting), and Log Archiving (for business continuity and compliance).

<Card title="Learn more about Logs" icon="book" iconType="duotone" href="https://www.aptible.com/docs/logging" />

# Metrics

![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/Metrics-overview.png)

For real-time performance monitoring of your app and database containers, Aptible provides essential metrics, including memory usage, CPU usage, and disk utilization. These metrics are available as in-app visualizations or sent to a destination for monitoring and alerting.

<Card title="Learn more about Metrics" icon="book" iconType="duotone" href="https://www.aptible.com/docs/metrics" />


# Sources



# Overview

Sources allow you to relate your deployed Apps back to their source repositories, allowing you to use the Aptible Dashboard to answer the question "*what's deployed where?*"

# Configuring Sources

To connect your App with it's Source, you'll need to configure your deployment pipeline to send Source information along with your deployments. See [Linking Apps to Sources](/core-concepts/apps/deploying-apps/linking-apps-to-sources) for more details.

# The Sources List

The Sources list view displays a list of all of the Sources configured across your deployed Apps. This view is useful for finding groups of Apps that are running code from the same Source (e.g., ephemeral environments or multiple instances of a single-tenant application).

![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/sources-list.png)

# Source Details

From the Source list page, you can click into a Source to see its details, including a list of Apps deployed from the Source and their current revision information

![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/sources-apps.png)

You can also view the Deployments tab, which will display historical deployments and their revision information made from that Source across all of your Apps.

![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/sources-deployments.png)


# App Scaling

Learn about scaling Apps CPU, RAM, and containers - manually or automatically

# Overview

Aptible Apps are scaled at the [Service](/core-concepts/apps/deploying-apps/services) level, meaning each App Service is scaled independently.

App Services can be scaled by adding more CPU/RAM (vertical scaling) or by adding more containers (horizontal). App Services can be scaled manually via the CLI or UI, automatically with the Autoscaling, or programmatically with Terraform.

Apps with more than two containers are deployed in a high-availability configuration, ensuring redundancy across different zones.

When Apps are scaled, a new set of [containers](/core-concepts/architecture/containers/overview) will be launched to replace the existing ones for each of your App's [Services](/core-concepts/apps/deploying-apps/services).

# High-availability Apps

Apps scaled to 2 or more Containers are automatically deployed in a high-availability configuration, with Containers deployed in separate [AWS Availability Zones](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-regions-availability-zones.html).

# Horizontal Scaling

Scale Apps horizontally by adding more [Containers](/core-concepts/architecture/containers/overview) to a given Service. Each App Service can scale up to 32 Containers.'

### Manual Horizontial Scaling

App Services can be manually scaled via the Dashboard or [`aptible apps:scale`](https://www.aptible.com/docs/reference/aptible-cli/cli-commands/cli-apps-scale) CLI command. Example:

```
  aptible apps:scale SERVICE [--container-count COUNT] 
```

### Horizontal Autoscaling

<Frame>
  ![Horizontal Autoscaling](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/horizontal-autoscale.png)
</Frame>

<Note>This feature is currently in "limited release". Contact Aptible Support to request access.</Note>

When Horizontal Autoscaling is enabled on a Service, the autoscaler evaluates Services every 5 minutes and generates scaling adjusted based on CPU usage (as percentage of total cores). Data is analyzed over a 30-minute period, with post-scaling cooldowns of 5 minutes for scaling down and 1 minute for scaling up. After any release, an additional 5-minute cooldown applies. Metrics are evaluated at the 99th percentile aggregated across all of the service containers over the past 30 minutes.

<Card title="Guide for Configuring Horizontial Autoscaling" icon="book-open-reader" iconType="duotone" href="https://www.aptible.com/docs/how-to-guides/app-guides/horizontal-autoscaling-guide" />

#### Configuration Options

<AccordionGroup>
  <Accordion title="Container & CPU Threshold Settings" icon="gear">
    The following container & CPU threshold settings are available for configuration:

    <Info>CPU thresholds are expressed as a number between 0 and 1, reflecting the actual percentage usage of your container's CPU limit. For instance, 2% usage with a 12.5% limit equals 16%, or 0.16.</Info>

    *   **Percentile**: Determines the percentile for evaluating RAM and CPU usage.
    *   **Minimum Container Count**: Sets the lowest container count to which the service can be scaled down by Autoscaler.
    *   **Maximum Container Count**: Sets the highest container count to which the service can be scaled up to by Autoscaler.
    *   **Scale Up Steps**: Sets the amount of containers to add when autoscaling (ex: a value of 2 will go from 1->3->5). Container count will never exceed the configured maximum.
    *   **Scale Down Steps**: Sets the amount of containers to remove when autoscaling (ex: a value of 2 will go from 4->2->1). Container count will never exceed the configured minimum.
    *   **Scale Down Threshold (CPU Usage)**: Specifies the percentage of the current CPU usage at which an up-scaling action is triggered.
    *   **Scale Up Threshold (CPU Usage)**: Specifies the percentage of the current CPU usage at which a down-scaling action is triggered.
  </Accordion>

  <Accordion title="Time-Based Settings" icon="gear">
    The following time-based settings are available for configuration:

    *   **Metrics Lookback Time Interval**: The duration in seconds for retrieving past performance metrics.
    *   **Post Scale Up Cooldown**: The waiting period in seconds after an automated scale-up before another scaling action can be considered.
    *   **Post Scale Down Cooldown**: A defined interval in seconds to pause after an automated scale-down, before evaluating the possibility of further scaling actions.
    *   **Post Release Cooldown**: The time in seconds to wait following any general scaling operation, allowing stabilization before considering additional scaling changes.
  </Accordion>
</AccordionGroup>

# Vertical Scaling

Scale Apps vertically by changing the size of Containers, i.e., changing their [Memory Limits](/core-concepts/scaling/memory-limits) and [CPU Limits](/core-concepts/scaling/container-profiles). The available sizes are determined by the [Container Profile.](/core-concepts/scaling/container-profiles)

### Manual Vertical Scaling

App Services can be manually scaled via the Dashboard or [`aptible apps:scale`](https://www.aptible.com/docs/reference/aptible-cli/cli-commands/cli-apps-scale) CLI command. Example:

```
    aptible apps:scale SERVICE [--container-size SIZE_MB]
```

### Vertical Autoscaling

<Frame>
  ![Vertical Autoscaling](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/vertical-autoscale.png)
</Frame>

<Info>Vertical Autoscaling is only available on the [Enterprise plan.](https://www.aptible.com/pricing)</Info>

When Vertical Autoscaling is enabled on a Service, the autoscaler also evaluates services every 5 minutes and generates scaling recommendations based:

*   RSS usage in GB divided by the CPU
*   RSS usage levels

Data is analyzed over a 30-minute lookback period. Post-scaling cooldowns are 5 minutes for scaling down and 1 minute for scaling up. An additional 5-minute cooldown applies after a service release. Metrics are evaluated at the 99th percentile aggregated across all of the service containers over the past 30 minutes.

#### Configuration Options

<AccordionGroup>
  <Accordion title="RAM & CPU Threshold Settings" icon="gear">
    The following RAM & CPU Threshold settings are available for configuration:

    *   **Percentile**: Determines the percentile for evaluating RAM and CPU usage.
    *   **Minimum Memory (MB)**: Sets the lowest memory limit to which the service can be scaled down by Autoscaler.
    *   **Maximum Memory (MB)**: Defines the upper memory threshold, capping the maximum memory allocation possible through Autoscaler. If blank, the container can scale to the largest size available.
    *   **Memory Scale Up Percentage**: Specifies the percentage of the current memory limit at which the service's memory usage triggers an up-scaling action.
    *   **Memory Scale Down Percentage**: Determines the percentage of the next lower memory limit that, when reached or exceeded by memory usage, initiates a down-scaling action.
    *   **Memory Optimized Memory/CPU Ratio Threshold**: Establishes the ratio of Memory (in GB) to CPU (in CPUs) at which values exceeding the threshold prompt a shift to an R (Memory Optimized) profile.
    *   **Compute Optimized Memory/CPU Ratio Threshold**: Sets the Memory-to-CPU ratio threshold, below which the service is transitioned to a C (Compute Optimized) profile.
  </Accordion>

  <Accordion title="Time-Based Settings" icon="gear">
    The following time-based settings are available for configuration:

    *   **Metrics Lookback Time Interval**: The duration in seconds for retrieving past performance metrics.
    *   Post Scale Up Cooldown: The waiting period in seconds after an automated scale-up before another scaling action can be considered.
    *   **Post Scale Down Cooldown**: A defined interval in seconds to pause after an automated scale-down, before evaluating the possibility of further scaling actions.
    *   **Post Release Cooldown**: The time in seconds to wait following any general scaling operation, allowing stabilization before considering additional scaling changes.
  </Accordion>
</AccordionGroup>

***

# FAQ

<AccordionGroup>
  <Accordion title="How do I scale my apps and services?">
    See our guide here for [How to scale apps and services](https://www.aptible.com/docs/how-to-guides/app-guides/how-to-scale-apps-services)
  </Accordion>

  <Accordion title="How can I get access to autoscaling?">
    Contact Aptible Support to request access!
  </Accordion>
</AccordionGroup>


# Container Profiles

Learn about using Container Profiles to optimize spend and performance

# Overview

<Info> CPU and RAM Optimized Container Profiles are only available on [Production and Enterprise plans.](https://www.aptible.com/pricing) </Info>

Container Profiles provide flexibility and cost-optimization by allowing users to select the workload-appropriate Profile. Aptible offers three Container Profiles with unique CPU-to-RAM ratios and sizes:

*   **General Purpose:** The default Container Profile, which works well for most use cases.
*   **CPU Optimized:** For CPU-constrained workloads, this Profile provides high-performance CPUs and more CPU per GB of RAM.
*   **RAM Optimized:** For memory-constrained workloads, this Profile provides more RAM for each CPU allocated to the Container.

The General Purpose Container Profile is available by default on all [Stacks](/core-concepts/architecture/stacks). Whereas CPU and RAM Optimized Container Profiles are only available on [Dedicated Stacks.](/core-concepts/architecture/stacks#dedicated-stacks)

All new Apps & Databases are default created with the General Purpose Container Profile. This applies to [Database Backups](/core-concepts/managed-databases/managing-databases/database-backups) and [Database Replicas.](/core-concepts/managed-databases/managing-databases/replication-clustering)

# Specifications per Container Profile

| Container Profile | Default | Available Stacks   | CPU:RAM Ratio   | RAM per CPU | Container Sizes | Cost           |
| ----------------- | ------- | ------------------ | --------------- | ----------- | --------------- | -------------- |
| General Purpose   | ✔️      | Shared & Dedicated | 1/4 CPU:1GB RAM | 4GB/CPU     | 512MB-240GB     | \$0.08/GB/Hour |
| RAM Optimized     |         | Dedicated          | 1/8 CPU:1GB RAM | 8GB/CPU     | 4GB-752GB       | \$0.05/GB/Hour |
| CPU Optimized     |         | Dedicated          | 1/2 CPU:1GB RAM | 2GB/CPU     | 2GB-368GB       | \$0.10/GB/Hour |

# Supported Availability Zones

It is important to note that not all container profiles are available in every AZ, whether for app or database containers.
In the event that this occurs during a scaling operation:

*   **App Containers:** Aptible will handle the migration of app containers to an AZ that supports the desired container
    profile seamlessly and with zero downtime, requiring no additional action from the user.
*   **Database Containers:** However, for database containers, Aptible will prevent the scaling operation and log an error
    message, indicating that it is necessary to move the database to a new AZ that supports the desired container profile.
    This process requires a full disk backup and restore but can be easily accomplished using Aptible's 1-click "Database
    Restart + Backup + Restore.” It is important to note that this operation will result in longer downtime and completion
    time than typical scaling operations. For more information on resolving this error, including expected downtime, please
    refer to our troubleshooting guide.

# FAQ

<Accordion title="How do I modify the Container Profile for an App or Database?">
  Container Profiles can only be modified from the Aptible Dashboard when scaling the app/service or database.  The Container Profile will take effect upon restart.

  ![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/Container-Profiles-2.png)
</Accordion>


# CPU Allocation



Learn how Aptible effectively manages CPU allocations to maximize performance and reliability

# Overview

Scaling up resources in Aptible directly increases the guaranteed CPU Allocation for a container. However, containers can sometimes burst above their CPU allocation if the underlying infrastructure host has available capacity. For example, if a container is scaled to a 4GB general-purpose container, it would have a 1 vCPU allocation or 100% CPU utilization in our metrics. You may see in your metrics graph that the CPU utilization bursts to higher values, like 150% or higher. This burst capability was allowed because the infrastructure host had excess capacity, which is not guaranteed. At other times, if your CPU metrics are flattening out at a usage of 100%, it likely signifies that the container(s) are being prevented from using more than their allocation because excess capacity is unavailable.

It's important to note that users cannot view the full CPU capacity of the host, so users must consider metric drains to monitor and alert on CPU usage to ensure that app services have adequate CPU allocation. To ensure a higher guaranteed CPU allocation, you must scale your resources.

# Modifying CPU Allocation

The guaranteed CPU Allocation can be increased or decreased by vertical scaling. See: [App Scaling](/core-concepts/scaling/app-scaling) or [Database Scaling](/core-concepts/scaling/database-scaling) for more information on vertical scaling.


# Database Scaling

Learn about scaling Databases CPU, RAM, IOPS and throughput

# Overview

Scaling your Databases on Aptible is straightforward and efficient. You can scale Database from the Dashboard, CLI, or Terraform to adjust your database resources like CPU, RAM, IOPS, and throughput, and Aptible ensures appropriate hardware is provisioned. All Database scaling operations are performed with **minimal downtime**, typically less than one minute.

## Vertical Scaling

Scale Databases vertically by changing the size of Containers, i.e., changing the [Memory Limits](/core-concepts/scaling/memory-limits) and [CPU Limits](/core-concepts/scaling/container-profiles). The available sizes are determined by the [Container Profile.](/core-concepts/scaling/container-profiles)

## Horizontal Scaling

While Databases cannot be scaled horizontally by adding more Containers, horizontal scaling can be achieved by setting up database replication and clustering. Refer to [Database Replication and Clustering](/core-concepts/managed-databases/managing-databases/replication-clustering) for more information.

## Disk Scaling

Database Disks can be scaled up to 16384GB. Database Disks can be resized at most once a day and can only be resized up (i.e., you cannot shrink your Database Disk).

If you do need to scale Database Disk down, you can either dump and restore to a smaller Database or create a replica and failover. Refer to our [Supported Databases](/core-concepts/managed-databases/supported-databases/overview) documentation to see if replication and failover is supported for your Database type.

## IOPS Scaling

Database IOPS can be scaled with no downtime. Database IOPS can only be scaled using the [`aptible db:modify`](/reference/aptible-cli/cli-commands/cli-db-modify) command. Refer to [Database Performance Tuning](/core-concepts/managed-databases/managing-databases/database-tuning#database-iops-performance) for more information.

## Throughput performance

All new Databases are provisioned with GP3 volume, with a default throughput performance of 125MiB/s. This can be scaled up to 1,000MiB/s by contacting [Aptible Support](/how-to-guides/troubleshooting/aptible-support). Refer to [Database Performance Tuning](/core-concepts/managed-databases/managing-databases/database-tuning#database-throughput-performance) for more information.

# FAQ

<AccordionGroup>
  <Accordion title="Is there downtime from scaling a Database?">
    Yes, all Database scaling operations are performed with **minimal downtime**, typically less than one minute.
  </Accordion>

  <Accordion title="How do I scale a Database">
    See related guide:

    <Card title="How to scale Databases" icon="book-open-reader" iconType="duotone" href="https://www.aptible.com/docs/scale-databases" />
  </Accordion>
</AccordionGroup>


# Memory Management

Learn how Aptible enforces memory limits to ensure predictable performance

# Overview

Memory limits are enforced through a feature called Memory Management.

When memory management is enabled on your infrastructure and a Container exceeds its memory allocation, the following happens:

1.  Aptible sends a log message to your [Log Drains](/core-concepts/observability/logs/log-drains/overview) (this includes [`aptible logs`](/reference/aptible-cli/cli-commands/cli-logs)) indicating that your Container exceeded its memory allocation, and dumps a list of the processes running in your Container for troubleshooting purposes.
2.  If there is free memory on the instance, Aptible increases your Container's memory allowance by 10%. This gives your Container a better shot at exiting cleanly.
3.  Aptible delivers a `SIGTERM` signal to all the processes in your Container, and gives your Container 10 seconds to exit. If your Container does not exit within 10 seconds, Aptible delivers a `SIGKILL` signal, effectively terminating all the processes in your Container immediately.
4.  Aptible triggers [Container Recovery](/core-concepts/architecture/containers/container-recovery) to restart your Container.

The [Metrics](/core-concepts/observability/metrics/overview) you see in the Dashboard are captured every minute. If your Container exceeds its RAM allocation very quickly and then is restarted, **the metrics you see in the Dashboard may not reflect the usage spike**.
As such, it's a good idea to refer to your logs as the authoritative source of information to know when you're exceeding your memory allocation.
Indeed, whenever your Containers are restarted, Aptible will log this message to all your [Log Drains](/core-concepts/observability/logs/log-drains/overview):

```
container exceeded its memory allocation
```

This message will also be followed by a snapshot of the memory usage of all the processes running in your Container, so you can identify memory hogs more easily.

Here is an example. The column that shows RAM usage is `RSS`, and that usage is expressed in kilobytes.

```
           PID    PPID      VSZ      RSS  STAT    COMMAND
          2688    2625      820       36  S       /usr/lib/erlang/erts-7.3.1/bin/epmd -daemon
          2625     914     1540      936  S       /bin/sh -e /srv/rabbitmq_server-3.5.8/sbin/rabbitmq-server
         13255     914     6248      792  S       /bin/bash
          2792    2708      764       12  S       inet_gethost 4
          2793    2792      764       44  S       inet_gethost 4
          2708    2625  1343560  1044596  S       /usr/lib/erlang/erts-7.3.1/bin/beam.smp [...]
```

## Understanding Memory Utilization

There are two main categories of memory on Linux: RSS and caches.

In Metrics on Aptible, RSS is published as an individual metric, and the sum of RSS + caches (i.e. total memory usage) is published as a separate metric.

It's important to understand the difference between RSS and Caches when optimizing against memory limits.

At a high level, RSS is memory that is allocated and used by your App or Database, and caches represent memory that is used by the operating system (Linux) to make your App or Database faster. In particular, caches are used to accelerate disk access.

If your container approaches its memory limit, the host system will attempt to reclaim some memory from your Container or terminate it if that's not possible. Memory used for caches can usually be reclaimed, whereas anonymous memory and memory-mapped files (RSS) usually cannot.

When monitoring memory usage, you should make sure RSS never approaches the memory limit. Crossing the limit would result in your Containers being restarted. For Databases, you should also usually ensure a decent amount of memory is available to be used for caches by the operating system.

In practice, you should normally ensure RSS does not exceed about \~70% of the memory limit. That said, this advice is very Database dependent: for [PostgreSQL](/core-concepts/managed-databases/supported-databases/postgresql), 30% is a better target, and for [Elasticsearch](/core-concepts/managed-databases/supported-databases/elasticsearch), 50% is a good target.

However, Linux allocates caches very liberally, so don't be surprised if your Container is using a lot of memory for caches. In fact, for a Database, cache usage will often cause your total memory usage to equal 100% of your memory limit: that's expected.

# Memory Limits FAQ

**What should my app do when it receives a `SIGTERM` from Aptible?**

Your app should try and exit gracefully within 10 seconds.

If your app is processing background work, you should ideally try and push it back to whatever queue it came from.

**How do I know the memory usage for a Container?**

See [Metrics](/core-concepts/observability/metrics/overview).

**How do I know the memory limit for a Container?**

You can view the current memory limit for any Container by looking at the Container's [Metrics](/core-concepts/observability/metrics/overview) in your Dashboard: the memory limit is listed right next to your current usage.

Additionally, Aptible sets the `APTIBLE_CONTAINER_SIZE` environment variable when starting your Containers. This indicates your Container's memory limit, in MB.

**How do I increase the memory limit for a Container?**

See [Scaling](/core-concepts/scaling/overview).


# Scaling - Overview

Learn more about scaling on-demand without worrying about any underlying configurations or capacity availability

# Overview

The Aptible platform simplifies the process of on-demand scaling, removing the complexities of underlying configurations and capacity considerations. With customizable container profiles, Aptible enables precise resource allocation, optimizing both performance and cost-efficiency.

# Learn more about scaling resources on Aptible

<CardGroup cols={3}>
  <Card title="App Scaling" icon="book" iconType="duotone" href="https://www.aptible.com/docs/core-concepts/scaling/app-scaling" />

  <Card title="Database Scaling" icon="book" iconType="duotone" href="https://www.aptible.com/docs/core-concepts/scaling/database-scaling" />

  <Card title="Container Profiles" icon="book" iconType="duotone" href="https://www.aptible.com/docs/core-concepts/scaling/container-profiles" />

  <Card title="CPU Allocation" icon="book" iconType="duotone" href="https://www.aptible.com/docs/core-concepts/scaling/cpu-isolation" />

  <Card title="Memory Management" icon="book" iconType="duotone" href="https://www.aptible.com/docs/core-concepts/scaling/memory-limits" />
</CardGroup>

# FAQ

<AccordionGroup>
  <Accordion title="Does Aptible offer autoscaling functionality?">
    Currently, Aptible is offering [Vertical Autoscaling for Apps for Enterprise Plans](https://www.aptible.com/docs/core-concepts/scaling/app-scaling#vertical-autoscaling) and [Horizontial Autoscaling](https://www.aptible.com/docs/core-concepts/scaling/app-scaling#horizontal-autoscaling) in limited release.
    Contact Aptible Support to request early access.
  </Accordion>
</AccordionGroup>


# Roles & Permissions



# Organization

Aptible organizations represent an administrative domain consisting of users and resources.

# Users

Users represent individuals or robots with access to your organization. A user's assigned roles determine their permissions and what they can access Aptible. Manage users in the Aptible dashboard by navigating to Settings > Members.

<Frame>
  ![Managing Members](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/org-members.png)
</Frame>

# Roles

Use roles to define users' access in your Aptible organization. Manage roles in the Aptible Dashboard by navigating to Settings > Roles.

<Frame>
  ![Role Management](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/role-mgmt.png)
</Frame>

## Types of Roles

### Account Owners

The Account Owners Role is one of the built-in roles in your organization that grants the following:

*   admin access to all resources
*   access to [billing information](/core-concepts/billing-payments) such as invoices, projections, plans, and contracts
*   the ability to invite users
*   the ability to manage all Roles
*   the ability to remove all users from the organization

### Aptible Deploy Owners

The Deploy Owners Role is one of the built-in roles in your organization that grants the following:

*   admin access to all resources
*   the ability to invite users
*   the ability to manage the Aptible Deploy Owners Role and Custom Roles
*   the ability to remove users within Aptible Deploy Owners Role and/or Custom Roles from the organization

### Custom Roles

Use custom roles to configure which Aptible environments a user can access and what permissions they have within those environments. Aptible provides many permission types so you can fine-tune user access.

Since roles define what environments users can access, we highly recommend using multiple environments and roles to ensure you are granting access based on [the least-privilege principle](https://csrc.nist.gov/glossary/term/least_privilege).

#### Custom Role Admin

The Custom Role Admin role is an optional role that grants:

*   access to resources as defined by the permission types of their custom role
*   the ability to add new users to the custom roles of which they are role admins

<Frame>
  ![Edit role admins](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/role-members.png)
</Frame>

#### Custom Role Members

Custom Role Members have access to resources as defined by the permission types of their custom role.

#### Custom Role Permissions

Manage custom role permission types in the Aptible Dashboard by navigating to Settings > Roles. Select the respective role, navigate to Environments, and grant the desired permissions for the separate environments.

<Frame>
  ![Edit permissions](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/role-env-perms-edit.png)
</Frame>

#### Read Permissions

Assign one of the following permissions to give users read permission in a specific environment:

*   **Basic Visibility**: can read general information about all resources
*   **Full Visibility (formerly Read)**: can read general information about all resources and app configurations

#### Write Permissions

To give users write permission to a given environment, you can assign the following permissions:

*   **Environment Admin** (formerly Write): can perform all actions listed below within the environment
*   **Deployment**: can create and deploy resources
*   **Destruction**: can destroy resources
*   **Ops**: can create and manage log and metric drains and restart and scale apps and databases
*   **Sensitive Access**:  can view and manage sensitive values such as app configurations, database credentials, and endpoint certificates
*   **Tunnel**: can tunnel into databases but cannot view database credentials

<Tip> Provide read-only database access by granting the Tunnel permission without the Sensitive Access permission. Use this to manage read-only database access within the database itself.</Tip>

#### Full Permission Type Matrix

This matrix describes the required permission (header) for actions available for a given resource(left column).

|                                | Environment Admin | Full Visibility | Deployment | Destruction | Ops | Sensitive Access | Tunnel |
| :----------------------------: | :---------------: | :-------------: | :--------: | :---------: | :-: | :--------------: | ------ |
|           Environment          |        ---        |       ---       |     ---    |     ---     | --- |        ---       | ---    |
|           Deprovision          |         ✔         |                 |            |      ✔      |     |                  |        |
|             Rename             |         ✔         |                 |            |             |     |                  |        |
| Manage Backup Retention Policy |         ✔         |                 |            |             |     |                  |        |
|              Apps              | Environment Admin | Full Visibility | Deployment | Destruction | Ops | Sensitive Access | Tunnel |
|             Create             |         ✔         |                 |      ✔     |             |     |         ✔        |        |
|           Deprovision          |         ✔         |                 |            |      ✔      |     |                  |        |
|       Read Configuration       |         ✔         |        ✔        |            |             |     |         ✔        |        |
|            Configure           |         ✔         |                 |      ✔     |             |     |         ✔        |        |
|             Rename             |         ✔         |                 |      ✔     |             |     |                  |        |
|             Deploy             |         ✔         |                 |      ✔     |             |     |                  |        |
|             Rebuild            |         ✔         |                 |      ✔     |             |     |                  |        |
|              Scale             |         ✔         |                 |      ✔     |             |  ✔  |                  |        |
|             Restart            |         ✔         |                 |      ✔     |             |  ✔  |                  |        |
|        Create Endpoints        |         ✔         |                 |      ✔     |             |     |                  |        |
|      Deprovision Endpoints     |         ✔         |                 |            |      ✔      |     |                  |        |
|           Stream Logs          |         ✔         |                 |      ✔     |             |  ✔  |                  |        |
|           SSH/Execute          |         ✔         |                 |            |             |     |         ✔        |        |
|           Scan Image           |         ✔         |                 |      ✔     |             |  ✔  |                  |        |
|            Databases           | Environment Admin | Full Visibility | Deployment | Destruction | Ops | Sensitive Access | Tunnel |
|             Create             |         ✔         |                 |      ✔     |             |     |                  |        |
|           Deprovision          |         ✔         |                 |            |      ✔      |     |                  |        |
|        Read Credentials        |         ✔         |                 |            |             |     |         ✔        |        |
|         Create Backups         |         ✔         |                 |      ✔     |             |  ✔  |                  |        |
|         Restore Backups        |         ✔         |                 |      ✔     |             |     |                  |        |
|         Delete Backups         |         ✔         |                 |            |      ✔      |     |                  |        |
|             Rename             |         ✔         |                 |      ✔     |             |     |                  |        |
|    Restart / Reload / Modify   |         ✔         |                 |      ✔     |             |  ✔  |                  |        |
|         Create Replicas        |         ✔         |                 |      ✔     |             |     |                  |        |
|         Unlink Replicas        |         ✔         |                 |            |      ✔      |     |                  |        |
|        Create Endpoints        |         ✔         |                 |      ✔     |             |     |                  |        |
|      Deprovision Endpoints     |         ✔         |                 |            |      ✔      |     |                  |        |
|         Create Tunnels         |         ✔         |                 |            |             |     |                  | ✔      |
|           Stream Logs          |         ✔         |                 |      ✔     |             |  ✔  |                  |        |
|      Log and Metric Drains     | Environment Admin | Full Visibility | Deployment | Destruction | Ops | Sensitive Access | Tunnel |
|             Create             |         ✔         |                 |      ✔     |             |  ✔  |                  |        |
|           Deprovision          |         ✔         |                 |      ✔     |      ✔      |  ✔  |                  |        |
|        SSL Certificates        | Environment Admin | Full Visibility | Deployment | Destruction | Ops | Sensitive Access | Tunnel |
|             Create             |         ✔         |                 |            |             |     |         ✔        |        |


# Password Authentication



Users can use password authentication as one of the authentication methods to access Aptible resources via the Dashboard and CLI.

# Requirements

Passwords must:

1.  be at least 10 characters, and no more than 72 characters.
2.  contain at least one uppercase letter (A-Z).
3.  contain at least one lowercase letter (a-z).
4.  include at least one digit or special character (^0-9!@#\$%^&\*()).

Aptible uses [Have I Been Pwned](https://haveibeenpwned.com) to implement a denylist of known compromised passwords.

# Account Lockout Policies

Aptible locks out users if there are:

1.  10 failed attempts in 1 minute
2.  20 failed attempts in 1 hour
3.  40 failed attempts in 1 day.

Aptible monitors for repeat unsuccessful login attempts and notifies customers of any such repeat attempts that may signal an account takeover attempt. For granular control over login data, such as reviewing every login from your team members, set up [SSO](/core-concepts/security-compliance/authentication/sso) using a SAML provider, and [require SSO](/core-concepts/security-compliance/authentication/sso#require-sso-for-access) for accessing Aptible.

# 2-Factor Authentication (2FA)

Regardless of SSO usage or requirements, Aptible strongly recommends using 2FA to protect your Aptible account and all other sensitive internet accounts.

## Enrollment

Users can enable 2FA Authentication in the Dashboard by navigating to Settings > Security Settings > Configure 2FA.

## Supported Protocols

Aptible supports:

1.  software second factors via the TOTP protocol. We recommend using [Google Authenticator](https://support.google.com/accounts/answer/1066447?hl=en) as your TOTP client
2.  hardware second factors via the FIDO protocol.

## Scope

When enabled, 2FA protects access to your Aptible account via the Dashboard, CLI, and API. 2FA does not restrict Git pushes - these are still authenticated with [SSH Public Keys](/core-concepts/security-compliance/authentication/ssh-keys). Sometimes, you may not push code with your user credentials, for example, if you deploy with a CI service such as Travis or Circle that performs all deploys via a robot user. If so, we encourage you to remove SSH keys from your Aptible user account.

Aptible 2FA protects logins, not individual requests. Making authenticated requests to the Aptible API is a two-step process:

1.  generate an access token using your credentials
2.  use that access token to make requests

2FA protects the first step. Once you have an access token, you can make as many requests as you want to the API until that token expires or is revoked.

## Recovering Account Access

Account owners can [reset 2FA for all other users](/how-to-guides/platform-guides/reset-aptible-2fa), including other account owners, but cannot reset their own 2FA.

## Auditing

[Organization](/core-concepts/security-compliance/access-permissions) administrators can audit 2FA enrollment via the Dashboard by navigating to Settings > Members.


# Provisioning (SCIM)

Learn about configuring Cross-domain Identity Management (SCIM) on Aptible

<Frame> ![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/scim-app-ui.png) </Frame>

## Overview

Aptible has implemented **SCIM 2.0** (System for Cross-domain Identity Management) to streamline the management of user identities across various systems. This implementation adheres closely to [RFC 7643](https://datatracker.ietf.org/doc/html/rfc7643), ensuring standardized communication and data exchange. SCIM 2.0 simplifies provisioning by automating the processes for creating, updating, and deactivating user accounts and managing roles within your organization. By integrating SCIM, Aptible enhances your ability to manage user data efficiently and securely across different platforms.

## How-to Guides

We offer detailed guides to help you set up provisioning with your Identity Provider (IdP). These guides cover the most commonly used providers:

*   [Aptible Provisioning with Okta](/how-to-guides/platform-guides/scim-okta-guide)
*   [Aptible Provisioning with Entra ID (formerly Azure AD)](/how-to-guides/platform-guides/scim-entra-guide)

These resources will walk you through the steps necessary to integrate SCIM with your preferred provider, ensuring a seamless and secure setup.

## Provisioning FAQ

### How Does SCIM Work?

SCIM (System for Cross-domain Identity Management) is a protocol designed to simplify user identity management across various systems. It enables automated processes for creating, updating, and deactivating user accounts. The main components of SCIM include:

1.  **User Provisioning**: Automates the creation, update, and deactivation of user accounts.
2.  **Group Management**: Manages roles (referred to as "Groups" in SCIM) and permissions for users.
3.  **Attribute Mapping**: Synchronizes user attributes consistently across systems.
4.  **Secure Token Exchange**: Utilizes OAuth bearer tokens for secure authentication and authorization of SCIM API calls.

### How long is a SCIM token valid for Aptible?

A SCIM token is valid for one year. After the year, if it expires, you will receive an error in your IDP indicating that your token is invalid.

![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/scim-token-invalid.png)

### Aptible Does Not Seem to Support Groups but Roles Instead. How Does That Work with SCIM?

Aptible leverages **Roles** instead of **Groups**. Despite this, the functionality is similar, and SCIM Groups are mapped to Aptible Roles. This mapping ensures that permissions and access controls are maintained consistently.

### What Parts of the SCIM Specifications Aren't Included in Aptible's SCIM Implementation?

Aptible aims to continually enhance support for SCIM protocol components. However, some parts are not currently implemented:

1.  **Search Queries Using POST**: Searching for resources using POST requests is not supported.
2.  **Bulk Operations**: Bulk operations for creating, updating, or deleting resources are not supported.
3.  **/Me Endpoint**: Accessing the authenticated user's information via the /Me endpoint is not supported.
4.  **/Schemas Endpoint**: Retrieving metadata about resource types via the /Schemas endpoint is not supported.
5.  **/ServiceProviderConfig Endpoint**: Accessing service provider configuration details via the /ServiceProviderConfig endpoint is not supported.
6.  **/ResourceTypes Endpoint**: Listing supported resource types via the /ResourceTypes endpoint is not supported.

### How Much Support is Required for Filtering Results?

While the SCIM protocol supports extensive filtering capabilities, Aptible's primary use case for filtering is straightforward. Aptible checks if a newly created user or group exists in your application based on a matching identifier. Therefore, supporting the `eq` (equals) operator is sufficient.

### I am connecting to an account with users who are already set up. How Does SCIM Behave?

When integrating SCIM with an account that already has users, SCIM will:

1.  **Match Existing Users**: It will identify existing users based on their unique identifier (email) and update their information if needed rather than creating new accounts.
2.  **Create New Users**: If a user does not exist, SCIM will create a new account with the specified attributes and assign the default role (referred to as "Group" in SCIM).
3.  **Role Assignments**: Newly created users will receive the default role. Existing role assignments for users already in the system will not be altered. SCIM will not remove or change existing roles.

### How Do I Correctly Disable SCIM and Retain a Clean Data Set?

To disable SCIM and manage the associated data within your Aptible Organization:

1.  **Retaining Created Roles and Users**: If you want to keep the roles and users created by SCIM, simply disable SCIM as an Aptible Organization owner. This action will remove the SCIM association but leave the created users and roles intact.

2.  **Removing SCIM-Created Data**: If you wish to remove users and roles created by SCIM, begin by unassigning any users and roles in your Identity Provider (IDP) that were created via SCIM. This action will soft delete these objects from your Aptible Organization. After all assignments have been removed, you can then deactivate the SCIM integration, ensuring a clean removal of all associated data.

### What authentication methods are supported by the Aptible SCIM API?

Aptible's SCIM implementation uses the **OAuth 2.0 Authorization Code grant flow** for authentication. It does not support the Client Credentials or Resource Owner Password Credentials grant flows. The Authorization Code grant flow is preferred for SaaS and cloud integrations due to its enhanced security.

### What is Supported by Aptible?

Aptible's SCIM implementation includes the following features:

1.  **User Management**: Automates the creation, update, and deactivation of user accounts.
2.  **Role Management (Groups)**: This function assigns newly created users the specified default role (referred to as "Groups" in SCIM).
3.  **Attribute Synchronization**: Ensures user attributes are consistently synchronized across systems.
4.  **Secure Authentication**: Uses OAuth bearer tokens for secure SCIM API calls.
5.  **Email as Unique Identifier**: Uses email as the unique identifier for validating and matching user data.

### I see you have guides for Identity Providers, but mine is not included. What should I do?

Aptible follows the SCIM 2.0 guidelines, so you should be able to integrate with us as long as the expected attributes are correctly mapped.

> 📘 Note We cannot guarantee the operation of an integration that has not been tested by Aptible. Proceeding with an untested integration is at your own risk.

**Required Attributes:**

*   **`userName`**: The unique identifier for the user, essential for correct user identification.
*   **`displayName`**: The name displayed for the user, typically their full name; used in interfaces and communications.
*   **`active`**: Indicates whether the user is active (`true`) or inactive (`false`); crucial for managing user access.
*   **`externalId`**: A unique identifier used to correlate the user across different systems; helps maintain consistency and data integrity.

**Optional but recommended Attributes:**

*   **`givenName`**: The user's first name; can be used as an alternative in conjunction with familyName to `displayName`.
*   **`familyName`**: The user's last name; also serves as an alternative in conjunction with givenName to `displayName`.

**Supported Operations**

*   **Sorting**: Supports sorting by `userName`, `id`, `meta.created`, and `meta.lastModified`.
*   **Pagination**: Supports `startIndex` and `count` for controlled data fetching.
*   **Filtering**: Supports basic filtering; currently limited to the `userName` attribute.

By ensuring these attributes are mapped correctly, your Identity Provider should integrate seamlessly with our system.

### Additional Notes

*   SCIM operations ensure that existing user data and role assignments are not disrupted unless explicitly updated.
*   Users will only be removed if they are disassociated from SCIM on the IDP side; they will not be removed by simply disconnecting SCIM, ensuring safe user account management.
*   Integrating SCIM with Aptible allows for efficient and secure synchronization of user data across your identity management systems.

For more detailed instructions on setting up SCIM with Aptible, please refer to the [Aptible SCIM documentation](#) or contact support for assistance.


# SSH Keys

Learn about using SSH Keys to authenticate with Aptible

## Overview

Public Key Authentication is a secure method for authentication, and how Aptible authenticates deployments initiated by pushing to an [App](/core-concepts/apps/overview)'s [Git Remote](/how-to-guides/app-guides/deploy-from-git#git-remote). You must provide a public SSH key to set up Public Key Authentication.

<Warning> If SSO is enabled for your Aptible organization, attempts to use the git remote will return an `App not found or not accessible` error. Users must be added to the [allowlist](/core-concepts/security-compliance/authentication/sso#exempt-users-from-sso-requirement) to access your Organization's resources via Git. </Warning>

## Supported SSH Key Types

Aptible supports the following SSH key types:

*   ssh-rsa

*   ssh-ed25519

*   ssh-dss

## Adding/Managing SSH Keys

<Frame>![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/1-SSHKeys.png)</Frame>

If you [don't already have an SSH Public Key](https://docs.github.com/en/authentication/connecting-to-github-with-ssh/checking-for-existing-ssh-keys), generate a new SSH key using this command:

```
ssh-keygen -t ed25519 -C "your_email@example.com"
```

If you are using a legacy system that doesn't support the Ed25519 algorithm, use the following:

```
shell ssh-keygen -t rsa -b 4096 -C "you@example.com"
```

Once you have generated your SSH key, follow these steps:

1.  In the Aptible dashboard, select the Settings option on the bottom left.

2.  Select the SSH Keys option under Account Settings.

3.  Reconfirm your credentials by entering your password on the page that appears.

4.  Follow the instructions for copying your Public SSH Key in Step 1 listed on the page.

5.  Paste your Public SSH Key in the text box located in Step 2 listed on the page.

# Featured Troubleshooting Guides

<Card title="git Push Permission Denied" icon="book-open-reader" iconType="duotone" href="https://www.aptible.com/docs/permission-denied-git-push" />


# Single Sign-On (SSO)



<Frame> ![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/SSO-app-ui.png) </Frame>

# Overview

<Info> SSO/SAML is only available on [Production and Enterprise](https://www.aptible.com/pricing)[ plans.](https://www.aptible.com/pricing)</Info>

Aptible provides Single Sign On (SSO) to an [organization's](/core-concepts/security-compliance/access-permissions) resources through a separate, single authentication service, empowering customers to manage Aptible users from their primary SSO provider or Identity Provider (IdP).

Aptible supports the industry-standard SAML 2.0 protocol for using an external provider. Most SSO Providers support SAML, including Okta and Google's GSuite. SAML provides a secure method to transfer identity and authentication information between the SSO provider and Aptible.

Each organization may have only one SSO provider configured. Many SSO providers allow for federation with other SSO providers using SAML. For example, allowing Google GSuite to provide login to Okta. If you need to support multiple SSO providers, you can use federation to enable login from the other providers to the one configured with Aptible.

<Card title="How to setup Single Sign-On (SSO)" icon="book-open-reader" iconType="duotone" href="https://www.aptible.com/docs/sso-setup" />

## Organization Login ID

When you complete [Single Sign On Provider Setup](/how-to-guides/platform-guides/setup-sso), your [organization's](/core-concepts/security-compliance/access-permissions) users can use the SSO link on the [SSO login page](https://dashboard.aptible.com/sso/) to begin using the configured SSO provider. They must enter an ID unique to your organization to indicate which organization they want to access.

That ID defaults to a randomly assigned unique identifier. [Account owners](/core-concepts/security-compliance/access-permissions) may keep that identifier or set an easier-to-remember one on the SSO settings page. Your organization's primary email domain or company name makes a good choice. That identifier is to make login easier for users.

<Warning> Do not change your SSO provider configuration after changing the Login ID. The URLs entered in your SSO provider configuration should continue to use the long, unique identifier initially assigned to your organization. Changing the SSO provider configuration to use the short, human-memorable identifier will break the SSO integration until you restore the original URLs. </Warning>

You will have to distribute the ID to your users so they can enter it when needed. To simplify this, you can embed the ID directly in the URL. For example, `https://dashboard.aptible.com/sso/example_id`. Users can then bookmark or link to that URL to bypass the need to enter the ID manually. You can start the login process without knowing your organization's unique ID if your SSO provider has an application "dashboard" or listing.

## Require SSO for Access

When `Require SSO for Access` is enabled, Users can only access their [organization's](/core-concepts/security-compliance/access-permissions) resources by using your [configured SAML provider](/how-to-guides/platform-guides/setup-sso) to authenticate with Aptible. This setting aids in enforcing restrictions within the SSO provider, such as password rotation or using specific second factors.

Require SSO for Access will prevent users from doing the following:

*   [Users](/core-concepts/security-compliance/access-permissions) cannot log in using the Aptible credentials and still access the organization's resources.
*   [Users](/core-concepts/security-compliance/access-permissions) cannot use their SSH key to access the git remote.

Manage the Require SSO for Access setting in the Aptible Dashboard by selecting Settings > Single Sign-On.

<Warning> Before enforcing SSO, we recommend notifying all the users in your organization. SSO will be the only way to access your organization at that point. </Warning>

## CLI Token for SSO

To use the [Aptible CLI](/reference/aptible-cli/cli-commands/overview) with Require SSO for Access enabled, users must:

1.  Generate an SSO token.
    1.  In the Aptible Dashboard, select the user's profile on the top right and then "CLI Token for SSO," which will bring you to the [CLI Token SSO settings page.](https://dashboard.aptible.com/settings/cli-sso-token)
2.  Provide the token to the CLI via the [`aptible login --sso $SSO_TOKEN`](/reference/aptible-cli/cli-commands/cli-login) command.

### Invalidating CLI Token for SSO

1.  Tokens will be automatically invalidated once the selected duration elapses.
2.  Generating a new token will not invalidate older tokens.
3.  To invalidate the token generated during your current session, use the "Logout" button on the bottom left of any page.
4.  To invalidate tokens generated during other sessions, except your current session, navigate to Settings > Security > "Log out all sessions"

## Exempt Users from SSO Requirement

Users exempted from the Require SSO for Access setting can log in using Aptible credentials and access the organization's resources. Users can be exempt from this setting in two ways:

*   users with an Account Owner role are always exempt from this setting
*   users added to the SSO Allow List

The SSO Allow List will only appear in the SSO settings once `Require SSO for Access` is enabled.

We recommend restricting the number of Users exempt from the `Require SSO for Access` settings, but there are some use cases where it is necessary; some examples include:

*   to allow [users](/core-concepts/security-compliance/access-permissions) to use their SSH key to access the git remote
*   to give contributors (e.g., consultants or contractors) access to your Aptible account without giving them an account in your SSO provider
*   to grant "robot" accounts access to your Aptible account to be used in Continuous Integration/Continuous Deployment systems


# HIPAA

Learn about achieving HIPAA compliance on Aptible

<Check>
  <Tooltip tip="This compliance framework's infrastructure controls/requirements are automatically satisfied when you deploy to a Dedicated Stack. See details below for more information.">Compliance-Ready</Tooltip>
</Check>

# Overview

Aptible’s story began with a focus on serving digital health companies. As a result, the Aptible platform was designed with HIPAA compliance in mind. It automates and enforces all the necessary infrastructure security and compliance controls, ensuring the safe storage and processing of HIPAA-protected health information and more.

# Achieving HIPAA on Aptible

<Steps>
  <Step title="Provision a Dedicated Stack to run your resources">
    <Info> Dedicated Stacks are available on [Production and Enterprise plans](https://www.aptible.com/pricing).</Info>
    Dedicated Stacks live on isolated infrastructure and are designed to support deploying resources with higher requirements— such as HIPAA. Aptible automates and enforces **100%** of the necessary infrastructure security and compliance controls for HIPAA compliance.
  </Step>

  <Step title="Execute a HIPAA BAA with Aptible">
    When you request your first dedicated stack, an Aptible team member will reach out to coordinate the execution of a Business Associate Agreement (BAA).
  </Step>

  <Step title="Show off your compliance" icon="party-horn">
    <Frame>
      ![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/screenshot-ui.6e552b45.png)
    </Frame>

    The Security & Compliance Dashboard and reporting serves as a great resource for showing off HIPAA compliance. When a Dedicated Stack is provisioned, the HIPAA required controls will show as 100% - by default.

    <Accordion title="Understanding the HIPAA Readiness Score">
      The Health Insurance Portability and Accountability Act of 1996 (HIPAA) is a federal law that dictates US standards to protect sensitive patient health information from being disclosed without the patient’s consent or knowledge. The [US Department of Health and Human Services (HHS)](https://www.hhs.gov/hipaa/index.html) issued the HIPAA Privacy Rule to implement the requirements of HIPAA. The HIPAA Security Rule protects a subset of information covered by the Privacy Rule.

      The Aptible Security & Compliance Dashboard provides a HIPAA readiness score based on controls required for meeting the minimum standards of the regulation, labeled HIPAA Required, as well as addressable controls that are not required to meet the specifications of the regulation but are recommended as a good security practice, labeled HIPAA Addressable.

      ## HIPAA Required Score

      HIPAA prescribes certain implementation specifications as “required, “meaning you must implement the control to meet the regulation requirements. An example of such a specification is 164.308(a)(7)(ii)(A), requiring implemented procedures to create and maintain retrievable exact copies of ePHI. You can meet this specification with Aptible’s [automated daily backup creation and retention policy](/core-concepts/managed-databases/managing-databases/database-backups).

      The HIPAA Required score gives you a binary indicator of whether or not you’re meeting the required specifications under the regulation. By default, all resources hosted on a [Dedicated Stack](/core-concepts/architecture/stacks) meet the required specifications of HIPAA, so if you plan on processing ePHI, it’s a good idea to host your containers on a Dedicated Stack from day 1.

      ## HIPAA Addressable Score

      The HHS developed the concept of “addressable implementation specifications” to provide covered entities and business associates additional flexibility regarding compliance with HIPAA. In meeting standards that contain addressable implementation specifications, a covered entity or business associate will do one of the following for each addressable specification:

      *   Implement the addressable implementation specifications;
      *   Implement one or more alternative security measures to accomplish the same purpose;
      *   Not implement either an addressable implementation specification or an alternative.

      The HIPAA Addressable score tells you what percentage of infrastructure controls you have implemented successfully to meet relevant addressable specifications per HIPAA guidelines.
    </Accordion>

    Add a `Secured by Aptible` badge and link to the Secured by Aptible page to show all the security & compliance controls implemented..

    <Frame>
      ![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/hipaa1.png)
    </Frame>
  </Step>
</Steps>

# Keep Reading

<CardGroup cols={2}>
  <Card title="Read HIPAA Compliance Guide for Startups" icon="book" iconType="duotone" href="https://www.aptible.com/blog/hipaa-compliance-guide-for-startups">
    Gain a deeper understanding of HIPAA compliance
  </Card>

  <Card title="Explore HITRUST" icon="book" iconType="duotone" href="https://www.aptible.com/docs/core-concepts/security-compliance/compliance-frameworks/hitrust">
    Learn why Aptible is the leading platform for achieving HITRUST
  </Card>
</CardGroup>

***

# FAQ

<AccordionGroup>
  <Accordion title="How much does it cost to get started with HIPAA Compliance on Aptible?">
    To begin with HIPAA compliance on Aptible, the Production plan is required, priced at \$499 per month.

    This plan includes one dedicated stack, ensuring the necessary isolation and guardrails for HIPAA requirements. Additional resources are billed on demand, with initial costs typically ranging between 200.00 USD to 500.00 USD.

    Additionally, Aptible offers a Startup Program that provides monthly credits over the first six months.

    [For more details, refer to the Aptible Pricing Page.](https://www.aptible.com/pricing)
  </Accordion>
</AccordionGroup>


# HITRUST

Learn about achieving HITRUST compliance on Aptible

<Check>
  <Tooltip tip="Aptible is designed to fast-track satisfying this compliance framework's infrastructure controls/requirements when deployed to a Dedicated Stack. See docs for more information.">Compliance Fast-Track</Tooltip>
</Check>

# Overview

Aptible’s story began with a focus on serving digital health companies. As a result, the Aptible platform was designed with high compliance in mind. It automates and enforces all the necessary infrastructure security and compliance controls, ensuring the safe storage and processing of PHI and more.

# Achieving HITRUST on Aptible

<Steps>
  <Step title="Provision a Dedicated Stack to run your resources">
    <Info> Dedicated Stacks are available on [Production and Enterprise plans](https://www.aptible.com/pricing).</Info>
    Dedicated Stacks live on isolated infrastructure and are designed to support deploying resources with higher requirements— such as HIPAA and HITRUST. Aptible automates and enforces majority of the necessary infrastructure security and compliance controls for HITRUST compliance. When you request your first dedicated stack, an Aptible team member will also reach out to coordinate the execution of a HIPAA Business Associate Agreement (BAA).
  </Step>

  <Step title="Review the Security & Compliance Dashboard and implement HITRUST required controls">
    <Frame>
      ![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/screenshot-ui.6e552b45.png)
    </Frame>

    The Security & Compliance Dashboard serves as a great resource for showing off compliance. When a Dedicated Stack is provisioned, most HITRUST controls will show as complete by default, the remaining controls will show as needing attention.

    <Accordion title="Understanding the HITRUST Readiness Score">
      The HITRUST Common Security Framework (CSF) Certification is a compliance framework based on ISO/IEC 27001. It integrates HIPAA, HITECH, and a variety of other state, local, and industry frameworks and best practices. Independent assessors award this certification when they find that an organization has achieved certain maturity levels in implementing the required HITRUST CSF controls.

      HITRUST CSF is unique because it allows customers to inherit security controls from the infrastructure they host their resources on if the infrastructure provider is also HITRUST CSF certified, enabling you to save time and resources when you begin your certification process. Aptible is HITRUST certified, meaning you can fully inherit up to 30% of security controls implemented and managed by Aptible and partially inherit up to 50% of security controls.

      The Aptible Security & Compliance Dashboard provides a HITRUST readiness score based on controls required for meeting the standards of HITRUST CSF regulation. The HITRUST score tells you what percentage of infrastructure controls you have successfully implemented to meet relevant HITRUST guidelines.
    </Accordion>
  </Step>

  <Step title="Request HITRUST Inhertiance from Aptible">
    Aptible is HITRUST CSF Certified. If you are pursuing your own HITRUST CSF Certification, you may request that Aptible assessment scores be incorporated into your own assessment. This process is referred to as HITRUST Inheritance.

    While it varies per customer, approximately 30%-40% of controls can be fully inherited, and about 20%-30% of controls can be partially inherited.

    <Card title="How to request HITRUST Inhertiance from Aptible" icon="book-open-reader" iconType="duotone" href="https://www.aptible.com/docs/how-to-guides/platform-guides/navigate-hitrust#how-to-request-hitrust-inhertiance" />
  </Step>

  <Step title="Show off your compliance" icon="party-horn">
    Use the Security & Compliance Dashboard to prove your compliance and show off with a `Secured by Aptible` badge

    <Frame>
      ![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/secured_by_aptible_hitrust.png)
    </Frame>
  </Step>
</Steps>


# PCI DSS

Learn about achieving PCI DSS compliance on Aptible

<Check>
  <Tooltip tip="Aptible is designed to fast-track satisfying this compliance framework's infrastructure controls/requirements when deployed to a Dedicated Stack. See docs for more information.">Compliance Fast-Track</Tooltip>
</Check>

# Overview

Aptible’s platform is designed to help businesses meet the strictest security and compliance requirements. With a heritage rooted in supporting security-conscious industries, Aptible automates and enforces critical infrastructure security and compliance controls required for PCI DSS compliance, enabling service providers to securely handle and process payment card data.

# Achieving PCI DSS on Aptible

<Steps>
  <Step title="Provision a Dedicated Stack to run your resources">
    <Info> Dedicated Stacks are available on [Production and Enterprise plans](https://www.aptible.com/pricing).</Info>
    [Dedicated Stacks](https://www.aptible.com/docs/core-concepts/architecture/stacks#stacks) live on isolated infrastructure and are designed to support deploying resources with stringent requirements like PCI DSS. Aptible automates and enforces **100%** of the necessary infrastructure security and compliance controls for PCI DSS compliance.
  </Step>

  <Step title="Review Aptible’s PCI DSS for Service Providers Level 2 attestation">
    Aptible provides a PCI DSS for Service Providers Level 2 attestation, available upon request through [trust.aptible.com](https://trust.aptible.com). This attestation outlines how Aptible meets the PCI DSS Level 2 requirements, simplifying your path to compliance by inheriting many of Aptible’s pre-established controls.
  </Step>

  <Step title="Leverage Aptible for your PCI DSS Compliance">
    Aptible supports your journey toward achieving **PCI DSS compliance**. Whether you're undergoing an internal audit or working with a Qualified Security Assessor (QSA), Aptible ensures that the required security controls—such as logging, access control, vulnerability management, and encryption—are actively enforced. Additionally, the platform can help streamline the evidence collection process necessary for your audit through our [Security & Compliance Dashboard](http://localhost:3000/core-concepts/security-compliance/security-compliance-dashboard/overview) dashboard.
  </Step>

  <Step title="Show off your compliance" icon="party-horn">
    Add a `Secured by Aptible` badge and link to the Secured by Aptible page to show all the security & compliance controls implemented.

    <Frame>
      ![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/secured_by_aptible_pcidss.png)
    </Frame>
  </Step>
</Steps>

# Keep Reading

<CardGroup cols={2}>
  <Card title="Explore HIPAA" icon="book" iconType="duotone" href="https://www.aptible.com/docs/core-concepts/security-compliance/compliance-frameworks/hipaa">
    Learn why Aptible is the leading platform for achieving HIPAA compliance
  </Card>

  <Card title="Explore HITRUST" icon="book" iconType="duotone" href="https://www.aptible.com/docs/core-concepts/security-compliance/compliance-frameworks/hitrust">
    Learn why Aptible is the leading platform for achieving HITRUST
  </Card>
</CardGroup>


# PIPEDA

Learn about achieving PIPEDA compliance on Aptible

<Check>
  <Tooltip tip="This compliance framework's infrastructure controls/requirements are automatically satisfied when you deploy to a Dedicated Stack. See details below for more information.">Compliance-Ready</Tooltip>
</Check>

# Overview

Aptible’s platform is designed to help businesses meet strict data privacy and security requirements. With a strong background in serving security-focused industries, Aptible offers essential infrastructure security controls that align with PIPEDA requirements.

# Achieving PIPEDA on Aptible

<Steps>
  <Step title="Provision a Dedicated Stack to run your resources">
    Dedicated Stacks live on isolated infrastructure and are designed to support deploying resources with higher requirements like PIPEDA. As part of the shared responsibility model, Aptible automates and enforces the necessary infrastructure security and compliance controls to help customers meet PIPEDA compliance.
  </Step>

  <Step title="Review Aptible’s PIPEDA compliance resources">
    Aptible provides PIPEDA compliance resources, available upon request through [trust.aptible.com](https://trust.aptible.com). These resources outline how Aptible aligns with PIPEDA requirements, simplifying your path to compliance by inheriting many of Aptible’s pre-established controls.
  </Step>

  <Step title="Perform a PIPEDA Assessment">
    While Aptible's platform aligns with the requirements of PIPEDA, it is the **client's responsibility** to perform an assessment and ensure that the requirements are fully met based on Aptible's [devision of responsibilies](https://www.aptible.com/docs/core-concepts/architecture/reliability-division). You can conduct your **PIPEDA Self-Assessment** using the official tool provided by the Office of the Privacy Commissioner of Canada, available [here](https://www.priv.gc.ca/en/privacy-topics/privacy-laws-in-canada/the-personal-information-protection-and-electronic-documents-act-pipeda/pipeda-compliance-help/pipeda-compliance-and-training-tools/pipeda_sa_tool_200807/).
  </Step>

  <Step title="Request PIPEDA Compliance Assistance">
    Aptible supports your journey toward achieving **PIPEDA compliance**. While clients must conduct their self-assessment, Aptible ensures that critical security controls—such as access management, encryption, and secure storage—are actively enforced. Additionally, the platform can streamline the documentation collection process for your compliance program.
  </Step>

  <Step title="How to request PIPEDA Assistance from Aptible">
    To get started with PIPEDA compliance or prepare for an audit, reach out to Aptible’s support team. They’ll provide guidance on ensuring all infrastructure controls meet PIPEDA requirements and assist with necessary documentation.
  </Step>

  <Step title="Show off your compliance" icon="party-horn">
    Leverage the **Security & Compliance Dashboard** to demonstrate your PIPEDA compliance to clients and partners. Once compliant, you can display the "Secured by Aptible" badge to showcase your commitment to protecting personal information and adhering to PIPEDA standards.

    <Frame>
      ![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/secured_by_aptible_pipeda.png)
    </Frame>
  </Step>
</Steps>

***

# FAQ

<AccordionGroup>
  <Accordion title="What is the relationship between PHIPA and PIPEDA?">
    The collection, use, and disclosure of personal information within the commercial sector is regulated by PIPEDA, which was enacted to manage these activities within private sector organizations. PIPEDA does not apply to personal information in provinces and territories that have “substantially similar” privacy legislation. The federal government has deemed PHIPA to be “substantially similar” to PIPEDA, exempting custodians and their agents from PIPEDA’s provisions when they collect, use, and disclose personal health information within Ontario. PIPEDA continues to apply to all commercial activities relating to the exchange of personal health information between provinces or internationally.
  </Accordion>

  <Accordion title="Does Aptible also adhere to PHIPA?">
    Aptible has been assessed towards PIPEDA compliance but not specifically towards PHIPA. While our technology stack meets the requirements common to both PIPEDA and PHIPA, it remains the client's responsibility to perform their own assessment to ensure full compliance with PHIPA when managing personal health information within Ontario.
  </Accordion>
</AccordionGroup>


# DDoS Protection

Learn how Aptible automatically provides DDoS Protection

# Overview

Aptible VPC-based approach means that most stack components are not accessible from the Internet, and cannot be targeted directly by a distributed denial-of-service (DDoS) attack. Aptible SSL/TLS endpoints include an AWS Elastic Load Balancer, which only supports valid TCP requests, meaning DDoS attacks such as UDP and SYN floods will not reach your app layer.

# PID Limits

Aptible limits the maximum number of tasks (processes or threads) running in your [containers](/core-concepts/architecture/containers/overview) to protect its infrastructure against DDoS attacks, such as fork bombs.

<Note> The PID limit for a single Container is set very high (on the order of the default for a Linux system), so unless your App is misbehaving and allocating too many processes or threads, you're unlikely to ever hit this limit.</Note>

PID usage and PID limit can be monitored through [Metric Drains](/core-concepts/observability/metrics/metrics-drains/overview).


# Managed Host Intrusion Detection (HIDS)



# Overview

<Info> Managed Host Intrusion Detection (HIDS) is only available on [Production and Enterprise plans.](https://www.aptible.com/pricing)</Info>

Aptible is a container orchestration platform that enables users to deploy containerized workloads onto dedicated isolated networks. Each isolated network and its associated cloud infrastructure is called a [Stack](/core-concepts/architecture/stacks).

Aptible stacks contain several AWS EC2 instances (virtual machines) on which Aptible users deploy their apps and databases in Docker containers. The Aptible security team is responsible for the integrity of these instances and provides a HIDS compliance report periodically as evidence of its activity.

# HIDS Compliance Report

Aptible includes access to the HIDS compliance report at no charge for all shared stacks. The report is also available for Dedicated Stacks for an additional cost. Contact Aptible Support for more information.

# Methodology

Aptible collects HIDS events using OSSEC, a leading open-source intrusion detection system. Aptible's security reporting platform ingests, and processes events generated by OSSEC in one of the following ways:

*   Automated review
*   Bulk review
*   Manual review

If an intrusion is suspected or detected, the Aptible security team activates its incident response process to assess, contain, and eradicate the threat and notifies affected users, if any.

# Review Process

The Aptible Security team uses the following review processes for intrusion detection.

## Automated Review

Aptible's security reporting platform automatically reviews a certain number of events generated by OSSEC.

Here are some examples of automated reviews:

*   Purely informational events, such as events indicating that OSSEC performed a periodic integrity check. Their sole purpose is to let them appear in the HIDS compliance report.
*   Acceptable security events. For example, an automated script running as root using `sudo`: using `sudo` is technically a relevant security event, but if the user already has root privileges, it cannot result in privilege escalation, so that event is automatically approved.

## Bulk Review

Aptible's security reporting platform integrates with several other systems with which members of the Aptible Operations and Security teams interact. Aptible's security reporting platform collects information from these different systems to determine whether the events generated by OSSEC can be approved without further review.

Here are some notable examples of bulk-reviewed events:

*   When a successful SSH login occurs on an Aptible instance, Aptible's monitoring determines whether the SSH login can be tied to an authorized Aptible Operations team member and, if so, prompts them via Slack to confirm that they did trigger this login. An alert is immediately escalated to the Aptible security team if no authorized team member is found or the team member takes too long to respond. Related IDS events will automatically be approved and flagged as bulk review when a login is approved.
*   When a member of the Aptible Operations team deploys updated software via AWS OpsWorks to Aptible hosts, corresponding file integrity alerts are automatically approved in Aptible's security reporting platform and flagged as bulk reviews.

## Manual Review

The Aptible Security team manually reviews any security event that is neither reviewed automatically nor in bulk.

Some examples of manually-reviewed events include:

*   Malware detection events. Malware detection is often racy and generates several false positives, which need to be manually reviewed by Aptible.
*   Configuration changes that were not otherwise bulk-reviewed. For example, changes that result from nightly automated security updates.

# List of Security Events

Security Events monitored by Aptible Host Intrusion Detection:

## CIS benchmark non-conformance

HIDS generates this event when Aptible's monitoring detects an instance that does not conform to the CIS controls Aptible is currently targeting. These events are often triggered on older instances that still need configuring to follow Aptible's latest security best practices.

Aptible's Security team remediates the underlying non-conformance by replacing or reconfiguring the instance, and the team uses the severity of the non-conformance to determine priority.

## File integrity change

HIDS generates this event when Aptible's monitoring detects changes to a monitored file. These events are often the result of package updates, deployments, or the activity of Aptible operations team members and are reviewed accordingly.

## Other informational event

HIDS generates this event when Aptible's monitoring detects an otherwise un-categorized informational event. These events are often auto-reviewed due to their informational nature, and the Aptible security team uses them for high-level reporting.

## Periodic rootkit check

Aptible performs a periodic scan for resident rootkits and other malware. HIDS generates this event every time the scan is performed. HIDS generates a rootkit check event alert if any potential infection is detected.

## Periodic system integrity check

Aptible performs a periodic system integrity check to scan for new files in monitored system directories and deleted files. HIDS generates this event every time the scan is performed.

Among others, this scan covers `/etc`, `/bin`, `/sbin`, `/boot`, `/usr/bin`, `/usr/sbin`.

Note that Aptible also monitors changes to files under these directories in real-time. If they change, HIDS generates a file integrity alert.

## Privilege escalation (e.g., sudo, su)

HIDS generates this event when Aptible's monitoring detects a user escalated their privileges on a host using tools such as sudo or su. This activity is often the result of automated maintenance scripts or the action of Aptible Operations team members and is reviewed accordingly.

## Rootkit check event

HIDS generates this event when Aptible's monitoring detects potential rootkit or malware infection. Due to the inherently racy nature of most rootkit scanning techniques, these events are often false positives, but they are all investigated by Aptible's security team.

## SSH login

HIDS generates this event when Aptible's monitoring detects host-level access via SSH. Whenever they log in to a host, Aptible operations team members are prompted to confirm that the activity is legitimate, so these events are often reviewed in bulk.

## Uncategorized event

HIDS generates this event for uncategorized events generated by Aptible's monitoring. These events are often reviewed directly by the Aptible security team.

## User or group modification

HIDS generates this event when Aptible's monitoring detects that a user or group was changed on the system. This change is usually the result of the activity of Aptible Operations team members.


# Security & Compliance - Overview

Learn how Aptible enables dev teams to meet regulatory compliance requirements (HIPAA, HITRUST, SOC 2, PCI) and pass security audits

# Overview

[Our story](/getting-started/introduction#our-story) began with a strong focus on security and compliance, making us the leading Platform as a Service (PaaS) for security and compliance.

We provide developer-friendly infrastructure guardrails and solutions to help our customers navigate security audits and achieve compliance. This includes:

*   **Security best practices, out-of-the-box**: When you provision a [dedicated stack](/core-concepts/architecture/stacks), you automatically unlock a [suite of security features](https://www.aptible.com/secured-by-aptible), including encryption, [DDoS protection](/core-concepts/security-compliance/ddos-pid-limits), host hardening, [intrusion detection](/core-concepts/security-compliance/hids), and [vulnerability scanning](/core-concepts/security-compliance/security-scans) — alleviating the need to worry about security best practices.
*   **Security and Compliance Dashboard**: The [Security & Compliance Dashboard](/core-concepts/security-compliance/security-compliance-dashboard/overview) provides a unified view of the implemented security controls —  track progress, achieve compliance, and easily generate summarized reports.
*   **Access control**: Secure access to your resources is ensured with [granular user permission](/core-concepts/security-compliance/access-permissions) controls, [Multi-Factor Authentication (MFA)](/core-concepts/security-compliance/authentication/password-authentication#2-factor-authentication-2fa), and [Single Sign-On (SSO)](/core-concepts/security-compliance/authentication/sso) support.
*   **Compliance made easy**: We provide HIPAA Business Associate Agreements (BAAs), HITRUST Inheritance, and streamlined SOC 2 compliance solutions — CISO-approved.

# Learn more about security functionality

<CardGroup cols={3}>
  <Card title=" Authentication" icon="book" iconType="duotone" href="https://www.aptible.com/docs/authenticating-with-aptible">
    Learn about password authentication, SCIM, SSH keys, and Single Sign-On (SSO)
  </Card>

  <Card title="Roles & Permissions" icon="book" iconType="duotone" href="https://www.aptible.com/docs/access-permissions">
    Learn to managr roles & permissions
  </Card>

  <Card title="Security & Compliance Dashboard" icon="book" iconType="duotone" href="https://www.aptible.com/docs/intro-compliance-dashboard">
    Learn to review, manage, and showcase your security & compliance controls
  </Card>

  <Card title="Security Scans" icon="book" iconType="duotone" href="https://www.aptible.com/docs/security-scans">
    Learn about Aptible's Docker Image security scans
  </Card>

  <Card title="DDoS Protection" icon="book" iconType="duotone" href="https://www.aptible.com/docs/pid-limits">
    Learn about Aptible's DDoS Protection
  </Card>

  <Card title="Managed Host Intrusion Detection (HIDS)" icon="book" iconType="duotone" href="https://www.aptible.com/docs/hids">
    Learn about Aptible's methodoloy and process for intrusion detection
  </Card>
</CardGroup>

# FAQ

<AccordionGroup>
  <Accordion title="How do I achieve HIPAA compliance with Aptible?">
    ## Read the guide

    <Card title="How to achieve HIPAA compliance" icon="book-open-reader" iconType="duotone" href="https://www.aptible.com/docs/achieve-hipaa" />
  </Accordion>

  <Accordion title="How do I achieve HITRUST compliance with Aptible?">
    ## Read the guide

    <Card title="How to navigate HITRUST Certification" icon="book-open-reader" iconType="duotone" href="https://www.aptible.com/docs/requesting-hitrust-inheritance" />
  </Accordion>

  <Accordion title="How should I navigate security questionnaires and audits?">
    ## Read the guide

    <Card title="How to navigate security questionnaires and audits" icon="book-open-reader" iconType="duotone" href="https://www.aptible.com/docs/security-questionnaires" />
  </Accordion>

  <Accordion title="Does Aptible provide anti-virus/anti-malware/anti-spyware software?">
    Aptible does not currently run antivirus on our platform; this is because the Aptible infrastructure does not run email clients or web browsers, which are by far the most common vector for virus infection. We do however run Host Intrusion Detection Software (HIDS 12) which scans for malware on container hosts. Additionally, our security program does mandate that we run antivirus on Aptible employee workstations and laptops.
  </Accordion>
</AccordionGroup>


# Compliance Readiness Scores



The performance of the security controls in the Security & Compliance Dashboard affects your readiness score towards regulations and frameworks like HIPAA and HITRUST. These scores tell you how effectively you have implemented infrastructure controls to meet these frameworks’ requirements.

![Image](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/f48c11f-compliance-visibility-scores-all.png)

Aptible has mapped the controls visualized in the Dashboard to HIPAA and HITRUST requirements.

# HIPAA Readiness Score

The Health Insurance Portability and Accountability Act of 1996 (HIPAA) is a federal law that dictates US standards to protect sensitive patient health information from being disclosed without the patient’s consent or knowledge. The [US Department of Health and Human Services (HHS)](https://www.hhs.gov/hipaa/index.html) issued the HIPAA Privacy Rule to implement the requirements of HIPAA. The HIPAA Security Rule protects a subset of information covered by the Privacy Rule.

The Aptible Security & Compliance Dashboard provides a HIPAA readiness score based on controls required for meeting the minimum standards of the regulation, labeled HIPAA Required, as well as addressable controls that are not required to meet the specifications of the regulation but are recommended as a good security practice, labeled HIPAA Addressable.

## HIPAA Required Score

HIPAA prescribes certain implementation specifications as “required, “meaning you must implement the control to meet the regulation requirements. An example of such a specification is 164.308(a)(7)(ii)(A), requiring implemented procedures to create and maintain retrievable exact copies of ePHI. You can meet this specification with Aptible’s [automated daily backup creation and retention policy](/core-concepts/managed-databases/managing-databases/database-backups).

The HIPAA Required score gives you a binary indicator of whether or not you’re meeting the required specifications under the regulation. By default, all resources hosted on a [Dedicated Stack](/core-concepts/architecture/stacks) meet the required specifications of HIPAA, so if you plan on processing ePHI, it’s a good idea to host your containers on a Dedicated Stack from day 1.

## HIPAA Addressable Score

The HHS developed the concept of “addressable implementation specifications” to provide covered entities and business associates additional flexibility regarding compliance with HIPAA. In meeting standards that contain addressable implementation specifications, a covered entity or business associate will do one of the following for each addressable specification:

*   Implement the addressable implementation specifications;
*   Implement one or more alternative security measures to accomplish the same purpose;
*   Not implement either an addressable implementation specification or an alternative.

The HIPAA Addressable score tells you what percentage of infrastructure controls you have implemented successfully to meet relevant addressable specifications per HIPAA guidelines.

# HITRUST-CSF Readiness Score

The [HITRUST Common Security Framework (CSF) Certification](https://hitrustalliance.net/product-tool/hitrust-csf/) is a compliance framework based on ISO/IEC 27001. It integrates HIPAA, HITECH, and a variety of other state, local, and industry frameworks and best practices. Independent assessors award this certification when they find that an organization has achieved certain maturity levels in implementing the required HITRUST CSF controls.

HITRUST CSF is unique because it allows customers to inherit security controls from the infrastructure they host their resources on if the infrastructure provider is also HITRUST CSF certified, enabling you to save time and resources when you begin your certification process. Aptible is HITRUST certified, meaning you can fully inherit up to 30% of security controls implemented and managed by Aptible and partially inherit up to 50% of security controls.

The Aptible Security & Compliance Dashboard provides a HITRUST readiness score based on controls required for meeting the standards of HITRUST CSF regulation. The HITRUST score tells you what percentage of infrastructure controls you have successfully implemented to meet relevant HITRUST guidelines.


# Control Performance



Security controls in-place check for the implementation of a specific safeguard. If you have not implemented a particular control , appropriate notifications are provided in the Aprible Dashboard to indicate the same, with relevant recommendations to remediate.

You can choose to ignore a control implementation, thereby no longer seeing the notification in the Aptible Dashboard and ensuring it does not affect your overall compliance readiness score.

In the example below, [container logging](/core-concepts/observability/logs/overview) was not implemented in the *aptible-misc* environment.

![Image](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/73a2f64-compliance-visibility-container-logging.png)

In such a scenario, you have two options:

## Option 1: Remediate and Implement Control

Based on the remediation recommendations provided in the platform for a control you haven’t implemented, you could follow the appropriate instructions to implement the control in question. Coming to the example provided above, the user with `write` access to the aptible-misc environment can configure a log drain collecting and aggregating their container logs in a destination of choice. Doing this would be an acceptable implementation of the specific control, thereby remediating the issue of non-compliance.

## Option 2: Ignore Implementation

You could also ignore the control implementation based on your organization’s judgment for the specific resource. Choosing to ignore the control implementation will signal to Aptible to also ignore the implementation of the particular control, which in the example above, was the *aptible-misc* environment. Doing so would no longer show you a warning in the UI indicating that you have not implemented the control  and would ensure it does not affect your compliance readiness score.

You can see control implementations you’ve ignored in the expanded view of each control. You can also unignore the control implementation if needed.

![Image](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/cff01f0-compliance-visibility-ignore.gif)


# Security & Compliance Dashboard



![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/screenshot-ui.6e552b45.png)

The Aptible Security & Compliance Dashboard provides a unified, easy-to-consume view of all the security controls Aptible fully enforces and manages on your behalf, as well as the configurations you manage on Aptible that can affect the security of your apps, databases, and endpoints hosted on the platform.

Security controls are safeguards implemented to protect various forms of data and infrastructure that are important for compliance satisfaction and general best-practice security.

You can use the Security & Compliance Dashboard to review the implementation details and the performance of the various security controls implemented on Aptible. Based on the performance of these controls, the Dashboard also provides you with actionable recommendations around control implementations you can configure for your hosted resources on the platform to improve your overall security posture and accelerate compliance with relevant frameworks like HIPAA and HITRUST.

Apart from being visualized in this Aptible Dashboard, you can export these controls as a print-friendly PDF to share externally with prospects and auditors to gain their trust and confidence faster. Access the Dashboard by logging into your [Aptible account](https://account.aptible.com/) and clicking the *Security and Compliance* tab in the navigation bar.

Each control comes with a description to give your teams an overview of what the safeguard entails and an auditor-friendly description to share externally during compliance audits. You can find these descriptions by clicking on any control from the list in the Security & Compliance Dashboard.


# Resources in Scope



Aptible considers any containerized apps, databases, and their associated endpoints across different Aptible environments hosted on your Shared and Dedicated Stacks and users with access to these workloads. Aptible tests each resource for various security controls Aptible has identified as per our [division of responsibilities](https://www.aptible.com/secured-by-aptible).

Aptible splits security controls across different categories that pertain to various pieces of an organization’s overall security posture. These categories include:

*   Access Management
*   Auditing
*   Business Continuity
*   Encryption
*   Network Protection
*   Platform Security
*   Vulnerability Management

Every control tests for security safeguard implementation for specific resources in scope. For example, the *Multi-factor Authentication* control tests for the activation and enforcement of [MFA/2FA](/core-concepts/security-compliance/authentication/password-authentication#2-factor-authentication-2fa) on the account level, whereas a control like *Cross-region backups* is applied on the database level, testing whether or not you’ve enabled the auto-creation of [geographically redundant copy of each database backup](/core-concepts/managed-databases/managing-databases/database-backups) for disaster recovery purposes.

You can see resources in scope by clicking on a control of interest.

![Image](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/c30c447-compliance-visibility-resources.jpeg)


# Shareable Compliance Posture Report



You can generate a shareable PDF of your overall security and compliance posture based on the controls implemented. This shareable report lets you quickly provide various internal stakeholders, external auditors, and customers with an in-depth understanding of your infrastructure security and compliance posture, thereby building trust in your organization’s security.

You can do this by clicking the *View as Printable Summary Report* button in the Security & Compliance Dashboard.

![Image](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/3ed3763-compliance-visibility-pdf-button.png)

Clicking this will open up a print-friendly view that details the implementation of the various controls against the resources in scope for each of them. You can then save this report as a PDF and download it to your local drive by following the instructions from the prompt.

![Image](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/cb3ff99-compliance-visibility-print-button.png)

The print-friendly report will honor the environment and control filters from the Compliance Visibility Dashboard. For example, if you’ve filtered to specific environments and control categories, the resulting print-friendly report would only highlight the control implementations pertaining to the filtered environments and categories.


# Security Scans

Learn about application vulnerability scanning provided by Aptible

Aptible can scan the packages in your Docker images for known vulnerabilities [Clair](https://github.com/coreos/clair) on demand.

# What is scanned?

Docker image security scans look for vulnerable OS packages installed in your Docker images on supported Linux distributions:

*   **Debian / Ubuntu**: packages installed using `dpkg` or its `apt-get` frontend.
*   **CentOS / Red Hat / Amazon Linux**: packages installed using `rpm` or its frontends `yum` and `dnf`.
*   **Alpine Linux**: packages installed using `apk`.

Docker image security scans do **not** scan for:

*   packages installed from source (e.g., using `make && make install`).
*   packages installed by language-level package managers, such as `bundler`, `npm`, `pip`, `yarn`, `composer`, `go install`, etc. (third-party vulnerability analysis providers support those, and you can incorporate them using a CI process, for example).

# FAQ

<AccordionGroup>
  <Accordion title="How do I access security scans?">
    Access Docker image security scans in the Aptible Dashboard by navigating to the respective app and selecting "Security Scan."
    ![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/Security-Scans.png)
  </Accordion>

  <Accordion title="What OSes are supported?">
    **Ubuntu, Debian, RHEL, Oracle, Alpine, and AWS Linux** are currently supported.

    Some operating systems, like CentOS, are not supported because the OS maintainers do not publish any kind of security database of package vulnerabilities.
    You will see an error message like "No OS detected by Clair" if this is the case.
  </Accordion>

  <Accordion title="What does it mean if my scan returns no vulnerabilities?">
    In the best case, this means that Aptible was able to identify packages installed in your container, and none of those packages have any "known" vulnerabilities.

    In the worst case, Aptible is unable to correlate any vulnerabilities to packages in your container.

    Vulnerability detection relies on your OS maintainers to publicly publish vulnerability information and keep it up to date.
    The most common reason for there being no vulnerabilities detected is if you're using an unsupported (e.g., End of Life) OS version, like Debian 9 or older, for which there is no longer any publicly maintained vulnerability database.
  </Accordion>

  <Accordion title="How do I handle the vulnerabilities found in security scans?">
    ## Read the guide

    <Card title="How to handle vulnerabilities found in security scans" icon="book-open-reader" href="https://www.aptible.com/docs/how-to-handle-vulnerabilities-found-in-security-scans" />
  </Accordion>
</AccordionGroup>


# Deploy your custom code

Learn how to deploy your custom code on Aptible

## Overview

The following guide is designed to help you deploy custom code on Aptible. During this process, Aptible will launch containers to run your custom app and Managed Databases for any data stores, like PostgreSQL, Redis, etc., that your app requires to run.

## Compatibility

Aptible supports many frameworks; you can deploy any code that meets the following requirements:

*   **Apps must run on Linux in Docker containers**

    *   To run an app on Aptible, you must provide Aptible with a Dockerfile. To that extent, all apps on Aptible must be able to run Linux in Docker containers.\
        <Tip> New to Docker? [Check out Docker’s getting started guide](https://docs.docker.com/get-started/).</Tip>

*   **Apps may only receive traffic over HTTP or TCP.**

    *   App endpoints (load balancers) are how you expose your Aptible app to the Internet. These endpoints only support traffic received over HTTP or TCP. While you cannot serve UDP services from Aptible, you may still connect to UDP services (such as DNS, SNMP, etc.) from apps hosted on Aptible.

*   **Apps must not depend on persistent storage.**

    *   App containers on Aptible are ephemeral and cannot be used for data persistence. To store your data with persistence, we recommend using a [Database](http://aptible.com/docs/databases) or third-party storage solution, such as AWS S3. Apps that rely on persistent local storage or a volume shared between multiple containers must be re-architected to run on Aptible. If you have questions about doing so, contact [Aptible Support](/how-to-guides/troubleshooting/aptible-support) for assistance.

# Deploy Code

<Info>Prerequisites: Ensure you have [Git](https://git-scm.com/downloads) installed, a Git repository with your application code, and a [Dockerfile](/core-concepts/apps/deploying-apps/image/deploying-with-git/overview) ready to deploy.</Info>

Using the Deploy Code tool in the Aptible Dashboard, you can deploy Custom Code. The tool will guide you through the following:

<Steps>
  <Step title="Deploy with Git Push">
    ![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/custom-code1.png)
  </Step>

  <Step title="Add an SSH key">
    ![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/custom-code2.png)
    If you have not done so already, you will be prompted to set up an [SSH key](/core-concepts/security-compliance/authentication/ssh-keys#ssh-keys).
  </Step>

  <Step title="Environment Setup">
    ![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/custom-code3.png)
    Select your [stack](/core-concepts/architecture/stacks) to deploy your resources. This will determine what region your resources are deployed to. Then, name the [environment](/core-concepts/architecture/environments) your resources will be grouped into.
  </Step>

  <Step title="Push your code to Aptible">
    ![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/custom-code4.png)
    Select **Custom Code** deployment, and from your command-line interface, add Aptible’s Git Server and push your code to our scan branch using the commands in the Aptible Dashboard
  </Step>

  <Step title="Provision a database and configure your app">
    ![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/custom-code4.png)
    Optionally, provision a database, configure your app with [environment variables](/core-concepts/apps/deploying-apps/configuration#configuration-variables), or add additional [services](/core-concepts/apps/deploying-apps/services) and commands.
  </Step>

  <Step title="Deploy your code and view logs">
    ![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/custom-code6.png)
    Deploy your code and view [logs](/core-concepts/observability/logs/overview) in real time
  </Step>

  <Step title="Expose your app to the internet">
    ![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/custom-code7.png)
    Now that your code is deployed, it's time to expose your app to the internet. Select the service that needs an [endpoint](/core-concepts/apps/connecting-to-apps/app-endpoints/overview), and Aptible will automatically provision a managed endpoint.
  </Step>

  <Step title="View your deployed app 🎉" icon="party-horn" />
</Steps>


# Node.js + Express - Starter Template

Deploy a starter template Node.js app using the Express framework on Aptible

<CardGroup cols={3}>
  <Card title="Deploy Now" icon="rocket" href="https://app.aptible.com/create" />

  <Card title="GitHub Repo" icon="github" href="https://github.com/aptible/template-express" />

  <Card title="View Example" icon="browser" href="https://app-52737.on-aptible.com/" />
</CardGroup>

# Overview

The following guide is designed to help you deploy a sample [Node.js](https://nodejs.org/) app using the [Express framework](https://expressjs.com/) from the Aptible Dashboard.

# Deploying the template

<Info> Prerequisite: Ensure you have [Git](https://git-scm.com/downloads) installed. </Info>

Using the [Deploy Code](https://app.aptible.com/create) tool in the Aptible Dashboard, you can deploy the **Express Template**. The tool will guide you through the following:

<Steps>
  <Step title="Deploy with Git Push">
    ![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/node1.png)
  </Step>

  <Step title="Add an SSH key">
    ![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/node2.png)
    If you have not done so already, you will be prompted to set up an [SSH key](/core-concepts/security-compliance/authentication/ssh-keys#ssh-keys).
  </Step>

  <Step title="Environment Setup">
    ![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/node3.png)\
    Select your [Stack](/core-concepts/architecture/stacks) to deploy your resources. This will determine what region your resources are deployed to. Then, name the [Environment](/core-concepts/architecture/environments) your resources will be grouped into.
  </Step>

  <Step title="Prepare the template">
    ![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/node4.png)
    Select **Express Template** for deployment, and follow command-line instructions.
  </Step>

  <Step title="Fill environment variables and deploy">
    ![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/node5.png)

    Aptible will automatically fill this template's required databases, services, and app's configuration with environment variable keys for you to fill with values. Once complete, save and deploy the code!

    Aptible will stream logs to you in live time:
    ![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/node6.png)
  </Step>

  <Step title="Expose your app to the internet">
    ![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/node7.png)
    Now that your code is deployed, it's time to expose your app to the internet. Select the service that needs an [endpoint](/core-concepts/apps/connecting-to-apps/app-endpoints/overview), and Aptible will automatically provision a managed endpoint.
  </Step>

  <Step title="View your deployed app" icon="party-horn">
    ![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/node8.png)
  </Step>
</Steps>

# Continue your journey

<Card title="Deploy custom code" icon="books" iconType="duotone" href="https://www.aptible.com/docs/custom-code-quickstart">
  Read our guide for deploying custom code on Aptible.
</Card>


# Deploy a starter template



Use a starter template to quickly deploy your **own code** or **sample code**.

<CardGroup cols={3}>
  <Card title="Custom Code" icon="globe" href="https://www.aptible.com/docs/custom-code-quickstart">
    Explore compatibility and deploy custom code
  </Card>

  <Card
    title="Ruby "
    href="https://www.aptible.com/docs/ruby-quickstart"
    icon={
    <svg width="30" height="30" viewBox="0 0 256 255" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMinYMin meet"><defs><linearGradient x1="84.75%" y1="111.399%" x2="58.254%" y2="64.584%" id="a"><stop stop-color="#FB7655" offset="0%"/><stop stop-color="#FB7655" offset="0%"/><stop stop-color="#E42B1E" offset="41%"/><stop stop-color="#900" offset="99%"/><stop stop-color="#900" offset="100%"/></linearGradient><linearGradient x1="116.651%" y1="60.89%" x2="1.746%" y2="19.288%" id="b"><stop stop-color="#871101" offset="0%"/><stop stop-color="#871101" offset="0%"/><stop stop-color="#911209" offset="99%"/><stop stop-color="#911209" offset="100%"/></linearGradient><linearGradient x1="75.774%" y1="219.327%" x2="38.978%" y2="7.829%" id="c"><stop stop-color="#871101" offset="0%"/><stop stop-color="#871101" offset="0%"/><stop stop-color="#911209" offset="99%"/><stop stop-color="#911209" offset="100%"/></linearGradient><linearGradient x1="50.012%" y1="7.234%" x2="66.483%" y2="79.135%" id="d"><stop stop-color="#FFF" offset="0%"/><stop stop-color="#FFF" offset="0%"/><stop stop-color="#E57252" offset="23%"/><stop stop-color="#DE3B20" offset="46%"/><stop stop-color="#A60003" offset="99%"/><stop stop-color="#A60003" offset="100%"/></linearGradient><linearGradient x1="46.174%" y1="16.348%" x2="49.932%" y2="83.047%" id="e"><stop stop-color="#FFF" offset="0%"/><stop stop-color="#FFF" offset="0%"/><stop stop-color="#E4714E" offset="23%"/><stop stop-color="#BE1A0D" offset="56%"/><stop stop-color="#A80D00" offset="99%"/><stop stop-color="#A80D00" offset="100%"/></linearGradient><linearGradient x1="36.965%" y1="15.594%" x2="49.528%" y2="92.478%" id="f"><stop stop-color="#FFF" offset="0%"/><stop stop-color="#FFF" offset="0%"/><stop stop-color="#E46342" offset="18%"/><stop stop-color="#C82410" offset="40%"/><stop stop-color="#A80D00" offset="99%"/><stop stop-color="#A80D00" offset="100%"/></linearGradient><linearGradient x1="13.609%" y1="58.346%" x2="85.764%" y2="-46.717%" id="g"><stop stop-color="#FFF" offset="0%"/><stop stop-color="#FFF" offset="0%"/><stop stop-color="#C81F11" offset="54%"/><stop stop-color="#BF0905" offset="99%"/><stop stop-color="#BF0905" offset="100%"/></linearGradient><linearGradient x1="27.624%" y1="21.135%" x2="50.745%" y2="79.056%" id="h"><stop stop-color="#FFF" offset="0%"/><stop stop-color="#FFF" offset="0%"/><stop stop-color="#DE4024" offset="31%"/><stop stop-color="#BF190B" offset="99%"/><stop stop-color="#BF190B" offset="100%"/></linearGradient><linearGradient x1="-20.667%" y1="122.282%" x2="104.242%" y2="-6.342%" id="i"><stop stop-color="#BD0012" offset="0%"/><stop stop-color="#BD0012" offset="0%"/><stop stop-color="#FFF" offset="7%"/><stop stop-color="#FFF" offset="17%"/><stop stop-color="#C82F1C" offset="27%"/><stop stop-color="#820C01" offset="33%"/><stop stop-color="#A31601" offset="46%"/><stop stop-color="#B31301" offset="72%"/><stop stop-color="#E82609" offset="99%"/><stop stop-color="#E82609" offset="100%"/></linearGradient><linearGradient x1="58.792%" y1="65.205%" x2="11.964%" y2="50.128%" id="j"><stop stop-color="#8C0C01" offset="0%"/><stop stop-color="#8C0C01" offset="0%"/><stop stop-color="#990C00" offset="54%"/><stop stop-color="#A80D0E" offset="99%"/><stop stop-color="#A80D0E" offset="100%"/></linearGradient><linearGradient x1="79.319%" y1="62.754%" x2="23.088%" y2="17.888%" id="k"><stop stop-color="#7E110B" offset="0%"/><stop stop-color="#7E110B" offset="0%"/><stop stop-color="#9E0C00" offset="99%"/><stop stop-color="#9E0C00" offset="100%"/></linearGradient><linearGradient x1="92.88%" y1="74.122%" x2="59.841%" y2="39.704%" id="l"><stop stop-color="#79130D" offset="0%"/><stop stop-color="#79130D" offset="0%"/><stop stop-color="#9E120B" offset="99%"/><stop stop-color="#9E120B" offset="100%"/></linearGradient><radialGradient cx="32.001%" cy="40.21%" fx="32.001%" fy="40.21%" r="69.573%" id="m"><stop stop-color="#A80D00" offset="0%"/><stop stop-color="#A80D00" offset="0%"/><stop stop-color="#7E0E08" offset="99%"/><stop stop-color="#7E0E08" offset="100%"/></radialGradient><radialGradient cx="13.549%" cy="40.86%" fx="13.549%" fy="40.86%" r="88.386%" id="n"><stop stop-color="#A30C00" offset="0%"/><stop stop-color="#A30C00" offset="0%"/><stop stop-color="#800E08" offset="99%"/><stop stop-color="#800E08" offset="100%"/></radialGradient><linearGradient x1="56.57%" y1="101.717%" x2="3.105%" y2="11.993%" id="o"><stop stop-color="#8B2114" offset="0%"/><stop stop-color="#8B2114" offset="0%"/><stop stop-color="#9E100A" offset="43%"/><stop stop-color="#B3100C" offset="99%"/><stop stop-color="#B3100C" offset="100%"/></linearGradient><linearGradient x1="30.87%" y1="35.599%" x2="92.471%" y2="100.694%" id="p"><stop stop-color="#B31000" offset="0%"/><stop stop-color="#B31000" offset="0%"/><stop stop-color="#910F08" offset="44%"/><stop stop-color="#791C12" offset="99%"/><stop stop-color="#791C12" offset="100%"/></linearGradient></defs><path d="M197.467 167.764l-145.52 86.41 188.422-12.787L254.88 51.393l-57.414 116.37z" fill="url(#a)"/><path d="M240.677 241.257L224.482 129.48l-44.113 58.25 60.308 53.528z" fill="url(#b)"/><path d="M240.896 241.257l-118.646-9.313-69.674 21.986 188.32-12.673z" fill="url(#c)"/><path d="M52.744 253.955l29.64-97.1L17.16 170.8l35.583 83.154z" fill="url(#d)"/><path d="M180.358 188.05L153.085 81.226l-78.047 73.16 105.32 33.666z" fill="url(#e)"/><path d="M248.693 82.73l-73.777-60.256-20.544 66.418 94.321-6.162z" fill="url(#f)"/><path d="M214.191.99L170.8 24.97 143.424.669l70.767.322z" fill="url(#g)"/><path d="M0 203.372l18.177-33.151-14.704-39.494L0 203.372z" fill="url(#h)"/><path d="M2.496 129.48l14.794 41.963 64.283-14.422 73.39-68.207 20.712-65.787L143.063 0 87.618 20.75c-17.469 16.248-51.366 48.396-52.588 49-1.21.618-22.384 40.639-32.534 59.73z" fill="#FFF"/><path d="M54.442 54.094c37.86-37.538 86.667-59.716 105.397-40.818 18.72 18.898-1.132 64.823-38.992 102.349-37.86 37.525-86.062 60.925-104.78 42.027-18.73-18.885.515-66.032 38.375-103.558z" fill="url(#i)"/><path d="M52.744 253.916l29.408-97.409 97.665 31.376c-35.312 33.113-74.587 61.106-127.073 66.033z" fill="url(#j)"/><path d="M155.092 88.622l25.073 99.313c29.498-31.016 55.972-64.36 68.938-105.603l-94.01 6.29z" fill="url(#k)"/><path d="M248.847 82.833c10.035-30.282 12.35-73.725-34.966-81.791l-38.825 21.445 73.791 60.346z" fill="url(#l)"/><path d="M0 202.935c1.39 49.979 37.448 50.724 52.808 51.162l-35.48-82.86L0 202.935z" fill="#9E1209"/><path d="M155.232 88.777c22.667 13.932 68.35 41.912 69.276 42.426 1.44.81 19.695-30.784 23.838-48.64l-93.114 6.214z" fill="url(#m)"/><path d="M82.113 156.507l39.313 75.848c23.246-12.607 41.45-27.967 58.121-44.42l-97.434-31.428z" fill="url(#n)"/><path d="M17.174 171.34l-5.57 66.328c10.51 14.357 24.97 15.605 40.136 14.486-10.973-27.311-32.894-81.92-34.566-80.814z" fill="url(#o)"/><path d="M174.826 22.654l78.1 10.96c-4.169-17.662-16.969-29.06-38.787-32.623l-39.313 21.663z" fill="url(#p)"/></svg>
    }
  >
    Deploy using a Ruby on Rails template
  </Card>

  <Card
    title="NodeJS"
    href="https://www.aptible.com/docs/node-js-quickstart"
    icon={
    <svg xmlns="http://www.w3.org/2000/svg" width="30" height="30" viewBox="0 0 58 64" fill="none">
    <path d="M26.3201 0.681001C27.9201 -0.224999 29.9601 -0.228999 31.5201 0.681001L55.4081 14.147C56.9021 14.987 57.9021 16.653 57.8881 18.375V45.375C57.8981 47.169 56.8001 48.871 55.2241 49.695L31.4641 63.099C30.6514 63.5481 29.7333 63.7714 28.8052 63.7457C27.877 63.7201 26.9727 63.4463 26.1861 62.953L19.0561 58.833C18.5701 58.543 18.0241 58.313 17.6801 57.843C17.9841 57.435 18.5241 57.383 18.9641 57.203C19.9561 56.887 20.8641 56.403 21.7761 55.891C22.0061 55.731 22.2881 55.791 22.5081 55.935L28.5881 59.451C29.0221 59.701 29.4621 59.371 29.8341 59.161L53.1641 45.995C53.4521 45.855 53.6121 45.551 53.5881 45.235V18.495C53.6201 18.135 53.4141 17.807 53.0881 17.661L29.3881 4.315C29.2515 4.22054 29.0894 4.16976 28.9234 4.16941C28.7573 4.16905 28.5951 4.21912 28.4581 4.313L4.79207 17.687C4.47207 17.833 4.25207 18.157 4.29207 18.517V45.257C4.26407 45.573 4.43207 45.871 4.72207 46.007L11.0461 49.577C12.2341 50.217 13.6921 50.577 15.0001 50.107C15.5725 49.8913 16.0652 49.5058 16.4123 49.0021C16.7594 48.4984 16.9443 47.9007 16.9421 47.289L16.9481 20.709C16.9201 20.315 17.2921 19.989 17.6741 20.029H20.7141C21.1141 20.019 21.4281 20.443 21.3741 20.839L21.3681 47.587C21.3701 49.963 20.3941 52.547 18.1961 53.713C15.4881 55.113 12.1401 54.819 9.46407 53.473L2.66407 49.713C1.06407 48.913 -0.00993076 47.185 6.9243e-05 45.393V18.393C0.0067219 17.5155 0.247969 16.6557 0.698803 15.9027C1.14964 15.1498 1.79365 14.5312 2.56407 14.111L26.3201 0.681001ZM33.2081 19.397C36.6621 19.197 40.3601 19.265 43.4681 20.967C45.8741 22.271 47.2081 25.007 47.2521 27.683C47.1841 28.043 46.8081 28.243 46.4641 28.217C45.4641 28.215 44.4601 28.231 43.4561 28.211C43.0301 28.227 42.7841 27.835 42.7301 27.459C42.4421 26.179 41.7441 24.913 40.5401 24.295C38.6921 23.369 36.5481 23.415 34.5321 23.435C33.0601 23.515 31.4781 23.641 30.2321 24.505C29.2721 25.161 28.9841 26.505 29.3261 27.549C29.6461 28.315 30.5321 28.561 31.2541 28.789C35.4181 29.877 39.8281 29.789 43.9141 31.203C45.6041 31.787 47.2581 32.923 47.8381 34.693C48.5941 37.065 48.2641 39.901 46.5781 41.805C45.2101 43.373 43.2181 44.205 41.2281 44.689C38.5821 45.279 35.8381 45.293 33.1521 45.029C30.6261 44.741 27.9981 44.077 26.0481 42.357C24.3801 40.909 23.5681 38.653 23.6481 36.477C23.6681 36.109 24.0341 35.853 24.3881 35.883H27.3881C27.7921 35.855 28.0881 36.203 28.1081 36.583C28.2941 37.783 28.7521 39.083 29.8161 39.783C31.8681 41.107 34.4421 41.015 36.7901 41.053C38.7361 40.967 40.9201 40.941 42.5101 39.653C43.3501 38.919 43.5961 37.693 43.3701 36.637C43.1241 35.745 42.1701 35.331 41.3701 35.037C37.2601 33.737 32.8001 34.209 28.7301 32.737C27.0781 32.153 25.4801 31.049 24.8461 29.351C23.9601 26.951 24.3661 23.977 26.2321 22.137C28.0321 20.307 30.6721 19.601 33.1721 19.349L33.2081 19.397Z" fill="#8CC84B"/></svg>
    }
  >
    Deploy using a Node.js + Express template
  </Card>

  <Card
    title="Django"
    href="https://www.aptible.com/docs/python-quickstart"
    icon={
    <svg width="30" height="30" viewBox="0 0 256 326" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMinYMin meet"><g fill="#2BA977"><path d="M114.784 0h53.278v244.191c-27.29 5.162-47.38 7.193-69.117 7.193C33.873 251.316 0 222.245 0 166.412c0-53.795 35.93-88.708 91.608-88.708 8.64 0 15.222.68 23.176 2.717V0zm1.867 124.427c-6.24-2.038-11.382-2.717-17.965-2.717-26.947 0-42.512 16.437-42.512 45.243 0 28.046 14.88 43.532 42.17 43.532 5.896 0 10.696-.332 18.307-1.351v-84.707z"/><path d="M255.187 84.26v122.263c0 42.105-3.154 62.353-12.411 79.81-8.64 16.783-20.022 27.366-43.541 39.055l-49.438-23.297c23.519-10.93 34.901-20.588 42.17-35.327 7.61-15.072 10.01-32.529 10.01-78.445V84.261h53.21zM196.608 0h53.278v54.135h-53.278V0z"/></g></svg>
    }
  >
    Deploy using a Python + Django template.
  </Card>

  <Card
    title="Laravel"
    href="https://www.aptible.com/docs/php-quickstart"
    icon={
    <svg height="30" viewBox="0 -.11376601 49.74245785 51.31690859" width="30" xmlns="http://www.w3.org/2000/svg"><path d="m49.626 11.564a.809.809 0 0 1 .028.209v10.972a.8.8 0 0 1 -.402.694l-9.209 5.302v10.509c0 .286-.152.55-.4.694l-19.223 11.066c-.044.025-.092.041-.14.058-.018.006-.035.017-.054.022a.805.805 0 0 1 -.41 0c-.022-.006-.042-.018-.063-.026-.044-.016-.09-.03-.132-.054l-19.219-11.066a.801.801 0 0 1 -.402-.694v-32.916c0-.072.01-.142.028-.21.006-.023.02-.044.028-.067.015-.042.029-.085.051-.124.015-.026.037-.047.055-.071.023-.032.044-.065.071-.093.023-.023.053-.04.079-.06.029-.024.055-.05.088-.069h.001l9.61-5.533a.802.802 0 0 1 .8 0l9.61 5.533h.002c.032.02.059.045.088.068.026.02.055.038.078.06.028.029.048.062.072.094.017.024.04.045.054.071.023.04.036.082.052.124.008.023.022.044.028.068a.809.809 0 0 1 .028.209v20.559l8.008-4.611v-10.51c0-.07.01-.141.028-.208.007-.024.02-.045.028-.068.016-.042.03-.085.052-.124.015-.026.037-.047.054-.071.024-.032.044-.065.072-.093.023-.023.052-.04.078-.06.03-.024.056-.05.088-.069h.001l9.611-5.533a.801.801 0 0 1 .8 0l9.61 5.533c.034.02.06.045.09.068.025.02.054.038.077.06.028.029.048.062.072.094.018.024.04.045.054.071.023.039.036.082.052.124.009.023.022.044.028.068zm-1.574 10.718v-9.124l-3.363 1.936-4.646 2.675v9.124l8.01-4.611zm-9.61 16.505v-9.13l-4.57 2.61-13.05 7.448v9.216zm-36.84-31.068v31.068l17.618 10.143v-9.214l-9.204-5.209-.003-.002-.004-.002c-.031-.018-.057-.044-.086-.066-.025-.02-.054-.036-.076-.058l-.002-.003c-.026-.025-.044-.056-.066-.084-.02-.027-.044-.05-.06-.078l-.001-.003c-.018-.03-.029-.066-.042-.1-.013-.03-.03-.058-.038-.09v-.001c-.01-.038-.012-.078-.016-.117-.004-.03-.012-.06-.012-.09v-21.483l-4.645-2.676-3.363-1.934zm8.81-5.994-8.007 4.609 8.005 4.609 8.006-4.61-8.006-4.608zm4.164 28.764 4.645-2.674v-20.096l-3.363 1.936-4.646 2.675v20.096zm24.667-23.325-8.006 4.609 8.006 4.609 8.005-4.61zm-.801 10.605-4.646-2.675-3.363-1.936v9.124l4.645 2.674 3.364 1.937zm-18.422 20.561 11.743-6.704 5.87-3.35-8-4.606-9.211 5.303-8.395 4.833z" fill="#ff2d20"/></svg>
    }
  >
    Deploy using a PHP + Laravel template
  </Card>

  <Card
    title="Python"
    href="https://www.aptible.com/docs/deploy-demo-app"
    icon={
    <svg width="30" height="30" viewBox="0 0 256 255" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMinYMin meet"><defs><linearGradient x1="12.959%" y1="12.039%" x2="79.639%" y2="78.201%" id="a"><stop stop-color="#387EB8" offset="0%"/><stop stop-color="#366994" offset="100%"/></linearGradient><linearGradient x1="19.128%" y1="20.579%" x2="90.742%" y2="88.429%" id="b"><stop stop-color="#FFE052" offset="0%"/><stop stop-color="#FFC331" offset="100%"/></linearGradient></defs><path d="M126.916.072c-64.832 0-60.784 28.115-60.784 28.115l.072 29.128h61.868v8.745H41.631S.145 61.355.145 126.77c0 65.417 36.21 63.097 36.21 63.097h21.61v-30.356s-1.165-36.21 35.632-36.21h61.362s34.475.557 34.475-33.319V33.97S194.67.072 126.916.072zM92.802 19.66a11.12 11.12 0 0 1 11.13 11.13 11.12 11.12 0 0 1-11.13 11.13 11.12 11.12 0 0 1-11.13-11.13 11.12 11.12 0 0 1 11.13-11.13z" fill="url(#a)"/><path d="M128.757 254.126c64.832 0 60.784-28.115 60.784-28.115l-.072-29.127H127.6v-8.745h86.441s41.486 4.705 41.486-60.712c0-65.416-36.21-63.096-36.21-63.096h-21.61v30.355s1.165 36.21-35.632 36.21h-61.362s-34.475-.557-34.475 33.32v56.013s-5.235 33.897 62.518 33.897zm34.114-19.586a11.12 11.12 0 0 1-11.13-11.13 11.12 11.12 0 0 1 11.13-11.131 11.12 11.12 0 0 1 11.13 11.13 11.12 11.12 0 0 1-11.13 11.13z" fill="url(#b)"/></svg>
    }
  >
    Deploy Python + Flask Demo app
  </Card>
</CardGroup>


# PHP + Laravel - Starter Template

Deploy a starter template PHP app using the Laravel framework on Aptible

<CardGroup cols={3}>
  <Card title="Deploy Now" icon="rocket" href="https://app.aptible.com/create" />

  <Card title="GitHub Repo" icon="github" href="https://github.com/aptible/template-laravel" />

  <Card title="View Live Example" icon="browser" href="https://app-52756.on-aptible.com/" />
</CardGroup>

# Overview

This guide will walk you through the process of launching a PHP app using the [Laravel framework](https://laravel.com/).

# Deploy Template

<Info> Prerequisite: Ensure you have [Git](https://git-scm.com/downloads) installed. </Info>

Using the [Deploy Code](https://app.aptible.com/create) tool in the Aptible Dashboard, you can deploy the **Laravel Template**. The tool will guide you through the following:

<Steps>
  <Step title="Deploy with Git Push">
    ![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/php1.png)
  </Step>

  <Step title="Add an SSH key">
    ![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/php2.png)
    If you have not done so already, you will be prompted to set up an [SSH key](/core-concepts/security-compliance/authentication/ssh-keys#ssh-keys).
  </Step>

  <Step title="Environment Setup">
    ![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/php3.png)
    Select your [stack](/core-concepts/architecture/stacks) to deploy your resources. This will determine what region your resources are deployed to. Then, name the [environment](/core-concepts/architecture/environments) your resources will be grouped into.
  </Step>

  <Step title="Prepare the template">
    ![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/php4.png)
    Select **Laravel Template** for deployment, and follow command-line instructions.
  </Step>

  <Step title="Fill environment variables and deploy!">
    ![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/php5.png)
    Aptible will automatically fill this template's required databases, services, and app's configuration with environment variable keys for you to fill with values. Once complete, save and deploy the code!

    Aptible will stream the logs to you in live time:
    ![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/php6.png)
  </Step>

  <Step title="Expose your app to the internet">
    ![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/php7.png)
    Now that your code is deployed, it's time to expose your app to the internet. Select the service that needs an [endpoint](/core-concepts/apps/connecting-to-apps/app-endpoints/overview), and Aptible will automatically provision a managed endpoint.
  </Step>

  <Step title="View your deployed app" icon="party-horn">
    ![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/php8.png)
  </Step>
</Steps>

# Continue your journey

<Card title="Deploy custom code" icon="books" iconType="duotone" href="https://www.aptible.com/docs/custom-code-quickstart">
  Read our guide for deploying custom code on Aptible.
</Card>


# Python + Django - Starter Template

Deploy a starter template Python app using the Django framework on Aptible

<CardGroup cols={3}>
  <Card title="Deploy Now" icon="rocket" href="https://app.aptible.com/create" />

  <Card title="GitHub Repo" icon="github" href="https://github.com/aptible/template-django" />

  <Card title="View Example" icon="browser" href="https://app-52709.on-aptible.com/" />
</CardGroup>

# Overview

This guide will walk you through the process of launching a [Python](https://www.python.org/) app using the [Django](https://www.djangoproject.com/) framework.

# Deploy Template

<Info> Prerequisite: Ensure you have [Git](https://git-scm.com/downloads) installed.</Info>

Using the [Deploy Code](https://app.aptible.com/create) tool in the Aptible Dashboard, you can deploy the **Django Template**. The tool will guide you through the following:

<Steps>
  <Step title="Deploy with Git Push">
    ![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/django1.png)
  </Step>

  <Step title="Add an SSH key">
    ![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/django2.png)
    If you have not done so already, you will be prompted to set up an [SSH key](/core-concepts/security-compliance/authentication/ssh-keys#ssh-keys).
  </Step>

  <Step title="Environment Setup">
    ![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/django3.png)
    Select your [stack](/core-concepts/architecture/stacks) to deploy your resources. This will determine what region your resources are deployed to. Then, the name the [environment](/core-concepts/architecture/environments) your resources will be grouped into.
  </Step>

  <Step title="Prepare the template">
    ![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/django4.png)
    Select **Django Template** for deployment, and follow command-line instructions.
  </Step>

  <Step title="Fill environment variables and deploy!">
    ![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/django5.png)
    Aptible will automatically fill this template's required databases, services, and app's configuration with environment variable keys for you to fill with values. Once complete, save and deploy the code!

    Aptible will stream the logs to you in live time:
    ![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/django6.png)
  </Step>

  <Step title="Expose your app to the internet">
    ![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/django7.png)
    Now that your code is deployed, it's time to expose your app to the internet. Select the service that needs an [endpoint](/core-concepts/apps/connecting-to-apps/app-endpoints/overview), and Aptible will automatically provision a managed endpoint.
  </Step>

  <Step title="View your deployed app" icon="party-horn">
    ![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/django8.png)
  </Step>
</Steps>

# Continue your journey

<Card title="Deploy custom code" icon="books" iconType="duotone" href="https://www.aptible.com/docs/custom-code-quickstart">
  Read our guide for deploying custom code on Aptible.
</Card>


# Python + Flask - Demo App

Deploy our Python demo app using the Flask framework with Managed PostgreSQL Database and Redis instance

<CardGroup cols={3}>
  <Card title="Deploy Now" icon="rocket" href="https://app.aptible.com/create" />

  <Card title="GitHub Repo" icon="github" href="https://github.com/aptible/deploy-demo-app" />

  <Card title="View Example" icon="browser" href="https://app-60388.on-aptible.com/" />
</CardGroup>

# Overview

The following guide is designed to help you deploy an example app on Aptible. During this process, Aptible will launch containers to run a Python app with a web server, a background worker, a Managed PostgreSQL Database, and a Redis instance.

<Frame>
  ![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/flask1.png)
</Frame>

The demo app displays the last 20 messages of the database, including any additional messages you record via the "message board." The application was designed to guide new users through a "Setup Checklist" which showcases various features of the Aptible platform (such as database migration, scaling, etc.) using both the dashboard and Aptible CLI.

# Deploy App

<Info> Prerequisite: Ensure you have [Git](https://git-scm.com/downloads) installed. </Info>

Using the [Deploy Code](https://app.aptible.com/create) tool in the Aptible Dashboard, you can deploy the **Deploy Demo App**. The tool will guide you through the following:

<Steps>
  <Step title="Deploy with Git Push">
    ![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/flask2.png)
  </Step>

  <Step title="Add an SSH key">
    ![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/flask3.png)
    If you have not done so already, you will be prompted to set up an [SSH key](/core-concepts/security-compliance/authentication/ssh-keys#ssh-keys).
  </Step>

  <Step title="Environment Setup">
    ![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/flask4.png)
    Select your [stack](/core-concepts/architecture/stacks) to deploy your resources. This will determine what region your resources are deployed to. Then, name the [environment](/core-concepts/architecture/environments) your resources will be grouped into.
  </Step>

  <Step title="Prepare the template">
    ![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/flask5.png)
    Select **Deploy Demo App** for deployment, and follow command-line instructions.
  </Step>

  <Step title="Fill environment variables and deploy">
    ![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/flask6.png)
    Aptible will automatically fill this template's app configuration, services, and required databases. This includes: a web server, a background worker, a Managed PostgreSQL Database, and a Redis instance. All you have to do is fill the complete the environment variables save and deploy the code!

    Aptible will show you the logs in live time:
    ![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/flask7.png)
  </Step>

  <Step title="Expose your app to the internet">
    ![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/flask8.png)
    Now that your code is deployed, it's time to expose your app to the internet. Select the service that needs an [endpoint](/core-concepts/apps/connecting-to-apps/app-endpoints/overview), and Aptible will automatically provision a managed endpoint.
  </Step>

  <Step title="View your deployed app" icon="party-horn">
    <Frame>
      ![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/flask9.png)
    </Frame>

    From here, you can optionally test the application's message board and/or "Setup Checklist."
  </Step>
</Steps>

# Continue your journey

<Card title="Deploy custom code" icon="books" iconType="duotone" href="https://www.aptible.com/docs/custom-code-quickstart">
  Read our guide for deploying custom code on Aptible.
</Card>


# Ruby on Rails - Starter Template

Deploy a starter template Ruby on Rails app on Aptible

<CardGroup cols={3}>
  <Card title="Deploy Now" icon="rocket" href="https://app.aptible.com/create" />

  <Card title="GitHub Repo" icon="github" href="https://github.com/aptible/template-rails" />

  <Card title="View Example" icon="browser" href="https://app-52710.on-aptible.com/" />
</CardGroup>

# Overview

This guide will walk you through the process of launching the [Rails Getting Started example](https://guides.rubyonrails.org/v4.2.7/getting_started.html) from the Aptible Dashboard.

# Deploying the template

<Info> Prerequisite: Ensure you have [Git](https://git-scm.com/downloads) installed.</Info>

Using the [Deploy Code](https://app.aptible.com/create) tool in the Aptible Dashboard, you can deploy the **Ruby on Rails Template**. The tool will guide you through the following:

<Steps>
  <Step title="Deploy with Git Push">
    ![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/ruby1.png)
  </Step>

  <Step title="Add an SSH key">
    ![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/ruby2.png)
    If you have not done so already, you will be prompted to set up an [SSH key](/core-concepts/security-compliance/authentication/ssh-keys#ssh-keys).
  </Step>

  <Step title="Environment Setup">
    ![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/ruby3.png)
    Select your [stack](/core-concepts/architecture/stacks) to deploy your resources. This will determine what region your resources are deployed to. Then, name the [environment](/core-concepts/architecture/environments) your resources will be grouped into.
  </Step>

  <Step title="Prepare the template">
    ![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/ruby4.png)
    Select `Ruby on Rails Template` for deployment, and follow command-line instructions.
  </Step>

  <Step title="Fill environment variables and deploy!">
    ![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/ruby4.png)
    Aptible will automatically fill this template's required databases, services, and app's configuration with environment variable keys for you to fill with values. Once complete, save and deploy the code!
  </Step>

  <Step title="View logs in real time">
    ![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/ruby6.png)
  </Step>

  <Step title="Expose your app to the internet">
    ![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/ruby7.png)
    Now that your code is deployed, it's time to expose your app to the internet. Select the service that needs an [endpoint](/core-concepts/apps/connecting-to-apps/app-endpoints/overview), and Aptible will automatically provision a managed endpoint.
  </Step>

  <Step title="View your deployed app 🎉" icon="party-horn">
    ![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/ruby8.png)
  </Step>
</Steps>

# Continue your journey

<Card title="Deploy custom code" icon="books" iconType="duotone" href="https://www.aptible.com/docs/custom-code-quickstart">
  Read our guide for deploying custom code on Aptible.
</Card>


# Aptible Documentation

A Platform as a Service (PaaS) that gives startups everything developers need to launch and scale apps and databases that are secure, reliable, and compliant — no manual configuration required.

## Explore compliance frameworks

<CardGroup cols={3}>
  <Card title="HIPAA" href="https://www.aptible.com/docs/core-concepts/security-compliance/compliance-frameworks/hipaa" img="https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/hipaa-icon.png">
    <Tooltip tip="This compliance framework's infrastructure controls/requirements are automatically satisfied when you deploy to a Dedicated Stack. See docs for more information.">Compliance-Ready </Tooltip>
  </Card>

  <Card title="PIPEDA" href="https://www.aptible.com/docs/core-concepts/security-compliance/compliance-frameworks/pipeda" img="https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/pipeda-icon.png">
    <Tooltip tip="This compliance framework's infrastructure controls/requirements are automatically satisfied when you deploy to a Dedicated Stack. See docs for more information.">Compliance-Ready</Tooltip>
  </Card>

  <Card title="GDPR" href="https://trust.aptible.com/" img="https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/gdpr-icon.png">
    <Tooltip tip="This compliance framework's infrastructure controls/requirements are automatically satisfied when you deploy to a Dedicated Stack. See docs for more information.">Compliance-Ready</Tooltip>
  </Card>

  <Card title="HITRUST" href="https://www.aptible.com/docs/core-concepts/security-compliance/compliance-frameworks/hitrust" img="https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/hitrust-icon.png">
    <Tooltip tip="Aptible is designed to fast-track satisfying this compliance framework's infrastructure controls/requirements when deployed to a Dedicated Stack. See docs for more information.">Compliance Fast-Track</Tooltip>
  </Card>

  <Card title="SOC 2" href="https://trust.aptible.com/" img="https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/soc-icon.png">
    <Tooltip tip="Aptible is designed to fast-track satisfying this compliance framework's infrastructure controls/requirements when deployed to a Dedicated Stack. See docs for more information.">Compliance Fast-Track</Tooltip>
  </Card>

  <Card title="PCI" href="https://www.aptible.com/docs/core-concepts/security-compliance/compliance-frameworks/pci" img="https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/pci-icon.png">
    <Tooltip tip="Aptible is designed to fast-track satisfying this compliance framework's infrastructure controls/requirements when deployed to a Dedicated Stack. See docs for more information.">Compliance Fast-Track</Tooltip>
  </Card>
</CardGroup>

## Deploy a starter template

Get started by deploying your own code or sample code from **Git** or **Docker**.

<CardGroup cols={3}>
  <Card title="Custom Code" icon="globe" href="https://www.aptible.com/docs/custom-code-quickstart">
    Explore compatibility and deploy custom code
  </Card>

  <Card
    title="Ruby "
    href="https://www.aptible.com/docs/ruby-quickstart"
    icon={
    <svg width="30" height="30" viewBox="0 0 256 255" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMinYMin meet"><defs><linearGradient x1="84.75%" y1="111.399%" x2="58.254%" y2="64.584%" id="a"><stop stop-color="#FB7655" offset="0%"/><stop stop-color="#FB7655" offset="0%"/><stop stop-color="#E42B1E" offset="41%"/><stop stop-color="#900" offset="99%"/><stop stop-color="#900" offset="100%"/></linearGradient><linearGradient x1="116.651%" y1="60.89%" x2="1.746%" y2="19.288%" id="b"><stop stop-color="#871101" offset="0%"/><stop stop-color="#871101" offset="0%"/><stop stop-color="#911209" offset="99%"/><stop stop-color="#911209" offset="100%"/></linearGradient><linearGradient x1="75.774%" y1="219.327%" x2="38.978%" y2="7.829%" id="c"><stop stop-color="#871101" offset="0%"/><stop stop-color="#871101" offset="0%"/><stop stop-color="#911209" offset="99%"/><stop stop-color="#911209" offset="100%"/></linearGradient><linearGradient x1="50.012%" y1="7.234%" x2="66.483%" y2="79.135%" id="d"><stop stop-color="#FFF" offset="0%"/><stop stop-color="#FFF" offset="0%"/><stop stop-color="#E57252" offset="23%"/><stop stop-color="#DE3B20" offset="46%"/><stop stop-color="#A60003" offset="99%"/><stop stop-color="#A60003" offset="100%"/></linearGradient><linearGradient x1="46.174%" y1="16.348%" x2="49.932%" y2="83.047%" id="e"><stop stop-color="#FFF" offset="0%"/><stop stop-color="#FFF" offset="0%"/><stop stop-color="#E4714E" offset="23%"/><stop stop-color="#BE1A0D" offset="56%"/><stop stop-color="#A80D00" offset="99%"/><stop stop-color="#A80D00" offset="100%"/></linearGradient><linearGradient x1="36.965%" y1="15.594%" x2="49.528%" y2="92.478%" id="f"><stop stop-color="#FFF" offset="0%"/><stop stop-color="#FFF" offset="0%"/><stop stop-color="#E46342" offset="18%"/><stop stop-color="#C82410" offset="40%"/><stop stop-color="#A80D00" offset="99%"/><stop stop-color="#A80D00" offset="100%"/></linearGradient><linearGradient x1="13.609%" y1="58.346%" x2="85.764%" y2="-46.717%" id="g"><stop stop-color="#FFF" offset="0%"/><stop stop-color="#FFF" offset="0%"/><stop stop-color="#C81F11" offset="54%"/><stop stop-color="#BF0905" offset="99%"/><stop stop-color="#BF0905" offset="100%"/></linearGradient><linearGradient x1="27.624%" y1="21.135%" x2="50.745%" y2="79.056%" id="h"><stop stop-color="#FFF" offset="0%"/><stop stop-color="#FFF" offset="0%"/><stop stop-color="#DE4024" offset="31%"/><stop stop-color="#BF190B" offset="99%"/><stop stop-color="#BF190B" offset="100%"/></linearGradient><linearGradient x1="-20.667%" y1="122.282%" x2="104.242%" y2="-6.342%" id="i"><stop stop-color="#BD0012" offset="0%"/><stop stop-color="#BD0012" offset="0%"/><stop stop-color="#FFF" offset="7%"/><stop stop-color="#FFF" offset="17%"/><stop stop-color="#C82F1C" offset="27%"/><stop stop-color="#820C01" offset="33%"/><stop stop-color="#A31601" offset="46%"/><stop stop-color="#B31301" offset="72%"/><stop stop-color="#E82609" offset="99%"/><stop stop-color="#E82609" offset="100%"/></linearGradient><linearGradient x1="58.792%" y1="65.205%" x2="11.964%" y2="50.128%" id="j"><stop stop-color="#8C0C01" offset="0%"/><stop stop-color="#8C0C01" offset="0%"/><stop stop-color="#990C00" offset="54%"/><stop stop-color="#A80D0E" offset="99%"/><stop stop-color="#A80D0E" offset="100%"/></linearGradient><linearGradient x1="79.319%" y1="62.754%" x2="23.088%" y2="17.888%" id="k"><stop stop-color="#7E110B" offset="0%"/><stop stop-color="#7E110B" offset="0%"/><stop stop-color="#9E0C00" offset="99%"/><stop stop-color="#9E0C00" offset="100%"/></linearGradient><linearGradient x1="92.88%" y1="74.122%" x2="59.841%" y2="39.704%" id="l"><stop stop-color="#79130D" offset="0%"/><stop stop-color="#79130D" offset="0%"/><stop stop-color="#9E120B" offset="99%"/><stop stop-color="#9E120B" offset="100%"/></linearGradient><radialGradient cx="32.001%" cy="40.21%" fx="32.001%" fy="40.21%" r="69.573%" id="m"><stop stop-color="#A80D00" offset="0%"/><stop stop-color="#A80D00" offset="0%"/><stop stop-color="#7E0E08" offset="99%"/><stop stop-color="#7E0E08" offset="100%"/></radialGradient><radialGradient cx="13.549%" cy="40.86%" fx="13.549%" fy="40.86%" r="88.386%" id="n"><stop stop-color="#A30C00" offset="0%"/><stop stop-color="#A30C00" offset="0%"/><stop stop-color="#800E08" offset="99%"/><stop stop-color="#800E08" offset="100%"/></radialGradient><linearGradient x1="56.57%" y1="101.717%" x2="3.105%" y2="11.993%" id="o"><stop stop-color="#8B2114" offset="0%"/><stop stop-color="#8B2114" offset="0%"/><stop stop-color="#9E100A" offset="43%"/><stop stop-color="#B3100C" offset="99%"/><stop stop-color="#B3100C" offset="100%"/></linearGradient><linearGradient x1="30.87%" y1="35.599%" x2="92.471%" y2="100.694%" id="p"><stop stop-color="#B31000" offset="0%"/><stop stop-color="#B31000" offset="0%"/><stop stop-color="#910F08" offset="44%"/><stop stop-color="#791C12" offset="99%"/><stop stop-color="#791C12" offset="100%"/></linearGradient></defs><path d="M197.467 167.764l-145.52 86.41 188.422-12.787L254.88 51.393l-57.414 116.37z" fill="url(#a)"/><path d="M240.677 241.257L224.482 129.48l-44.113 58.25 60.308 53.528z" fill="url(#b)"/><path d="M240.896 241.257l-118.646-9.313-69.674 21.986 188.32-12.673z" fill="url(#c)"/><path d="M52.744 253.955l29.64-97.1L17.16 170.8l35.583 83.154z" fill="url(#d)"/><path d="M180.358 188.05L153.085 81.226l-78.047 73.16 105.32 33.666z" fill="url(#e)"/><path d="M248.693 82.73l-73.777-60.256-20.544 66.418 94.321-6.162z" fill="url(#f)"/><path d="M214.191.99L170.8 24.97 143.424.669l70.767.322z" fill="url(#g)"/><path d="M0 203.372l18.177-33.151-14.704-39.494L0 203.372z" fill="url(#h)"/><path d="M2.496 129.48l14.794 41.963 64.283-14.422 73.39-68.207 20.712-65.787L143.063 0 87.618 20.75c-17.469 16.248-51.366 48.396-52.588 49-1.21.618-22.384 40.639-32.534 59.73z" fill="#FFF"/><path d="M54.442 54.094c37.86-37.538 86.667-59.716 105.397-40.818 18.72 18.898-1.132 64.823-38.992 102.349-37.86 37.525-86.062 60.925-104.78 42.027-18.73-18.885.515-66.032 38.375-103.558z" fill="url(#i)"/><path d="M52.744 253.916l29.408-97.409 97.665 31.376c-35.312 33.113-74.587 61.106-127.073 66.033z" fill="url(#j)"/><path d="M155.092 88.622l25.073 99.313c29.498-31.016 55.972-64.36 68.938-105.603l-94.01 6.29z" fill="url(#k)"/><path d="M248.847 82.833c10.035-30.282 12.35-73.725-34.966-81.791l-38.825 21.445 73.791 60.346z" fill="url(#l)"/><path d="M0 202.935c1.39 49.979 37.448 50.724 52.808 51.162l-35.48-82.86L0 202.935z" fill="#9E1209"/><path d="M155.232 88.777c22.667 13.932 68.35 41.912 69.276 42.426 1.44.81 19.695-30.784 23.838-48.64l-93.114 6.214z" fill="url(#m)"/><path d="M82.113 156.507l39.313 75.848c23.246-12.607 41.45-27.967 58.121-44.42l-97.434-31.428z" fill="url(#n)"/><path d="M17.174 171.34l-5.57 66.328c10.51 14.357 24.97 15.605 40.136 14.486-10.973-27.311-32.894-81.92-34.566-80.814z" fill="url(#o)"/><path d="M174.826 22.654l78.1 10.96c-4.169-17.662-16.969-29.06-38.787-32.623l-39.313 21.663z" fill="url(#p)"/></svg>
    }
  >
    Deploy using a Ruby on Rails template
  </Card>

  <Card
    title="NodeJS"
    href="https://www.aptible.com/docs/node-js-quickstart"
    icon={
    <svg xmlns="http://www.w3.org/2000/svg" width="30" height="30" viewBox="0 0 58 64" fill="none">
    <path d="M26.3201 0.681001C27.9201 -0.224999 29.9601 -0.228999 31.5201 0.681001L55.4081 14.147C56.9021 14.987 57.9021 16.653 57.8881 18.375V45.375C57.8981 47.169 56.8001 48.871 55.2241 49.695L31.4641 63.099C30.6514 63.5481 29.7333 63.7714 28.8052 63.7457C27.877 63.7201 26.9727 63.4463 26.1861 62.953L19.0561 58.833C18.5701 58.543 18.0241 58.313 17.6801 57.843C17.9841 57.435 18.5241 57.383 18.9641 57.203C19.9561 56.887 20.8641 56.403 21.7761 55.891C22.0061 55.731 22.2881 55.791 22.5081 55.935L28.5881 59.451C29.0221 59.701 29.4621 59.371 29.8341 59.161L53.1641 45.995C53.4521 45.855 53.6121 45.551 53.5881 45.235V18.495C53.6201 18.135 53.4141 17.807 53.0881 17.661L29.3881 4.315C29.2515 4.22054 29.0894 4.16976 28.9234 4.16941C28.7573 4.16905 28.5951 4.21912 28.4581 4.313L4.79207 17.687C4.47207 17.833 4.25207 18.157 4.29207 18.517V45.257C4.26407 45.573 4.43207 45.871 4.72207 46.007L11.0461 49.577C12.2341 50.217 13.6921 50.577 15.0001 50.107C15.5725 49.8913 16.0652 49.5058 16.4123 49.0021C16.7594 48.4984 16.9443 47.9007 16.9421 47.289L16.9481 20.709C16.9201 20.315 17.2921 19.989 17.6741 20.029H20.7141C21.1141 20.019 21.4281 20.443 21.3741 20.839L21.3681 47.587C21.3701 49.963 20.3941 52.547 18.1961 53.713C15.4881 55.113 12.1401 54.819 9.46407 53.473L2.66407 49.713C1.06407 48.913 -0.00993076 47.185 6.9243e-05 45.393V18.393C0.0067219 17.5155 0.247969 16.6557 0.698803 15.9027C1.14964 15.1498 1.79365 14.5312 2.56407 14.111L26.3201 0.681001ZM33.2081 19.397C36.6621 19.197 40.3601 19.265 43.4681 20.967C45.8741 22.271 47.2081 25.007 47.2521 27.683C47.1841 28.043 46.8081 28.243 46.4641 28.217C45.4641 28.215 44.4601 28.231 43.4561 28.211C43.0301 28.227 42.7841 27.835 42.7301 27.459C42.4421 26.179 41.7441 24.913 40.5401 24.295C38.6921 23.369 36.5481 23.415 34.5321 23.435C33.0601 23.515 31.4781 23.641 30.2321 24.505C29.2721 25.161 28.9841 26.505 29.3261 27.549C29.6461 28.315 30.5321 28.561 31.2541 28.789C35.4181 29.877 39.8281 29.789 43.9141 31.203C45.6041 31.787 47.2581 32.923 47.8381 34.693C48.5941 37.065 48.2641 39.901 46.5781 41.805C45.2101 43.373 43.2181 44.205 41.2281 44.689C38.5821 45.279 35.8381 45.293 33.1521 45.029C30.6261 44.741 27.9981 44.077 26.0481 42.357C24.3801 40.909 23.5681 38.653 23.6481 36.477C23.6681 36.109 24.0341 35.853 24.3881 35.883H27.3881C27.7921 35.855 28.0881 36.203 28.1081 36.583C28.2941 37.783 28.7521 39.083 29.8161 39.783C31.8681 41.107 34.4421 41.015 36.7901 41.053C38.7361 40.967 40.9201 40.941 42.5101 39.653C43.3501 38.919 43.5961 37.693 43.3701 36.637C43.1241 35.745 42.1701 35.331 41.3701 35.037C37.2601 33.737 32.8001 34.209 28.7301 32.737C27.0781 32.153 25.4801 31.049 24.8461 29.351C23.9601 26.951 24.3661 23.977 26.2321 22.137C28.0321 20.307 30.6721 19.601 33.1721 19.349L33.2081 19.397Z" fill="#8CC84B"/></svg>
    }
  >
    Deploy using a Node.js + Express template
  </Card>

  <Card
    title="Django"
    href="https://www.aptible.com/docs/python-quickstart"
    icon={
    <svg width="30" height="30" viewBox="0 0 256 326" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMinYMin meet"><g fill="#2BA977"><path d="M114.784 0h53.278v244.191c-27.29 5.162-47.38 7.193-69.117 7.193C33.873 251.316 0 222.245 0 166.412c0-53.795 35.93-88.708 91.608-88.708 8.64 0 15.222.68 23.176 2.717V0zm1.867 124.427c-6.24-2.038-11.382-2.717-17.965-2.717-26.947 0-42.512 16.437-42.512 45.243 0 28.046 14.88 43.532 42.17 43.532 5.896 0 10.696-.332 18.307-1.351v-84.707z"/><path d="M255.187 84.26v122.263c0 42.105-3.154 62.353-12.411 79.81-8.64 16.783-20.022 27.366-43.541 39.055l-49.438-23.297c23.519-10.93 34.901-20.588 42.17-35.327 7.61-15.072 10.01-32.529 10.01-78.445V84.261h53.21zM196.608 0h53.278v54.135h-53.278V0z"/></g></svg>
    }
  >
    Deploy using a Python + Django template.
  </Card>

  <Card
    title="Laravel"
    href="https://www.aptible.com/docs/php-quickstart"
    icon={
    <svg height="30" viewBox="0 -.11376601 49.74245785 51.31690859" width="30" xmlns="http://www.w3.org/2000/svg"><path d="m49.626 11.564a.809.809 0 0 1 .028.209v10.972a.8.8 0 0 1 -.402.694l-9.209 5.302v10.509c0 .286-.152.55-.4.694l-19.223 11.066c-.044.025-.092.041-.14.058-.018.006-.035.017-.054.022a.805.805 0 0 1 -.41 0c-.022-.006-.042-.018-.063-.026-.044-.016-.09-.03-.132-.054l-19.219-11.066a.801.801 0 0 1 -.402-.694v-32.916c0-.072.01-.142.028-.21.006-.023.02-.044.028-.067.015-.042.029-.085.051-.124.015-.026.037-.047.055-.071.023-.032.044-.065.071-.093.023-.023.053-.04.079-.06.029-.024.055-.05.088-.069h.001l9.61-5.533a.802.802 0 0 1 .8 0l9.61 5.533h.002c.032.02.059.045.088.068.026.02.055.038.078.06.028.029.048.062.072.094.017.024.04.045.054.071.023.04.036.082.052.124.008.023.022.044.028.068a.809.809 0 0 1 .028.209v20.559l8.008-4.611v-10.51c0-.07.01-.141.028-.208.007-.024.02-.045.028-.068.016-.042.03-.085.052-.124.015-.026.037-.047.054-.071.024-.032.044-.065.072-.093.023-.023.052-.04.078-.06.03-.024.056-.05.088-.069h.001l9.611-5.533a.801.801 0 0 1 .8 0l9.61 5.533c.034.02.06.045.09.068.025.02.054.038.077.06.028.029.048.062.072.094.018.024.04.045.054.071.023.039.036.082.052.124.009.023.022.044.028.068zm-1.574 10.718v-9.124l-3.363 1.936-4.646 2.675v9.124l8.01-4.611zm-9.61 16.505v-9.13l-4.57 2.61-13.05 7.448v9.216zm-36.84-31.068v31.068l17.618 10.143v-9.214l-9.204-5.209-.003-.002-.004-.002c-.031-.018-.057-.044-.086-.066-.025-.02-.054-.036-.076-.058l-.002-.003c-.026-.025-.044-.056-.066-.084-.02-.027-.044-.05-.06-.078l-.001-.003c-.018-.03-.029-.066-.042-.1-.013-.03-.03-.058-.038-.09v-.001c-.01-.038-.012-.078-.016-.117-.004-.03-.012-.06-.012-.09v-21.483l-4.645-2.676-3.363-1.934zm8.81-5.994-8.007 4.609 8.005 4.609 8.006-4.61-8.006-4.608zm4.164 28.764 4.645-2.674v-20.096l-3.363 1.936-4.646 2.675v20.096zm24.667-23.325-8.006 4.609 8.006 4.609 8.005-4.61zm-.801 10.605-4.646-2.675-3.363-1.936v9.124l4.645 2.674 3.364 1.937zm-18.422 20.561 11.743-6.704 5.87-3.35-8-4.606-9.211 5.303-8.395 4.833z" fill="#ff2d20"/></svg>
    }
  >
    Deploy using a PHP + Laravel template
  </Card>

  <Card
    title="Python"
    href="https://www.aptible.com/docs/deploy-demo-app"
    icon={
    <svg width="30" height="30" viewBox="0 0 256 255" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMinYMin meet"><defs><linearGradient x1="12.959%" y1="12.039%" x2="79.639%" y2="78.201%" id="a"><stop stop-color="#387EB8" offset="0%"/><stop stop-color="#366994" offset="100%"/></linearGradient><linearGradient x1="19.128%" y1="20.579%" x2="90.742%" y2="88.429%" id="b"><stop stop-color="#FFE052" offset="0%"/><stop stop-color="#FFC331" offset="100%"/></linearGradient></defs><path d="M126.916.072c-64.832 0-60.784 28.115-60.784 28.115l.072 29.128h61.868v8.745H41.631S.145 61.355.145 126.77c0 65.417 36.21 63.097 36.21 63.097h21.61v-30.356s-1.165-36.21 35.632-36.21h61.362s34.475.557 34.475-33.319V33.97S194.67.072 126.916.072zM92.802 19.66a11.12 11.12 0 0 1 11.13 11.13 11.12 11.12 0 0 1-11.13 11.13 11.12 11.12 0 0 1-11.13-11.13 11.12 11.12 0 0 1 11.13-11.13z" fill="url(#a)"/><path d="M128.757 254.126c64.832 0 60.784-28.115 60.784-28.115l-.072-29.127H127.6v-8.745h86.441s41.486 4.705 41.486-60.712c0-65.416-36.21-63.096-36.21-63.096h-21.61v30.355s1.165 36.21-35.632 36.21h-61.362s-34.475-.557-34.475 33.32v56.013s-5.235 33.897 62.518 33.897zm34.114-19.586a11.12 11.12 0 0 1-11.13-11.13 11.12 11.12 0 0 1 11.13-11.131 11.12 11.12 0 0 1 11.13 11.13 11.12 11.12 0 0 1-11.13 11.13z" fill="url(#b)"/></svg>
    }
  >
    Deploy Python + Flask Demo app
  </Card>
</CardGroup>

## Provision secure, managed databases

Instantly provision secure, encrypted databases - **managed 24x7 by the Aptible SRE team**.

<CardGroup cols={4}>
  <Card title="Elasticsearch" href="https://www.aptible.com/docs/elasticsearch" img="https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/Elasticsearch.png" />

  <Card title="InfluxDB" href="https://www.aptible.com/docs/influxdb" img="https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/InfluxDB.png" />

  <Card title="MongoDB" href="https://www.aptible.com/docs/mongodb" img="https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/MongoDB.png" />

  <Card title="MySQL" href="https://www.aptible.com/docs/mysql" img="https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/MySQL.png" />

  <Card title="PostgreSQL" href="https://www.aptible.com/docs/postgresql" img="https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/PostgreSQL.png" />

  <Card title="RabbitMQ" href="https://www.aptible.com/docs/rabbitmq" img="https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/RabbitMQ.png" />

  <Card title="Redis" href="https://www.aptible.com/docs/redis" img="https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/Redis.png" />

  <Card title="SFTP" href="https://www.aptible.com/docs/sftp" img="https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/SFTP.png" />
</CardGroup>

## Use tools developers love

<CardGroup cols={2}>
  <Card title="Install the Aptible CLI" href="https://www.aptible.com/docs/reference/aptible-cli/overview">
    ```
     brew install --cask aptible
    ```
  </Card>

  <Card title="Browse tools & integrations" href="https://www.aptible.com/docs/core-concepts/integrations/overview" img="https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/Integrations-icon.png" />
</CardGroup>

## Get help when you need it

<CardGroup cols={2}>
  <Card title="Troubleshooting Guides" icon="circle-info" href="https://www.aptible.com/docs/common-erorrs">
    Hitting an error? Read our troubleshooting guides for common errors
  </Card>

  <Card title="Contact Support" icon="comment" href="https://app.aptible.com/support">
    Have a question? Reach out to Aptible Support
  </Card>
</CardGroup>


# Introduction to Aptible

Learn what Aptible is and why scaling companies use it to host their apps and data in the cloud

## Overview

Aptible is a [Platform as a Service](/reference/glossary#paas) (PaaS) used by companies that want their development teams to focus on their product, not managing infrastructure.

Like other PaaS solutions, Aptible streamlines the code shipping process for development teams, facilitating deployment, monitoring, and infrastructure scaling. This includes:

*   A simplified app deployment process to deploy code in seconds

*   Seamless integration with your CI/CD tools

*   Performance monitoring via Aptible's observability tools or integration with your existing toolset

*   A broad range of apps, databases, and frameworks to easily start and scale your projects

*   Flexibility in choosing your preferred interfaces — using the Aptible CLI, dashboard, or our Terraform provider

What sets Aptible apart from other PaaS solutions is our commitment to scalability, reliability, and security & compliance.

### Scalability

To ensure we stay true to our mission of allowing our customers to focus on their product and not infrastructure — we’ve engineered our platform to seamlessly accommodate the growth of organizations. This includes:

*   On-demand scaling or automatically with vertical autoscaling (BETA)

*   A variety of Container Profiles — General Purpose, RAM Optimized, or CPU Optimized — to fine-tune resource allocation and optimize costs

*   Large-size instance types are available to support large workloads as you grow — scale vertically up to 653GB RAM, 200GB CPUs, 16384GB Disk, or horizontally up to 32 containers

> Check out our [customer success stories](https://www.aptible.com/customers) to learn more from companies that have scaled their infrastructure on Aptible, from startup to enterprise.

### Reliability

We believe in reliable infrastructure for all. That’s why we provide reliability-focused functionality to minimize downtime — by default, and we make implementing advanced reliability practices, like multi-region support, a breeze. This includes:

*   Zero-downtime app deployments and minimal downtime for databases (typical 1 minute)

*   Instant rollbacks for failed deployments and high-availability app deployments — by default

*   Fully Managed Databases with monitoring, maintenance, replicas, and in-place upgrades to ensure that your databases run smoothly and securely

*   Uptime averaging at 99.98%, with a guaranteed SLA of 99.95%, and 24/7 Site Reliability Engineers (SRE) monitoring to safeguard your applications

*   Multi-region support to minimize impact from major outages

### Security & Compliance

[Our story](/getting-started/introduction#our-story) began with a focus on security & compliance — making us the leading PaaS for security & compliance. We provide developer-friendly infrastructure guardrails and solutions to help our customers navigate security audits and achieve compliance. This includes:

*   A Security and Compliance Dashboard to review what’s implemented, track progress, achieve compliance, and easily share a summarized report,

*   Encryption, DDoS protection, host hardening, intrusion detection, and vulnerability scanning, so you don’t have to think about security best practices

*   Secure access to your resources with granular user permission controls, Multi-Factor Authentication (MFA), and Single Sign-On (SSO) support

*   HIPAA Business Associate Agreements (BAAs), HITRUST Inheritance, and streamlined SOC 2 compliance — CISO-approved

## Our story

Our journey began in **2013**, a time when HIPAA, with all its complexities, was still relatively new and challenging to decipher. As we approached September 2013, an impending deadline loomed large—the HIPAA Omnibus Rule was set to take effect in September 2023, mandating thousands of digital health companies to comply with HIPAA basically overnight. Recognizing this imminent need, Aptible embarked on a mission to simplify HIPAA for developers in healthcare, from solo developers at startups to large-scale development teams who lacked the time/resources to delve into the compliance space.

We brought a platform to the market that made HIPAA compliance achievable from day 1. Soon after, we expanded our scope to support HITRUST, SOC 2, ISO 27001, and more — establishing ourselves as the **go-to PaaS for digital health companies**.

As we continued to evolve our platform, we realized we had created something exceptional—a platform that streamlines security and compliance, offers reliable and high-performance infrastructure as the default, allows for easy resource scaling, and, to top it all off, features a best-in-class support team providing invaluable infrastructure expertise to our customers. It became evident that it could benefit a broader range of companies beyond the digital health sector. This realization led to a pivotal shift in our mission—to **alleviate infrastructure challenges for all dev teams**, not limited to healthcare.

## Explore more

<CardGroup cols={2}>
  <Card title="Supported Regions" href="https://www.aptible.com/docs/core-concepts/architecture/stacks#supported-regions" img="https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/Regions-icon.png" />

  <Card title="Tools & integrations" href="https://www.aptible.com/docs/core-concepts/integrations/overview" img="https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/Integrations-icon.png" />
</CardGroup>


# How to access configuration variables during Docker build



By design (for better or worse), Docker doesn't allow setting arbitrary environment variables during the Docker build process: that is only possible when running [Containers](/core-concepts/architecture/containers/overview) after the [Image](/core-concepts/apps/deploying-apps/image/overview) is built.

The rationale for this is that [Dockerfiles](/core-concepts/apps/deploying-apps/image/deploying-with-git/overview) should be fully portable and not tied to any specific environment.

A direct consequence of this design is that your [Configuration](/core-concepts/apps/deploying-apps/configuration) variables, set via [`aptible config:set`](/reference/aptible-cli/cli-commands/cli-config-set), are not available to commands executed during the Docker build.

It's a good idea to follow Docker best practice and avoid depending on Configuration variables in instructions in your Dockerfile, but if you absolutely need to, Aptible provides a workaround: `.aptible.env`.

## `.aptible.env`

When building your image, Aptible injects a `.aptible.env` file at the root of your repository prior to running the Docker build. The file contains your Configuration variables, and can be sourced by a shell.

Here's an example:

```ruby
RAILS_ENV=production
DATABASE_URL=postgresql://user:password@host:123/db
```

If needed, you can use this file to access environment variables during your build, like this:

```ruby
# Assume that you've already ADDed your repo:
ADD . /app
WORKDIR /app

# The bundle exec rake assets:precompile command
# will run with your configuration
RUN set -a && . /app/.aptible.env && \
        bundle exec rake assets:precompile
```

> ❗️ Do **not** use the `.aptible.env` file outside of Dockerfile instructions. This file is only injected when your image is built, so changes to your configuration will **not** be reflected in the `.aptible.env` file unless you deploy again or rebuild. Outside of your Dockerfile, your configuration variables are accessible in the [Container Environment](/core-concepts/architecture/containers/overview).


# How to define services



Learn how to define [services](/core-concepts/apps/deploying-apps/services)

## Implicit Service (CMD)

If your App's [Image](/core-concepts/apps/deploying-apps/image/overview) includes a `CMD` and/or `ENTRYPOINT` declaration, a single implicit `cmd` service will be created for it when you deploy your App.

[Containers](/core-concepts/architecture/containers/overview) for the implicit `cmd` Service will execute the `CMD` your image defines (if you have an `ENTRYPOINT` defined, then the `CMD` will be passed as arguments to the `ENTRYPOINT`).

This corresponds to Docker's behavior when you use `docker run`, so if you've started Containers for your image locally using `docker run my-image`, you can expect Containers started on Aptible to behave identically.

Typically, the `CMD` declaration is something you'd add in your Dockerfile, like so:

```sql
FROM alpine:3.5
ADD . /app
CMD ["/app/run"]
```

> 📘 Using an implicit service is recommended if your App only has one Service.

## Explicit Services (Procfiles)

Procfiles are used to define \[Explicit Services (Procfiles) for an app. They are completely optional: in the absence of a Procfile, Aptible will fall back to an Implicit Service. Explicit services allow you to specify commands for each service, like `web` or `worker` while implicit services use the `cmd` or `ENTRYPOINT` defined in the image.

### Step 01: Providing a Procfile

There are two ways to provide a Procfile:

*   **Deploying via Git Push:** If you are deploying via Git, add a file named `Procfile` at the root of your repository.
*   **Deploying via Docker Image:** If you are using Docker Image, it must be located at `/.aptible/Procfile` in your Docker image. See [Procfiles and `.aptible.yml` with Direct Docker Image Deploy](/core-concepts/apps/deploying-apps/image/deploying-with-docker-image/procfile-aptible-yml-direct-docker-deploy) for more information.

> 📘 Note the following when using Procfile:\
> **-Procfile syntax:** The [Procfile syntax is standardized](https://ddollar.github.io/foreman/), and consists of a mapping of one or more Service names to commands that should be executed for those Services. The two should be separated by a `:` character.\
> **-Procfile commands:** The commands in your Procfile (i.e. the section to the right of the : character) is interpreted differently depending on whether your image has an ENTRYPOINT or not:

### Step 02: Executing your Procfile

#### Images without an `ENTRYPOINT`

If your image does not have an `ENTRYPOINT`, the Procfile will be executed using a shell (`/bin/sh`). This means you can use shell syntax, such as:

```sql
web: setup && run "$ENVIRONMENT"
```

**Advanced: PID 1 in your Container is a shell**

> 📘 The following is advanced information. You don't need to understand or leverage this information to use Aptible, but it might be relevant if you want to precisely control the behavior of your Containers. PID 1 is the process that receives signals when your Container is signaled (e.g. PID receives `SIGTERM` when your Container needs to shut down during a deployment). Since a shell is used as the command in your Containers to interpret your Procfile, this means PID 1 will be a shell. Shells don't typically forward signals, which means that when your Containers receive `SIGTERM`, they'll do nothing if a shell is running as PID 1. As a result, running a shell there may not be desirable.

If you'd like to get the shell out of the equation when running your Containers, you can use the exec call, like so:

```sql
web: setup && exec run "$ENVIRONMENT"
```

This will replace the shell with the run program as PID 1.

#### Images with an `ENTRYPOINT`

If your image has an `ENTRYPOINT`, Aptible will not use a shell to interpret your Procfile. Instead, your Procfile line is split according to shell rules, then simply passed to your Container's `ENTRYPOINT` as a series of arguments.

For example, if your Procfile looks like this:

```
web: run "$ENVIRONMENT"
```

Then, your `ENVIRONMENT` will receive the **literal** strings `run` and `$ENVIRONMENT` as arguments (i.e. the value for `$ENVIRONMENT` will **not** be interpolated).

This means your Procfile doesn't need to reference commands that exist in your Container: it only means to reference commands that make sense to your `ENTRYPOINT`.

However, it also means that you can't interpolate variables in your Procfile line. If you do need shell processing for interpolation with an `ENTRYPOINT`, here are two options:

**Call a shell from the Procfile**

The simplest option is to alter your `Procfile` to call a shell itself, like so:

```sql
web: sh -c 'setup && exec run "$ENVIRONMENT"'
```

**Use a launcher script**

A better approach is to add a launcher script in your Docker image, and delegate shell processing there. To do so, create a file called `/app.sh` in your image, with the following contents, and make it executable:

```sql
#!/bin/sh
# Make this executable
# Adjust the commands as needed, of course!
setup && exec run "$ENVIRONMENT"
```

Once you have this launcher script, your Procfile can simply reference the launcher script, which is simpler and more explicit:

```sql
web: /app.sh
```

Of course, you can use any name you like: `/app.sh` isn't the only one that works! Just make sure the Procfile references the launcher script.

## Step 03: Scale your services (optionally)

Aptible will automatically provision the services defined in your Procfile into app containers. You can scale services independently via the Aptible Dashboard or Aptible CLI:

```sql
aptible apps:scale SERVICE [--container-count COUNT] [--container-size SIZE_MB]
```

When a service is scaled with 2+ containers, the platform will automatically deploy your app containers with high-availability.


# How to deploy via Docker Image

Learn how to deploy your code to Aptible from a Docker Image

## Overview

Aptible lets you [deploying via Docker image](/how-to-guides/app-guides/migrate-dockerfile-to-direct-image-deploy). Additionally, [Aptible's Terraform Provider](/reference/terraform) currently only supports this deployment method.

This guide will cover the process for deploying via Docker image to Aptible via the CLI, Terraform, or CI/CD.

## Deploying via the CLI

> ⚠️ Prerequisites: Install the [Aptible CLI](/reference/aptible-cli/cli-commands/overview)

### 01: Create an app

Use the `aptible apps:create` to create an [app](/core-concepts/apps/overview). Note the handle you give to the app. We'll refer to it as `$APP_HANDLE`.

### 02: Deploy a Docker image to your app

Use the `aptible deploy` command to deploy a public Docker image to your app like so:

```js
aptible deploy --app "$APP_HANDLE" \
        --docker-image httpd:alpine
```

After you've deployed using [aptible deploy](/reference/aptible-cli/cli-commands/cli-deploy), if you update your image or would like to deploy a different image, use [aptible deploy](/reference/aptible-cli/cli-commands/cli-deploy) again (if your Docker image's name hasn't changed, you don't even need to pass the --docker-image argument again).

> 📘 If you are migrating from [Dockerfile Deploy](/how-to-guides/app-guides/deploy-from-git), you should also add the --git-detach flag to this command the first time you deploy. See [Migrating from Dockerfile Deploy](/how-to-guides/app-guides/migrate-dockerfile-to-direct-image-deploy) for more information.

## Deploying via Terraform

> ⚠️ Prerequisites: Install the [Aptible CLI](/reference/aptible-cli/cli-commands/overview) and the Terraform CLI

### 01: Create an app

[Apps](https://www.aptible.com/documentation/deploy/reference/apps.html) can be created using the **terraform** **`aptible_app`** resource.

```js
resource "aptible_app" "APP" {
    env_id = ENVIRONMENT_ID
    handle = "APP_HANDLE"
}
```

### Step 2: Deploy a Docker Image

Set your Docker repo with the registry username and registry password as the configuration variables: `APTIBLE_DOCKER_IMAGE`, `APTIBLE_PRIVATE_REGISTRY_USERNAME`, and `APTIBLE_PRIVATE_REGISTRY_PASSWORD`.

```lua
resource "aptible_app" "APP" {
    env_id = ENVIRONMENT_ID
    handle = "APP_HANDLE"
    config = {
        "KEY" = "value"
        "APTIBLE_DOCKER_IMAGE" = "quay.io/aptible/deploy-demo-app"
        "APTIBLE_PRIVATE_REGISTRY_USERNAME" = "registry_username"
        "APTIBLE_PRIVATE_REGISTRY_PASSWORD" = "registry_password"
    }
}
```

> 📘 Please ensure you have the correct image, username, and password set every time you run. `terraform apply` See [Terraform's refresh Terraform configuration documentation](https://developer.hashicorp.com/terraform/cli/commands/refresh) for more infromation

## Deploying via CI/CD

See related guide: [How to deploy to Aptible with CI/CD](/how-to-guides/app-guides/how-to-deploy-aptible-ci-cd#deploying-with-docker)


# How to deploy from Git

Guide for deploying from Git using Dockerfile Deploy

## **Overview**

With Aptible, you have the option to deploy your code directly from Git using [Dockerfile Deploy](/how-to-guides/app-guides/deploy-from-git). This method involves pushing your source code, including a Dockerfile, to Aptible's Git repository. Aptible will then create a Docker image for you, simplifying the deployment process. This guide will walk you through the steps of using Dockerfile Deploy to deploy your code from Git to Aptible.

## Deploying via the Dashboard

The easiest way to deploy with Dockerfile Deploy within the Aptible Dashboard is by deploying a [template](/getting-started/deploy-starter-template/overview) or [custom code](/getting-started/deploy-custom-code) using the Deploy tool.

## Deploying via the CLI

> ⚠️ Prerequisites: Install the [Aptible CLI](/reference/aptible-cli/cli-commands/overview)

**Step 1: Create an app**

Use the `aptible apps:create` to create an [app](/core-concepts/apps/overview). Note the provided Git Remote. As we advance in this article, we'll refer to it as `$GIT_URL`.

**Step 2: Create a git repository on your local workstation**

Example:

```pl
git init test-dockerfile-deploy
cd test-dockerfile-deploy
```

**Step 3: Add your** [**Dockerfile**](/core-concepts/apps/deploying-apps/image/deploying-with-git/overview) **in the root of the repository**

Example:

```pl
# Declare a base image:
FROM httpd:alpine

# Tell Aptible this app will be accessible over port 80:
EXPOSE 80

# Tell Aptible to run "httpd -f" to start this app:
CMD ["httpd", "-f"]
```

Step 4: Deploy to Aptible:

```pl
# Commit the Dockerfile
git add Dockerfile
git commit -m "Add a Dockerfile"

# This URL is available in the Aptible Dashboard under "Git Remote".
# You got it after creating your app.
git remote add aptible "$GIT_URL"

# Push to Aptible
git push aptible master
```

## Deploying via Terraform

Dockerfile Deploy is not supported by Terraform. Use [Direct Docker Image Deploy](/how-to-guides/app-guides/migrate-dockerfile-to-direct-image-deploy) with Terraform instead.


# Deploy Metric Drain with Terraform



Deploying [Metric Drains](/core-concepts/observability/metrics/metrics-drains/overview) with [Aptible's Terraform Provider](https://registry.terraform.io/providers/aptible/aptible/latest) is relativley straight-forward, with some minor configuration exceptions. Aptible's Terraform Provider uses the Aptible CLI for authorization and authentication, so please run `aptible login` before we get started.

## Prerequisites

1.  [Terraform](https://developer.hashicorp.com/terraform/install?ajs_aid=c5fc0f0b-590f-4dee-bf72-6f6ed1017286\&product_intent=terraform)
2.  The [Aptible CLI](/reference/aptible-cli/cli-commands/overview)

You also need to be logged in to Aptible.

```
$ aptible login
```

## Getting Started

First, lets set up your Terraform directory to work with Aptible. Create a directory with a `main.tf` file and then run `terraform init` in the root of the directory.

Next, you will define where you want your metric drain to capture metrics. Whether this is a new environment or an exisiting one. If you are placing this in an exisiting environment you can skip this step, just make sure you have your [environment ID](https://github.com/aptible/terraform-provider-aptible/blob/master/docs/index.md#determining-the-environment-id).

```js
data "aptible_stack" "test-stack" {
    name = "test-stack"
}

resource "aptible_environment" "test-env" {
    stack_id = data.aptible_stack.test-stack.stack_id
    // if you use a shared stack above, you will have to manually grab your org_id
    org_id = data.aptible_stack.test-stack.org_id
    handle = "test-env"
}
```

Next, we will actually create the metric drain resource in Terraform, please select the drain type you wish to use from below.

<Tabs>
  <Tab title="Datadog">
    ```js
    resource "aptible_metric_drain" "datadog_drain" {
    env_id     = data.aptible_environment.example.env_id
    drain_type = "datadog"
    api_key    = "xxxxx-xxxxx-xxxxx"
    }
    ```
  </Tab>

  <Tab title="Aptible InfluxDB Database">
    ```js
    resource "aptible_metric_drain" "influxdb_database_drain" {
    env_id      = data.aptible_environment.example.env_id
    database_id = aptible_database.example.database_id
    drain_type  = "influxdb_database"
    handle      = "aptible-hosted-metric-drain"
    }
    ```
  </Tab>

  <Tab title="InfluxDB">
    ```js
    resource "aptible_metric_drain" "influxdb_drain" {
    env_id     = data.aptible_environment.example.env_id
    drain_type = "influxdb"
    handle     = "influxdb-metric-drain"
    url        = "https://influx.example.com:443"
    username   = "example_user"
    password   = "example_password"
    database   = "metrics"
    }
    ```
  </Tab>
</Tabs>

To check to make sure your changes are valid (in case of any changes not mentioned), run `terraform validate`

To deploy the above changes, run `terraform apply`

## Troubleshooting

## App configuration issues with Datadog

> Some users have reported issues with applications not sending logs to Datadog, applications will need additional configuration set. Below is an example.

```js
    resource "aptible_app" "load-test-datadog" {
        env_id = data.aptible_environment.example_environment.env_id
        handle = "example-app"
        config = {
            "APTIBLE_DOCKER_IMAGE" : "docker.io/datadog/agent:latest",
            "DD_APM_NON_LOCAL_TRAFFIC" : true,
            "DD_BIND_HOST" : "0.0.0.0",
            "DD_API_KEY" :"xxxxx-xxxxx-xxxxx",
            "DD_HOSTNAME_TRUST_UTS_NAMESPACE" : true,
            "DD_ENV" : "your environment",
            "DD_HOSTNAME" : "dd-hostname" # this does not have to match the hostname
        }
        service {
            process_type = "cmd"
            container_count = 1
            container_memory_limit = 1024
        }
    }
```

As a final note, if you have any questions about the Terraform provider please reach out to support or checkout our public [Terraform Provider Repository](https://github.com/aptible/terraform-provider-aptible) for more information!


# How to migrate from deploying via Docker Image to deploying via Git

Guide for migrating from deploying via Docker Image to deploying via Git

## Overview

Suppose you configured your app to [deploy via Docker Image](/how-to-guides/app-guides/migrate-dockerfile-to-direct-image-deploy), i.e., you deployed using [`aptible deploy`](/reference/aptible-cli/cli-commands/cli-deploy) in the past, and you want to switch to [deploying via Git](/how-to-guides/app-guides/deploy-from-git) instead. In that case, you will need to take the following steps:

**Step 1:** Push your git repository to a temporary branch. This action will not trigger a deploy, but we'll use it in just a moment:

```perl
BRANCH="deploy-$(date "+%s")"
git push aptible "master:$BRANCH"
```

**Step 2:** Deploy the temporary branch (using the `--git-commitish` argument), and use an empty string for the `--docker-image` argument to disable deploying via Docker Image.

```perl
aptible deploy --app "$APP_HANDLE" \
        --git-commitish "$BRANCH" \
        --docker-image ""
```

**Step 3:** Use `git push aptible master` for all deploys moving forward.

Please note if your [app](/core-concepts/apps/overview) has [Private Registry Credentials](/core-concepts/apps/overview), Aptible will attempt to log in using these credentials. Unless the app uses a private base image in its Dockerfile, these credentials should not be necessary. To prevent private registry authentication, unset the credentials when deploying:

```perl
aptible deploy --app "$APP_HANDLE" \
        --git-commitish "$BRANCH" \
        --docker-image "" \
        --private-registry-username "" \
        --private-registry-password ""
```

Congratulations! You are now set to deploy via Git.


# How to establish client certificate authentication

Client certificate authentication, also known as two-way SSL authentication, is a form of mutual Transport Layer Security(TLS) authentication that involves both the server and the client in the authentication process. Users and the third party they are working with need to establish, own, and manage this type of authentication.

## Standard TLS Authentication v. Mutual TLS Authentication

The standard TLS authentication process works as follows:

1.  The client sends a request to the server.

2.  The server presents its SSL certificate to the client.

3.  The client validates the server's SSL certificate with the certificate authority that issued the server's certificate. If the certificate is valid, the client generates a random encryption key, encrypts it with the server's public key, and then sends it to the server.

4.  The server decrypts the encryption key using its private key. The server and client now share a secret encryption key and can communicate securely.

Mutual TLS authentication includes additional steps:

1.  The server will request the client's certificate.

2.  The client sends its certificate to the server.

3.  The server validates the client's certificate with the certificate authority that issued it. If the certificate is valid, the server can trust that the client is who it claims to be.

## Generating a Client Certificate

Client certificate authentication is more secure than using an API key or basic authentication because it verifies the identity of both parties involved in the communication and provides a secure method of communication. However, setting up and managing client certificate authentication is also more complex because certificates must be generated, distributed, and validated for each client. A client certificate is typically a digital certificate used to authenticate requests to a remote server.

For example, if you are working with a third-party API, their server can ensure that only trusted clients can access their API by requiring client certificates. The client in this example would be your application sending the API request. We recommend that you verify accepted Certificate Authorities with your third-party API provider and then generate a client certificate using these steps:

1.  Generate a private key. This must be securely stored and should never be exposed or transmitted. It's used to generate the Certificate Signing Request (CSR) and to decrypt incoming messages.

2.  Use the private key to generate a Certificate Signing Request (CSR). The CSR includes details like your organization's name, domain name, locality, and country.

3.  Submit this CSR to a trusted Certificate Authority (CA). The CA verifies the information in the CSR to ensure that it's accurate. After verification, the CA will issue a client certificate, which is then sent back to you.

4.  Configure your application or client to use both the private key and the client certificate when making requests to the third-party service.

> 📘 Certificates are only valid for a certain time (like one or two years), after which they need to be renewed. Repeat the process above to get a new certificate when the old one expires.

## Commercial Certificate Authorities (CAs)

Popular CAs that issue client certificates for use in client certificate authentication:

1.  DigiCert: one of the most popular providers of SSL/TLS certificates and can also issue client certificates.

2.  GlobalSign: offers PersonalSign certificates that can be used for client authentication.

3.  Sectigo (formerly Comodo): provides several client certificates, including the Sectigo Personal Authentication Certificate.

4.  Entrust Datacard: offers various certificate services, including client certificates.

5.  GoDaddy: known primarily for its domain registration services but also offers SSL certificates, including client certificates.


# How to expose a web app to the Internet



This guide assumes you already have a web app running on Aptible. If you don't have one already, you can create one using one of our [Quickstart Guides](/getting-started/deploy-starter-template/overview).

This guide will walk you through the process of setting up an [HTTP(S) endpoint](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/overview) with [external placement](/core-concepts/apps/connecting-to-apps/app-endpoints/overview#endpoint-placement) using a [custom domain](/core-concepts/apps/connecting-to-apps/app-endpoints/custom-domain) and [managed TLS](/core-concepts/apps/connecting-to-apps/app-endpoints/managed-tls).

Let's unpack this sentence:

*   [HTTP(S) Endpoint](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/overview): the endpoint will accept HTTPS and HTTP traffic. Aptible will handle HTTPS termination for you, so your app simply needs to process HTTP requests.

*   [External Placement](/core-concepts/apps/connecting-to-apps/app-endpoints/overview#endpoint-placement): the endpoint will be reachable from the public internet.

*   [Custom Domain](/core-concepts/apps/connecting-to-apps/app-endpoints/custom-domain): the endpoint will use a domain you provide(e.g. `www.example.com`).

*   [Managed TLS](/core-concepts/apps/connecting-to-apps/app-endpoints/managed-tls): Aptible will provision an SSL / TLS certificate on your behalf.

Learn more about other choices here: [Endpoints](/core-concepts/apps/connecting-to-apps/app-endpoints/overview). Let's move on to the process.

## Create the endpoint

In the Aptible Dashboard:

*   Navigate to your app

*   Navigate to the Endpoints tab

*   Create a new endpoint

    *   Update the following settings and leave the rest as default:

        *   **Type**: Custom Domain with Managed HTTPS.

        *   **Endpoint Placement**: External.

        *   **Domain Name**: the domain name you intend to use. In the example above, that was `www.example.com`, but yours will be different.

*   Save and wait for the endpoint to provision. If provisioning fails, jump to [Endpoint Provisioning Failed](/how-to-guides/app-guides/expose-web-app-to-internet#endpoint-provisioning-failed).

> 📘 The domain name you choose should **not** be a domain apex. For example, [www.example.com](http://www.example.com/) is fine, but just example.com is not.

> For more information, see: [How do I use my domain apex with Aptible?](/how-to-guides/app-guides/use-domain-apex-with-endpoints/overview)

## Create a CNAME to the endpoint

Aptible will present you with an [endpoint hostname](/core-concepts/apps/connecting-to-apps/app-endpoints/custom-domain#endpoint-hostname) and [managed HTTPS validation records](/core-concepts/apps/connecting-to-apps/app-endpoints/managed-tls#managed-https-validation-records) once the endpoint provisions. The two have different but overlapping use cases.

### Endpoint hostname

The Endpoint Hostname is a domain name that points to your endpoint.

However, you shouldn't send your traffic directly there. Instead, you should create a CNAME DNS record (using your DNS provider) from the name you intend to use with your app (`www.example.com` in the example above) to the Endpoint Hostname.

So, create that CNAME now.

### Validation records

Managed TLS uses the validation records to provision a certificate for your domain via [Let's Encrypt](https://letsencrypt.org/). When you create those records, Aptible can provide certificates for you. If you don't create them, then Let's Encrypt won't let Aptible provision certificates for you.

As it happens, the CNAME you created for the Endpoint Hostname is *also* a validation record. That makes sense: you're sending your traffic to the endpoint; that's enough proof for Let's Encrypt that you're indeed using Aptible and that we should be able to create certificates for you. Note that there are two validation records. We recommend you create both, but you're not going to need the second one (the one starting with `_acme-challenge`) for this tutorial.

## Validate the endpoint

Confirm that you've created the CNAME from your domain name to the Endpoint Hostname in the Dashboard. Aptible will provision a certificate for you, then deploy it across your app.

If all goes well, you'll see a success message (if not, see [Endpoint Certificate Renewal Failed](/how-to-guides/app-guides/expose-web-app-to-internet#endpoint-certificate-renewal-failed) below).

You can navigate to your custom domain (over HTTP or HTTPS), and your app will be accessible.

## Next steps

Now that your app is available over HTTPS, enabling an automated [HTTPS Redirect](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/https-redirect) is a good idea.

You can also learn more about endpoints here: [Endpoints](/core-concepts/apps/connecting-to-apps/app-endpoints/overview).

## Troubleshooting

### Endpoint Provisioning Failed

If endpoint provisioning fails, restart your app using the [`aptible restart`](/reference/aptible-cli/cli-commands/cli-restart) command. You will see a prompt asking you to do so.

Note this failure is most likely due to an app health check failure. We have troubleshooting instructions here: [My deploy failed with *HTTP health checks failed*](/how-to-guides/troubleshooting/common-errors-issues/http-health-check-failed).

If this doesn't help, contact [Aptible Support](/how-to-guides/troubleshooting/aptible-support).

### Endpoint Certificate Renewal Failed

This failure is probably due to an issue with the CNAME you created. There are two possible causes here:

*   The CNAME change is taking a little to propagate. Here, it's a good idea to wait for a few minutes (or seconds, if you're in a hurry!) and then retry via the Dashboard.

*   The CNAME is wrong. An excellent way to check for this is to access your domain name (`www.example.com` in the examples above, but yours will be different). If you see an Aptible page saying something like "you're almost done", you probably got it right, and you can retry via the Dashboard. If not, double-check the CNAME you created.

If this doesn't help, contact [Aptible Support](/how-to-guides/troubleshooting/aptible-support).


# How to generate certificate signing requests



> 📘 If you're unsure about creating certificates or don't want to manage them, use Aptible's [Managed TLS](/core-concepts/apps/connecting-to-apps/app-endpoints/managed-tls) option!

A [Certificate Signing Request](https://en.wikipedia.org/wiki/Certificate_signing_request) (CSR) file contains information about an SSL / TLS certificate you'd like a Certification Authority (CA) to issue. If you'd like to use a [Custom Certificate](/core-concepts/apps/connecting-to-apps/app-endpoints/custom-certificate) with your [Endpoints](/core-concepts/apps/connecting-to-apps/app-endpoints/overview), you will need to generate a CSR:

**Step 1:** You can generate a new CSR using OpenSSL's `openssl req` command:

```bash
openssl req -newkey rsa:2048 -nodes \
        -keyout "$DOMAIN.key" -out "$DOMAIN.csr"
```

**Step 2:** Store the private key (the `$DOMAIN.key` file) and CSR (the `$DOMAIN.csr` file) in a secure location, then request a certificate from the CA of your choice.

**Step 3:** Once your CSR is approved, request an "NGiNX / other" format if the CA asks what certificate format you prefer.

## Matching Certificates, Private Keys and CSRs

If you are unsure which certificates, private keys, and CSRs match each other, you can compare the hashes of the modulus of each:

```bash
openssl x509 -noout -modulus -in certificate.crt | openssl md5
openssl rsa -noout -modulus -in "$DOMAIN.key" | openssl md5
openssl req -noout -modulus -in "$DOMAIN.csr" | openssl md5
```

The certificate, private key and CSR are compatible if all three hashes match. You can use `diff3` to compare the moduli from all three files at once:

```bash
openssl x509 -noout -modulus -in certificate.crt > certificate-mod.txt
openssl rsa -noout -modulus -in "$DOMAIN.key" > private-key-mod.txt
openssl req -noout -modulus -in "$DOMAIN.csr" > csr-mod.txt
diff3 cert-mod.txt privkey-mod.txt csr-mod.txt
```

If all three files are identical, `diff3` will produce no output.

> 📘 You can reuse a private key and CSR when renewing an SSL / TLS certificate, but from a security perspective, it's often a better idea to generate a new key and CSR when renewing.


# Getting Started with Docker



On Aptible, we offer two application deployment strategies - [Dockerfile Deploy](/how-to-guides/app-guides/deploy-from-git) and [Direct Docker Image Deploy](/how-to-guides/app-guides/migrate-dockerfile-to-direct-image-deploy). You’ll notice that both options involve Docker, a popular container runtime platform. Aptible uses Docker to help deploy your applications in containers, allowing you to easily scale, manage, and deploy applications in isolation. In this guide, we’ll review the basics of using Docker to deploy on Aptible. 

## Writing a Dockerfile

For both deployment options offered on Aptible, you’ll need to know how to write a Dockerfile. A Dockerfile contains all the instructions to describe how a Docker Image should be built. Docker has a great guide on [Dockerfile Best Practices](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/), which we recommend checking out before starting. You can also use the Dockerfiles included in our [Starter Templates](/getting-started/deploy-starter-template/overview) as a reference to kickstart your own. Below is an example taken from our [Ruby on Rails Starter Template](/getting-started/deploy-starter-template/ruby-on-rails):

```ruby
# syntax = docker / dockerfile: 1

#[1] Choose a parent image to base your image on
FROM ruby: latest

#[2] Do things that are necessary for your Application to run
RUN apt - get update \
 && apt - get - y install build - essential libpq - dev \
 && rm - rf /var/lib/apt / lists/*

ADD Gemfile /app/
ADD Gemfile.lock /app/
WORKDIR /app
RUN bundle install

ADD . /app

EXPOSE 3000

# [3] Configure the default process to run when running the container
CMD ["bundle", "exec", "rails", "server", "-b", "0.0.0.0", "-p", "3000"]
```

You can typically break down a basic Dockerfile into three main sections - we’ve marked them as \[1], \[2], and \[3] in the example. 

1.  Choose a parent image:

    *   This is the starting point for most users. A parent image provides a foundation for your own image - every subsequent line in your Dockerfile modifies the parent image. 

    *   You can find parent images to use from container registries like [Docker Hub](https://hub.docker.com/search?q=\&type=image). 
2.  Build your image

    *   The instructions in this section help build your image. In the example, we use `RUN`, which executes and commits a command before moving on to the next instruction, `ADD`, which adds a file or directory from your source to a destination, `WORKDIR`, which changes the working directory for subsequent instructions, and `EXPOSE`, which instructs the container to listen on the specified port at runtime. 

    *   You can find detailed information for each instruction on Docker’s Dockerfile reference page.
3.  Configure the default container process

    *   The CMD instruction provides defaults for running a container. 

    *   We’ve included the executable command bundle in the example, but you don’t necessarily need to. If you don’t include an executable command, you must provide an `ENTRYPOINT` instead.

> 📘 On Aptible, you can optionally include a [Procfile](/how-to-guides/app-guides/define-services) in the root directory to define explicit services. How we interpret the commands in your Procfile depends on whether or not you have an ENTRYPOINT defined.

## Building a Docker Image

A Docker image is the packaged version of your application - it contains the instructions necessary to build a container on the Docker platform. Once you have a Dockerfile, you can have Aptible build and deploy your image via [Dockerfile Deploy](/how-to-guides/app-guides/deploy-from-git) or build it yourself and provide us the Docker Image via [Direct Docker Image Deploy](/how-to-guides/app-guides/migrate-dockerfile-to-direct-image-deploy). 

The steps below, which require the [Aptible CLI](/reference/aptible-cli/cli-commands/overview) and [Docker CLI](https://docs.docker.com/get-docker/), provide a general outline on building and deploying a Docker image to Aptible. 

1.  docker build with your Dockerfile and context to build your image.

2.  docker push to push your image to a container registry, like Docker Hub. 

3.  `aptible deploy --docker-image “$DOCKER_IMAGE” --app “$APP”` to deploy your image to an App on Aptible


# Horizontal Autoscaling Guide



<Note>This feature is currently in "limited release". Contact Aptible Support to request access.</Note>

[Horizontal Autoscaling (HAS)](/core-concepts/scaling/app-scaling#horizontal-autoscaling) is a powerful feature that allows your application to automatically adjust its computing resources based on ongoing usage. This guide will walk you through the benefits, ideal use cases, and best practices for implementing HAS in your Aptible deployments.

By leveraging HAS, you can optimize resource utilization, improve application performance, and potentially reduce costs. Whether you're running a web service, API, or any other scalable application, understanding and properly configuring HAS can significantly enhance your infrastructure's efficiency and reliability.

Let's dive into the key aspects of Horizontal Autoscaling and how you can make the most of this feature for your Aptible-hosted applications.

# Key Benefits of Horizontal Autoscaling

*   Cost efficiency & Performance: Ensure your App Services are always using the optimal amount of containers. Scale loads with periods of high and low usage that can be parallelized - efficiently.
*   Greater reliability: Reduce the likelihood of an expensive computation (ie. a web request) consuming all of your fixed size processing capability
*   Reduced engineering time: Save time manually scaling your app services with greater automation

# What App Services are good candidates for HAS?

**First, let’s consider what sort of process is NOT a candidate:**

*   Job workers, unless your jobs are idempotent and/or your queue follows exactly-once semantics
*   Services that have a costly startup time
    *   Scaling up happens during times of increased load, so a restart that takes a long time to complete during these times is not ideal
*   Services that cannot be easily parallelized
    *   If your workload is not easily parallelized, you could end up in a scenario where all the load is on one container and the others do near-zero work.

### So what’s a good candidate?

*   Services that have predictable and well-understood load patterns
    *   We talk about this more in [How to set thresholds and container minimums for App Services](#how-to-set-thresholds-and-container-minimums-for-app-services)
*   Services that have a workload that can be easily parallelized
    *   Web workers as an example, since each web request is completely independent from another
*   Services that experience periods of high/low load
    *   However, there’s no real risk to setting up HAS on any service just in case they ever experience higher load than expected, as long as having multiple processes running at the same time is not a problem (see above for processed that are not candidates).

# How to set thresholds and container minimums for App Services

Horizontal Autoscaling is configured per App Service. Guidelines to keep in mind for configuration:

*   Minimum number of containers - Should be set to 2 as a minimum if you want High-Availability
*   Max number of containers - This one depends on how many requests you want to be able to handle under load, and will differ due to specifics of how your app behaves. If you’ve done load testing with your app and understand how many requests your app can handle with the container size you’re currently using, it is a matter of calculating how many more containers you’d want.
*   Min CPU threshold - You should set this to slightly above the CPU usage your app exhibits when there’s no/minimal usage to ensure scale downs happen, any lower and your app will never scale down. If you want scale downs to happen faster, you can set this threshold higher.
*   Max CPU threshold - A good rule of thumb is 80-90%. There is some lead time to scale ups occurring, as we need a minimum amount of metrics to have been gathered before the next scale-up event happens, so setting this close to 100% can lead to bottlenecks. If you want scale ups to happen faster, you can set this threshold lower.
*   Scale Up, and Scale Down Steps - These are set to 1 by default, but you are able to modify the values if you want autoscaling events to jump up or down by more than 1 container at a time.

<Tip>CPU thresholds are expressed as a decimal between 0 and 1, representing the percentage of your container's allocated CPU that is actively used by your app. For instance, if a container with a 25% CPU limit is using 12% of its allocated CPU, this would be expressed as 0.48 (or 48%).</Tip>

### Let’s go through an example:

We have a service that exhibits periods of load and periods of near-zero use. It is a production service that is critical to us, so we want a high-availability setup, which means our minimum containers will be 2. Metrics for this service are as follows:

| Container Size | CPU Limit | Low Load CPU Usage     | High Load CPU Usage     |
| -------------- | --------- | ---------------------- | ----------------------- |
| 1GB            | 25%       | 3% (12% of allocation) | 22% (84% of allocation) |

Since our low usage is 12%, the HAS default of 0.1 won’t work for us - we would never scale down. Let’s set it to 0.2 to be conservative

At 84% usage when under load, we’re near the limit but not quite topped out. Usually this would mean you need to validate whether this service would actually benefit from having more containers running. In this case, let’s say our monitoring tools have surfaced that request queueing gets high during these times. We could set our scale up threshold to 0.8, the default, or set it a bit lower if we want to be conservative.

With this, we can expect our service to scale up during periods of high load, up to the maximum number of containers if necessary. If we had set our max CPU limit to something like 0.9, the scaling up would be unlikely to trigger *in this particular scenario.*

With the metrics look-back period set to 10 minutes and our scale-up cooldown set to a minute(the default), we can expect our service to scale up by 1 container every 5 minutes as long as our load across all containers stays above 80%, until we reach the maximum containers we set in the configuration. Note the 5 minutes between each event - that is currently a hardcoded minimum cooldown.

Since we set a min CPU (scale down) threshold high enough to be above our containers minimal usage, we have guaranteed scale downs will occur. We could set our scale-down threshold higher if we want to be more aggressive about maximizing container utility.


# How to create an app



Learn how to create an [app](/core-concepts/apps/overview)

> ❗️Apps handles cannot start with "internal-" because applications with that prefix cannot have [Endpoints](/core-concepts/apps/connecting-to-apps/app-endpoints/overview)

## Using the Dashboard

Apps can be created/provisioned within the Dashboard the following ways:

*   Using the [**Deploy**](https://app.aptible.com/create) tool will automatically create a new app in a new environment as you deploy your code ![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/create-app1.png)

*   From the Environment by:

    *   Navigating to the respective Environment

    *   Selecting the **Apps** tab

    *   Selecting **Create App**

![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/create-app2.png)

## Using the CLI

Apps can be created/provsioned via the Aptible CLI by using the [`aptible apps:create`](/reference/aptible-cli/cli-commands/cli-apps-create) command.

```js
aptible apps:create HANDLE
```

## Using Terraform

Apps can be created/provsioned via the [Aptible Terraform Provider](https://registry.terraform.io/providers/aptible/aptible/latest/docs) by using the terraform\_aptible\_app resource.

```js
data "aptible_app" "APP" {
    handle = "APP_HANDLE"
}
```


# How to deploy to Aptible with CI/CD



## Overview

To make it easier to deploy on Aptible—whether you're migrating from another platform or deploying your first application—we offer integrations with several continuous integration services.

*   [Deploying with Git](/how-to-guides/app-guides/how-to-deploy-aptible-ci-cd#deploying-with-git)

*   [Deploying with Docker](/how-to-guides/app-guides/how-to-deploy-aptible-ci-cd#deploying-with-docker)

If your team is already using a Git-based deployment workflow, deploying your app to Aptible should be relatively straightforward.

## Deploying with Git

### Prerequisites

To deploy to Aptible via Git, you must have a public SSH key associated with your account. We recommend creating a robot user to manage your deployment:

1.  Create a `Robots` [custom Aptible role](/core-concepts/security-compliance/access-permissions) in your Aptible organization. Grant it "Read" and "Manage" permissions for the environment where you would like to deploy.

2.  Invite a new robot user with a valid email address (for example, `deploy@yourdomain.com`) to the `Robots` role.

3.  Sign out of your Aptible account, accept the invitation from the robot user's email address, and set a password for the robot's Aptible account.

4.  Generate a new SSH key pair to be used by the robot user, and don't set a password: `ssh-keygen -t ed25519 -C "your_email@example.com"`

5.  Register the [SSH Public Key](/core-concepts/security-compliance/authentication/ssh-keys) with Aptible for the robot user.

<Tabs>
  <Tab title="GitHub Actions">
    ### Configuring the Environment

    First, you'll need to configure a few [environment variables](https://docs.github.com/en/actions/learn-github-actions/variables#defining-configuration-variables-for-multiple-workflows) and [secrets](https://docs.github.com/en/actions/security-guides/encrypted-secrets#using-encrypted-secrets-in-a-workflow) for your repository:

    1.  Environment variable: `APTIBLE_APP`, the name of the App to deploy.
    2.  Environment variable: `APTIBLE_ENVIRONMENT`, the name of the Aptible environment in which your App lives.
    3.  Secret: `APTIBLE_USERNAME`, the username of the Aptible user with which to deploy the App.
    4.  Secret: `APTIBLE_PASSWORD`, the password of the Aptible user with which to deploy the App.

    ### Configuring the Workflow

    Finally, you must configure the workflow to deploy your application to Aptible:

    ```sql
    on:
      push:
        branches: [ main ]

    jobs:
      deploy:
        runs-on: ubuntu-latest
        steps:
          - uses: actions/checkout@v4
            with:
              fetch-depth: 0
          - name: Deploy to Aptible
            uses: aptible/aptible-deploy-action@v4
            with:
              type: git
              app: ${{ vars.APTIBLE_APP }}
              environment: ${{ vars.APTIBLE_ENVIRONMENT }}
              username: ${{ secrets.APTIBLE_USERNAME }}
              password: ${{ secrets.APTIBLE_PASSWORD }}
    ```
  </Tab>

  <Tab title="CircleCI">
    ### Configuring SSH

    To deploy to Aptible via CircleCI, [add your SSH Private Key via the CircleCI Dashboard](https://circleci.com/docs/2.0/add-ssh-key/#circleci-cloud-or-server-3-x) with the following values:

    *   **Hostname:** `beta.aptible.com`
    *   **Private Key:** The contents of the SSH Private Key created in the previous step.

    ### Configuring the Environment

    You also need to set environment variables on your project with the name of your Aptible environment and app, in `APTIBLE_ENVIRONMENT` and `APTIBLE_APP`, respectively. You can add these to your project using [environment variables](https://circleci.com/docs/2.0/env-vars/) on the Circle CI dashboard.

    ### Configuring the Deployment

    Finally, you must configure the Circle CI project to deploy your application to Aptible:

    ```sql
    version: 2.1

    jobs:
      git-deploy:
        docker:
          - image: debian:latest
        filters:
          branches:
            only:
              - circle-deploy
        steps:
          # Add your private key to your repo: https://circleci.com/docs/2.0/configuration-reference/#add-ssh-keys
          - checkout
          - run:
              name: Git push and deploy to Aptible
              command: |
                apt-get update && apt-get install -y git openssh-client
                ssh-keyscan beta.aptible.com >> ~/.ssh/known_hosts
                git remote add aptible git@beta.aptible.com:$APTIBLE_ENVIRONMENT/$APTIBLE_APP.git
                git push aptible $CIRCLE_SHA1:master

    workflows:
      version: 2
      deploy:
        jobs:
          - git-deploy
    ```

    Let’s break down how this works. We begin by defining when the deployment should run (when a push is made to the `circle-deploy` branch):

    ```sql
    jobs:
      git-deploy:
        docker:
          - image: debian:latest
        filters:
          branches:
            only:
              - circle-deploy
    ```

    The most important part of this configuration is the value of the `command` key under the `run` step. Here we add our SSH private key to the Circle CI environment, configure a new remote for our repository on Aptible’s platform, and push our branch to Aptible:

    ```sql
    jobs:
      git-deploy:
        # # #
        steps:
          - checkout
          - run:
              name: Git push and deploy to Aptible
              command: |
                apt-get update && apt-get install -y git openssh-client
                ssh-keyscan beta.aptible.com >> ~/.ssh/known_hosts
                git remote add aptible git@beta.aptible.com:$APTIBLE_ENVIRONMENT/$APTIBLE_APP.git
                git push aptible $CIRCLE_SHA1:master
    ```

    From there, the procedure for a [Dockerfile-based deployment](/how-to-guides/app-guides/deploy-from-git) remains the same!
  </Tab>

  <Tab title="Travis CI">
    ### Configuring SSH

    To deploy to Aptible via Travis CI, [add your SSH Private Key via the Travis CI repository settings](https://docs.travis-ci.com/user/environment-variables/#defining-variables-in-repository-settings) with the following values:

    *   **Name:** `APTIBLE_GIT_SSH_KEY`
    *   **Value:** The ***base64-encoded*** contents of the SSH Private Key created in the previous step.

    > ⚠️ Warning
    >
    > The SSH private key added to the Travis CI environment variable must be base64-encoded.

    ### Configuring the Environment

    You also need to set environment variables on your project with the name of your Aptible environment and app, in `APTIBLE_ENVIRONMENT` and `APTIBLE_APP`, respectively. You can add these to your project using [environment variables](https://docs.travis-ci.com/user/environment-variables/#defining-variables-in-repository-settings) on the Travis CI dashboard.

    ### Configuring the Deployment

    Finally, you must configure the Travis CI project to deploy your application to Aptible:

    ```sql
    language: generic
    sudo: true

    services:
      - docker

    jobs:
      include:
        - stage: push
          if: branch = travis-deploy
          addons:
            ssh_known_hosts: beta.aptible.com
          before_script:
            - mkdir -p ~/.ssh
            # to save it, cat <<KEY>> | base64 and save that in secrets
            - echo "$APTIBLE_GIT_SSH_KEY" | base64 -d > ~/.ssh/id_rsa
            - chmod 0400 ~/.ssh/id_rsa
            - eval "$(ssh-agent -s)"
            - ssh-add ~/.ssh/id_rsa
            - ssh-keyscan beta.aptible.com >> ~/.ssh/known_hosts

          script:
            - git remote add aptible git@beta.aptible.com:$APTIBLE_ENVIRONMENT/$APTIBLE_APP.git
            - git push aptible $TRAVIS_COMMIT:master
    ```

    Let’s break down how this works. We begin by defining when the deployment should run (when a push is made to the `travis-deploy` branch) and where we are going to deploy (so we add `beta.aptible.com` as a known host):

    ```sql
    # # #
    jobs:
      include:
        - stage: push
          if: branch = travis-deploy
          addons:
            ssh_known_hosts: beta.aptible.com
    ```

    The Travis CI configuration then allows us to split our script into two parts, with the `before_script` configuring the Travis CI environment to use our SSH key:

    ```sql
          # Continued from above
          before_script:
            - mkdir -p ~/.ssh
            # to save it, cat <<KEY>> | base64 and save that in secrets
            - echo "$APTIBLE_GIT_SSH_KEY" | base64 -d > ~/.ssh/id_rsa
            - chmod 0400 ~/.ssh/id_rsa
            - eval "$(ssh-agent -s)"
            - ssh-add ~/.ssh/id_rsa
            - ssh-keyscan beta.aptible.com >> ~/.ssh/known_hosts
    ```

    Finally, our `script` block configures a new remote for our repository on Aptible’s platform, and pushes our branch to Aptible:

    ```sql
          # Continued from above
          script:
            - git remote add aptible git@beta.aptible.com:$APTIBLE_ENVIRONMENT/$APTIBLE_APP.git
            - git push aptible $TRAVIS_COMMIT:master
    ```

    From there, the procedure for a [Dockerfile-based deployment](/how-to-guides/app-guides/deploy-from-git) remains the same!
  </Tab>

  <Tab title="GitLab CI">
    ### Configuring SSH

    To deploy to Aptible via GitLab CI, [add your SSH Private Key via the GitLab CI dashboard](https://docs.gitlab.com/ee/ci/ssh_keys/#ssh-keys-when-using-the-docker-executor) with the following values:

    *   **Key:** `APTIBLE_GIT_SSH_KEY`
    *   **Value:** The ***base64-encoded*** contents of the SSH Private Key created in the previous step.

    > ⚠️ Warning
    >
    > The SSH private key added to the GitLab CI environment variable must be base64-encoded.

    ### Configuring the Environment

    You also need to set environment variables on your project with the name of your Aptible environment and app, in `APTIBLE_ENVIRONMENT` and `APTIBLE_APP`, respectively. You can add these to your project using [project variables](https://docs.gitlab.com/ee/ci/variables/#add-a-cicd-variable-to-a-project) on the GitLab CI dashboard.

    ### Configuring the Deployment

    Finally, you must configure the GitLab CI pipeline to deploy your application to Aptible:

    ```sql
    image: debian:latest

    git_deploy_job:
      only:
        - gitlab-deploy
      before_script:
        - apt-get update && apt-get install -y git
        # taken from: https://docs.gitlab.com/ee/ci/ssh_keys/
        - 'command -v ssh-agent >/dev/null || ( apt-get update -y && apt-get install openssh-client -y )'
        - eval $(ssh-agent -s)
        # to save it, cat <<KEY>> | base64 and save that in secrets
        - echo "$DEMO_APP_APTIBLE_GIT_SSH_KEY" | base64 -d | tr -d '
    ' | ssh-add -
        - mkdir -p ~/.ssh
        - chmod 700 ~/.ssh
      script:
        - |
          ssh-keyscan beta.aptible.com >> ~/.ssh/known_hosts
          git remote add aptible git@beta.aptible.com:$DEMO_APP_APTIBLE_ENVIRONMENT/$DEMO_APP_APTIBLE_APP.git
          git push aptible $CI_COMMIT_SHA:master
    ```

    Let’s break down how this works. We begin by defining when the deployment should run (when a push is made to the `gitlab-deploy` branch), and then we define the `before_script` that will configure SSH in our job environment:

    ```sql
      # . . .
      before_script:
        - apt-get update && apt-get install -y git
        # taken from: https://docs.gitlab.com/ee/ci/ssh_keys/
        - 'command -v ssh-agent >/dev/null || ( apt-get update -y && apt-get install openssh-client -y )'
        - eval $(ssh-agent -s)
        - echo "$DEMO_APP_APTIBLE_GIT_SSH_KEY" | base64 -d | tr -d '
    ' | ssh-add -
        - mkdir -p ~/.ssh
        - chmod 700 ~/.ssh
    ```

    Finally, our `script` block configures a new remote for our repository on Aptible’s platform, and pushes our branch to Aptible:

    ```sql
      # Continued from above
      script:
        - |
          ssh-keyscan beta.aptible.com >> ~/.ssh/known_hosts
          git remote add aptible git@beta.aptible.com:$DEMO_APP_APTIBLE_ENVIRONMENT/$DEMO_APP_APTIBLE_APP.git
          git push aptible $CI_COMMIT_SHA:master
    ```

    From there, the procedure for a [Dockerfile-based deployment](/how-to-guides/app-guides/deploy-from-git) remains the same!
  </Tab>
</Tabs>

## Deploying with Docker

### Prerequisites

To deploy to Aptible with a Docker image via a CI integration, you should create a robot user to manage your deployment:

1.  Create a `Robots` [custom Aptible role](/core-concepts/security-compliance/access-permissions) in your Aptible organization. Grant it "Read" and "Manage" permissions for the environment where you would like to deploy.

2.  Invite a new robot user with a valid email address (for example, `deploy@yourdomain.com`) to the `Robots` role.

3.  Sign out of your Aptible account, accept the invitation from the robot user's email address, and set a password for the robot's Aptible account.

<Tabs>
  <Tab title="GitHub Actions">
    Some of the below instructions and more information can also be found on the Github Marketplace page for the [Deploy to Aptible Action.](https://github.com/marketplace/actions/deploy-to-aptible#example-with-container-build-and-docker-hub)

    ## Configuring the Environment

    To deploy to Aptible via GitHub Actions, you must first [create encrypted secrets for your repository](https://docs.github.com/en/actions/security-guides/encrypted-secrets#creating-encrypted-secrets-for-a-repository) with Docker registry and Aptible credentials:

    `DOCKERHUB_USERNAME` and `DOCKERHUB_TOKEN`
    The credentials for your private Docker registry (in this case, DockerHub).

    `APTIBLE_USERNAME` and `APTIBLE_PASSWORD`
    The credentials for the robot account created to deploy to Aptible.

    ## Configuring the Workflow

    Additionally, you will need to set some environment variables within the GitHub Actions workflow:

    `IMAGE_NAME`
    The Docker image you wish to deploy from your Docker registry.

    `APTIBLE_ENVIRONMENT`
    The name of the Aptible environment acting as the target for this deployment.

    `APTIBLE_APP`
    The name of the app within the Aptible environment we are deploying with this workflow.

    ## Configuring the Workflow

    Finally, you must configure the workflow to deploy your application to Aptible:

    ```ruby
    on:
      push:
        branches: [ main ]

    env:
      IMAGE_NAME: user/app:latest
      APTIBLE_ENVIRONMENT: "my_environment"
      APTIBLE_APP: "my_app"

    jobs:
      deploy:
        runs-on: ubuntu-latest

        steps:
          # Allow multi-platform builds.
          - name: Set up QEMU
            uses: docker/setup-qemu-action@v2

          # Allow use of secrets and other advanced docker features.
          - name: Set up Docker Buildx
            uses: docker/setup-buildx-action@v2

          # Log into Docker Hub
          - name: Login to DockerHub
            uses: docker/login-action@v2
            with:
              username: ${{ secrets.DOCKERHUB_USERNAME }}
              password: ${{ secrets.DOCKERHUB_TOKEN }}

          # Build image using default dockerfile.
          - name: Build and push
            uses: docker/build-push-action@v3
            with:
              push: true
              tags: ${{ env.IMAGE_NAME }}

          # Deploy to Aptible
          - name: Deploy to Aptible
            uses: aptible/aptible-deploy-action@v4
            with:
              username: ${{ secrets.APTIBLE_USERNAME }}
              password: ${{ secrets.APTIBLE_PASSWORD }}
              environment: ${{ env.APTIBLE_ENVIRONMENT }}
              app: ${{ env.APTIBLE_APP }}
              docker_img: ${{ env.IMAGE_NAME }}
              private_registry_username: ${{ secrets.DOCKERHUB_USERNAME }}
              private_registry_password: ${{ secrets.DOCKERHUB_TOKEN }}
    ```
  </Tab>

  <Tab title="TravisCI">
    ## Configuring the Environment

    You also need to set environment variables on your project with the name of your Aptible environment and app, in APTIBLE\_ENVIRONMENT and APTIBLE\_APP, respectively. You can add these to your project using environment variables on the Travis CI dashboard.

    To define how the Docker image is built and deployed, you’ll need to set a few additional variables:

    `APTIBLE_USERNAME` and `APTIBLE_PASSWORD`
    The credentials for the robot account created to deploy to Aptible.

    `APTIBLE_DOCKER_IMAGE`
    The name of the Docker image you wish to deploy to Aptible.

    If you are using a private registry to store your Docker image, you also need to specify credentials to be passed to Aptible:

    `APTIBLE_PRIVATE_REGISTRY_USERNAME`
    The username of the account that can access the private registry containing the Docker image.

    `APTIBLE_PRIVATE_REGISTRY_PASSWORD`
    The password of the account that can access the private registry containing the Docker image.

    ## Configuring the Deployment

    Finally, you must configure the workflow to deploy your application to Aptible:

    ```ruby
    language: generic
    sudo: true

    services:
      - docker

    jobs:
      include:
      - stage: build-and-test
        script: |
          make build
          make test
      - stage: push
        if: branch = main
        script: |
          # login to your registry
          docker login \
            -u $APTIBLE_PRIVATE_REGISTRY_EMAIL \
            -p $APTIBLE_PRIVATE_REGISTRY_PASSWORD
          # push your docker image to your registry
          make push

          # download the latest aptible cli and install it
          wget https://omnibus-aptible-toolbelt.s3.amazonaws.com/aptible/omnibus-aptible-toolbelt/latest/aptible-toolbelt_latest_debian-9_amd64.deb && \
            dpkg -i ./aptible-toolbelt_latest_debian-9_amd64.deb && \
            rm ./aptible-toolbelt_latest_debian-9_amd64.deb

          # login and deploy your app
          aptible login \
            --email "$APTIBLE_USERNAME" \
            --password "$APTIBLE_PASSWORD"
          aptible deploy \
            --environment "$APTIBLE_ENVIRONMENT" \
            --app "$APTIBLE_APP"
    ```

    Let’s break down how this works. The script for the `build-and-test` stage does what it says on the label: It builds our Docker image as runs tests on it, as we’ve defined in a Makefile.

    Then, script from the `push` stage pushes our image to the Docker registry:

    ```ruby
    # login to your registry
    docker login \
      -u $APTIBLE_PRIVATE_REGISTRY_EMAIL \
      -p $APTIBLE_PRIVATE_REGISTRY_PASSWORD
    # push your docker image to your registry
    make push
    ```

    Finally, it installs the Aptible CLI in the Travis CI build environment, logs in to Aptible, and deploys your Docker image to the specified envrionment and app:

    ```ruby
    # download the latest aptible cli and install it
    wget https://omnibus-aptible-toolbelt.s3.amazonaws.com/aptible/omnibus-aptible-toolbelt/aptible-toolbelt-latest_amd64.deb && \
      dpkg -i ./aptible-toolbelt-latest_amd64.deb && \
      rm ./aptible-toolbelt-latest_amd64.deb

    # login and deploy your app
    aptible login \
      --email "$APTIBLE_USERNAME" \
      --password "$APTIBLE_PASSWORD"
    aptible deploy \
      --environment "$APTIBLE_ENVIRONMENT" \
      --app "$APTIBLE_APP"
    ```
  </Tab>
</Tabs>

From there, you can review our resources for [Direct Docker Image Deployments!](/how-to-guides/app-guides/migrate-dockerfile-to-direct-image-deploy)


# How to scale apps and services



Learn how to manually scale apps and services on Aptible

## Overview

[Apps](/core-concepts/apps/overview) can be scaled on a [Service](/core-concepts/apps/deploying-apps/services)-by-Service basis: any given Service for your App can be scaled independently of others.

## Using the Dashboard

*   Within the Aptible Dashboard apps and services can be manually scaled by:

    *   Navigating to the Environment in which your App lives

    *   Selecting the **Apps** tab

    *   Selecting the respective App

    *   Selecting **Scale**

![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/scale-apps1.png)

## Using the CLI

Apps and services can be manually scaled via the Aptible CLI using the [`aptible apps:scale`](/reference/aptible-cli/cli-commands/cli-apps-scale) command.

## Using Terraform

Apps and services can be scaled programmatically via Aptible [Terraform Provider](https://registry.terraform.io/providers/aptible/aptible/latest/docs) by using the nested service element for the App resource:

```js
resource "aptible_app" "APP" {
    env_id = ENVIRONMENT_ID
    handle = "APP_HANDLE"
    service {
        process_type = "SERVICE_NAME1"
        container_count = 1
        container_memory_limit = 1024
    }
    service {
        process_type = "SERVICE_NAME2"
        container_count = 2
        container_memory_limit = 2048
    }
}
```


# Circle CI



Once you've completed the steps for [CI Integration](/how-to-guides/app-guides/integrate-aptible-with-ci/overview), set up Circle CI as follows:

**Step 1:** Add the private key you created for the robot user to your Circle CI project through the **Project Settings > SSH keys** page on Circle CI.

**Step 2:** Add a custom deploy step that pushes to Aptible following Circle's [deployment instructions](https://circleci.com/docs/configuration#deployment). It should look something like this (adjust branch names as needed):

```ruby
deployment:
  production:
    branch: production
    commands:
      - git fetch --depth=1000000
      - git push git@beta.aptible.com:$ENVIRONMENT_HANDLE/$APP_HANDLE.git $CIRCLE_SHA1:master
```

> 📘 In the above example, `git@beta.aptible.com:$ENVIRONMENT_HANDLE/$APP_HANDLE.git` represents your App's Git Remote.

> Also, see [My deploy failed with a git error referencing objects, trees, revisions or commits](/how-to-guides/troubleshooting/common-errors-issues/git-reference-error) to understand why you need `git fetch` here.


# Codeship



You don't need to create a new SSH public key for your robot user when using Codeship. Once you've completed the steps for [CI Integration](/how-to-guides/app-guides/integrate-aptible-with-ci/overview), set up Codeship as follows:

**Step 1:** Copy the public key from your Codeship project's General Settings page, and add it as a [new key](/core-concepts/security-compliance/authentication/ssh-keys) for your robot user.

**Step 2:** Add a Custom Script deployment in Codeship with the following commands:

```bash
git fetch --depth=1000000
git push git@beta.aptible.com:$ENVIRONMENT_HANDLE/$APP_HANDLE.git $CI_COMMIT_ID:master
```

> 📘 In the above example, `git@beta.aptible.com:$ENVIRONMENT_HANDLE/$APP_HANDLE.git` represents your App's Git Remote.

> Also, see [My deploy failed with a git error referencing objects, trees, revisions or commits](/how-to-guides/troubleshooting/common-errors-issues/git-reference-error) to understand why you need `git fetch` here.


# Jenkins



Once you've completed the steps for [CI Integration](/how-to-guides/app-guides/integrate-aptible-with-ci/overview), set up Jenkins using these steps:

1.  In Jenkins, using the Git plugin, add a new repository to your build:

    1.  For the Repository URL, use your App's Git Remote

    2.  Upload the private key you created for your robot user as a credential.

    3.  Under "Advanced...", name this repository `aptible`.
2.  Then, add a post-build "Git Publisher" trigger, to deploy to the `master` branch of your newly-created `aptible` remote.


# How to integrate Aptible with CI Platforms



At a high level, integrating Aptible with your CI platform boils down to the following steps:

*   Create a robot [User](/core-concepts/security-compliance/access-permissions) in Aptible for your CI platform.

*   Trigger a deploy to Aptible whenever your CI process completes. How you do this depends on [how you're deploying to Aptible](/core-concepts/apps/deploying-apps/image/overview):

## Creating a Robot User

1.  Create a "Robots" [role](/core-concepts/security-compliance/access-permissions) in your Aptible [organization](/core-concepts/security-compliance/access-permissions), and grant it "Read" and "Manage" [permissions](/core-concepts/security-compliance/access-permissions) for the [environment](/core-concepts/architecture/environments) you'd like to automate deployment to.

2.  Invite a new user to this Robots role. This user needs to have an actual email address. You can use something like `deploy@yourdomain.com`.

3.  Log out of your Aptible account, accept the invitation you received for the robot user by email, and create a password for the robot user.

Suppose you use this user to deploy an app using [Dockerfile Deploy](/how-to-guides/app-guides/integrate-aptible-with-ci/overview#dockerfile-deploy). In that case, you're also going to need an SSH keypair for the robot user to let them connect to your app's [Git Remote](/core-concepts/apps/deploying-apps/image/deploying-with-git/overview#git-remote):

1.  Generate an SSH key pair for the robot user using `ssh-keygen -f deploy.pem`. Don't set a password for the key.

2.  Register the [SSH Public Key](/core-concepts/security-compliance/authentication/ssh-keys) with Aptible for the robot user.

## Triggering a Deploy

## Dockerfile Deploy

Most CI platforms expose a form of "after-success" hook you can use to trigger a deploy to Aptible after your tests have passed. You'll need to use it to trigger a deploy to Aptible by running `git push`. For the `git push` to work, you'll also need to provide your CI platform with the SSH key you created for your robot user. To that end, most CI platforms let you provide encrypted files to store in your repository.

## Direct Docker Image Deploy

To deploy with Direct Docker Image Deploy:

1.  Build and publish a Docker Image when your build succeeds.

2.  Install the [Aptible CLI](/reference/aptible-cli/cli-commands/overview) in your CI environment.

3.  Log in as the robot user, and use [`aptible deploy`](/reference/aptible-cli/cli-commands/cli-deploy) to trigger a deploy to Aptible.

***

**Keep reading**

*   [Circle CI](/how-to-guides/app-guides/integrate-aptible-with-ci/circle-cl)
*   [Codeship](/how-to-guides/app-guides/integrate-aptible-with-ci/codeship)
*   [Jenkins](/how-to-guides/app-guides/integrate-aptible-with-ci/jenkins)
*   [Travis CI](/how-to-guides/app-guides/integrate-aptible-with-ci/travis-cl)


# Travis CI



Once you've completed the steps for [CI Integration](/how-to-guides/app-guides/integrate-aptible-with-ci/overview), set up Travis CI as follows:

**Step 1:** Encrypt the private key you created for the robot user and store it in the repo. To do so, follow Travis CI's [instructions on encrypting files](http://docs.travis-ci.com/user/encrypting-files/). We recommend using the "Automated Encryption" method.

**Step 2:** Add an `after_success` deploy step. Here again, follow Travis CI's [instructions on custom deployment](http://docs.travis-ci.com/user/deployment/custom/). The `after_success` in your `.travis.yml` file should look like this:

```ruby
after_success:
  - git fetch --depth=1000000
  - chmod 600 .travis/deploy.pem
  - ssh-add .travis/deploy.pem
  - git remote add aptible git@beta.aptible.com:$ENVIRONMENT_HANDLE/$APP_HANDLE.git
  - git push aptible master
```

<Tip> 📘 In the above example, `git@beta.aptible.com:$ENVIRONMENT_HANDLE/$APP_HANDLE.git` represents your App's Git Remote. </Tip>

> Also, see [My deploy failed with a git error referencing objects, trees, revisions or commits](/how-to-guides/troubleshooting/common-errors-issues/git-reference-error) to understand why you need `git fetch` here.


# How to make Dockerfile Deploys faster



Make [Dockerfile Deploy](/how-to-guides/app-guides/deploy-from-git) faster by structuring your Dockerfile to maximize efficiency by leveraging the Docker build cache:

## Gems installed via Bundler

In order for the Docker build cache to cache gems installed via Bundler:

1.  Add the Gemfile and Gemfile.lock files to the image.

2.  Run `bundle install`, *before* adding the rest of the repo (via `ADD .`).

Here's an example of how that might look in a Dockerfile:

```ruby
FROM ruby

# If needed, install system dependencies here

# Add Gemfile and Gemfile.lock first for caching
ADD Gemfile /app/
ADD Gemfile.lock /app/
WORKDIR /app
RUN bundle install

ADD . /app

# If needed, add additional RUN commands here
```

## Packages installed via NPM

In order for the Docker build cache to cache packages installed via npm:

1.  Add the `package.json` file to the image.

2.  Run `npm install`, *before* adding the rest of the repo (via `ADD .`).

Here's an example of how that might look in a Dockerfile:

```node
FROM node

# If needed, install system dependencies here

# Add package.json before rest of repo for caching
ADD package.json /app/
WORKDIR /app
RUN npm install

ADD . /app

# If needed, add additional RUN commands here
```

## Packages installed via PIP

In order for the Docker build cache to cache packages installed via pip:

1.  Add the `requirements.txt` file to the image.

2.  Run `pip install`, *before* adding the rest of the repo (via `ADD .`).

Here's an example of how that might look in a Dockerfile:

```python
FROM python

# If needed, install system dependencies here

# Add requirements.txt before rest of repo for caching
ADD requirements.txt /app/
WORKDIR /app
RUN pip install -r requirements.txt

ADD . /app
```


# How to migrate from Dockerfile Deploy to Direct Docker Image Deploy



If you are currently using [Dockerfile Deploy](/how-to-guides/app-guides/deploy-from-git) and would like to migrate to a Direct Docker Image Deploy, use the following instructions:

1.  If you have a `Procfile` or `.aptible.yml` file in your repository, you must embed it in your Docker image. To do so, follow the instructions at [Procfiles and `.aptible.yml` with Direct Docker Image Deploy](/core-concepts/apps/deploying-apps/image/deploying-with-docker-image/procfile-aptible-yml-direct-docker-deploy).

2.  If you modified your image to add the `Procfile` or `.aptible.yml`, rebuild your image and push it again.

3.  Deploy using `aptible deploy` as documented in [Using `aptible deploy`](/reference/aptible-cli/cli-commands/cli-deploy), with one exception: the first time you deploy (you don't need to do it again), add the `--git-detach` flag to this command. Adding the `--git-detach` flag ensures Aptible ignores your app's Companion Git Repository in the future.

## What if you don't add `--git-detach`?

If you don't add the `--git-detach` flag, Aptible will fall back to a deprecated mode of operation called [Companion Git Repository](/core-concepts/apps/deploying-apps/image/deploying-with-docker-image/companion-git-repository).

In this mode, Aptible uses the `Procfile` and `.aptible.yml` from your Git repository, if any, and ignores everything else (e.g., `Dockerfile`, source code). Aptible deploys your Docker Image directly instead. Because of this behavior, using this mode of operation isn't recommended. Instead, embed your `Procfile` and `.aptible.yml` in your Docker Image, and add the `--git-detach` flag to disable the Companion Git Repository.


# How to migrate a NodeJS app from Heroku to Aptible

Guide for migrating a NodeJS app from Heroku to Aptible

## Overview

Migrating applications from one PaaS to another might sound like a daunting task, but thankfully similarities between platforms makes transitioning easier than expected. However, while Heroku and Aptible are both PaaS applications with similar value props, there are some notable differences between them.

Today, developers are often switching to Aptible to access easier turn-key compliance and security at reasonable prices with stellar scalability and reliability.

One of the most common app types that’s transitioned over is a NodeJS app. We’ll guide you through the various considerations you need to make as well as give you a step-by-step guide to transition your NodeJS app to Aptible.

## Set up

Before starting, you should install Aptible’s CLI which will make setting configurations and deploying applications easier. The full guide on installing Aptible’s CLI can be found [here](/reference/aptible-cli/cli-commands/overview). Installing Aptible typically doesn’t take more than a few minutes.

Additionally, you should [set up an Aptible account](https://dashboard.aptible.com/signup) and create an Aptible app to pair with your existing project.

## Example

We’ll be moving over a stock NodeJS application with a Postgres database. However, if you use a different database, you’ll still be able to take advantage of most of this tutorial. We chose Postgres for this example because it is the most common stack pair.

## Things to consider

While Aptible and Heroku have a lot of similarities, there are some differences in how applications are organized and deployed. We’ll summarize those in this section before moving on to a traditional step-by-step guide.

### Aptible mandates Docker

While many Heroku projects already use Docker, Heroku projects can rely on just Git and Heroku’s [Buildpacks](https://elements.heroku.com/buildpacks/heroku/heroku-buildpack-nodejs). Because Heroku originally catered to hobbyists, supporting projects without a Dockerfile was appropriate.

However, Aptible’s focus on production-grade deployments and evergreen reliability mean all of our adopters use containerization. Accordingly, Aptible requires Dockerfiles to build an application, even if the application isn’t using the Docker registry.

If you don’t have a Dockerfile already, you can easily add one.

### Similar Constraints

Like Heroku, Aptible only supports Linux for deployments (with all apps run inside a Docker container). Also like Heroku, Aptible only supports packets via ports 80 and 443, corresponding to TCP / HTTP and TLS / HTTPS.

If you need to use UDP, your application will need to connect to an external service that manages UDP endpoints.

Additionally, like Heroku, Aptible applications are inherently ephemeral and are not expected to have persistent storage. While Aptible’s [pristine state](https://www.aptible.com/blog/gracefully-handling-memory-management) feature (which clears the app’s file system on a restart) can be disabled, it is not recommended. Instead, permanent storage should be delegated to an external service like S3 or Cloud Storage.

### Docker Support

Similar to Heroku, Aptible supports both (i) deploying applications via Dockerfile Deploy—where Aptible builds your image—or (ii) pulling a pre-built image from a Docker Registry.

### Aptible doesn’t mandate Procfiles

Unlike Heroku which requires Procfiles, Aptible considers Procfiles as optional. When a Procfile is missing, Aptible will infer command via the Dockerfile’s `CMD` declaration (known as an [Implicit Service](/how-to-guides/app-guides/define-services#implicit-service-cmd)). In short, Aptible requires Dockerfiles while Heroku requires Procfiles.

When switching over from Heroku, you can optionally keep your Procfile. Procfile syntax [is standardized](https://ddollar.github.io/foreman/) and is therefore consistent between Aptible and Heroku. Procfiles can be useful when an application has multiple services. However, you might need to change its location. If you are using the [Dockerfile Deploy](/how-to-guides/app-guides/deploy-from-git) approach, the Procfile should remain in your root director. However, if you are using [Direct Docker Image Deploy](/how-to-guides/app-guides/migrate-dockerfile-to-direct-image-deploy), the Procfile should be moved to `/.aptible/Procfile`.

Alternatively, for `.yaml` fans, you can use Aptible’s optional `.aptible.yml` format. Similar to Procfiles, applications using Dockerfile Deploy should store the `.aptible.yml` file in the root folder, while apps using Direct Docker Image Deploy should store them at `/.aptible/.aptible.yml`.

### Private Registry Authentication

If you are using Docker’s private registries, you’ll need to authorize Aptible to pull images from those private registries.

## Step-by-step guide

### 1. Create a Dockerfile (if you don’t have one already)

For users that don’t have a Dockerfile, you can create a Dockerfile by running

```node
touch Dockerfile
```

Next, we can add some contents, such as stating a node runtime, establishing a work directory, and commands to install packages.

```node
FROM node:lts

WORKDIR /app

COPY package.json /app
COPY package-lock.json /app

RUN npm ci

COPY . /app
```

We also want to expose the right port. For many Node applications, this is port 3000.

```js
EXPOSE 3000
```

Finally, we want to introduce a command for starting an application. We will use Docker’s `CMD` utility to accomplish this. `CMD` accepts an array of individual words. For instance, for **npm start** we could do:

```js
CMD [ "npm", "start" ]
```

In total, that creates a Dockerfile that looks like the following.

```js
FROM node:lts

WORKDIR /app

COPY package.json /app
COPY package-lock.json /app

RUN npm ci

COPY . /app

EXPOSE 3000

ARG DATABASE_URL

CMD [ "npm", "start" ]
```

### 2. Move over Procfiles (if applicable)

If you wish to still use your Procfile and also want to use Docker’s registry, you need to move your Procfile’s location into inside the `.aptible` folder. We can do this by running:

```js
mkdir .aptible #if it doesn't exist yet
cp Profile /.aptible/Procfile
```

### 3. Set up Aptible’s remote

Assuming you followed Aptible’s instructions to [provision your account](/getting-started/deploy-custom-code) and grant SSH access, you are ready to set Aptible as a remote.

```bash
git remote add aptible <your remote url> 
#your remote should look like ~ git@beta.aptible.com:<env name>/<app name>.git
```

### 4. Migrating databases

If you previously used Heroku PostgreSQL you’ll find comfort in Aptible’s [managed database solution](https://www.aptible.com/product#databases), which supports PostgreSQL, Redis, Elasticsearch, InfluxDB, mySQL, and MongoDB. Similar to Heroku, Aptible supports automated backups, replicas, failover logic, encryption, network isolation, and automated scaling.

Of course, beyond provisioning a new database, you will need to migrate your data from Heroku to Aptible. You may also want to put your database on maintenance mode when doing this to avoid additional data being written to the database during the process. You can accomplish that by running:

```bash
heroku maintenance:on --app <APP_NAME>
```

Then, create a fresh backup of your data. We’ll use this to move the data to Aptible.

```bash
heroku pg:backups:capture --app <APP_NAME>
```

After, you’ll want to download the backup as a file.

```bash
heroku pg:backups:download --app <APP_NAME>
```

This will download a file named `latest.dump`, which needs to be converted into a SQL file to be imported into Postgres. We can do this by using the `pg_restore` utility. If you do not have the `pg_restore` utility, you can install it [on Mac using Homebrew](https://www.cyberithub.com/how-to-install-pg_dump-and-pg_restore-on-macos-using-7-easy-steps/) or [Postgres.app](https://postgresapp.com/downloads.html), and [one of the many Postgres clients](https://wiki.postgresql.org/wiki/PostgreSQL_Clients) on Linux.

```bash
pg_restore -f - --table=users latest.dump > data.sql
```

Then, we’ll want to move this into Aptible.

We can create a new Database running the desired version. Assuming the environment variables above are set, this command can be copied and pasted as-is to create the Database.

```bash
aptible db:create "new_database" \
  --type postgresql \
  --version "14" \
  --environment "my_environment" \
  --disk-size "100" \
  --container-size "4096"
```

You can use your current environment, or [create a new environment](/core-concepts/architecture/environments). Then, we will use the Aptible CLI to connect to the database.

```bash
aptible db:tunnel "new_database" --environment "my_environment"
```

This should return the tunnel’s URL, e.g.:

![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/node-heroku-aptible.png)

Keeping the session open, open a new Terminal tab and store the tunnel’s URL as an environment variable:

```bash
TARGET_URL='postgresql://aptible:passw0rd@localhost.aptible.in:5432/db'
```

Using the environment variable, we can use our terminal’s pSQL client to import our exported data from Heroku (here named as `data.sql`) into the database.

```bash
psql $TARGET_URL -f data.sql > /dev/null
```

You might get some error messages noting that the role `aptible`, `postgres`, and the database `db` already exists. These are okay. You can learn more about potential errors by reading our database import guide [here](/how-to-guides/database-guides/dump-restore-postgresql).

### 5. \[Deploy using Git] Push your code to Aptible

If we aren’t going to use the Docker registry, we can instead directly push to Aptible, which will build an image and deploy it. To do this, first commit our changes and push our code to Aptible.

```bash
git add -A
git commit -m "Re-organization for Aptible" 
git push aptible <branch name> #e.g. main or master
```

### 6. \[Deploying with Docker] Private Registry registration

If you used Docker’s registry for your Heroku deployments, and you were using a private registry, you’ll need to register your credentials with Aptible’s `config` utility.

```bash
aptible config:set APTIBLE_PRIVATE_REGISTRY_USERNAME=YOUR_USERNAME APTIBLE_PRIVATE_REGISTRY_PASSWORD=YOUR_USERNAME
```

### 7. \[Deploying with Docker] Deploy with Docker

While you can get a detailed overview of how to deploy with Docker from our [dedicated guide](/how-to-guides/app-guides/migrate-dockerfile-to-direct-image-deploy), we will summarize the core steps.

Most Docker registries supply long-term credentials, which you only need to provide to Aptible once. We can do that using the following command:

```bash
aptible deploy \
--app "$APP_HANDLE" \
--docker-image "$DOCKER_IMAGE" \
--private-registry-username "$USERNAME" \
--private-registry-password "$PASSWORD"
```

After, we just need to provide the Docker Image URL to deploy to Aptible:

```bash
aptible deploy --app "$APP_HANDLE" \
        --docker-image "$DOCKER_IMAGE"
```

If the image URL is consistent, you can skip the `--docker-image` tag on subsequent deploys.

## Closing Thoughts

And that’s it! Moving from Heroku to Aptible is actually a fairly simple process. With some modified configurations, you can switch PaaS platforms in less than a day.


# All App Guides

Explore guides for deploying and managing Apps on Aptible

*   [How to create an app](/how-to-guides/app-guides/how-to-create-app)
*   [How to scale apps and services](/how-to-guides/app-guides/how-to-scale-apps-services)
*   [How to set and modify configuration variables](/how-to-guides/app-guides/set-modify-config-variables)
*   [How to deploy to Aptible with CI/CD](/how-to-guides/app-guides/how-to-deploy-aptible-ci-cd)
*   [How to define services](/how-to-guides/app-guides/define-services)
*   [How to deploy via Docker Image](/how-to-guides/app-guides/deploy-docker-image)
*   [How to deploy from Git](/how-to-guides/app-guides/deploy-from-git)
*   [How to migrate from deploying via Docker Image to deploying via Git](/how-to-guides/app-guides/deploying-docker-image-to-git)
*   [How to integrate Aptible with CI Platforms](/how-to-guides/app-guides/integrate-aptible-with-ci/overview)
*   [How to synchronize configuration and code changes](/how-to-guides/app-guides/synchronize-config-code-changes)
*   [How to migrate from Dockerfile Deploy to Direct Docker Image Deploy](/how-to-guides/app-guides/migrate-dockerfile-to-direct-image-deploy)
*   [Deploy Metric Drain with Terraform](/how-to-guides/app-guides/deploy-metric-drain-with-terraform)
*   [Getting Started with Docker](/how-to-guides/app-guides/getting-started-with-docker)
*   [How to access configuration variables during Docker build](/how-to-guides/app-guides/access-config-vars-during-docker-build)
*   [How to migrate a NodeJS app from Heroku to Aptible](/how-to-guides/app-guides/migrate-nodjs-from-heroku-to-aptible)
*   [How to generate certificate signing requests](/how-to-guides/app-guides/generate-certificate-signing-requests)
*   [How to expose a web app to the Internet](/how-to-guides/app-guides/expose-web-app-to-internet)
*   [How to use Nginx with Aptible Endpoints](/how-to-guides/app-guides/use-nginx-with-aptible-endpoints)
*   [How to make Dockerfile Deploys faster](/how-to-guides/app-guides/make-docker-deploys-faster)
*   [How to use Domain Apex with Endpoints](/how-to-guides/app-guides/use-domain-apex-with-endpoints/overview)
*   [How to use S3 to accept file uploads](/how-to-guides/app-guides/use-s3-to-accept-file-uploads)
*   [How to use cron to run scheduled tasks](/how-to-guides/app-guides/use-cron-to-run-scheduled-tasks)
*   [How to serve static assets](/how-to-guides/app-guides/serve-static-assets)
*   [How to establish client certificate authentication](/how-to-guides/app-guides/establish-client-certificiate-auth)


# How to serve static assets



> 📘 This article is about static assets served by your app such as CSS or JavaScript files. If you're looking for strategies for storing files uploaded by or generated for your customers, see [How do I accept file uploads when using Aptible?](/how-to-guides/app-guides/use-s3-to-accept-file-uploads) instead.

Broadly speaking, there are two ways to serve static assets from an Aptible web app:

## Serving static assets from a web container running on Aptible

> ❗️ This approach is typically only appropriate for development and staging apps. See [Serving static assets from a third-party object store or CDN](/how-to-guides/app-guides/serve-static-assets#serving-static-assets-from-a-third-party-object-store-or-cdn) to understand why and review a production-ready approach. Note that using a third-party object store is often simpler to maintain as well.

Using this method, you'll serve assets from the same web container that is serving application requests on Aptible.

Many web frameworks (such as Django or Rails) have asset serving mechanisms that you can use to build assets, and will automatically serve assets for you after you've done so.

Typically, you'll have to run an asset pre-compilation step ahead of time for this to work. Ideally, you want do so in your `Dockerfile` to ensure the assets are built once and are available in your web containers.

Unfortunately, in many frameworks, building assets requires access to at least a subset of your app's configuration (e.g., for Rails, at the very least, you'll need `RAILS_ENV` to be set, perhaps more depending on your app), but building Docker images is normally done **without configuration**.

Here are a few solutions you can use to work around this problem:

## Use Aptible's `.aptible.env`

If you are building on Aptible using [Dockerfile Deploy](/how-to-guides/app-guides/deploy-from-git), you can access your app's configuration variables during the build. This means you can load those variables, then build your assets.

To do so with a Rails app, you'd want to add this block toward the end of your `Dockerfile`:

```bash
RUN set -a \
 && . ./.aptible.env \
 && bundle exec rake assets:precompile
```

For a Django app, you might use something like this:

```bash
RUN set -a \
 && . ./.aptible.env \
 && python manage.py collectstatic
```

> 📘 Review [Accessing Configuration variables during the Docker build](/how-to-guides/app-guides/access-config-vars-during-docker-build) for more information about `.aptible.env` and important caveats.

## Build assets upon container startup

An alternative is to build assets when your web container starts. If your app has a [Procfile](/how-to-guides/app-guides/define-services), you can do so like this, for example (adjust as needed):

```bash
# Rails example:
web: bundle exec rake assets:precompile && exec bundle exec rails s -b 0.0.0.0 -p 3000

# Django example:
web: python manage.py collectstatic && exec gunicorn --access-logfile=- --error-logfile=- --bind=0.0.0.0:8000 --workers=3 mysite.wsgi
```

Alternatively, you could add an `ENTRYPOINT` in your image to do the same thing.

An upside of this approach is that all your configuration variables will be available when the container starts, so this approach is largely guaranteed to work as long as there is no bug in your app.

However, an important downside of this approach is that it will slow down the startup of your containers: instead of building assets once and for all when building your image, your app will rebuild them every time it starts. This includes restarts triggered by [Container Recovery](/core-concepts/architecture/containers/container-recovery) should your app crash.

Overall, this approach is only suitable if your asset build is fairly quick and/or you can tolerate a slower startup.

## Minimize environment requirements and provide them in the Dockerfile

Alternatively, you can refactor your App not to require environment variables to build assets.

For a Django app, you'd typically do that by creating a minimal settings module dedicated to building assets and settings, e.g., `DJANGO_SETTINGS_MODULE=myapp.static_settings` prior to running `collectstatic`

For a Rails app, you'd do that by creating a minimal `RAILS_ENV` dedicated to building assets and settings e.g. `RAILS_ENV=assets` prior to running `assets:precompile`.

If you can take the time to refactor your App slightly, this approach is by far the best one if you are going to serve assets from your container.

## Serving static assets from a third-party object store or CDN

## Reasons to use a third-party object store

There are two major problems with serving assets from your web containers:

### Performance

If you serve your assets from your web containers, you'll typically do so from your application server (e.g. Unicorn for Ruby, Gunicorn for Python, etc.).

However, application servers are optimized for serving application code, not assets. Serving assets is a comparatively dumb task that simpler web servers are better suited for.

For example, when it comes to serving assets, a Unicorn Ruby server serving assets from Ruby code is going to be very inefficient compared to an Nginx or Apache web server.

Likewise, an object store will be a lot more efficient at serving assets than your application server, which is one reason why you should favor using one.

### Interaction with Zero-Downtime Deploys

When you deploy your app, [Zero-Downtime Deployment](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/overview#zero-downtime-deployment) requires that there will be a period when containers from both your old code release and new code release are serving traffic at the same time.

If you are serving assets from a web container, this means the following interaction could happen:

1.  A client requests a page.

2.  That request is routed to a container running your new code, which responds with a page that links to assets.

3.  The client requests a linked asset.

4.  That request is routed to a container running your old code.

When this interaction happens, if you change your assets, the asset served by your Container running the old code may not be the one you expect. And, if you fingerprint your assets, it may not be found at all.

For your client, both cases will result in a broken page

Using an object store solves this problem: as long as you fingerprint assets, you can ensure your object store is able to serve assets from *all* your code releases.

To do so, simply upload all assets to the object store of your choice for a release prior to deploying it, and never remove assets from past releases until you're absolutely certain they're no longer referenced anywhere.

This is another reason why you should be using an object store to serve static assets.

> 📘 Considering the low pricing of object stores and the relatively small size of most application assets, you might not need to bother with cleaning up older assets: keeping them around may cost you only a few cents per month.

## How to use a third-party object store

To push assets to an object store from an app on Aptible, you'll need to:

*   Identify and incorporate a library that integrates with your framework of choice to push assets to the object store of your choice. There are many of those for the most popular frameworks.

*   Add credentials for the object store in your App's [Configuration](/core-concepts/apps/deploying-apps/configuration).

*   Build and push assets to the object store as part of your release on Aptible. The easiest and best way to do this is to run your asset build and push as part of [`before_release`](/core-concepts/apps/deploying-apps/releases/aptible-yml#before-release) commands on Aptible.

For example, if you're running a Rails app and using [the Asset Sync gem](https://github.com/rumblelabs/asset_sync) to automatically sync your assets to S3 at the end of the Rails assets pipeline, you might use the following [`.aptible.yml`](/core-concepts/apps/deploying-apps/releases/aptible-yml) file:

```bash
before_release:
  - bundle exec rake assets:precompile
```


# How to set and modify configuration variables



Learn how to set and modify [configuration variables](/core-concepts/apps/deploying-apps/configuration) for apps

## Using the Dashboard

Configuration variables can be set or modified in the Dashboard in the following ways:

*   While deploying new code by:

    *   Using the [**Deploy**](https://app.aptible.com/create) tool will allow you to set environment variables as you deploy your code ![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/config-var1.png)
*   For existing apps by:

    *   Navigating to the respective app

    *   Selecting the **Configuration** tab

    *   Selecting **Edit** within Edit Environment Variables ![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/config-var2.png)

## Using the CLI

Configuration variables can be set or modified via the CLI in the following ways:

*   Using [`aptible deploy`](/reference/aptible-cli/cli-commands/cli-deploy) command
*   Using the [`aptible config:set`](/reference/aptible-cli/cli-commands/cli-config-set) command

## Size Limits

A practical limit for configuration variable length is 65,536 characters.


# How to synchronize configuration and code changes



Updating the [configuration](/core-concepts/apps/deploying-apps/configuration) of your [app](/core-concepts/apps/overview) using [`aptible config:set`](/reference/aptible-cli/cli-commands/cli-config-set) then deploying your app through [Dockerfile Deploy](/how-to-guides/app-guides/deploy-from-git) or [Direct Docker Image Deploy](/how-to-guides/app-guides/migrate-dockerfile-to-direct-image-deploy) will deploy your app twice:

*   Once to apply the [Configuration](/core-concepts/apps/deploying-apps/configuration) changes.
*   Once to deploy the new [Image](/core-concepts/apps/deploying-apps/image/overview).

This process may be inconvenient when you need to update your configuration and ship new code that depends on the updated configuration **simultaneously**. To solve this problem, the Aptible CLI lets you deploy and update your app configuration as one atomic operation.

## For Dockerfile Deploy

To synchronize a Configuration change and code release when using [Dockerfile Deploy](/how-to-guides/app-guides/deploy-from-git):

**Step 1:** Push your code to a new deploy branch on Aptible. Any name will do, as long as it's not `master`, but we recommend giving it a random-ish name like in the example below. Pushing to a branch other than `master` will **not** trigger a deploy on Aptible. However, the new code will be available for future deploys.

```js
BRANCH="deploy-$(date "+%s")"
git push aptible "master:$BRANCH"
```

**Step 2:** Deploy this branch along with the new Configuration variables using the [`aptible deploy`](/reference/aptible-cli/cli-commands/cli-deploy) command:

```js
aptible deploy \
  --app "$APP_HANDLE" \
  --git-commitish "$BRANCH" \
  FOO=BAR QUX=
```

Please note that you can provide some common configuration variables as arguments to CLI commands instead of updating the app configuration. For example, if you need to include [Private Registry Authentication](/core-concepts/apps/overview) credentials to let Aptible pull a source Docker image, you can use this command:

```js
aptible deploy \
  --app "$APP_HANDLE" \
  --git-commitish "$BRANCH" \
  --private-registry-username "$USERNAME" \
  --private-registry-password "$PASSWORD"
```

## For Direct Docker Image Deploy

Please use the [`aptible deploy`](/reference/aptible-cli/cli-commands/cli-deploy) CLI command to deploy your app if you are using [Direct Docker Image Deploy](/how-to-guides/app-guides/migrate-dockerfile-to-direct-image-deploy). If you are not using `aptible deploy`, please review the [Direct Docker Image Deploy](/how-to-guides/app-guides/migrate-dockerfile-to-direct-image-deploy) instructions. When using `aptible deploy` with Direct Docker Image Deploy, you may append environment variables to the [`aptible deploy`](/reference/aptible-cli/cli-commands/cli-deploy) command:

```js
aptible deploy \
  --app "$APP_HANDLE" \
  --docker-image "$DOCKER_IMAGE" \
  FOO=BAR QUX=
```


# How to use cron to run scheduled tasks

Learn how to use cron to run and automate scheduled tasks on Aptible

## Overview

Cron jobs can be used to run, and automate scheduled tasks. On Aptible, users can run cron jobs with the use of an individual app or with a service associated with an app, defined in the app's [procfile](/how-to-guides/app-guides/define-services).

[Supercronic](https://github.com/aptible/supercronic) is an open-source tool created by Aptible that avoids common issues with cron job implementation in containerized platforms.

This guide is designed to walk you through getting started with cron jobs on Aptible with the use of Supercronic.

## Getting Started

**Step 1:** Install [Supercronic](https://github.com/aptible/supercronic#installation) in your Docker image.

**Step 2:** Add a `crontab` to your repository. Here is an example `crontab` you might want to adapt or reuse:

```bash
# Run every minute
*/1 * * * * bundle exec rake some:task

# Run once every hour
@hourly curl -sf example.com >/dev/null && echo 'got example.com!'
```

> 📘 For a complete crontab reference, review the documentation from the library Supercronic uses to parse crontabs, [cronexpr](https://github.com/gorhill/cronexpr#implementation).

> 📘 Unless you've specified otherwise with the `TZ` [environment variable](/core-concepts/architecture/containers/overview), the schedule for your crontab will be interpreted in UTC.

**Step 3:** Copy the `crontab` to your Docker image with a directive such as this one:

```bash
ADD crontab /app/crontab
```

> 📘 The example above grabs a file named `crontab` found at the root of your repository and copies it under `/app` in your image. Adjust as needed.

**Step 4:** Add a new service (if your app already has a Procfile), or deploy a new app altogether to start Supercronic and run your cron jobs. If you are adding a service, use this `Procfile` declaration:

```bash
cron: exec /usr/local/bin/supercronic /app/crontab
```

If you are adding a new app, you can use the same `Procfile` declaration or add a `CMD` declaration to your [Dockerfile](/core-concepts/apps/deploying-apps/image/deploying-with-git/overview):

```bash
CMD ["supercronic", "/app/crontab"]
```


# AWS Domain Apex Redirect

This tutorial will guide you through the process of setting up an Apex redirect using AWS S3, AWS CloudFront, and AWS Certificate Manager.

The heavy lifting is automated using CloudFormation, so this entire process shouldn't require more than a few minutes of active work.

Before starting, you will need the following:

*   The domain you want to redirect away from (e.g.: `example.com`, `myapp.io`, etc.).

*   The subdomain you want to redirect to (e.g.: `app`, `www`, etc.).

*   Access to the DNS configuration for the domain. Your DNS provider must support ALIAS records (also known as CNAME flattening). We support the following DNS providers in this tutorial: Amazon Route 53, CloudFlare, DNSimple. If your DNS provider does not support ALIAS records, then we encourage you to migrate your NS records to one that does.

*   Access to one of the mailboxes used by AWS Certificate Manager to validate ownership of your domain. If you registered the domain yourself, that should be the case, but otherwise, review the [relevant AWS Certificate Manager documentation](http://docs.aws.amazon.com/acm/latest/userguide/gs-acm-validate.html) first.

*   An AWS account.

After completing this tutorial, you will have an inexpensive highly-available redirect from your domain apex to your subdomain, which will require absolutely no maintenance going forward.

## Create the CloudFormation Stack

Navigate to [the CloudFormation Console](https://console.aws.amazon.com/cloudformation/home?region=us-east-1), and click "Create Stack".

Note that **you must create this stack in the** **`us-east-1`** **region**, but your redirect will be served globally with minimal latency via AWS CloudFront.

Choose "Specify an Amazon S3 template URL", and use the following template URL:

```url
https://s3.amazonaws.com/www.aptible.com/assets/cloudformation-redirect.yaml
```

Click "Next", then:

*   For the `Stack name`, choose any name you'll recognize in the future, e.g.: `redirect-example-com`.

*   For the `Domain` parameter, input the domain you want to redirect away from.

*   For the `Subdomain` parameter, use the subdomain. Don't include the domain itself there! For example, you want to redirect to `app.example.com`, then just input `app`.

*   For the `ViewerBucketName` parameter, input any name you'll recognize in the future. You **cannot use dots** here. A name like `redirect-example-com` will work here too.

Then, hit "Next", and click through the following screen as well.

## Validate Domain Ownership

In order to set up the apex redirect to require no maintenance, the CloudFormation template we provide uses AWS Certificate Manager to automatically provision and renew a (free) certificate to serve the redirect from your domain apex to your subdomain.

To make this work, you'll need to validate with AWS that you own the domain you're using. So, once the CloudFormation stack enters the state `CREATE_IN_PROGRESS`, navigate to your mailbox, and look for an email from AWS to validate your domain ownership.

Once you receive it, read the instructions and click through to validate.

## Wait for a little while!

Wait for the CloudFormation stack to enter the state `CREATE_COMPLETE`.

This process will take about one hour, so sit back while CloudFormation does the work and come back once it's complete (but we'd suggest you stay around for the first 5 minutes or so in case an error shows up).

If, for some reason, the process fails, review the error in the stack's Events tab. This may be caused by choosing a bucket name that is already in use. Once you've identified the error, delete the stack, and start over again.

## Configure your DNS provider

Once CloudFormation is done working, you need to tie it all together by routing requests from your domain apex to CloudFormation.

To do this, you'll need to get the `DistributionHostname` provided by CloudFormation as an output for the stack. You can find it in CloudFormation under the Outputs tab for the stack after its state changes to `CREATE_COMPLETE`.

Once you have the hostname in hand, the instructions depend on your DNS provider.

If you're setting up a redirect for a domain that's already serving production traffic, now is a good time to check that the redirect works the way you expect.

To do so, use `curl` and verify that the following requests return a redirect to the right host (you should see a `Location` header in the response):

```sql
# $DOMAIN should be set to your domain apex.
# $DISTRIBUTION should be set to the DistributionHostname.

# This should redirect to your subdomain over HTTP.
curl -v -H 'Host: $DOMAIN' 'http://$DISTRIBUTION'

# This should redirect to your subdomain over HTTPS.
curl -v -H 'Host: $DOMAIN' 'https://$DISTRIBUTION'
```

### If you use Amazon Route 53

Navigate to the Hosted Zone for your domain, then create a new record using the following options:

*   Name: *Leave this blank* (this represents your domain apex).

*   Type: A.

*   Alias: Yes.

*   Alias Target: the `DistributionHostname` you got from CloudFormation.

## If you use Cloudflare

Navigate to the CloudFlare dashboard for your domain, and create a new record with the following options:

*   Type: CNAME.

*   Name: Your domain.

*   Domain Name: the `DistributionHostname` you got from CloudFormation.

Cloudflare will note that CNAME flattening will be used. That's OK, and expected.

## If you use DNSimple

Navigate to the DNSimple dashboard for your domain, and create a new record with the following options:

*   Type: ALIAS

*   Name: *Leave this blank* (this represents your domain apex).

*   Alias For: the `DistributionHostname` you got from CloudFormation.


# Domain Apex ALIAS



Setting up an ALIAS record lets you serve your App from your [domain apex](/how-to-guides/app-guides/use-domain-apex-with-endpoints/overview) directly, but there are significant tradeoffs involved in this approach:

First, this will break some Aptible functionality. Specifically, if you use an ALIAS record, Aptible will no longer be able to serve your [Maintenance Page](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/maintenance-page) from its backup error page server, [Brickwall](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/maintenance-page#brickwall). In fact, what happens exactly will depend on your DNS provider:

*   Amazon Route 53: no error page will be served. Customers will most likely be presented with an error page from their browser indicating that the site is not working.

*   Cloudflare, DNSimple: a generic Aptible error page will be served.

Second, depending on the provider, the ALIAS record may break in the future if Aptible needs to replace the underlying load balancer for your Endpoint. Specifically, this will be the case if your DNS provider is Amazon Route 53. We'll do our best to notify you if such a replacement needs to happen, but we cannot guarantee that you won't experience disruption during said replacement.

If, given these tradeoffs, you still want to set up an ALIAS record directly to your Aptible Endpoint, please contact [Aptible Support](/how-to-guides/troubleshooting/aptible-support) for instructions.

If not, use this alternate approach: [Redirecting from your domain apex to a subdomain](/how-to-guides/app-guides/use-domain-apex-with-endpoints/domain-apex-redirect).


# Domain Apex Redirect



The general idea behind setting up a redirection is to sidestep your domain apex entirely and redirect your users transparently to a subdomain, from which you will be able to create a CNAME to an Aptible [Endpoint Hostname](/core-concepts/apps/connecting-to-apps/app-endpoints/custom-domain#endpoint-hostname).

Most customers often choose to use a subdomain such as www or app for this purpose.

To set up a redirection from your domain apex to a subdomain, we strongly recommend using a combination of AWS S3, AWS CloudFront, and AWS Certificate Manager. Using these three services, you can set up a redirection that is easy to set up and requires absolutely no maintenance going forward.

To make things easier for you, Aptible provides detailed instructions to set this up, including a CloudFormation template that will automate all the heavy lifting for you.

To use this template, review the instructions here: [How do I set up an apex redirect using Amazon AWS](/how-to-guides/app-guides/use-domain-apex-with-endpoints/aws-domain-apex-redirect).


# How to use Domain Apex with Endpoints



> 📘 This article assumes that you have created an [Endpoint](/core-concepts/apps/connecting-to-apps/app-endpoints/overview) for your App, and that you have the [Endpoint Hostname](/core-concepts/apps/connecting-to-apps/app-endpoints/custom-domain#endpoint-hostname) (the string that looks like `elb-XXX.aptible.in`) in hand.

> If you don't have that, start here: [How do I expose my web app on the Internet?](/how-to-guides/app-guides/expose-web-app-to-internet).

As noted in the [Custom Domain](/core-concepts/apps/connecting-to-apps/app-endpoints/custom-domain) documentation, Aptible requires that you create a CNAME from the domain of your choice to the Endpoint Hostname. Unfortunately, DNS does not allow the creation of CNAMEs for domain apexes (also known as "bare domains" or "root domains"). There are two options to work around this problem and we strongly recommend using the Redirect option.

## Redirect to a Subdomain

The general idea behind setting up a redirection is to sidestep your domain apex entirely and redirect your users transparently to a subdomain, from which you will be able to create a CNAME to an Aptible [Endpoint Hostname](/core-concepts/apps/connecting-to-apps/app-endpoints/custom-domain#endpoint-hostname).

Most customers often choose to use a subdomain such as www or app for this purpose.

To set up a redirection from your domain apex to a subdomain, we strongly recommend using a combination of AWS S3, AWS CloudFront, and AWS Certificate Manager. Using these three services, you can set up a redirection that is easy to set up and requires absolutely no maintenance going forward.

To make things easier for you, Aptible provides detailed instructions to set this up, including a CloudFormation template that will automate all the heavy lifting for you.

To use this template, review the instructions here: [How do I set up an apex redirect using Amazon AWS](/how-to-guides/app-guides/use-domain-apex-with-endpoints/aws-domain-apex-redirect).

## Use an ALIAS record

Setting up an ALIAS record lets you serve your App from your [domain apex](/how-to-guides/app-guides/use-domain-apex-with-endpoints/overview) directly, but there are significant tradeoffs involved in this approach:

First, this will break some Aptible functionality. Specifically, if you use an ALIAS record, Aptible will no longer be able to serve your [Maintenance Page](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/maintenance-page) from its backup error page server, [Brickwall](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/maintenance-page#brickwall). In fact, what happens exactly will depend on your DNS provider:

*   Amazon Route 53: no error page will be served. Customers will most likely be presented with an error page from their browser indicating that the site is not working.

*   Cloudflare, DNSimple: a generic Aptible error page will be served.

Second, depending on the provider, the ALIAS record may break in the future if Aptible needs to replace the underlying load balancer for your Endpoint. Specifically, this will be the case if your DNS provider is Amazon Route 53. We'll do our best to notify you if such a replacement needs to happen, but we cannot guarantee that you won't experience disruption during said replacement.

If, given these tradeoffs, you still want to set up an ALIAS record directly to your Aptible Endpoint, please contact [Aptible Support](/how-to-guides/troubleshooting/aptible-support) for instructions.

> 📘 Both approaches require a provider that supports ALIAS records (also known as CNAME flattening), such as Amazon Route 53, Cloudflare, or DNSimple.

> If your DNS records are hosted somewhere else, you will need to migrate to one of these providers or use a different solution (we strongly recommend against doing that).

> Note that you only need to update the NS records for your domain. You can keep using your existing provider as a registrar, and you don't need to transfer the domain over to one of the providers we recommend.

***

**Keep reading:**

*   [Domain Apex ALIAS](/how-to-guides/app-guides/use-domain-apex-with-endpoints/domain-apex-alias)
*   [AWS Domain Apex Redirect](/how-to-guides/app-guides/use-domain-apex-with-endpoints/aws-domain-apex-redirect)
*   [Domain Apex Redirect](/how-to-guides/app-guides/use-domain-apex-with-endpoints/domain-apex-redirect)


# How to use Nginx with Aptible Endpoints



Nginx is a popular choice for a reverse proxy to route requests through to Aptible [endpoints](/core-concepts/apps/connecting-to-apps/app-endpoints/overview) using a `proxy_pass` directive.

One major pitfall of using Nginx with Aptible endpoints is that, by default, Nginx disregards DNS TTLs and caches the IPs of its upstream servers forever. In contrast, the IPs for Aptible endpoints change periodically (under the hood, Aptible use AWS ELBs, from which they inherit this property). This contrast means that Nginx will, by default, eventually use the wrong IPs when pointed at an Aptible endpoint through a `proxy_pass` directive. To work around this problem, avoid the following configuration pattern in your Nginx configuration:

```sql
location / {
    proxy_pass https://hostname-of-an-endpoint;
}
```

Instead, use this:

```sql
resolver 8.8.8.8;
set $upstream_endpoint https://hostname-of-an-endpoint;

location / {
    proxy_pass $upstream_endpoint;
}
```


# How to use S3 to accept file uploads

Learn how to connect your app to S3 to accept file uploads

## Overview

As noted in the [Container Lifecycle](/core-concepts/architecture/containers/overview) documentation, [Containers](/core-concepts/architecture/containers/overview) on Aptible are fundamentally ephemeral, and you should **never use the filesystem for long-term file or data storage**.

The best approach for storing files uploaded by your customers (or, more broadly speaking, any blob data generated by your app, such as PDFs, etc.) is to use a third-party object store, such as AWS S3.

You can store data in an Aptible [database](/core-concepts/managed-databases/managing-databases/overview), but often at a performance cost.

## Using AWS S3 for PHI

> ❗️ If you are storing regulated or sensitive information, ensure you have the proper agreements with your storage provider. For example, you'll need to execute a BAA with AWS and use encryption (client-side or server-side) to store PHI in AWS S3.

For storing PHI on Amazon S3, you must get a separate BAA with Amazon Web Services. This BAA will require that you encrypt all data stored on S3. You have three options for implementing encryption, ranked from best to worst based on the combination of ease of implementation and security:

1.  **Server-side encryption with customer-provided keys** ([SSE-C](https://docs.aws.amazon.com/AmazonS3/latest/dev/ServerSideEncryptionCustomerKeys.html)): You specify the key when uploading and downloading objects to/from S3. You are responsible for remembering the encryption key but don't have to choose or maintain an encryption library.

2.  **Client-side encryption** ([CSE](https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingClientSideEncryption.html)): This approach is the most challenging but also gives you complete control. You pick an encryption library and implement the encryption/decryption logic.

3.  **Server-side encryption with Amazon-provided keys** ([SSE](https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingServerSideEncryption.html)): This is the most straightforward approach but the least secure. You need only specify that encryption should occur on PUT, and you never need to keep track of encryption keys. The downside is that if any of your privileged AWS accounts (or access keys) are compromised, your S3 data may be compromised and unprotected by a secondary key.

There are two ways to serve S3 media files:

1.  Generate a pre-signed URL so that the client can access them directly from S3 (note: this will not work if you're using client-side encryption)

2.  Route all media requests through your app, fetch the S3 file within your app code, then re-serve it to the client.

The first approach is superior from a performance perspective. However, if these are PHI-sensitive media files, we recommend the second approach due to the control it gives you concerning audit logging, as you can more easily connect specific S3 file access to individual users in your system.


# Automate Database migrations



Many app frameworks provide libraries for managing database migrations between different revisions of an app.

For example, Rails' ActiveRecord library allows users to define migration files and then run `bundle exec rake db:migrate` to execute them.

To automatically run migrations on each deploy to Aptible, you can use a [`before_release`](/core-concepts/apps/deploying-apps/releases/aptible-yml#before-release) command.

To do so, add the following to your [`.aptible.yml`](/core-concepts/apps/deploying-apps/releases/aptible-yml) file (adjust the command as needed depending on your framework):

```bash
before_release:
  - bundle exec rake db:migrate
```

> ❗️ Don't break your App when running Database migrations! It's easy to forget that your App will be running when automated Database migrations execute, but it's important not to. For example, if your migration locks a table for 10 minutes (e.g., to create a new index synchronously), then that table is going to read-only for 10 minutes. If your App needs to write to this table to function, **it will be down**. Also, if your App is a web App, review the docs over here: [Concurrent Releases](/core-concepts/apps/deploying-apps/releases/overview#concurrent-releases).

## Migration Scripts

If you need to run more complex migration scripts (e.g., with `if` branches, etc.), we recommend encapsulating this logic in a separate script:

```python
#!/bin/sh
# This file lives at script/before_release.sh

if [ "$RAILS_ENV" == "staging" ]; then
  bundle exec rake db:[TASK]
else
  bundle exec rake db:[OTHER_TASK]
fi
```

> ❗️The script needs to be made executable. To do so, run `chmod script/before_release.sh`.

Your new `.aptible.yml` would read:

```bash
before_release:
  - script/before_release.sh
```


# How to configure Aptible PostgreSQL Databases

Learn how to configure PostgreSQL Databases on Aptible

## Overview

This guide will walk you through the steps of changing, applying, and checking settings, in addition to configuring access control, for an Aptible PostgreSQL]\(/core-concepts/managed-databases/supported-databases/postgresql) database.

## Changing Settings

As described in Aptible’s [PostgreSQL Configuration](/core-concepts/managed-databases/supported-databases/postgresql#configuration) documentation, the [`ALTER SYSTEM`](https://www.postgresql.org/docs/current/sql-altersystem.html)command can be used to make persistent, global changes to [`pg_settings`](https://www.postgresql.org/docs/current/view-pg-settings.html).

*   `ALTER SYSTEM SET` changes a setting to a specified value. For example, `ALTER SYSTEM SET max_connections = 500;`.

*   `ALTER SYSTEM RESET` resets a setting to the default value set in [`postgresql.conf`](https://github.com/aptible/docker-postgresql/blob/master/templates/etc/postgresql/PG_VERSION/main/postgresql.conf.template) i.e. the Aptible default setting. For example, `ALTER SYSTEM RESET max_connections`.

## Applying Settings

Changes to settings are not necessarily applied immediately. The setting’s `context` determines when the change is applied. The current contexts for settings that can be changed with `ALTER SYSTEM` are:

*   `postmaster` - Server settings that cannot be changed after the Database starts. Restarting the Database is required to apply these settings.

*   `backend` and `superuser-backend` - Connection settings that cannot be changed after the connection is established. New connections will use the updated settings.

*   `sighup` - Server settings that can be changed at runtime. The Database’s configuration must be reloaded in order to apply these settings.

*   `user` and `superuser` - Session settings that can be changed with `SET` . New sessions will use the updated settings by default and reloading the configuration will apply it to all existing sessions that have not changed the setting.

Any time the Database container restarts including when it crashes or when the [`aptible db:reload`](/reference/aptible-cli/cli-commands/cli-db-reload) or [`aptible db:restart`](/reference/aptible-cli/cli-commands/cli-db-restart) CLI commands are run will apply any pending changes. `aptible db:reload` is recommended as it incurs the least amount of downtime. Restarting the Database is the only way to apply `postmaster` settings. It will also ensure that all `backend` and `superuser-backend` settings are being used by all open connections since restarting the Database will terminate all connections, forcing clients to establish new connections.

For settings that can be changed at runtime, the `pg_reload_conf` function (i.e. running `SELECT pg_reload_conf();`) will apply the changes to the Database and existing sessions. This is required to apply `sighup` settings without restarting the Database. `user` and `superuser` settings don’t require the configuration to be reloaded but, if it isn’t, the changes will only apply to new sessions so it’s recommended in order to ensure all sessions are using the same default configuration.

## Checking Setting Values and Contexts

### Show pg\_settings

The `pg_settings` view contains information on the current settings being used by the Database. The following query selects the relevant columns from `pg_settings` for a single setting:

```js
SELECT name, setting, context, pending_restart
FROM pg_settings
WHERE name = 'max_connections';

```

Note that `setting` is the current value for the session and does not reflect changes that have not yet been applied. The `pending_restart` column indicates if a setting has been changed that cannot be applied until the Database is restarted. Running `SELECT pg_reload_conf();`, will update this column and if it’s `TRUE` (`t`) you know that the Database needs to be restarted.

### Show pending restarts

Using this, you can reload the config and then query if any settings have been changed that require the Database to be restarted.

```js
SELECT name, setting, context, pending_restart
FROM pg_settings
WHERE pending_restart IS TRUE;

```

### Show non-default Settings:

Using this, you can show all non-default settings:

```js
SELECT name, current_setting(name), source, sourcefile, sourceline
FROM pg_settings
WHERE(source <> 'default' OR name = 'server_version') 
AND name NOT IN('config_file', 'data_directory', 'hba_file', 'ident_file');
```

### Show all settings

Using this, you can show all non-default settings:

```js
SHOW ALL;
```

## Configuring Access Control

The [`pg_hba.conf` file](https://www.postgresql.org/docs/current/auth-pg-hba-conf.html) (host-based authentication) controls where the PostgreSQL database can be accessed from and is traditionally the way you would restrict access. However, Aptible PostgreSQL Databases configure [`pg_hba.conf`](https://github.com/aptible/docker-postgresql/blob/master/templates/etc/postgresql/PG_VERSION/main/pg_hba.conf.template) to allow access from any source and it cannot be modified. Instead, access is controlled by the Aptible infrastructure. By default, Databases are only accessible from within the Stack that they run on but they can be exposed to external sources via [Database Endpoints](/core-concepts/managed-databases/connecting-databases/database-endpoints) or [Network Integrations](/core-concepts/integrations/network-integrations).


# How to connect Fivetran with your Aptible databases

Learn how to connect Fivetran with your Aptible Databases

## Overview

[Fivetran](https://www.fivetran.com/) is a cloud-based platform that automates data movement, allowing easy extraction, loading, and transformation of data between various sources and destinations. Fivetran is compatible with Aptible Postgres and MySQL databases.

## Connecting with PostgreSQL Databases

> ⚠️ Prerequisites: A Fivetran account with the role to Create Destinations

To connect your existing Aptible [PostgreSQL](/core-concepts/managed-databases/supported-databases/postgresql) Database to Fivetran:

**Step 1: Configure Fivetran**

Follow Fivetran’s [General PostgreSQL Guide](https://fivetran.com/docs/databases/postgresql/setup-guide), noting the following:

*   The only supported “Connection method” is to Connect Directly

*   `pgoutput` is the preferred method. All PostgreSQL databases version 10+ have this as the default logical replication plugin.

*   The `wal_level` and `max_replication_slots` settings will already be present on your Aptible PostgreSQL database

    *   Note: The default `max_replication_slots` is 10. You may need to increase this if you have many Aptible replicas or 3rd party replication using the allotted replication slots.

*   The step to add a record to `pg_hba.conf` file can be skipped, as the settings Aptible sets for you are sufficient to allow a connection/authentication.

*   Aptible PostgreSQL databases use the default value for `wal_sender_timeout` , so you’ll likely have to run `ALTER SYSTEM SET wal_sender_timeout 0;` or something similar, see related guide: [How to configure Aptible PostgreSQL Databases](/how-to-guides/database-guides/configure-aptible-postgresql-databases)

**Step 2: Expose your database to Fivetram**

You’ll need to expose the PostgreSQL Database to your Fivetran instance:

*   If you're running it as an Aptible App in the same Stack then it can access it by default.

*   Otherwise, create a [Database Endpoint](/core-concepts/managed-databases/connecting-databases/database-endpoints). Be sure to only allow [Fivetran's IP addresses](https://fivetran.com/docs/getting-started/ips) to connect!

## Connecting with MySQL Databases

> ⚠️ Prerequisites: A Fivetran account with the role to Create Destinations

To connect your existing Aptible [MySQL](/core-concepts/managed-databases/supported-databases/mysql) Database to Fivetran:

**Step 1: Configure Fivetran** Follow Fivetran’s [General MySQL Guide](https://fivetran.com/docs/destinations/mysql/setup-guide), noting the following:

*   The only supported “Connection method” is to Connect Directly

**Step 2: Expose your database to Fivetram**

You’ll need to expose the PostgreSQL Database to your Fivetran instance:

*   If you're running it as an Aptible App in the same Stack then it can access it by default.

*   Otherwise, create a [Database Endpoint](/core-concepts/managed-databases/connecting-databases/database-endpoints). Be sure to only allow [Fivetran's IP addresses](https://fivetran.com/docs/getting-started/ips) to connect!

## Troubleshooting

*   Fivetran replication queries can return a large amount of data per query. Fivetran support can tune down page size per query to smaller sizes, and this has resulted in positive results as a troubleshooting step.

*   Very large Text / BLOB columns can have a potential impact on the Fivetran replication process. Customers have had success unblocking Fivetran replication by removing large Text / BLOB columns from the target Fivetran schema.


# Dump and restore MySQL



The goal of this guide is to dump the data from one MySQL [Database](/core-concepts/managed-databases/managing-databases/overview) and restore it to another. This is generally done to upgrade to a new MySQL version but can be used in any situation where data needs to be migrated to a new Database instance.

> 📘 MySQL only supports upgrade between General Availability releases, so upgrading multiple versions (i.e. 5.6 => 8.0) requires going through the upgrade process multiple times.

## Preparation

#### Step 0: Install the necessary tools

Install the [Aptible CLI](/reference/aptible-cli/cli-commands/overview) and [MySQL](https://dev.mysql.com/doc/refman/5.7/en/installing.html). This guide uses the `mysqldump` and `mysql` client tools.

#### Step 1: Workspace

The amount of time it takes to dump and restore a Database is directly related to the size of the Database and network bandwidth. If the Database being dumped is small (\< 10 GB) and bandwidth is decent, then dumping locally is usually fine. Otherwise, consider dumping and restoring from a server with more bandwidth, such as an AWS EC2 Instance.

Another thing to consider is available disk space. There should be at least as much space locally available as the Database is currently taking up on disk. See the Database's [metrics](/core-concepts/observability/metrics/overview) to determine the current amount of space it's taking up. If there isn't enough space locally, this would be another good indicator to dump and restore from a server with a large enough disk.

All of the following instructions should be completed on the selected machine.

#### Step 2: Test the table definitions

If data is being transferred to a Database running a different MySQL version than the original, first check that the table definitions can be restored on the desired version by following the [How](/how-to-guides/database-guides/test-upgrade-incompatibiltiies) [to use mysqldump to test for upgrade incompatibilities](/how-to-guides/database-guides/test-upgrade-incompatibiltiies) guide.

If the same MySQL version is being used, this is not necessary.

#### Step 3: Test the upgrade

It's recommended to test the upgrade before performing it in production. The easiest way to do this is to restore the latest backup of the Database and perform the upgrade against the restored Database. The restored Database should have the same container size as the production Database.

Example:

```sql
aptible backup:restore 1234 --handle upgrade-test --container-size 4096
```

> 📘 If you're performing the test to get an estimate of how much downtime is required to perform the upgrade, you'll need to dump the restored Database twice in order to get an accurate time estimate. The first time will ensure that all of the backup data has been synced to the disk. The second backup will take approximately the same amount of time as the production dump.

#### Step 4: Configuration

Collect information on the Database you'd like to test and store it in the following environment variables for use later in the guide:

*   `SOURCE_HANDLE` - The handle (i.e., name) of the Database.

*   `SOURCE_ENVIRONMENT` - The handle of the environment the Database belongs to.

Example:

```sql
SOURCE_HANDLE='source-db'
SOURCE_ENVIRONMENT='test-environment'
```

Collect information on the target Database and store it in the following environment variables:

*   `TARGET_HANDLE` - The handle (i.e., name) for the Database.

*   `TARGET_VERSION` - The target MySQL version. Run `aptible db:versions` to see a full list of options. This must be within one General Availability version of the source Database.

*   `TARGET_ENVIRONMENT` - The handle of the environment to create the Database in.

Example:

```sql
TARGET_HANDLE='upgrade-test'
TARGET_VERSION='8.0'
TARGET_ENVIRONMENT='test-environment'
```

#### Step 5: Create the target Database

Create a new Database running the desired version. Assuming the environment variables above are set, this command can be copied and pasted as-is to create the Database.

```sql
aptible db:create "$TARGET_HANDLE" \
  --type mysql \
  --version "$TARGET_VERSION" \
  --environment "$TARGET_ENVIRONMENT"
```

## Execution

#### Step 1: Scale Services down

Scale all [Services](/core-concepts/apps/deploying-apps/services) that use the Database down to zero Containers. It's usually easiest to prepare a script that scales all Services down and another that scales them back up to their current values once the upgrade has been completed. Current Container counts can be found in the [Aptible Dashboard](https://dashboard.aptible.com/) or by running [`APTIBLE_OUTPUT_FORMAT=json aptible apps`](/reference/aptible-cli/cli-commands/cli-apps).

Example:

```sql
aptible apps:scale --app my-app cmd --container-count 0
```

While this step is not strictly required, it ensures that the Services don't write to the Database during the upgrade and that its [HTTP(S) Endpoints](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/overview) will show the App's [Maintenance Page](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/maintenance-page) if anyone tries to access them.

#### Step 2: Dump the data

In a terminal, create a [Database Tunnel](/core-concepts/managed-databases/connecting-databases/database-tunnels) to the source Database using the Aptible CLI.

```sql
aptible db:tunnel "$SOURCE_HANDLE" --environment "$SOURCE_ENVIRONMENT" --port 5432
```

The tunnel will block the current terminal until it's stopped. In another terminal, collect the tunnel's [Database Credentials](/core-concepts/managed-databases/connecting-databases/database-credentials), which is printed by [`aptible db:tunnel`](/reference/aptible-cli/cli-commands/cli-db-tunnel). Then dump the database and database object definitions into a file. `dump.sql` in this case.

```sql
MYSQL_PWD="$PASSWORD" mysqldump  --user root --host localhost.aptible.in --port 5432 --all-databases --routines --events  > dump.sql
```

The following error may come up when dumping:

```sql
Unknown table 'COLUMN_STATISTICS' in information_schema (1109)
```

This is due to a new flag that is enabled by default in `mysqldump 8`. You can disable this flag and resolve the error by adding `--column-statistics=0` to the above command.

You now have a copy of your Database's database object definitions in `dump.sql`! The Database Tunnel can be closed by following the instructions that `aptible db:tunnel` printed when the tunnel started.

#### Step 3: Restore the data

Create a [Database Tunnel](/core-concepts/managed-databases/connecting-databases/database-tunnels) to the target Database using the Aptible CLI.

```sql
aptible db:tunnel "$TARGET_HANDLE" --environment "$TARGET_ENVIRONMENT" --port 5432
```

Again, the tunnel will block the current terminal until it's stopped. In another terminal, apply the table definitions to the target Database.

```sql
MYSQL_PWD="$PASSWORD" mysql --user root --host localhost.aptible.in --port 5432 < dump.sql
```

> 📘 If there are any errors, they will need to be addressed in order to be able to upgrade the source Database to the desired version. Consult the [MySQL Documentation](https://dev.mysql.com/doc/) for details about the errors you encounter.

#### Step 4: Deprovision target Database

Once you've updated the source Database, you can try the dump again by deprovisioning the target Database and starting from the [Create the target Database](/how-to-guides/database-guides/dump-restore-mysql#create-the-target-database) step.

```sql
aptible db:deprovision "$TARGET_HANDLE" --environment "$TARGET_ENVIRONMENT"
```

#### Step 5: Delete Final Backups (Optional)

If the `$TARGET_ENVIRONMENT` is configured to [retain final Database Backups](/core-concepts/managed-databases/managing-databases/database-backups#retention-and-disposal), which is enabled by default, you may want to delete the final backup for the target Database.

You can obtain a list of final backups by running the following:

```sql
aptible backup:orphaned --environment "$TARGET_ENVIRONMENT"
```

Then, delete the backup(s) by ID using the [`aptible backup:purge`](/reference/aptible-cli/cli-commands/cli-backup-purge) command.

#### Step 6: Update Services

Once the upgrade is complete, any Services that use the existing Database need to be updated to use the upgraded target Database. Assuming you're supplying the [Database Credentials](/core-concepts/managed-databases/connecting-databases/database-credentials) through the App's [Configuration](/core-concepts/apps/deploying-apps/configuration), this can usually be easily done with the [`aptible config:set`](/reference/aptible-cli/cli-commands/cli-config-set) command.

Example:

```sql
aptible config:set --app my-app DB_URL='mysql://aptible:pa$word@db-stack-1234.aptible.in:5432/db'
```

#### Step 7: Scale Services back up

If Services were scaled down before performing the upgrade, they need to be scaled back up afterward. This would be the time to run the scale-up script that was mentioned in [Scale Services down](/how-to-guides/database-guides/dump-restore-mysql#scale-services-down)

Example:

```sql
aptible apps:scale --app my-app cmd --container-count 2
```

## Cleanup

Once the original Database is no longer necessary, it should be deprovisioned, or it will continue to incur costs. Note that this will delete all automated Backups. If you'd like to retain the Backups, contact [Aptible Support](/how-to-guides/troubleshooting/aptible-support) to update them.

```sql
aptible db:deprovision "$SOURCE_HANDLE" --environment "$SOURCE_ENVIRONMENT"
```


# Dump and restore PostgreSQL



The goal of this guide is to dump the schema and data from one PostgreSQL [Database](/core-concepts/managed-databases/managing-databases/overview) and restore it to another. This is generally done to upgrade to a new PostgreSQL version but can be used in any situation where data needs to be migrated to a new Database instance.

## Preparation

## Workspace

The amount of time it takes to dump and restore a Database is directly related to the size of the Database and network bandwidth. If the Database being dumped is small (\< 10 GB) and bandwidth is decent, then dumping locally is usually fine. Otherwise, consider dumping and restoring from a server with more bandwidth, such as an AWS EC2 Instance.

Another thing to consider is available disk space. There should be at least as much space locally available as the Database is currently taking up on disk. See the Database's [metrics](/core-concepts/observability/metrics/overview) to determine the current amount of space it's taking up. If there isn't enough space locally, this would be another good indicator to dump and restore from a server with a large enough disk.

All of the following instructions should be completed on the selected machine.

## Test the schema

If data is being transferred to a Database running a different PostgreSQL version than the original, first check that the schema can be restored on the desired version by following the [How to test a PostgreSQL Database's schema on a new version](/how-to-guides/database-guides/test-schema-new-version) guide.

If the same PostgreSQL version is being used, this is not necessary.

## Test the upgrade

Testing the schema should catch most issues but it's also recommended to test the upgrade before performing it in production. The easiest way to do this is to restore the latest backup of the Database and performing the upgrade against the restored Database. The restored Database should have the same container size as the production Database.

Example:

```sql
aptible backup:restore 1234 --handle upgrade-test --container-size 4096
```

Note that if you're performing the test to get an estimate of how much downtime is required to perform the upgrade, you'll need to dump the restored Database twice in order to get an accurate time estimate. The first time will ensure that all of the backup data has been synced to the disk. The second backup will take approximately the same amount of time as the production dump.
Tools
Install the [Aptible CLI](/reference/aptible-cli/cli-commands/overview) and [PostgreSQL Client Tools](https://www.postgresql.org/download/). This guide uses the `pg_dumpall` and `psql` client tools.

## Configuration

Collect information on the Database you'd like to upgrade and store it in the following environment variables for use later in the guide:

*   `SOURCE_HANDLE` - The handle (i.e. name) of the Database.

*   `SOURCE_ENVIRONMENT` - The handle of the environment the Database belongs to.

Example:

```sql
SOURCE_HANDLE='source-db'
SOURCE_ENVIRONMENT='test-environment'
```

Collect information on the target Database and store it in in the following environment variables:

*   `TARGET_HANDLE` - The handle (i.e. name) for the Database.

*   `TARGET_VERSION` - The target PostgreSQL version. Run `aptible db:versions` to see a full list of options.

*   `TARGET_ENVIRONMENT` - The handle of the environment to create the Database in.

*   `TARGET_DISK_SIZE` - The size of the target Database's disk in GB. This must be at least be as large as the current Database takes up on disk but can be smaller than its overall disk size.

*   `TARGET_CONTAINER_SIZE` (Optional) - The size of the target Database's container in MB. Having more memory and CPU available speeds up the dump and restore process, up to a certain point. See the [Database Scaling](/core-concepts/scaling/database-scaling#ram-scaling) documentation for a full list of supported container sizes.

Example:

```sql
TARGET_HANDLE='dump-test'
TARGET_VERSION='14'
TARGET_ENVIRONMENT='test-environment'
TARGET_DISK_SIZE=100
TARGET_CONTAINER_SIZE=4096
```

## Create the target Database

Create a new Database running the desired version. Assuming the environment variables above are set, this command can be copied and pasted as-is to create the Database.

```sql
aptible db:create "$TARGET_HANDLE" \
  --type postgresql \
  --version "$TARGET_VERSION" \
  --environment "$TARGET_ENVIRONMENT" \
  --disk-size "$TARGET_DISK_SIZE" \
  --container-size "${TARGET_CONTAINER_SIZE:-4096}"
```

## Execution

## Scale Services down

Scale all [Services](/core-concepts/apps/deploying-apps/services) that use the Database down to zero containers. It's usually easiest to prepare a script that scales all Services down and another that scales them back up to their current values once the upgrade has been complete. Current container counts can be found in the [Aptible Dashboard](https://dashboard.aptible.com/) or by running [`APTIBLE_OUTPUT_FORMAT=json aptible apps`](/reference/aptible-cli/cli-commands/cli-apps).

Example scale command:

```sql
aptible apps:scale --app my-app cmd --container-count 0
```

While this step is not strictly required, it ensures that the Services don't write to the Database during the upgrade and that its [HTTP(S) Endpoints](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/overview) will show the App's [Maintenance Page](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/maintenance-page) if anyone tries to access them.

## Dump the data

In a separate terminal, create a [Database Tunnel](/core-concepts/managed-databases/connecting-databases/database-tunnels) to the source Database using the Aptible CLI.

```sql
aptible db:tunnel "$SOURCE_HANDLE" --environment "$SOURCE_ENVIRONMENT"
```

The tunnel will block the current terminal until it's stopped. Collect the tunnel's information, which is printed by [`aptible db:tunnel`](/reference/aptible-cli/cli-commands/cli-db-tunnel), and store it in the following environment variables in the original terminal:

*   `SOURCE_URL` - The full URL of the Database tunnel.

*   `SOURCE_PASSWORD` - The Database's password.

Example:

```sql
SOURCE_URL='postgresql://aptible:pa$word@localhost.aptible.in:5432/db'
SOURCE_PASSWORD='pa$word'
```

Dump the data into a file. `dump.sql` in this case.

```sql
PGPASSWORD="$SOURCE_PASSWORD" pg_dumpall -d "$SOURCE_URL" --no-password \
  | grep -E -i -v 'ALTER ROLE aptible .*PASSWORD' > dump.sql
```

The output of `pg_dumpall` is piped into `grep` in order to remove any SQL commands that may change the default `aptible` user's password. If these commands were to run on the target Database, it would be updated to match the source Database. This would result in the target Database's password no longer matching what's displayed in the [Aptible Dashboard](https://dashboard.aptible.com/) or printed by commands like [`aptible db:url`](/reference/aptible-cli/cli-commands/cli-db-url) or [`aptible db:tunnel`](/reference/aptible-cli/cli-commands/cli-db-tunnel) which could cause problems down the road.

You now have a copy of your Database's schema and data in `dump.sql`! The Database Tunnel can be closed by following the instructions that `aptible db:tunnel` printed when the tunnel started.

## Restore the data

In a separate terminal, create a [Database Tunnel](/core-concepts/managed-databases/connecting-databases/database-tunnels) to the target Database using the Aptible CLI.

```sql
aptible db:tunnel "$TARGET_HANDLE" --environment "$TARGET_ENVIRONMENT"
```

Again, the tunnel will block the current terminal until it's stopped. Collect the tunnel's full URL, which is printed by [`aptible db:tunnel`](/reference/aptible-cli/cli-commands/cli-db-tunnel), and store it in the `TARGET_URL` environment variable in the original terminal.

Example:

```sql
TARGET_URL='postgresql://aptible:passw0rd@localhost.aptible.in:5432/db'
```

Apply the data to the target Database.

```sql
psql $TARGET_URL -f dump.sql > /dev/null
```

The output of `psql` can be noisy depending on the size of the source Database. In order to reduce the noise, the output is redirected to `/dev/null` so that only error messages are displayed.

The following errors may come up when restoring the Database:

```sql
ERROR:  role "aptible" already exists
ERROR:  role "postgres" already exists
ERROR:  database "db" already exists
```

These errors are expected because Aptible creates these resources on all PostgreSQL Databases when they are created. The errors are a result of the dump attempting to re-create the existing resources. If these are the only errors, the upgrade was successful!

### Errors

If there are additional errors, they will need to be addressed in order to be able to upgrade the source Database to the desired version. Consult the [PostgreSQL Documentation](https://www.postgresql.org/docs/) for details about the errors you encounter.

Once you've updated the source Database, you can try the dump again by deprovisioning the target Database and starting from the [Create the target Database](/how-to-guides/database-guides/dump-restore-postgresql#create-the-target-database) step.

```sql
aptible db:deprovision "$TARGET_HANDLE" --environment "$TARGET_ENVIRONMENT"
```

If the `$TARGET_ENVIRONMENT` is configured to [retain final Database Backups](/core-concepts/managed-databases/managing-databases/database-backups#retention-and-disposal), which is enabled by default, you may want to delete the final backup for the target Database.

You can obtain a list of final backups by running:

```sql
aptible backup:orphaned --environment "$TARGET_ENVIRONMENT"
```

Then, delete the backup(s) by ID using the [`aptible backup:purge`](/reference/aptible-cli/cli-commands/cli-backup-purge) command.

## Update Services

Once the upgrade is complete, any Services that use the existing Database need to be updated to use the upgraded target Database. Assuming you're supplying the [Database Credentials](/core-concepts/managed-databases/connecting-databases/database-credentials) through the App's [Configuration](/core-concepts/apps/deploying-apps/configuration), this can usually be easily done with the [`aptible config:set`](/reference/aptible-cli/cli-commands/cli-config-set) command.

Example config command:

```sql
aptible config:set --app my-app DB_URL='postgresql://user:passw0rd@db-stack-1234.aptible.in:5432/db'
```

## Scale Services back up

If Services were scaled down before performing the upgrade, they need to be scaled back up afterward. This would be the time to run the scale-up script that was mentioned in [Scale Services down](/how-to-guides/database-guides/dump-restore-postgresql#scale-services-down)

Example:

```sql
aptible apps:scale --app my-app cmd --container-count 2
```

## Cleanup

## Vacuum and Analyze

Vacuuming the target Database after upgrading reclaims space occupied by dead tuples and analyzing the tables collects information on the table's contents in order to improve query performance.

```sql
psql "$TARGET_URL" --tuples-only --no-align --command \
  'SELECT datname FROM pg_database WHERE datistemplate IS FALSE' |

while IFS= read -r db; do
  psql "$TARGET_URL" << EOF
    \connect "$db"

    VACUUM ANALYZE;
EOF
done
```

## Deprovision

Once the original Database is no longer necessary, it should be deprovisioned or it will continue to incur costs. Note that this will delete all automated Backups. If you'd like to retain the Backups, contact [Aptible Support](/how-to-guides/troubleshooting/aptible-support) to update them.

```sql
aptible db:deprovision "$SOURCE_HANDLE" --environment "$SOURCE_ENVIRONMENT"
```


# How to scale databases

Learn how to scale databases on Aptible

## Overview

Aptible [Databases](/core-concepts/managed-databases/managing-databases/overview) can be manually scaled with minimal downtime (typically less than 1 minute). There are several elements of databases that can be scaled, such as CPU, RAM, IOPS, and throughput. See [Database Scaling](/core-concepts/scaling/database-scaling) for more information.

## Using the Aptible Dashboard

Databases can be scaled within the Aptible Dashboard by:

*   Navigating to the Environment in which your Database lives in

*   Selecting the **Databases** tab

*   Selecting the respective Database

*   Selecting **Scale**

![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/scale-databases1.png)

## Using the CLI

Databases can be scaled via the Aptible CLI using the [`aptible db:restart`](/reference/aptible-cli/cli-commands/cli-db-restart) command.

## Using Terraform

Databases can be programmatically scaled using the Aptible [Terraform Provider](https://registry.terraform.io/providers/aptible/aptible/latest/docs) using the `terraform_aptible_database` resource:

```js
 resource "aptible_database" "DATABASE" {
    env_id = ENVIRONMENT_ID
    handle = "DATABASE_HANDLE"
    database_type = "redis"
    container_size = 512
    disk_size = 10
}
```


# All Database Guides

Explore guides for deploying and managing databases on Aptible

*   [How to configure Aptible PostgreSQL Databases](/how-to-guides/database-guides/configure-aptible-postgresql-databases)

*   [How to connect Fivetran with your Aptible databases](/how-to-guides/database-guides/connect-fivetran-with-aptible-db)

*   [How to scale databases](/how-to-guides/database-guides/how-to-scale-databases)

*   [Automate Database migrations](/how-to-guides/database-guides/automate-database-migrations)

*   [Upgrade PostgreSQL with logical replication](/how-to-guides/database-guides/upgrade-postgresql)

*   [Dump and restore PostgreSQL](/how-to-guides/database-guides/dump-restore-postgresql)

*   [Test a PostgreSQL Database's schema on a new version](/how-to-guides/database-guides/test-schema-new-version)

*   [Dump and restore MySQL](/how-to-guides/database-guides/dump-restore-mysql)

*   [Use mysqldump to test for upgrade incompatibilities](/how-to-guides/database-guides/test-upgrade-incompatibiltiies)

*   [Upgrade MongoDB](/how-to-guides/database-guides/upgrade-mongodb)

*   [Upgrade Redis](/how-to-guides/database-guides/upgrade-redis)


# Test a PostgreSQL Database's schema on a new version

The goal of this guide is to test the schema of an existing Database against another Database version in order to see if it's compatible with the desired version. The primary reason to do this is to ensure a Database's schema is compatible with a higher version before upgrading.

## Preparation

#### Step 0: Install the necessary tools

Install the [Aptible CLI](/reference/aptible-cli/cli-commands/overview) and [PostgreSQL Client Tools](https://www.postgresql.org/download/). This guide uses the `pg_dumpall` and `psql` client tools.

#### Step 1: Configuration

Collect information on the Database you'd like to test and store it in the following environment variables for use later in the guide:

*   `SOURCE_HANDLE` - The handle (i.e. name) of the Database.

*   `SOURCE_ENVIRONMENT` - The handle of the environment theDatabase belongs to.

Example:

```sql
SOURCE_HANDLE='source-db'
SOURCE_ENVIRONMENT='test-environment'
```

Collect information on the target Database and store it in in the following environment variables:

*   `TARGET_HANDLE` - The handle (i.e. name) for the Database.

*   `TARGET_VERSION` - The target PostgreSQL version. Run `aptible db:versions` to see a full list of options.

*   `TARGET_ENVIRONMENT` - The handle of the environment to create the Database in.

Example:

```sql
TARGET_HANDLE='schema-test'
TARGET_VERSION='14'
TARGET_ENVIRONMENT='test-environment'
```

#### Step 2: Create the target Database

Create a new Database running the desired version. Assuming the environment variables above are set, this command can be copied and pasted as-is to create the Database.

```sql
aptible db:create "$TARGET_HANDLE" --type postgresql --version "$TARGET_VERSION" --environment "$TARGET_ENVIRONMENT"
```

By default, [`aptible db:create`](/reference/aptible-cli/cli-commands/cli-db-create) creates a Database with a 1 GB of memory and 10 GB of disk space. This should be sufficient for most schema tests but, if more memory or disk is required, the `--container-size` and `--disk-size` arguments can be used.

## Execution

#### Step 1: Dump the schema

Create a [Database Tunnel](/core-concepts/managed-databases/connecting-databases/database-tunnels) to the source Database using the Aptible CLI.

```sql
aptible db:tunnel "$SOURCE_HANDLE" --environment "$SOURCE_ENVIRONMENT"
```

The tunnel will block the current terminal until it's stopped. In another terminal, collect the tunnel's information, which is printed by [`aptible db:tunnel`](/reference/aptible-cli/cli-commands/cli-db-tunnel), and store it in the following environment variables:

*   `SOURCE_URL` - The full URL of the Database tunnel.

*   `SOURCE_PASSWORD` - The Database's password.

Example:

```sql
SOURCE_URL='postgresql://aptible:pa$word@localhost.aptible.in:5432/db'
SOURCE_PASSWORD='pa$word'
```

Dump the schema into a file. `schema.sql` in this case.

```sql
PGPASSWORD="$SOURCE_PASSWORD" pg_dumpall -d "$SOURCE_URL" --schema-only --no-password \
  | grep -E -i -v 'ALTER ROLE aptible .*PASSWORD' > schema.sql
```

The output of `pg_dumpall` is piped into `grep` in order to remove any SQL commands that may change the default `aptible` user's password. If these commands were to run on the target Database, it would be updated to match the source Database. This would result in the target Database's password no longer matching what's displayed in the [Aptible Dashboard](https://dashboard.aptible.com/) or printed by commands like [`aptible db:url`](/reference/aptible-cli/cli-commands/cli-db-url) or [`aptible db:tunnel`](/reference/aptible-cli/cli-commands/cli-db-tunnel) which could cause problems down the road.

You now have a copy of your Database's schema in `schema.sql`! The Database Tunnel can be closed by following the instructions that `aptible db:tunnel` printed when the tunnel started.

#### Step 2: Restore the schema

Create a [Database Tunnel](/core-concepts/managed-databases/connecting-databases/database-tunnels) to the target Database using the Aptible CLI.

```sql
aptible db:tunnel "$TARGET_HANDLE" --environment "$TARGET_ENVIRONMENT"
```

Again, the tunnel will block the current terminal until it's stopped. In another terminal, store the tunnel's full URL, which is printed by [`aptible db:tunnel`](/reference/aptible-cli/cli-commands/cli-db-tunnel), in the `TARGET_URL` environment variable.

Example:

```sql
TARGET_URL='postgresql://aptible:p@ssword@localhost.aptible.in:5432/db'
```

Apply the schema to the target Database.

```sql
psql $TARGET_URL -f schema.sql > /dev/null
```

The output of `psql` can be noisy depending on the complexity of the source Database's schema. In order to reduce the noise, the output is redirected to `/dev/null` so that only error messages are displayed.

The following errors may come up when restoring the schema:

```sql
ERROR:  role "aptible" already exists
ERROR:  role "postgres" already exists
ERROR:  database "db" already exists
```

These errors are expected because Aptible creates these resources on all PostgreSQL Databases when they are created. The errors are a result of the schema dump attempting to re-create the existing resources. If these are the only errors, the upgrade was successful!

If there are additional errors, they will need to be addressed in order to be able to upgrade the source Database to the desired version. Consult the [PostgreSQL Documentation](https://www.postgresql.org/docs/) for details about the errors you encounter.

Once you've updated the source Database's schema you can test the changes by deprovisioning the target Database, see the [Cleanup](/how-to-guides/database-guides/test-schema-new-version#cleanup) section, and starting from the [Create the target Database](/how-to-guides/database-guides/test-schema-new-version#create-the-target-database) step.

## Cleanup

#### Step 1: Deprovision the target Database

```sql
aptible db:deprovision "$TARGET_HANDLE" --environment "$TARGET_ENVIRONMENT"
```

#### Step 2: Delete Final Backups (Optional)

If the `$TARGET_ENVIRONMENT` is configured to [retain final Database Backups](/core-concepts/managed-databases/managing-databases/database-backups#retention-and-disposal), which is enabled by default, you may want to delete the final backups for all target Databases you created for this test.

You can obtain a list of final backups by running:

```sql
aptible backup:orphaned --environment "$TARGET_ENVIRONMENT"
```

Then, delete the backup(s) by ID using the [`aptible backup:purge`](/reference/aptible-cli/cli-commands/cli-backup-purge) command.


# Use mysqldump to test for upgrade incompatibilities



The goal of this guide is to use `mysqldump` to test the table definitions of an existing Database against another Database version in order to see if it's compatible with the desired version. The primary reason to do this is to ensure a Database is compatible with a higher version before upgrading without waiting for lengthy data-loading operations.

## Preparation

#### Step 0: Install the necessary tools

Install the [Aptible CLI](/reference/aptible-cli/cli-commands/overview) and [MySQL](https://dev.mysql.com/doc/refman/5.7/en/installing.html). This guide uses the `mysqldump` and `mysql` client tools.

#### Step 1: Configuration

Collect information on the Database you'd like to test and store it in the following environment variables for use later in the guide:

*   `SOURCE_HANDLE` - The handle (i.e. name) of the Database.

*   `SOURCE_ENVIRONMENT` - The handle of the environment the Database belongs to.

Example:

```sql
SOURCE_HANDLE='source-db'
SOURCE_ENVIRONMENT='test-environment'
```

Collect information on the target Database and store it in the following environment variables:

*   `TARGET_HANDLE` - The handle (i.e., name) for the Database.

*   `TARGET_VERSION` - The target MySQL version. Run `aptible db:versions` to see a full list of options. This must be within one General Availability version of the source Database.

*   `TARGET_ENVIRONMENT` - The handle of the Environment to create the Database in.

Example:

```sql
TARGET_HANDLE='upgrade-test'
TARGET_VERSION='8.0'
TARGET_ENVIRONMENT='test-environment'
```

#### Step 2: Create the target Database

Create a new Database running the desired version. Assuming the environment variables above are set, this command can be copied and pasted as-is to create the Database.

```sql
aptible db:create "$TARGET_HANDLE" \
  --type mysql \
  --version "$TARGET_VERSION" \
  --environment "$TARGET_ENVIRONMENT"
```

By default, [`aptible db:create`](/reference/aptible-cli/cli-commands/cli-db-create) creates a Database with 1 GB of memory and 10 GB of disk space. This is typically sufficient for testing table definition compatibility, but if more memory or disk is required, the `--container-size` and `--disk-size` arguments can be used.

## Execution

#### Step 1: Dump the table definition

In a terminal, create a [Database Tunnel](/core-concepts/managed-databases/connecting-databases/database-tunnels) to the source Database using the Aptible CLI.

```sql
aptible db:tunnel "$SOURCE_HANDLE" --environment "$SOURCE_ENVIRONMENT" --port 5432
```

The tunnel will block the current terminal until it's stopped. In another terminal, collect the tunnel's [Database Credentials](/core-concepts/managed-databases/connecting-databases/database-credentials), which are printed by [`aptible db:tunnel`](/reference/aptible-cli/cli-commands/cli-db-tunnel). Then dump the database and database object definitions into a file. `defs.sql` in this case.

```sql
MYSQL_PWD="$PASSWORD" mysqldump  --user root --host localhost.aptible.in --port 5432 --all-databases --no-data --routines --events  > defs.sql
```

The following error may come up when dumping the table definitions:

```sql
Unknown table 'COLUMN_STATISTICS' in information_schema (1109)
```

This is due to a new flag that is enabled by default in `mysqldump 8`. You can disable this flag and resolve the error by adding `--column-statistics=0` to the above command.

You now have a copy of your Database's database object definitions in `defs.sql`! The Database Tunnel can be closed by following the instructions that `aptible db:tunnel` printed when the tunnel started.

#### Step 2: Restore the table definitions

Create a [Database Tunnel](/core-concepts/managed-databases/connecting-databases/database-tunnels) to the target Database using the Aptible CLI.

```sql
aptible db:tunnel "$TARGET_HANDLE" --environment "$TARGET_ENVIRONMENT" --port 5432
```

Again, the tunnel will block the current terminal until it's stopped. In another terminal, apply the table definitions to the target Database.

```sql
MYSQL_PWD="$PASSWORD" mysql --user aptible --host localhost.aptible.in --port 5432 < defs.sql
```

If there are any errors, they will need to be addressed in order to be able to upgrade the source Database to the desired version. Consult the [MySQL Documentation](https://dev.mysql.com/doc/) for details about the errors you encounter.

Once you've updated the source Database's table definitions, you can test the changes by deprovisioning the target Database, see the [Cleanup](/how-to-guides/database-guides/test-upgrade-incompatibiltiies#cleanup) section, and starting from the [Create the target Database](/how-to-guides/database-guides/test-upgrade-incompatibiltiies#create-the-target-database) step.

## Cleanup

#### Step 1: Deprovision the target Database

```sql
aptible db:deprovision "$TARGET_HANDLE" --environment "$TARGET_ENVIRONMENT"
```

#### Step 2: Delete Final Backups (Optional)

If the `$TARGET_ENVIRONMENT` is configured to [retain final Database Backups](/core-concepts/managed-databases/managing-databases/database-backups#retention-and-disposal), which is enabled by default, you may want to delete the final backups for all target Databases you created for this test.

You can obtain a list of final backups by running the following:

```sql
aptible backup:orphaned --environment "$TARGET_ENVIRONMENT"
```

Then, delete the backup(s) by ID using the [`aptible backup:purge`](/reference/aptible-cli/cli-commands/cli-backup-purge) command.


# Upgrade MongoDB



The goal of this guide is to upgrade a MongoDB [Database](/core-concepts/managed-databases/managing-databases/overview) to a newer release. The process is quick and easy to complete but only works from one release to the next, so in order to upgrade multiple releases, the process must be completed multiple times.

## Preparation

#### Step 0: Install the necessary tools

Install the [Aptible CLI](/reference/aptible-cli/cli-commands/overview) and the [MongoDB shell](https://www.mongodb.com/docs/v4.4/administration/install-community/), `mongo` .

#### Step 1: Configuration

Collect information on the Database you'd like to upgrade and store it in the following environment variables for use later in the guide:

*   `DB_HANDLE` - The handle (i.e. name) of the Database.

*   `ENVIRONMENT` - The handle of the environment the Database belongs to.

*   `VERSION` - The desired MongoDB version. Run `aptible db:versions` to see a full list of options.

Example:

```bash
DB_HANDLE='my-redis'
ENVIRONMENT='test-environment'
VERSION='4.0'
```

#### Step 2: Contact Aptible Support

An Aptible team member must update the Database's metadata to the new version in order to upgrade the Database. When contacting [Aptible Support](/how-to-guides/troubleshooting/aptible-support) please adhere to the following rules to ensure a smooth upgrade process:

*   Ensure that you have [Administrator Access](/core-concepts/security-compliance/access-permissions#write-permissions) to the Database's Environment. If you do not, please have someone with access contact support or CC an [Account Owner or Deploy Owner](/core-concepts/security-compliance/access-permissions) for approval.

*   Use the same email address that's associated with your Aptible user account to contact support.

*   Include the configuration values above. You may run the following command to generate a request with the required information:

```bash
echo "Please upgrade our MongoDB database, ${ENVIRONMENT} - ${DB_HANDLE}, to version ${VERSION}. Thank you."
```

## Execution

#### Step 1: Restart the Database

Once support has updated the Database, restarting it will apply the change. You may do so at your convenience with the [`aptible db:reload`](/reference/aptible-cli/cli-commands/cli-db-reload) CLI command:

```bash
aptible db:reload "$DB_HANDLE" --environment "$ENVIRONMENT"
```

When upgrading a replica set, restart secondary members first, then the primary member.

#### Step 2: Tunnel into the Database

In a separate terminal, create a [Database Tunnel](/core-concepts/managed-databases/connecting-databases/database-tunnels) to the Database using the Aptible CLI.

```bash
aptible db:tunnel "$DB_HANDLE" --environment "$ENVIRONMENT"
```

The tunnel will block the current terminal until it's stopped. Collect the tunnel's full URL, which is printed by [`aptible db:tunnel`](/reference/aptible-cli/cli-commands/cli-db-tunnel), and store it in the `DB_URL` environment variable in the original terminal.

Example:

```bash
DB_URL='postgresql://aptible:pa$word@localhost.aptible.in:5432/db'
```

#### Step 3: Enable Backward-Incompatible Features

Run the [`setFeatureCompatibilityVersion`](https://www.mongodb.com/docs/manual/reference/command/setFeatureCompatibilityVersion/) admin command on the Database:

```bash
echo "db.adminCommand({ setFeatureCompatibilityVersion: '${VERSION}' })" |
  mongo --ssl --authenticationDatabase admin "$DB_URL"
```


# Upgrade PostgreSQL with logical replication



The goal of this guide is to [upgrade a PostgreSQL Database](/core-concepts/managed-databases/managing-databases/database-upgrade-methods) to a newer version by means of [logical replication](/core-concepts/managed-databases/managing-databases/database-upgrade-methods#logical-replication). Aptible uses [pglogical](https://github.com/2ndQuadrant/pglogical) to create logical replicas.

> 📘 The main benefit of using logical replication is that the replica can be created beforehand and will stay up-to-date with the source Database until it's time to cut over to the new Database. This allows for upgrades to be performed with minimal downtime.

## Preparation

#### **Step 0: Prerequisites**

Install [Aptible CLI](/reference/aptible-cli/cli-commands/overview) and the [PostgreSQL Client Tools,](https://www.postgresql.org/download/) `psql`.

#### **Step 1: Test the schema**

If data is being transferred to a Database running a different PostgreSQL version than the original, first check that the schema can be restored on the desired version by following the [How to test a PostgreSQL Database's schema on a new version](/how-to-guides/database-guides/test-schema-new-version) guide.

#### **Step 2: Test the upgrade**

Testing the schema should catch a number of issues, but it's also recommended to test the upgrade before performing it in production. The easiest way to do this is to restore the latest backup of the Database and perform the upgrade against the restored Database. The restored Database should have the same Container size as the production Database.

Example:

```sql
aptible backup:restore 1234
--handle upgrade-test
--container- size 4096
```

#### **Step 3: Configuration**

Collect information on the Database you'd like to upgrade and store it in the following environment variables for use later in the guide:

*   `SOURCE_HANDLE` - The handle (i.e. name) of the Database.

*   `ENVIRONMENT` - The handle of the Environment the Database belongs to.

Example:

```sql
SOURCE_HANDLE = 'source-db'
ENVIRONMENT = 'test-environment'
```

Collect information on the replica and store it in the following environment variables:

*   `REPLICA_HANDLE` - The handle (i.e., name) for the Database.

*   `REPLICA_VERSION` - The desired PostgreSQL version. Run `aptible db:versions` to see a full list of options.

*   `REPLICA_CONTAINER_SIZE` (Optional) - The size of the replica's container in MB. Having more memory and CPU available speeds up the initialization process up to a certain point. See the [Database Scaling](/core-concepts/scaling/database-scaling#ram-scaling) documentation for a full list of supported container sizes.

Example:

```sql
REPLICA_HANDLE = 'upgrade-test'
REPLICA_VERSION = '14'
REPLICA_CONTAINER_SIZE = 4096
```

#### **Step 4: Tunnel into the source Database**

In a separate terminal, create a [Database Tunnel](/core-concepts/managed-databases/connecting-databases/database-tunnels) to the source Database using the `aptible db:tunnel` command.

Example:

```sql
aptible db:tunnel "$SOURCE_HANDLE" --environment "$ENVIRONMENT"
```

The tunnel will block the current terminal until it's stopped. Collect the tunnel's full URL, which is printed by [`aptible db:tunnel`](/reference/aptible-cli/cli-commands/cli-db-tunnel), and store it in the `SOURCE_URL` environment variable in the original terminal.

Example:

```sql
SOURCE_URL = 'postgresql://aptible:pa$word@localhost.aptible.in:5432/db'
```

#### **Step 5: Check for existing pglogical nodes**

Each PostgreSQL database on the server can only have a single `pglogical` node. If there's already an existing node, the replica will fail setup. The following script will check for existing pglogical nodes.

```sql
psql "$SOURCE_URL" --tuples-only --no-align --command \
  'SELECT datname FROM pg_database WHERE datistemplate IS FALSE' |

while IFS= read -r db; do
  psql "$SOURCE_URL" -v ON_ERROR_STOP=1 << EOF &> /dev/null
    \connect "$db"
    SELECT pglogical.pglogical_node_info();
EOF

  if [ $? -eq 0 ]; then
    echo "pglogical node found on $db"
  fi
done
```

If the command does not report any nodes, no action is necessary. If it does, either replication will have to be set up manually instead of using `aptible db:replicate --logical`, or the node will have to be dropped.

Note that if logical replication was previously attempted, but failed, then the node could be left behind from the previous attempt. See the [Cleanup](/how-to-guides/database-guides/upgrade-postgresql#cleanup) section and follow the instructions for cleaning up the source Database.

#### **Step 6: Check for tables without a primary key**

Logical replication requires that rows be uniquely identifiable in order to function properly. This is most easily accomplished by ensuring all tables have a primary key.

The following script will iterate over all PostgreSQL databases on the Database server and list tables that do not have a primary key:

```sql
psql "$SOURCE_URL" --tuples-only --no-align --command \
'SELECT datname FROM pg_database WHERE datistemplate IS FALSE' |

while IFS= read -r db; do
  echo "Database: $db"
  psql "$SOURCE_URL" << EOF
\connect "$db";

    SELECT tab.table_schema, tab.table_name
    FROM information_schema.tables tab
    LEFT JOIN information_schema.table_constraints tco
              ON tab.table_schema = tco.table_schema
              AND tab.table_name = tco.table_name
              AND tco.constraint_type = 'PRIMARY KEY'
    WHERE tab.table_type = 'BASE TABLE'
          AND tab.table_schema NOT IN('pg_catalog', 'information_schema', 'pglogical')
          AND tco.constraint_name IS NULL
    ORDER BY table_schema, table_name;
EOF
done
```

If all of the databases return `(0 rows)` then no action is necessary.

Example output:

```sql
Database: db
You are now connected to database "db" as user "aptible".
 table_schema | table_name
--------------+------------
(0 rows)

Database: postgres
You are now connected to database "postgres" as user "aptible".
 table_schema | table_name
--------------+------------
(0 rows)
```

If any tables come back without a primary key, one can be added to an existing column or a new column with [`ALTER TABLE`](https://www.postgresql.org/docs/current/sql-altertable.html).

#### **Step 7: Create the replica**

The upgraded replica can be created ahead of the actual upgrade as it will stay up-to-date with the source Database.

```sql
aptible db:replicate "$SOURCE_HANDLE" "$REPLICA_HANDLE" \
  --logical \
  --version "$REPLICA_VERSION" \
  --environment "$ENVIRONMENT" \
  --container-size "${REPLICA_CONTAINER_SIZE:-4096}"
```

If the command raises errors, review the operation logs output by the command for an explanation as to why the error occurred. In order to attempt logical replication after the issue(s) have been addressed, the source Database will need to be cleaned up. See the [Cleanup](/how-to-guides/database-guides/upgrade-postgresql#cleanup) section and follow the instructions for cleaning up the source Database. The broken replica also needs to be deprovisioned in order to free up its handle to be used by the new replica:

```sql
aptible db:deprovision "$REPLICA_HANDLE" --environment "$ENVIRONMENT"
```

If the operation is successful, then the replica has been successfully set up. All that remains is for it to finish initializing (i.e. pulling all existing data), then it will be ready to be cut over to.

> 📘 `pglogical` will copy the source Database's structure at the time the subscription is created. However, subsequent changes to the Database structure, a.k.a. Data Definition Language (DDL) commands, are not included in logical replication. These commands need to be applied to the replica as well as the source Database to ensure that changes to the data are properly replicated.

> `pglogical` provides a convenient `replicate_ddl_command` function that, when run on the source Database, applies a DDL command to the source Database then queues the statement to be applied to the replica. For example, to add a column to a table:

```sql
SELECT pglogical.replicate_ddl_command('ALTER TABLE public.foo ADD COLUMN bar TEXT;');
```

> ❗️ `pglogical` creates temporary replication slots that may show up inactive at times, theses temporary slots must not be deleted. Deleting these slots will disrupt `pglogical`

## Execution

#### **Step 1: Tunnel into the replica**

In a separate terminal, create a [Database Tunnel](/core-concepts/managed-databases/connecting-databases/database-tunnels) to the replica using the Aptible CLI.

```sql
aptible db:tunnel "$REPLICA_HANDLE" --environment "$ENVIRONMENT"
```

The tunnel will block the current terminal until it's stopped. Collect the tunnel's full URL, which is printed by [`aptible db:tunnel`](/reference/aptible-cli/cli-commands/cli-db-tunnel), and store it in the `REPLICA_URL` environment variable in the original terminal.

Example:

```sql
REPLICA_URL='postgresql://aptible:passw0rd@localhost.aptible.in:5432/db'
```

#### **Step 2: Wait for initialization to complete**

While replicas are usually created very quickly, it can take some time to pull all of the data from the source Database depending on its disk footprint. The replica can be queried to see what tables still need to be initialized.

```sql
SELECT * FROM pglogical.local_sync_status WHERE NOT sync_status = 'r';
```

If any rows are returned, the replica is still initializing. This query can be used in a short script to test and wait for initialization to complete on all databases on the replica:

```sql
psql "$REPLICA_URL" --tuples-only --no-align --command \
  'SELECT datname FROM pg_database WHERE datistemplate IS FALSE' |

while IFS= read -r db; do
  while psql "$REPLICA_URL" --tuples-only --quiet << EOF | grep -E '.+'; do
    \connect "$db"
    SELECT * FROM pglogical.local_sync_status WHERE NOT sync_status = 'r';
EOF
    sleep 3
  done
done
```

There is a [known issue](https://github.com/2ndQuadrant/pglogical/issues/337) with `pglogical` in which, during replica initialization, replication may pause until the next time the source Database is written to. For production Databases, this usually isn't an issue since it's being actively used, but for Databases that aren't used much, like Databases that may have been restored to test logical replication, this issue can arise.

The following script works similarly to the one above, but it also creates a table, writes to it, then drops the table in order to ensure that initialization continues even if the source Database is idle:

```sql
psql "$REPLICA_URL" --tuples-only --no-align --command \
  'SELECT datname FROM pg_database WHERE datistemplate IS FALSE' |

while IFS= read -r db; do
  while psql "$REPLICA_URL" --tuples-only --quiet << EOF | grep -E '.+'; do
    \connect "$db"
    SELECT * FROM pglogical.local_sync_status WHERE NOT sync_status = 'r';
EOF
    psql "$SOURCE_URL" -v ON_ERROR_STOP=1 --quiet << EOF
      \connect "$db"
      CREATE TABLE _aptible_logical_sync (col INT);
      INSERT INTO _aptible_logical_sync VALUES (1);
      DROP TABLE _aptible_logical_sync;
EOF

    sleep 3
  done
done
```

Once the query returns zero rows from the replica or one of the scripts completes, the replica has finished initializing, which means it's ready to be cut over to.

#### **Optional: Speeding Up Initialization**

Each index on a table adds overhead to inserting rows, so the more indexes a table has, the longer it will take to be copied over. This can cause large Databases or those with many indexes to take much longer to initialize. If the initialization process appears to be going slowly, all of the indexes (except for primary keys) can be disabled:

```sql
psql "$REPLICA_URL" --tuples-only --no-align --command \
  'SELECT datname FROM pg_database WHERE datistemplate IS FALSE' |

while IFS= read -r db; do
  echo "Database: $db"
  psql "$REPLICA_URL" << EOF
    \connect "$db"

    UPDATE pg_index SET indisready = FALSE WHERE indexrelid IN (
      SELECT idx.indexrelid FROM pg_index idx
      INNER JOIN pg_class cls ON idx.indexrelid = cls.oid
      INNER JOIN pg_namespace nsp ON cls.relnamespace = nsp.oid
      WHERE nsp.nspname !~ '^pg_'
      AND nsp.nspname NOT IN ('information_schema', 'pglogical')
      AND idx.indisprimary IS FALSE
    );
EOF
done

# Reload in order to restart the current COPY operation without indexes
aptible db:reload "$REPLICA_HANDLE" --environment "$ENVIRONMENT"
```

After the replica has been initialized, the indexes will need to be rebuilt. This can still take some time for large tables but is much faster than the indexes being evaluated each time a row is inserted:

```sql
psql "$REPLICA_URL" --tuples-only --no-align --command \
  'SELECT datname FROM pg_database WHERE datistemplate IS FALSE' |

while IFS= read -r db; do
  echo "Database: $db"
  psql "$REPLICA_URL" --tuples-only --no-align --quiet << EOF |
    \connect "$db"

    SELECT CONCAT('"', nsp.nspname, '"."', cls.relname, '"') FROM pg_index idx
      INNER JOIN pg_class cls ON idx.indexrelid = cls.oid
      INNER JOIN pg_namespace nsp ON cls.relnamespace = nsp.oid
      WHERE nsp.nspname !~ '^pg_'
      AND nsp.nspname NOT IN ('information_schema', 'pglogical')
      AND idx.indisprimary IS FALSE
      AND idx.indisready IS FALSE;
EOF

  while IFS= read -r index; do
    echo "Reindexing: $index"
    psql "$REPLICA_URL" --quiet << EOF
      \connect "$db"

      REINDEX INDEX CONCURRENTLY $index;
EOF
  done
done
```

If any indexes have issues reindexing `CONCURRENTLY` this keyword can be removed, but note that when not indexing concurrently, the table the index belongs to will be locked, which will prevent writes while indexing.

#### **Step 3: Enable synchronous replication**

Enabling synchronous replication ensures that all data that is written to the source Database is also written to the replica:

```sql
psql "$SOURCE_URL" << EOF
  ALTER SYSTEM SET synchronous_standby_names=aptible_subscription;
  SELECT pg_reload_conf();
EOF
```

> ❗️ Performance Alert: synchronous replication ensures that transactions are committed on both the primary and replica databases simultaneously, which can introduce noticable latency on commit times, especially on databases with higher relative volumes of changes. In this case, you may want to ensure that you wait to enable synchronous replication until you are close to performing the cutover in order to minimize the impact of slower commits on the primary database.

#### **Step 4: Scale Services down**

This step is optional. Scaling all [Services](/core-concepts/apps/deploying-apps/services) that use the source Database to zero containers ensures that they can’t write to the Database during the cutover. This will result in some downtime in exchange for preventing replication conflicts that can result from Services writing to both the source and replica Databases at the same time.

It's usually easiest to prepare a script that scales all Services down and another that scales them back up to their current values once the upgrade has been completed. Current container counts can be found in the [Aptible Dashboard](https://dashboard.aptible.com/) or by running [`APTIBLE_OUTPUT_FORMAT=json aptible apps`](/reference/aptible-cli/cli-commands/cli-apps).

Example scale command:

```
aptible apps:scale --app my-app cmd --container-count 0
```

#### **Step 5: Update all Apps to use the replica**

Assuming [Database's Credentials](/core-concepts/managed-databases/connecting-databases/database-credentials) are provided to Apps via the [App's Configuration](/core-concepts/apps/deploying-apps/configuration), this can be done relatively easily using the [`aptible config:set`](/reference/aptible-cli/cli-commands/cli-config-set) command. This step is also usually easiest to complete by preparing a script that updates all relevant Apps.

Example config command:

```sql
aptible config:set --app my-app DB_URL='postgresql://user:passw0rd@db-stack-1234.aptible.in:5432/db'
```

#### **Step 6: Sync sequences**

Ensure that the sequences on the replica are up-to-date with the source Database:

```sql
psql "$SOURCE_URL" --tuples-only --no-align --command \
  'SELECT datname FROM pg_database WHERE datistemplate IS FALSE' |

while IFS= read -r db; do
  psql "$SOURCE_URL" << EOF
    \connect "$db"
    SELECT pglogical.synchronize_sequence( seqoid ) FROM pglogical.sequence_state;
EOF
done
```

#### **Step 7: Stop replication**

Now that all the Apps have been updated to use the new replica, there is no need to replicate changes from the source Database.

Drop the `pglogical` subscriptions, nodes, and extensions from the replica:

```sql
psql "$REPLICA_URL" --tuples-only --no-align --command \
  'SELECT datname FROM pg_database WHERE datistemplate IS FALSE' |

while IFS= read -r db; do
  psql "$REPLICA_URL" << EOF
    \connect "$db"
    SELECT pglogical.drop_subscription('aptible_subscription');
    SELECT pglogical.drop_node('aptible_subscriber');
    DROP EXTENSION pglogical;
EOF
done
```

Clear `synchronous_standby_names` on the source Database:

```sql
psql "$SOURCE_URL" << EOF
  ALTER SYSTEM RESET synchronous_standby_names;
  SELECT pg_reload_conf();
EOF
```

#### **Step 8: Scale Services up**

Scale any Services that were scaled down to zero Containers back to their original number of Containers. If a script was created to do this, now is the time to run it.

Example scale command:

```sql
aptible apps:scale --app my-app cmd --container-count 2
```

Once all of the Services have come back up, the upgrade is complete!

## Cleanup

#### Step 1: Vacuum and Analyze

Vacuuming the target Database after upgrading reclaims space occupied by dead tuples and analyzing the tables collects information on the table's contents in order to improve query performance.

```sql
psql "$REPLICA_URL" --tuples-only --no-align --command \
  'SELECT datname FROM pg_database WHERE datistemplate IS FALSE' |

while IFS= read -r db; do
  psql "$REPLICA_URL" << EOF
    \connect "$db"

    VACUUM ANALYZE;
EOF
done
```

#### Step 2: Source Database

> 🚧 Caution: If you're cleaning up from a failed replication attempt and you're not sure if `pglogical` was being used previously, check with other members of your organization before performing cleanup as this may break existing `pglogical` subscribers.

Drop the `pglogical` replication slots (if they exist), nodes, and extensions:

```sql
psql "$SOURCE_URL" --tuples-only --no-align --command \
  'SELECT datname FROM pg_database WHERE datistemplate IS FALSE' |

while IFS= read -r db; do
  psql "$SOURCE_URL" << EOF
    \connect "$db"

    SELECT pg_drop_replication_slot((
      SELECT pglogical.pglogical_gen_slot_name(
        '$db',
        'aptible_publisher_$REPLICA_ID',
        'aptible_subscription'
      )
    ));

    \set ON_ERROR_STOP 1

    SELECT pglogical.drop_node('aptible_publisher_$REPLICA_ID');
    DROP EXTENSION pglogical;
EOF
done
```

Note that you'll need to substitute `REPLICA_ID` into the script for it to properly run! If you don't remember what it is, you can always also run:

```sql
SELECT pglogical.pglogical_node_info();
```

from a `psql` client to discover what the pglogical publisher is named.

If the script above raises errors about replication slots being active, then replication was not stopped properly. Ensure that the instructions in the [Stop replication](/how-to-guides/database-guides/upgrade-postgresql#stop-replication) section have been completed.

#### Step 3: Reset max\_worker\_processes

[`aptible db:replicate --logical`](/reference/aptible-cli/cli-commands/cli-db-replicate) may have increased the `max_worker_processes` on the replica to ensure that it has enough to support replication. Now that replication has been terminated, the setting can be set back to the default by running the following command:

```sql
psql "$REPLICA_URL" --command "ALTER SYSTEM RESET max_worker_processes;"
```

See [How Logical Replication Works](/reference/aptible-cli/cli-commands/cli-db-replicate#how-logical-replication-works) in the command documentation for more details.

#### **Step 4: Unlink the Databases**

Aptible maintains a link between replicas and their source Database to ensure the source Database cannot be deleted before the replica. To deprovision the source Database after switching to the replica, users with the appropriate [roles and permissions](/core-concepts/security-compliance/access-permissions#full-permission-type-matrix) can unlink the replica from the source database. Navigate to the replica's settings page to complete the unlinking process.

#### **Step 5: Deprovision**

Once the original Database is no longer necessary, it should be deprovisioned, or it will continue to incur costs. Note that this will delete all automated Backups. If you'd like to retain the Backups, contact [Aptible Support](/how-to-guides/troubleshooting/aptible-support) to update them.

```sql
aptible db:deprovision "$SOURCE_HANDLE" --environment "$SOURCE_ENVIRONMENT"
```


# Upgrade Redis



This guide covers how to upgrade a Redis [Database](/core-concepts/managed-databases/managing-databases/overview) to a newer release.

<Tip> Starting with Redis 6, the Access Control List feature was introduced by Redis. In specific scenarios, this change also changes how a Redis Database can be upgraded. To help describe when each upgrade method applies, we'll use the term `pre-ACL` to describe Redis version 5 and below, and `post-ACL` to describe Redis version 6 and beyond.</Tip>

<Accordion title="Pre-ACL to Pre-ACL and Post-ACL to Post-ACL Upgrades">
  <Note> **Prerequisite:** Install the [Aptible CLI](/reference/aptible-cli/cli-commands/overview)</Note>

  <Steps>
    <Step title="Collection Configuration Information">
      Collect information on the Database you'd like to upgrade and store it in the following environment variables for use later in the guide:

      *   `DB_HANDLE` - The handle (i.e. name) of the Database.

      *   `ENVIRONMENT` - The handle of the environment the Database belongs to.

      *   `VERSION` - The desired Redis version. Run `aptible db:versions` to see a full list of options.

      ```bash
        DB_HANDLE='my-redis'
        ENVIRONMENT='test-environment'
        VERSION='5.0-aof'
      ```
    </Step>

    <Step title="Contact the Aptible Support Team">
      An Aptible team member must update the Database's metadata to the new version in order to upgrade the Database. When contacting [Aptible Support](/how-to-guides/troubleshooting/aptible-support) please adhere to the following rules to ensure a smooth upgrade process:

      *   Ensure that you have [Administrator Access](/core-concepts/security-compliance/access-permissions#write-permissions) to the Database's Environment. If you do not, please have someone with access contact support or CC an [Account Owner or Deploy Owner](/core-concepts/security-compliance/access-permissions) for approval.

      *   Use the same email address that's associated with your Aptible user account to contact support.

      *   Include the configuration values above. You may run the following command to generate a request with the required information:

      ```bash
        echo "Please upgrade our Redis database, ${ENVIRONMENT} - ${DB_HANDLE}, to version ${VERSION}. Thank you."
      ```
    </Step>

    <Step title="Restart the Database">
      Once support has updated the Database version, you'll need to restart the database to apply the upgrade. You may do so at your convenience with the [`aptible db:reload`](/reference/aptible-cli/cli-commands/cli-db-reload) CLI command:

      ```bash
        aptible db:reload --environment $ENVIRONMENT $DB_HANDLE
      ```
    </Step>
  </Steps>
</Accordion>

<Accordion title="Pre-ACL to Post-ACL Upgrades">
  <Accordion title="Method 1: Use Replication to Orchestrate a Minimal-Downtime Upgrade">
    <Note> **Prerequisite:** Install the [Aptible CLI](/reference/aptible-cli/cli-commands/overview) and [Redis CLI](https://redis.io/docs/install/install-redis/)</Note>

    <Steps>
      <Step title="Collect Configuration Information">
        **Step 1: Configuration**

        Collect information on the Database you'd like to upgrade and store it in the following environment variables in a terminal session for use later in the guide:

        *   `OLD_HANDLE` - The handle (i.e. name) of the Database.

        *   `ENVIRONMENT` - The handle of the Environment the Database belongs to.

        Example:

        ```bash
          SOURCE_HANDLE = 'old-db'
          ENVIRONMENT = 'test-environment'
        ```

        Collect information for the new Database and store it in the following environment variables:

        *   `NEW_HANDLE` - The handle (i.e., name) for the Database.

        *   `NEW_VERSION` - The desired Redis version. Run `aptible db:versions` to see a full list of options. Note that there are different ["flavors" of Redis](/core-concepts/managed-databases/supported-databases/redis) for each version. Double-check that the new version has the same flavor as the original database's version.

        *   `NEW_CONTAINER_SIZE` (Optional) - The size of the new Database's container in MB. You likely want this value to be the same as the original database's container size. See the [Database Scaling](/core-concepts/scaling/database-scaling#ram-scaling) documentation for a full list of supported container sizes.

        *   `NEW_DISK_SIZE` (Optional) - The size of the new Database's disk in GB. You likely want this value to be the same as the original database's disk size.

        Example:

        ```bash
          NEW_HANDLE = 'upgrade-test'
          NEW_VERSION = '7.0'
          NEW_CONTAINER_SIZE = 2048
          NEW_DISK_SIZE = 10
        ```
      </Step>

      <Step title="Provision the new Database">
        Create the new Database using `aptible db:create`.

        Example:

        ```bash
          aptible db:create "$NEW_HANDLE" \
          --type "redis" \
          --version "$NEW_VERSION" \
          --container-size $NEW_CONTAINER_SIZE \
          --disk-size $NEW_DISK_SIZE \
          --environment "$ENVIRONMENT"
        ```
      </Step>

      <Step title="Tunnel into the new Database">
        In a separate terminal, create a [Database Tunnel](/core-concepts/managed-databases/connecting-databases/database-tunnels) to the new Database using the `aptible db:tunnel` command.

        Example:

        ```bash
          aptible db:tunnel "$NEW_HANDLE" --environment "$ENVIRONMENT"
        ```

        The tunnel will block the current terminal until it's stopped. Collect the tunnel's full URL, which is printed by [aptible db:tunnel](/reference/aptible-cli/cli-commands/cli-db-tunnel), and store it in the `NEW_URL` environment variable in the original terminal.

        Example:

        ```bash
          NEW_URL ='redis://aptible:pa$word@localhost.aptible.in:6379'
        ```
      </Step>

      <Step title="Retrieve the Old Database's Database Credentials">
        To initialize replication, you'll need the [Database Credentials](/core-concepts/managed-databases/connecting-databases/database-credentials) of the old database. We'll refer to these values as the following:

        *   `OLD_HOST`

        *   `OLD_PORT`

        *   `OLD_PASSWORD`
      </Step>

      <Step title="Connect to the New Database">
        Using the Redis CLI in the original terminal, connect to the new database:

        ```bash
          redis-cli -u $NEW_URL
        ```
      </Step>

      <Step title="Initialize Replication">
        Using the variables from Step 4, run the following commands on the new database to initialize replication.

        ```bash
          REPLICA OF $OLD_HOST $OLD_PORT
          CONFIG SET masterauth $OLD_PASSWORD
        ```
      </Step>

      <Step title="Cutover to the New Database">
        When you're ready to cutover, point your Apps to the new Database and run `REPLICAOF NO ONE` via the Redis CLI to stop replication. Finally, deprovision the old database using the command aptible db:deprovision.
      </Step>
    </Steps>
  </Accordion>

  <Accordion title="Method 2: Dump and Restore to a new Redis Database">
    <Tip>We recommend Method 1 above, but you can also dump and restore to upgrade if you'd like. This method introduces extra downtime, as you must take your database offline before conducting the dump to prevent new writes and data loss. </Tip>

    <Note> **Prerequisite:** Install the [Aptible CLI](/reference/aptible-cli/cli-commands/overview), [Redis CLI](https://redis.io/docs/install/install-redis/), and [rdb tool](https://github.com/sripathikrishnan/redis-rdb-tools) </Note>

    <Steps>
      <Step title="Collection Configuration Information">
        Collect information on the Database you'd like to upgrade and store it in the following environment variables in a terminal session for use later in the guide:

        *   `OLD_HANDLE` - The handle (i.e. name) of the Database.

        *   `ENVIRONMENT` - The handle of the Environment the Database belongs to

        Example:

        ```bash
          SOURCE_HANDLE = 'old-db'
          ENVIRONMENT = 'test-environment'
        ```

        Collect information for the new Database and store it in the following environment variables:

        *   `NEW_HANDLE` - The handle (i.e., name) for the Database.

        *   `NEW_VERSION` - The desired Redis version. Run `aptible db:versions` to see a full list of options. Note that there are different ["flavors" of Redis](/core-concepts/managed-databases/supported-databases/redis) for each version. Double-check that the new version has the same flavor as the original database's version.

        *   `NEW_CONTAINER_SIZE` (Optional) - The size of the new Database's container in MB. You likely want this value to be the same as the original database's container size. See the [Database Scaling](/core-concepts/scaling/database-scaling#ram-scaling) documentation for a full list of supported container sizes.

        *   `NEW_DISK_SIZE` (Optional) - The size of the new Database's disk in GB. You likely want this value to be the same as the original database's disk size.

        Example:

        ```bash
          NEW_HANDLE = 'upgrade-test'
          NEW_VERSION = '7.0'
          NEW_CONTAINER_SIZE = 2048
          NEW_DISK_SIZE = 10
        ```
      </Step>

      <Step title="Provision the New Database">
        Create the new Database using `aptible db:create`.

        Example:

        ```bash
          aptible db:create "$NEW_HANDLE" \
          --type "redis" \
          --version "$NEW_VERSION" \
          --container - size $NEW_CONTAINER_SIZE \
          --disk - size $NEW_DISK_SIZE \
          --environment "$ENVIRONMENT"
        ```
      </Step>

      <Step title="Tunnel into the Old Database">
        In a separate terminal, create a [Database Tunnel](/core-concepts/managed-databases/connecting-databases/database-tunnels) to the old Database using the `aptible db:tunnel` command.

        Example:

        ```bash
          aptible db:tunnel "$NEW_HANDLE" --environment "$ENVIRONMENT"
        ```

        The tunnel will block the current terminal until it's stopped. Collect the tunnel's full URL, which is printed by `aptible db:tunnel`, and store it in the `OLD_URL` environment variable in the original terminal.

        Example:

        ```bash
          OLD_URL = 'redis://aptible:pa$word@localhost.aptible.in:6379'
        ```
      </Step>

      <Step title="Dump the Old Database">
        Dump the old database to a file locally using rdb and the Redis CLI.

        Example:

        ```bash
          redis-cli -u $OLD_URL --rdb dump.rdb
        ```
      </Step>

      <Step title="Tunnel into the New Database">
        In a separate terminal, create a [Database Tunnel](/core-concepts/managed-databases/connecting-databases/database-tunnels) to the new Database using the `aptible db:tunnel` command, and save the Connection URL as `NEW_URL`.
      </Step>

      <Step title="Restore the Redis Dump using rdb">
        Using the rdb tool, restore the dump to the new Database.

        ```
          rdb --command protocol dump.rdb | redis - cli - u $NEW_URL--pipe
        ```
      </Step>

      <Step title="Cutover to the New Database">
        Point your Apps and other resources to your new database and deprovision the old database using the command `aptible db:deprovision`.
      </Step>
    </Steps>
  </Accordion>
</Accordion>


# Browse Guides

Explore guides for using the Aptible platform

# Getting Started

<CardGroup cols={3}>
  <Card title="Custom Code" icon="globe" href="https://www.aptible.com/docs/custom-code-quickstart">
    Explore compatibility and deploy custom code
  </Card>

  <Card
    title="Ruby "
    href="https://www.aptible.com/docs/ruby-quickstart"
    icon={
    <svg width="30" height="30" viewBox="0 0 256 255" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMinYMin meet"><defs><linearGradient x1="84.75%" y1="111.399%" x2="58.254%" y2="64.584%" id="a"><stop stop-color="#FB7655" offset="0%"/><stop stop-color="#FB7655" offset="0%"/><stop stop-color="#E42B1E" offset="41%"/><stop stop-color="#900" offset="99%"/><stop stop-color="#900" offset="100%"/></linearGradient><linearGradient x1="116.651%" y1="60.89%" x2="1.746%" y2="19.288%" id="b"><stop stop-color="#871101" offset="0%"/><stop stop-color="#871101" offset="0%"/><stop stop-color="#911209" offset="99%"/><stop stop-color="#911209" offset="100%"/></linearGradient><linearGradient x1="75.774%" y1="219.327%" x2="38.978%" y2="7.829%" id="c"><stop stop-color="#871101" offset="0%"/><stop stop-color="#871101" offset="0%"/><stop stop-color="#911209" offset="99%"/><stop stop-color="#911209" offset="100%"/></linearGradient><linearGradient x1="50.012%" y1="7.234%" x2="66.483%" y2="79.135%" id="d"><stop stop-color="#FFF" offset="0%"/><stop stop-color="#FFF" offset="0%"/><stop stop-color="#E57252" offset="23%"/><stop stop-color="#DE3B20" offset="46%"/><stop stop-color="#A60003" offset="99%"/><stop stop-color="#A60003" offset="100%"/></linearGradient><linearGradient x1="46.174%" y1="16.348%" x2="49.932%" y2="83.047%" id="e"><stop stop-color="#FFF" offset="0%"/><stop stop-color="#FFF" offset="0%"/><stop stop-color="#E4714E" offset="23%"/><stop stop-color="#BE1A0D" offset="56%"/><stop stop-color="#A80D00" offset="99%"/><stop stop-color="#A80D00" offset="100%"/></linearGradient><linearGradient x1="36.965%" y1="15.594%" x2="49.528%" y2="92.478%" id="f"><stop stop-color="#FFF" offset="0%"/><stop stop-color="#FFF" offset="0%"/><stop stop-color="#E46342" offset="18%"/><stop stop-color="#C82410" offset="40%"/><stop stop-color="#A80D00" offset="99%"/><stop stop-color="#A80D00" offset="100%"/></linearGradient><linearGradient x1="13.609%" y1="58.346%" x2="85.764%" y2="-46.717%" id="g"><stop stop-color="#FFF" offset="0%"/><stop stop-color="#FFF" offset="0%"/><stop stop-color="#C81F11" offset="54%"/><stop stop-color="#BF0905" offset="99%"/><stop stop-color="#BF0905" offset="100%"/></linearGradient><linearGradient x1="27.624%" y1="21.135%" x2="50.745%" y2="79.056%" id="h"><stop stop-color="#FFF" offset="0%"/><stop stop-color="#FFF" offset="0%"/><stop stop-color="#DE4024" offset="31%"/><stop stop-color="#BF190B" offset="99%"/><stop stop-color="#BF190B" offset="100%"/></linearGradient><linearGradient x1="-20.667%" y1="122.282%" x2="104.242%" y2="-6.342%" id="i"><stop stop-color="#BD0012" offset="0%"/><stop stop-color="#BD0012" offset="0%"/><stop stop-color="#FFF" offset="7%"/><stop stop-color="#FFF" offset="17%"/><stop stop-color="#C82F1C" offset="27%"/><stop stop-color="#820C01" offset="33%"/><stop stop-color="#A31601" offset="46%"/><stop stop-color="#B31301" offset="72%"/><stop stop-color="#E82609" offset="99%"/><stop stop-color="#E82609" offset="100%"/></linearGradient><linearGradient x1="58.792%" y1="65.205%" x2="11.964%" y2="50.128%" id="j"><stop stop-color="#8C0C01" offset="0%"/><stop stop-color="#8C0C01" offset="0%"/><stop stop-color="#990C00" offset="54%"/><stop stop-color="#A80D0E" offset="99%"/><stop stop-color="#A80D0E" offset="100%"/></linearGradient><linearGradient x1="79.319%" y1="62.754%" x2="23.088%" y2="17.888%" id="k"><stop stop-color="#7E110B" offset="0%"/><stop stop-color="#7E110B" offset="0%"/><stop stop-color="#9E0C00" offset="99%"/><stop stop-color="#9E0C00" offset="100%"/></linearGradient><linearGradient x1="92.88%" y1="74.122%" x2="59.841%" y2="39.704%" id="l"><stop stop-color="#79130D" offset="0%"/><stop stop-color="#79130D" offset="0%"/><stop stop-color="#9E120B" offset="99%"/><stop stop-color="#9E120B" offset="100%"/></linearGradient><radialGradient cx="32.001%" cy="40.21%" fx="32.001%" fy="40.21%" r="69.573%" id="m"><stop stop-color="#A80D00" offset="0%"/><stop stop-color="#A80D00" offset="0%"/><stop stop-color="#7E0E08" offset="99%"/><stop stop-color="#7E0E08" offset="100%"/></radialGradient><radialGradient cx="13.549%" cy="40.86%" fx="13.549%" fy="40.86%" r="88.386%" id="n"><stop stop-color="#A30C00" offset="0%"/><stop stop-color="#A30C00" offset="0%"/><stop stop-color="#800E08" offset="99%"/><stop stop-color="#800E08" offset="100%"/></radialGradient><linearGradient x1="56.57%" y1="101.717%" x2="3.105%" y2="11.993%" id="o"><stop stop-color="#8B2114" offset="0%"/><stop stop-color="#8B2114" offset="0%"/><stop stop-color="#9E100A" offset="43%"/><stop stop-color="#B3100C" offset="99%"/><stop stop-color="#B3100C" offset="100%"/></linearGradient><linearGradient x1="30.87%" y1="35.599%" x2="92.471%" y2="100.694%" id="p"><stop stop-color="#B31000" offset="0%"/><stop stop-color="#B31000" offset="0%"/><stop stop-color="#910F08" offset="44%"/><stop stop-color="#791C12" offset="99%"/><stop stop-color="#791C12" offset="100%"/></linearGradient></defs><path d="M197.467 167.764l-145.52 86.41 188.422-12.787L254.88 51.393l-57.414 116.37z" fill="url(#a)"/><path d="M240.677 241.257L224.482 129.48l-44.113 58.25 60.308 53.528z" fill="url(#b)"/><path d="M240.896 241.257l-118.646-9.313-69.674 21.986 188.32-12.673z" fill="url(#c)"/><path d="M52.744 253.955l29.64-97.1L17.16 170.8l35.583 83.154z" fill="url(#d)"/><path d="M180.358 188.05L153.085 81.226l-78.047 73.16 105.32 33.666z" fill="url(#e)"/><path d="M248.693 82.73l-73.777-60.256-20.544 66.418 94.321-6.162z" fill="url(#f)"/><path d="M214.191.99L170.8 24.97 143.424.669l70.767.322z" fill="url(#g)"/><path d="M0 203.372l18.177-33.151-14.704-39.494L0 203.372z" fill="url(#h)"/><path d="M2.496 129.48l14.794 41.963 64.283-14.422 73.39-68.207 20.712-65.787L143.063 0 87.618 20.75c-17.469 16.248-51.366 48.396-52.588 49-1.21.618-22.384 40.639-32.534 59.73z" fill="#FFF"/><path d="M54.442 54.094c37.86-37.538 86.667-59.716 105.397-40.818 18.72 18.898-1.132 64.823-38.992 102.349-37.86 37.525-86.062 60.925-104.78 42.027-18.73-18.885.515-66.032 38.375-103.558z" fill="url(#i)"/><path d="M52.744 253.916l29.408-97.409 97.665 31.376c-35.312 33.113-74.587 61.106-127.073 66.033z" fill="url(#j)"/><path d="M155.092 88.622l25.073 99.313c29.498-31.016 55.972-64.36 68.938-105.603l-94.01 6.29z" fill="url(#k)"/><path d="M248.847 82.833c10.035-30.282 12.35-73.725-34.966-81.791l-38.825 21.445 73.791 60.346z" fill="url(#l)"/><path d="M0 202.935c1.39 49.979 37.448 50.724 52.808 51.162l-35.48-82.86L0 202.935z" fill="#9E1209"/><path d="M155.232 88.777c22.667 13.932 68.35 41.912 69.276 42.426 1.44.81 19.695-30.784 23.838-48.64l-93.114 6.214z" fill="url(#m)"/><path d="M82.113 156.507l39.313 75.848c23.246-12.607 41.45-27.967 58.121-44.42l-97.434-31.428z" fill="url(#n)"/><path d="M17.174 171.34l-5.57 66.328c10.51 14.357 24.97 15.605 40.136 14.486-10.973-27.311-32.894-81.92-34.566-80.814z" fill="url(#o)"/><path d="M174.826 22.654l78.1 10.96c-4.169-17.662-16.969-29.06-38.787-32.623l-39.313 21.663z" fill="url(#p)"/></svg>
    }
  >
    Deploy using a Ruby on Rails template
  </Card>

  <Card
    title="NodeJS"
    href="https://www.aptible.com/docs/node-js-quickstart"
    icon={
    <svg xmlns="http://www.w3.org/2000/svg" width="30" height="30" viewBox="0 0 58 64" fill="none">
    <path d="M26.3201 0.681001C27.9201 -0.224999 29.9601 -0.228999 31.5201 0.681001L55.4081 14.147C56.9021 14.987 57.9021 16.653 57.8881 18.375V45.375C57.8981 47.169 56.8001 48.871 55.2241 49.695L31.4641 63.099C30.6514 63.5481 29.7333 63.7714 28.8052 63.7457C27.877 63.7201 26.9727 63.4463 26.1861 62.953L19.0561 58.833C18.5701 58.543 18.0241 58.313 17.6801 57.843C17.9841 57.435 18.5241 57.383 18.9641 57.203C19.9561 56.887 20.8641 56.403 21.7761 55.891C22.0061 55.731 22.2881 55.791 22.5081 55.935L28.5881 59.451C29.0221 59.701 29.4621 59.371 29.8341 59.161L53.1641 45.995C53.4521 45.855 53.6121 45.551 53.5881 45.235V18.495C53.6201 18.135 53.4141 17.807 53.0881 17.661L29.3881 4.315C29.2515 4.22054 29.0894 4.16976 28.9234 4.16941C28.7573 4.16905 28.5951 4.21912 28.4581 4.313L4.79207 17.687C4.47207 17.833 4.25207 18.157 4.29207 18.517V45.257C4.26407 45.573 4.43207 45.871 4.72207 46.007L11.0461 49.577C12.2341 50.217 13.6921 50.577 15.0001 50.107C15.5725 49.8913 16.0652 49.5058 16.4123 49.0021C16.7594 48.4984 16.9443 47.9007 16.9421 47.289L16.9481 20.709C16.9201 20.315 17.2921 19.989 17.6741 20.029H20.7141C21.1141 20.019 21.4281 20.443 21.3741 20.839L21.3681 47.587C21.3701 49.963 20.3941 52.547 18.1961 53.713C15.4881 55.113 12.1401 54.819 9.46407 53.473L2.66407 49.713C1.06407 48.913 -0.00993076 47.185 6.9243e-05 45.393V18.393C0.0067219 17.5155 0.247969 16.6557 0.698803 15.9027C1.14964 15.1498 1.79365 14.5312 2.56407 14.111L26.3201 0.681001ZM33.2081 19.397C36.6621 19.197 40.3601 19.265 43.4681 20.967C45.8741 22.271 47.2081 25.007 47.2521 27.683C47.1841 28.043 46.8081 28.243 46.4641 28.217C45.4641 28.215 44.4601 28.231 43.4561 28.211C43.0301 28.227 42.7841 27.835 42.7301 27.459C42.4421 26.179 41.7441 24.913 40.5401 24.295C38.6921 23.369 36.5481 23.415 34.5321 23.435C33.0601 23.515 31.4781 23.641 30.2321 24.505C29.2721 25.161 28.9841 26.505 29.3261 27.549C29.6461 28.315 30.5321 28.561 31.2541 28.789C35.4181 29.877 39.8281 29.789 43.9141 31.203C45.6041 31.787 47.2581 32.923 47.8381 34.693C48.5941 37.065 48.2641 39.901 46.5781 41.805C45.2101 43.373 43.2181 44.205 41.2281 44.689C38.5821 45.279 35.8381 45.293 33.1521 45.029C30.6261 44.741 27.9981 44.077 26.0481 42.357C24.3801 40.909 23.5681 38.653 23.6481 36.477C23.6681 36.109 24.0341 35.853 24.3881 35.883H27.3881C27.7921 35.855 28.0881 36.203 28.1081 36.583C28.2941 37.783 28.7521 39.083 29.8161 39.783C31.8681 41.107 34.4421 41.015 36.7901 41.053C38.7361 40.967 40.9201 40.941 42.5101 39.653C43.3501 38.919 43.5961 37.693 43.3701 36.637C43.1241 35.745 42.1701 35.331 41.3701 35.037C37.2601 33.737 32.8001 34.209 28.7301 32.737C27.0781 32.153 25.4801 31.049 24.8461 29.351C23.9601 26.951 24.3661 23.977 26.2321 22.137C28.0321 20.307 30.6721 19.601 33.1721 19.349L33.2081 19.397Z" fill="#8CC84B"/></svg>
    }
  >
    Deploy using a Node.js + Express template
  </Card>

  <Card
    title="Django"
    href="https://www.aptible.com/docs/python-quickstart"
    icon={
    <svg width="30" height="30" viewBox="0 0 256 326" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMinYMin meet"><g fill="#2BA977"><path d="M114.784 0h53.278v244.191c-27.29 5.162-47.38 7.193-69.117 7.193C33.873 251.316 0 222.245 0 166.412c0-53.795 35.93-88.708 91.608-88.708 8.64 0 15.222.68 23.176 2.717V0zm1.867 124.427c-6.24-2.038-11.382-2.717-17.965-2.717-26.947 0-42.512 16.437-42.512 45.243 0 28.046 14.88 43.532 42.17 43.532 5.896 0 10.696-.332 18.307-1.351v-84.707z"/><path d="M255.187 84.26v122.263c0 42.105-3.154 62.353-12.411 79.81-8.64 16.783-20.022 27.366-43.541 39.055l-49.438-23.297c23.519-10.93 34.901-20.588 42.17-35.327 7.61-15.072 10.01-32.529 10.01-78.445V84.261h53.21zM196.608 0h53.278v54.135h-53.278V0z"/></g></svg>
    }
  >
    Deploy using a Python + Django template.
  </Card>

  <Card
    title="Laravel"
    href="https://www.aptible.com/docs/php-quickstart"
    icon={
    <svg height="30" viewBox="0 -.11376601 49.74245785 51.31690859" width="30" xmlns="http://www.w3.org/2000/svg"><path d="m49.626 11.564a.809.809 0 0 1 .028.209v10.972a.8.8 0 0 1 -.402.694l-9.209 5.302v10.509c0 .286-.152.55-.4.694l-19.223 11.066c-.044.025-.092.041-.14.058-.018.006-.035.017-.054.022a.805.805 0 0 1 -.41 0c-.022-.006-.042-.018-.063-.026-.044-.016-.09-.03-.132-.054l-19.219-11.066a.801.801 0 0 1 -.402-.694v-32.916c0-.072.01-.142.028-.21.006-.023.02-.044.028-.067.015-.042.029-.085.051-.124.015-.026.037-.047.055-.071.023-.032.044-.065.071-.093.023-.023.053-.04.079-.06.029-.024.055-.05.088-.069h.001l9.61-5.533a.802.802 0 0 1 .8 0l9.61 5.533h.002c.032.02.059.045.088.068.026.02.055.038.078.06.028.029.048.062.072.094.017.024.04.045.054.071.023.04.036.082.052.124.008.023.022.044.028.068a.809.809 0 0 1 .028.209v20.559l8.008-4.611v-10.51c0-.07.01-.141.028-.208.007-.024.02-.045.028-.068.016-.042.03-.085.052-.124.015-.026.037-.047.054-.071.024-.032.044-.065.072-.093.023-.023.052-.04.078-.06.03-.024.056-.05.088-.069h.001l9.611-5.533a.801.801 0 0 1 .8 0l9.61 5.533c.034.02.06.045.09.068.025.02.054.038.077.06.028.029.048.062.072.094.018.024.04.045.054.071.023.039.036.082.052.124.009.023.022.044.028.068zm-1.574 10.718v-9.124l-3.363 1.936-4.646 2.675v9.124l8.01-4.611zm-9.61 16.505v-9.13l-4.57 2.61-13.05 7.448v9.216zm-36.84-31.068v31.068l17.618 10.143v-9.214l-9.204-5.209-.003-.002-.004-.002c-.031-.018-.057-.044-.086-.066-.025-.02-.054-.036-.076-.058l-.002-.003c-.026-.025-.044-.056-.066-.084-.02-.027-.044-.05-.06-.078l-.001-.003c-.018-.03-.029-.066-.042-.1-.013-.03-.03-.058-.038-.09v-.001c-.01-.038-.012-.078-.016-.117-.004-.03-.012-.06-.012-.09v-21.483l-4.645-2.676-3.363-1.934zm8.81-5.994-8.007 4.609 8.005 4.609 8.006-4.61-8.006-4.608zm4.164 28.764 4.645-2.674v-20.096l-3.363 1.936-4.646 2.675v20.096zm24.667-23.325-8.006 4.609 8.006 4.609 8.005-4.61zm-.801 10.605-4.646-2.675-3.363-1.936v9.124l4.645 2.674 3.364 1.937zm-18.422 20.561 11.743-6.704 5.87-3.35-8-4.606-9.211 5.303-8.395 4.833z" fill="#ff2d20"/></svg>
    }
  >
    Deploy using a PHP + Laravel template
  </Card>

  <Card
    title="Python"
    href="https://www.aptible.com/docs/deploy-demo-app"
    icon={
    <svg width="30" height="30" viewBox="0 0 256 255" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMinYMin meet"><defs><linearGradient x1="12.959%" y1="12.039%" x2="79.639%" y2="78.201%" id="a"><stop stop-color="#387EB8" offset="0%"/><stop stop-color="#366994" offset="100%"/></linearGradient><linearGradient x1="19.128%" y1="20.579%" x2="90.742%" y2="88.429%" id="b"><stop stop-color="#FFE052" offset="0%"/><stop stop-color="#FFC331" offset="100%"/></linearGradient></defs><path d="M126.916.072c-64.832 0-60.784 28.115-60.784 28.115l.072 29.128h61.868v8.745H41.631S.145 61.355.145 126.77c0 65.417 36.21 63.097 36.21 63.097h21.61v-30.356s-1.165-36.21 35.632-36.21h61.362s34.475.557 34.475-33.319V33.97S194.67.072 126.916.072zM92.802 19.66a11.12 11.12 0 0 1 11.13 11.13 11.12 11.12 0 0 1-11.13 11.13 11.12 11.12 0 0 1-11.13-11.13 11.12 11.12 0 0 1 11.13-11.13z" fill="url(#a)"/><path d="M128.757 254.126c64.832 0 60.784-28.115 60.784-28.115l-.072-29.127H127.6v-8.745h86.441s41.486 4.705 41.486-60.712c0-65.416-36.21-63.096-36.21-63.096h-21.61v30.355s1.165 36.21-35.632 36.21h-61.362s-34.475-.557-34.475 33.32v56.013s-5.235 33.897 62.518 33.897zm34.114-19.586a11.12 11.12 0 0 1-11.13-11.13 11.12 11.12 0 0 1 11.13-11.131 11.12 11.12 0 0 1 11.13 11.13 11.12 11.12 0 0 1-11.13 11.13z" fill="url(#b)"/></svg>
    }
  >
    Deploy Python + Flask Demo app
  </Card>
</CardGroup>

# App

<CardGroup cols={4}>
  <Card title="How deploy via Docker Image" icon="book-open-reader" iconType="duotone" href="https://www.aptible.com/docs/direct-docker-image-deploy-example" />

  <Card title="How to deploy to Aptible with CI/CD" icon="book-open-reader" iconType="duotone" href="https://www.aptible.com/docs/continuous-integration-provider-deployment" />

  <Card title="How to explose a web app to the internet" icon="book-open-reader" iconType="duotone" href="https://www.aptible.com/docs/expose-web-app" />

  <Card title="See more" icon="angles-right" href="https://www.aptible.com/docs/deployment-guides" />
</CardGroup>

# Database

<CardGroup cols={4}>
  <Card title="How to automate database migrations" icon="book-open-reader" iconType="duotone" href="https://www.aptible.com/docs/automating-database-migrations" />

  <Card title="How to upgrade PostgreSQL with Logical Replication" icon="book-open-reader" iconType="duotone" href="https://www.aptible.com/docs/logical-replication" />

  <Card title="How to dump and restore MySQL" icon="book-open-reader" iconType="duotone" href="https://www.aptible.com/docs/mysql-dump-and-restore" />

  <Card title="See more" icon="angles-right" href="https://www.aptible.com/docs/database-guides" />
</CardGroup>

# Observability

<CardGroup cols={4}>
  <Card title="How to deploy and use Grafana" icon="book-open-reader" iconType="duotone" href="https://www.aptible.com/docs/deploying-grafana-on-deploy" />

  <Card title="How to set up Elasticsearch Log Rotation" icon="book-open-reader" iconType="duotone" href="https://www.aptible.com/docs/elasticsearch-log-rotation" />

  <Card title="How to set up Datadog APM" icon="book-open-reader" iconType="duotone" href="https://www.aptible.com/docs/datadog-apm" />

  <Card title="See more" icon="angles-right" href="https://www.aptible.com/docs/observability-guides" />
</CardGroup>

# Account and Platform

<CardGroup cols={4}>
  <Card title="Best Practices Guide" icon="book-open-reader" iconType="duotone" href="https://www.aptible.com/docs/best-practices-guide" />

  <Card title="How to achieve HIPAA compliance" icon="book-open-reader" iconType="duotone" href="https://www.aptible.com/docs/achieve-hipaa" />

  <Card title="How to minimize downtime caused by AWS outages" icon="book-open-reader" iconType="duotone" href="https://www.aptible.com/docs/business-continuity" />

  <Card title="See more" icon="angles-right" href="https://www.aptible.com/docs/platform-guides" />
</CardGroup>

# Troubleshooting Common Errors

<CardGroup cols={4}>
  <Card title="git Push Permission Denied" icon="book-open-reader" iconType="duotone" href="https://www.aptible.com/docs/permission-denied-git-push" />

  <Card title="HTTP Health Checks Failed" icon="book-open-reader" iconType="duotone" href="https://www.aptible.com/docs/http-health-checks-failed" />

  <Card title="Application is Currently Unavailable" icon="book-open-reader" iconType="duotone" href="https://www.aptible.com/docs/application-crashed" />

  <Card title="See more" icon="angles-right" href="https://www.aptible.com/docs/common-erorrs" />
</CardGroup>


# How to access operation logs

For all operations performed, Aptible collects operation logs. These logs are retained only for active resources and can be viewed in the following ways.

## Using the Dashboard

*   Within the resource summary by:

    *   Navigating to the respective resource

    *   Selecting the **Activity** tab![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/operation-logs1.png)

    *   Selecting **Logs**
*   Within the **Activity** dashboard by:

    *   Navigating to the **Activity** page

    *   Selecting the **Logs** button for the respective operation

        *   Note: This page only shows operations performed in the last 7 days.

## Using the CLI

*   By using the [aptible operation:logs](/reference/aptible-cli/cli-commands/cli-operation-logs) command

    *   Note: This command only shows operations performed in the last 90 days.
*   For actively running operations, by using

    *   [`aptible logs`](/core-concepts/observability/logs/overview) to stream all logs for an app or database


# How to deploy and use Grafana

Learn how to deploy and use Aptible-hosted analytics and monitoring with Grafana

## Overview

[Grafana](https://grafana.com/) is an open-source platform for analytics and monitoring. It's an ideal choice to use in combination with an [InfluxDB metric drain.](/core-concepts/observability/metrics/metrics-drains/influxdb-metric-drain) Grafan is useful in a number of ways:

*   It makes it easy to build beautiful graphs and set up alerts.

*   It works out of the box with InfluxDB.

*   It works very well in a containerized environment like Aptible.

## Set up

### Deploying with Terraform

The **easiest and recommended way** to set up Grafana on Aptible is using the [Aptible Metrics Terraform Module](https://registry.terraform.io/modules/aptible/metrics/aptible/latest). This provisions Aptible metric drains with pre-built Grafana dashboards and alerts for monitoring RAM and CPU usage for your Aptible apps and databases. This simplifies the setup of metric drains so you can start monitoring your Aptible resources immediately, all hosted within your Aptible account. If you would rather set it up from scratch, use this guide.

### Deploying via the CLI

#### Step 1: Provision a PostgreSQL database

Grafana needs a Database to store sessions and Dashboard definitions. It works great with [PostgreSQL](/core-concepts/managed-databases/supported-databases/postgresql), which you can deploy on Aptible.

#### Step 2: Configure the database

Once you have created the PostgreSQL Database, create a tunnel using the [`aptible db:tunnel`](/reference/aptible-cli/cli-commands/cli-db-tunnel) command, then connect using `psql` and run the following commands to create a `sessions` database for use by Grafana:

```sql
CREATE DATABASE sessions;
```

Then, connect to the newly-created `sessions` database:

```sql
\c sessions;
```

And finally, create a table for Grafana to store sessions in:

```sql
CREATE TABLE session (
        key       CHAR(16) NOT NULL,
        data      BYTEA,
        expiry    INTEGER NOT NULL,
        PRIMARY KEY (key)
);
```

#### Step 3: Deploy the Grafana app

Grafana is available as a Docker image and can be configured using environment variables. As a result, you can use [Direct Docker Image Deploy](/how-to-guides/app-guides/migrate-dockerfile-to-direct-image-deploy) to easily deploy Grafana on Aptible.

Here is the minimal deployment configuration to get you started. In the example below, you'll have to substitute a number of variables:

*   `$ADMIN_PASSWORD`: Generate a strong password for your Grafana `admin` user.

*   `$SECRET_KEY`: Generate a random string (40 characters will do).

*   `$YOUR_DOMAIN`: The domain name you intend to use to connect to Grafana (e.g. `grafana.example.com`).

*   `$DB_USERNAME`: The username for your PostgreSQL database. For a PostgreSQL database on Aptible, this will be `aptible`.

*   `$DB_PASSWORD`: The password for your PostgreSQL database.

*   `$DB_HOST`: The host for your PostgreSQL database.

*   `$DB_PORT`: The port for your PostgreSQL database.

```sql
aptible apps:create grafana

aptible deploy --app grafana --docker-image grafana/grafana \
        "GF_SECURITY_ADMIN_PASSWORD=$ADMIN_PASSWORD" \
        "GF_SECURITY_SECRET_KEY=$SECRET_KEY" \
        "GF_DEFAULT_INSTANCE_NAME=aptible" \
        "GF_SERVER_ROOT_URL=https://$YOUR_DOMAIN" \
        "GF_SESSION_PROVIDER=postgres" \
        "GF_SESSION_PROVIDER_CONFIG=user=$DB_USERNAME password=$DB_PASSWORD host=$DB_HOST port=$DB_PORT dbname=sessions sslmode=require" \
        "GF_LOG_MODE=console" \
        "GF_DATABASE_TYPE=postgres" \
        "GF_DATABASE_HOST=$DB_HOST:$DB_PORT" \
        "GF_DATABASE_NAME=db" \
        "GF_DATABASE_USER=$DB_USERNAME" \
        "GF_DATABASE_PASSWORD=$DB_PASSWORD" \
        "GF_DATABASE_SSL_MODE=require" \
        "FORCE_SSL=true"
```

> 📘 There are many more configuration options available in Grafana. Review [Grafana's configuration documentation](http://docs.grafana.org/installation/configuration/) for more information.

#### Step 4: Expose Grafana

Finally, follow the [How do I expose my web app on the Internet?](/how-to-guides/app-guides/expose-web-app-to-internet) tutorial to expose your Grafana app over the internet. Make sure to use the same domain you configured Grafana with (`$YOUR_DOMAIN` in the example above)!

## Using Grafana

#### Step 1: Log in

Once you've exposed Grafana, you can navigate to `$YOUR_DOMAIN` to access Grafana. Connect using the username `admin` and the password you configured above (`ADMIN_PASSWORD`).

#### Step 2: Connect to an InfluxDB Database

Once logged in to Grafana, you can connect Grafana to an [InfluxDB](/core-concepts/managed-databases/supported-databases/influxdb) database by creating a new data source. To do so, click the Grafana icon in the top left, then navigate to data sources and click "Add data source".

The following assumes you have provisioned an InfluxDB database. You'll need to interpolate the following values

*   `$INFLUXDB_HOST`: The hostname for your InfluxDB database. This is of the form `db-$STACK-$ID.aptible.in`.

*   `$INFLUXDB_PORT`: The port for your InfluxDB database.

*   `$INFLUXDB_USERNAME`: The username for your InfluxDB database. Typically `aptible`.

*   `$INFLUXDB_PASSWORD`: The password.

These parameters are represented by the connection URL for your InfluxDB database in the Aptible dashboard and CLI. For example, if your connection URL is `https://foo:bar@db-qux-123.aptible.in:456`, then the parameters are:

*   `$INFLUXDB_HOST`: `db-qux-123.aptible.in`

*   `$INFLUXDB_PORT`: `456`

*   `$INFLUXDB_USERNAME`: `foo`

*   `$INFLUXDB_PASSWORD`: `bar`

Once you have those parameters in Grafana, use the following configuration for your data source:

*   **Name**: Any name of your choosing. This will be used to reference this data source in the Grafana web interface.

*   **Type**: InfluxDB

*   **HTTP settings**:

    *   **URL**: `https://$INFLUXDB_HOST:$INFLUXDB_PORT`.

    *   **Access**: `proxy`

*   **HTTP Auth**: Leave everything unchecked

*   **Skip TLS Verification**: Do not select

*   **InfluxDB Details**: - Database: If you provisioned this InfluxDB database on Aptible and/or are using it for an [InfluxDB database](/core-concepts/managed-databases/supported-databases/influxdb) metric drain, set this to `db`. Otherwise, use the database of your choice. - User: `$INFLUXDB_USERNAME` - Password: `$INFLUXDB_PASSWORD`

Finally, save your changes.

#### Step 3: Set up Queries

Here are a few suggested queries to get started with an InfluxDB metric drain. These queries are designed with Grafana in mind. To copy those queries into Grafana, use the [raw text editor mode](http://docs.grafana.org/features/datasources/influxdb/#text-editor-mode-raw) in Grafana.

> 📘 In the queries below, `$__interval` and `$timeFilter` will automatically be interpolated by Grafana. Leave those parameters as-is.

**RSS Memory Utilization across all resources**

```sql
SELECT MAX("memory_rss_mb") AS rss_mb
FROM "metrics"
WHERE $timeFilter
GROUP BY
        time($__interval),
        "app", "database", "service", "host"
        fill(null)
```

**CPU Utilization for a single App**

In the example below, replace `ENVIRONMENT` with the handle for your [environment](/core-concepts/architecture/environments) and `HANDLE` with the handle for your [app](/core-concepts/apps/overview)

```sql
SELECT MEAN("milli_cpu_usage") / 1000 AS cpu
FROM "metrics"
WHERE
        environment = 'ENVIRONMENT' AND
        app = 'HANDLE' AND
        $timeFilter
GROUP BY
        time($__interval),
        "service", "host"
        fill(null)
```

#### Disk Utilization across all Databases

```sql
SELECT LAST(disk_usage_mb) / LAST(disk_limit_mb) AS utilization
FROM "metrics"
WHERE
        "database" <> '' AND
        $timeFilter
GROUP BY
        time($__interval),
        "database", "service", "host"
        fill(null)
```

## Grafana documentation

Once you've added your first data source, you might also want to consider following [Grafana's getting started documentation](http://docs.grafana.org/guides/getting_started/) to familiarize yourself with Grafana.

> 📘 If you get an error connecting, use the [`aptible logs`](/reference/aptible-cli/cli-commands/cli-logs) commands to troubleshoot.

> That said, an error logging in is very likely due to not properly creating the `sessions` database and the `session` table in it as indicated in [Configuring the database](/how-to-guides/observability-guides/deploy-use-grafana#configuring-the-database).

## Upgrading Grafana

To upgrade Grafana, deploy the desired version to your existing app containers:

```sql
aptible deploy --app grafana --docker-image grafana/grafana:VERSION
```

> 📘 **Doing a big upgrade?** If you need to downgrade, you can redeploy with a lower version. Alternatively, you can deploy a test Grafana app to ensure it works beforehand and deprovisioned the test app once complete.


# How to set up Elasticsearch Log Rotation



> ❗️ These instructions apply only to Kibana/Elasticsearch versions 7.4 or higher. Earlier versions of Elasticsearch and Kibana did not provide all of the UI features mentioned in this guide. Instead, for version 6.8 or earlier, refer to our [aptible/elasticsearch-logstash-s3-backup](https://github.com/aptible/elasticsearch-logstash-s3-backup) application.

If you're using Elasticsearch to hold log data, you'll almost certainly be creating new indexes periodically - by default, Logstash or Aptible [log drains](/core-concepts/observability/logs/log-drains/overview) will do so daily. New indexes will necessarily mean that as time passes, you'll need more and more disk space, but also, less obviously, more and more RAM. Elasticsearch allocates RAM on a per-index basis, and letting your log retention grow unchecked will almost certainly lead to fatal issues when the database runs out of RAM or disk space.

## Components

We recommend using a combination of Elasticsearch's native features to ensure you do not accumulate too many open indexes by backing up your indexes to S3 in your own AWS account:

*   [Index Lifecycle Management](https://www.elastic.co/guide/en/elasticsearch/reference/current/index-lifecycle-management.html) can be configured to delete indexes over a certain age.
*   [Snapshot Lifecycle Management](https://www.elastic.co/guide/en/elasticsearch/reference/current/snapshot-lifecycle-management.html) can be configured to back up indexes on a schedule, for example, to S3 using the Elasticsearch [S3 Repository Plugin](https://www.elastic.co/guide/en/elasticsearch/plugins/current/repository-s3.html), which is available by default.

## Configuring a snapshot repository in S3

**Step 1:** Create an S3 bucket. We will use "aptible\_logs" as the bucket name for this example.

**Step 2:** Create a dedicated user to minimize the permissions of the access key, which will be stored in the database. Elasticsearch recommends creating an IAM policy with the minimum access level required. They provide a [recommended policy here](https://www.elastic.co/guide/en/elasticsearch/plugins/current/repository-s3-repository.html#repository-s3-permissions).

**Step 3:** Register the snapshot repository using the [Elasticsearch API](https://www.elastic.co/guide/en/elasticsearch/reference/7.x/put-snapshot-repo-api.html) directly because the Kibana UI does not provide you a way to specify your IAM keypair. In this example, we'll call the repository "s3\_repository" and configure it to use the "aptible\_logs" bucket created above:

```bash
curl -X PUT "https://username:password@localhost:9200/_snapshot/s3_repository?pretty" -H 'Content-Type: application/json' -d'
{
  "type": "s3",
  "settings": {
    "bucket" : "aptible_logs",
    "access_key": "AWS_ACCESS_KEY_ID",
    "secret_key": "AWS_SECRET_ACCESS_KEY",
    "protocol": "https",
    "server_side_encryption": true
  }
}
'
```

Be sure to provide the correct username, password, host, and port needed to connect to your database, likely as provided by the [database tunnel](/core-concepts/managed-databases/connecting-databases/database-tunnels), if you're connecting that way.

[The full documentation of available options is here.](https://www.elastic.co/guide/en/elasticsearch/plugins/current/repository-s3-usage.html)

## Backing up your indexes

To backup your indexes, use Elasticsearch's [Snapshot Lifecycle Management](https://www.elastic.co/guide/en/elasticsearch/reference/current/snapshot-lifecycle-management.html) to automate daily backups of your indexes. In Kibana, you'll find these settings under Elasticsearch Management > Snapshot and Restore. Snapshots are incremental, so you can set the schedule as frequently as you like, but at least daily is recommended. You can find the [full documentation for creating a policy here](https://www.elastic.co/guide/en/kibana/7.x/snapshot-repositories.html#kib-snapshot-policy).

## Limiting the live retention

Now that you have a Snapshot Lifecycle policy configured to backup your data to S3, the final step is to ensure you delete indexes after a specific time in Elasticsearch. Deleting indexes will ensure both RAM and disk space requirements are relatively fixed, given a fixed volume of logs. For example, you may keep only 30 days in Elasticsearch, and if you need older indexes, you can retrieve them by restoring the snapshot from S3.

**Step 1:** Create a new policy by navigating to Elasticsearch Management > Index Lifecycle Policies. Under "Hot phase", disable rollover - we're already creating a new index daily, which should be sufficient. Enable the "Delete phase" and set it for 30 days from index creation (or to your desired live retention).

**Step 2:** Specify to Elasticsearch which new indexes you want this policy to apply automatically. In Kibana, go to Elasticsearch Management > Index Management, then click Index Templates. Create a new template using the Index pattern `logstash-*`. You can leave all other settings as default. This template will ensure all new daily indexes get the lifecycle policy applied.

```
{
  index.lifecycle.name": "rotation"
}
```

**Step 3:** Apply the lifecycle policy to any existing indexes. Under Elasticsearch Management > Index Management, select one by one each `logstash-*` index, click Manage, and then Apply Lifecycle Policy. Choose the policy you created earlier. If you want to apply the policy in bulk, you'll need to use the [update settings API](https://www.elastic.co/guide/en/elasticsearch/reference/master/set-up-lifecycle-policy.html#apply-policy-multiple) directly.

## Snapshot Lifecycle Management as an alternative to Aptible backups

Aptible [database backups](/core-concepts/managed-databases/managing-databases/database-backups) allow for the easy restoration of a backup to an Aptible database using a single [CLI command](/reference/aptible-cli/cli-commands/cli-backup-restore). However, the data retained with [Snapshot Lifecycle Management](https://www.elastic.co/guide/en/elasticsearch/reference/current/snapshot-lifecycle-management.html) is sufficient to restore the Elasticsearch database in the event of corruption, and you can configure Elasticsearch take much more frequent backups.


# How to set up a self-hosted Elasticsearch Log Drain with Logstash and Kibana (ELK)

This guide will walk you through setting up a self-hosted Elasticsearch - Logstash - Kibana (ELK) stack on Aptible.

## Create an Elasticsearch database

Use the [`aptible db:create`](/reference/aptible-cli/cli-commands/cli-db-create) command to create a new [Elasticsearch](/core-concepts/managed-databases/supported-databases/elasticsearch) Database:

```
aptible db:create "$DB_HANDLE" --type elasticsearch
```

> 📘 Add the `--disk-size X` option to provision a larger-than-default Database.

## Set up a log drain

**Step 1:** In the Aptible dashboard, create a new [log drain](/core-concepts/observability/logs/log-drains/overview):

![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/elk1.png)

**Step 2:** Select Elasticsearch as the destination

![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/elk2.png)

**Step 3:** Save the Log Drain:

![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/elk4.png)

## Set up Kibana

Kibana is an open-source, browser-based analytics and search dashboard for Elasticsearch. Follow our [Running Kibana](/how-to-guides/observability-guides/setup-kibana) guide to deploying Kibana on Aptible.

## Set up Log Rotation

If you let logs accumulate in Elasticsearch, you'll need more and more RAM and disk space to store them. To avoid this, set up log archiving. We recommend archiving logs to S3. Follow the instructions in our [Elasticsearch Log Rotation](/how-to-guides/observability-guides/elasticsearch-log-rotation) guide.


# How to export Activity Reports

Learn how to export Activity Reports

## Overview

[Activity Reports](/how-to-guides/observability-guides/export-activity-reports) provide historical data of all operations in a given environment, including operations executed on resources that were later deleted. These reports are generated on a weekly basis for each environment, and they can be accessed for the duration of the environment's existence.

## Using the Dashboard

Activity Reports can be downloaded in CSV format within the Aptible Dashboard by:

*   Selecting the respective Environment

*   Selecting the **Activity Reports** tab

![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/App_UI_Activity_Reports.png)


# How to set up a self-hosted HTTPS Log Drain



[HTTPS log drains](/core-concepts/observability/logs/log-drains/https-log-drains) enable you to direct logs to HTTPS endpoints. This feature is handy for configuring Logstash and redirecting logs to another location while applying filters or adding additional information. To that end, we provide a sample Logstash app you can deploy on Aptible to do so: [aptible/docker-logstash](https://github.com/aptible/docker-logstash).

Once you've deployed this app, expose it using the [How do I expose my web app on the Internet?](/how-to-guides/app-guides/expose-web-app-to-internet)) guide and then create a new HTTPS log drain to route logs there.


# All Observability Guides

Explore guides for enhancing observability on Aptible

*   [How to access operation logs](/how-to-guides/observability-guides/access-operation-logs)

*   [How to export Activity Reports](/how-to-guides/observability-guides/export-activity-reports)

*   [How to set up Datadog APM](/how-to-guides/observability-guides/setup-datadog-apm)

*   [How to set up application performance monitoring](/how-to-guides/observability-guides/setup-application-performance-monitoring)

*   [How to deploy and use Grafana](/how-to-guides/observability-guides/deploy-use-grafana)

*   [How to set up a self-hosted Elasticsearch Log Drain with Logstash and Kibana (ELK)](/how-to-guides/observability-guides/elk)

*   [How to set up Elasticsearch Log Rotation](/how-to-guides/observability-guides/elasticsearch-log-rotation)

*   [How to set up a Papertrail Log Drain](/how-to-guides/observability-guides/papertrail-log-drain)

*   [How to set up a self-hosted HTTPS Log Drain](/how-to-guides/observability-guides/https-log-drain)

*   [How to set up Kibana on Aptible](/how-to-guides/observability-guides/setup-kibana)


# How to set up a Papertrail Log Drain

Learn how to set up a PaperTrail Log Drain on Aptible

## Set up a Papertrail Logging Destination

**Step 1:** Sign up for a Papertrail account.

**Step 2:** In Papertrail, find the "Log Destinations" tab. Select "Create a Log Destination," then "Create":

![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/papertrail1.png)

![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/papertrail2.png)

![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/papertrail3.png)

**Step 3:** Once created, note the host and port Papertrail displays for your new log destination.

![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/papertrail4.png)

## Set up a Log Drain

**Step 1:** In the Aptible dashboard, create a new [log drain](/core-concepts/observability/logs/log-drains/overview) by navigating to the "Log Drains" tab in the environment of your choice:

![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/papertrail5.png)

**Step 2:** Select Papertrail as the destination.

![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/papertrail6.png)

**Step 3:** Input the host and port you received earlier and save your changes.


# How to set up application performance monitoring

Learn how to set up application performance monitoring

## Overview

To fully utilize our APM solution with Aptible, we suggest integrating an APM tool directly within your app containers. This simple yet effective step will allow for seamless monitoring and optimization of your application's performance.

Most APM tools let you do so through a library that hooks into your app framework or server.

## New Relic

New Relic is a popular solution used by Aptible customers To monitor application's performance to optimize and improve its functionality. To set up New Relic with your Aptible resources, create a New Relic account and follow the [installation instructions for New Relic APM.](https://docs.newrelic.com/introduction-apm/)


# How to set up Datadog APM

Guide for setting up Datadog Application Performance Monitoring (APM) on your Aptible apps

## Overview

Datadog APM (Application Performance Monitoring) can be configured with Aptible to monitor and analyze the performance of Aptible apps and services in real-time.

## Set up

> ⚠️ **Prerequisites:** An Aptible account, the Aptible CLI, Git, and a Datadog account

**Step 1: Enable tracing in your application code**

Follow Datadog’s instructions for running enabling tracing, and preparing the Datadog agent in containers:

*   [All Tracing Guides](https://docs.datadoghq.com/tracing/guide/)
*   [All Tracing Libraries](https://docs.datadoghq.com/tracing/trace_collection/dd_libraries/)
*   [Tutorial - Enabling Tracing for a Java Application and Datadog Agent in Containers](https://docs.datadoghq.com/tracing/guide/tutorial-enable-java-containers/)
*   [Tutorial - Enabling Tracing for a Python Application and Datadog Agent in Containers](https://docs.datadoghq.com/tracing/guide/tutorial-enable-python-containers/)
*   [Tutorial - Enabling Tracing for a Go Application and Datadog Agent in Containers](https://docs.datadoghq.com/tracing/guide/tutorial-enable-go-containers/)

**Step 2: Deploy the Datadog Agent as an Aptible app**

Create an Aptible app to run your Datadog agent in a container, add the necessary configurations, deploy your app, and expose it with an app endpoint.

Notes:

*   You’ll need to update `DD_API_KEY=foo` in the commands below to reference your actual [Datadog API Key](https://docs.datadoghq.com/account_management/api-app-keys/).
*   Datadog requires a value to be set for `DD_HOSTNAME`. The agent doesn't have the necessary access to [detect the hostname](https://docs.datadoghq.com/agent/troubleshooting/hostname_containers/?tab=amazonecsonec2) so it can be set to the value of your choice.
*   These commands reference v7 of the Datadog Agent, the latest version tested on Aptible.

```shell
aptible apps:create datadog-agent
aptible config:set --app datadog-agent DD_API_KEY=foo DD_HOSTNAME=foo
aptible deploy --app datadog-agent --docker-image=datadog/agent:7
aptible endpoints:https:create --app datadog-agent --default-domain cmd
```

**Step 3: Update ENV Variables**

Update the ENV for each of your apps for which you enabled tracing in Step 1, so these apps report their instrumentation data to the Datadog Agent app deployed in Step 2.

Notes:

*   You’ll need to update `DD_TRACE_AGENT_URL=https://app-42.on-aptible.com` to the actual address of the Datadog Agent app endpoint created in Step 2.
*   You’ll need to update `--app yourapp` to your actual app’s handle.
*   Note that we’re configuring the agent to connect over port 443 instead of 8126. This is because in Step 2, we created an HTTPS endpoint for the Datadog Agent app. Aptible manages the TLS certificate and encryption for that endpoint, ensuring encrypted communication between each of your apps and the Datadog Agent.
*   The `DD_TRACE_AGENT_URL` ENV variable works automatically for the Java, Python, Ruby, Node.js, PHP, C++ and .Net tracing [libraries](https://docs.datadoghq.com/tracing/trace_collection/dd_libraries/ruby/#tracer-settings), but for other libraries, you may need to update the library’s configuration code to explicitly reference this ENV variable. Follow [the instructions for your language/framework’s specific tracing library](https://docs.datadoghq.com/tracing/trace_collection/library_config/).

```shell
aptible config:set DD_TRACE_AGENT_URL=https://app-42.on-aptible.com --app yourapp
```


# How to set up Kibana on Aptible



> ❗️ These instructions apply only to Kibana/Elasticsearch versions 7.0 or higher. Earlier versions on Deploy did not make use of Elasaticsearch's native authentication or encryption, so we built our own Kibana App compatible with those versions, which you can find here: [aptible/docker-kibana](https://github.com/aptible/docker-kibana)

Deploying Kibana on Aptible is not materially different from deploying any other prepackaged software. Below we will outline the basic configuration and best practices for deploying [Elastic's official Kibana image](https://hub.docker.com/_/kibana).

## Deploying Kibana

Since Elastic provides prebuilt Docker images for Kibana, you can deploy their image directly using the [`aptible deploy`](/reference/aptible-cli/cli-commands/cli-deploy) command:

```sql
aptible deploy --app $HANDLE --docker-image kibana:7.8.1 \
  RELEASE_HEALTHCHECK_TIMEOUT=300 \
  FORCE_SSL=true \
  ELASTICSEARCH_HOSTS="$URL" \
  ELASTICSEARCH_USERNAME="$USERNAME" \
  ELASTICSEARCH_PASSWORD="$PASSWORD"
```

For the above Elasticsearch settings, refer to the [database credentials](/core-concepts/managed-databases/connecting-databases/database-credentials) of your Elasticsearch Database. You must input the `ELASTICSEARCH_HOSTS` variable in this format:`https://$HOSTNAME:$PORT/`.

> 📘 Specifying a Kibana image requires a specific version number tag. The `latest` tag is not supported. You must specify the same version for Kibana that your Elasticsearch database is running.

You can make additional customizations using environment variables; refer to Elastic's [Kibana environment variable documentation](https://www.elastic.co/guide/en/kibana/current/docker.html#environment-variable-config) for a list of available variables.

## Exposing Kibana

You will need to create an [HTTP(S) endpoint](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/overview) to expose Kibana for access. While Kibana requires authentication, and you should force users to connect via HTTPS, you should also consider using [IP Filtering](/core-concepts/apps/connecting-to-apps/app-endpoints/ip-filtering) to prevent unwanted intrusion attempts.

## Logging in to Kibana

You can connect to Kibana using the username and password provided by your Elasticsearch database's [credentials](/core-concepts/managed-databases/connecting-databases/database-credentials), or any other user credentials with appropriate permissions.

## Scaling Kibana

The [default memory limit](https://www.elastic.co/guide/en/kibana/current/production.html#memory) that Kibana ships with is 1.4 GB, so you should use a 2 GB container size at a minimum to avoid exceeding the memory limit. As an example, at the 1 GB default Container size, it takes 3 minutes before Kibana starts accepting HTTP requests - hence the `RELEASE_HEALTHCHECK_TIMEOUT` [Configuration](/core-concepts/apps/deploying-apps/configuration) variable is set to 5 minutes above.

You should not scale the Kibana App to more than one container. User session information is not shared between containers, and if you scale the service to more than one container, you will get stuck in an authentication loop.


# Advanced Best Practices Guide

Learn how to take your infrastructure to the next level with advanced best practices

# Overview

> 📘 Read our [Best Practices Guide](/how-to-guides/platform-guides/best-practices-guide) before proceeding.

This guide will provide advanced information for users who want to maximize the value and usage of the Aptible platform. With these advanced best practices, you'll be able to deploy your infrastructure with best practices for performance, reliability, developer efficiency, and security.

## Planning

### Authentication

*   Set up [SSO](/core-concepts/security-compliance/authentication/sso).
    *   Using an SSO provider can help enforce login policies, including password rotation, MFA requirements, and improve users' ability to audit and verify access is revoked upon workforce changes.

### Disaster Recovery

*   Plan for Regional failure using our [Business Continuity guide](/how-to-guides/platform-guides/minimize-downtown-outages)
    *   While unprecedented, an AWS Regional failure will test the preparedness of any team. If the Recovery time objective and recovery point objective set by users are intended to cover a regional disaster, Aptible recommends creating a dedicated stack in a separate region as a baseline ahead of a potential regional failure.

### CI/CD Strategy

*   Align the release process across staging and production
    *   To minimize issues experienced in production, users should repeat the established working process for releasing a staging environment. This not only gives users confidence when deploying to production but should also allow users to reproduce any issues that arise in production within the staging environment. Follow [these steps](/how-to-guides/app-guides/integrate-aptible-with-ci/overview) to integrate Aptible with a CI Platform.
*   Use a build artifact for deployment.
    *   Using [image-based deployment](/how-to-guides/app-guides/migrate-dockerfile-to-direct-image-deploy) allows users to ensure the exact image that passed the testing process is deployed to production, and users may retain that exact image for any future needs. Docker provides users the ability to [tag images](https://docs.docker.com/engine/reference/commandline/tag/), which allows images to be uniquely identified and reused when needed.   Each git-based deployment introduces a chance that the resulting image may differ. If code passes internal testing and is deployed to staging one week and then production the next, the image build process may have a different result even if dependencies are pinned. The worst case scenario may be that users need to roll back to a prior version, but due to external circumstances that image can no longer be built.

## Operational Practices

### Apps

*   Avoid using git-companion repositories.
    *   Git companion repositories were introduced as a stopgap between git-based and image-based deployments and are considered deprecated. Having a git repository associated with an app that is deployed via an image can be very confusing to manage, so Aptible recommends against using git companion repositories. There is now an easier way to provide Procfiles and .aptible.yml when using Direct Docker Image Deploy. In practice, this means users should no longer need to use a companion git repository. For more information, [review this outline of](/core-concepts/apps/deploying-apps/image/deploying-with-docker-image/procfile-aptible-yml-direct-docker-deploy) using Procfiles and .aptible.yml with Direct Docker Image Deploy.
*   Ensure your migrations backwards compatible
    *   For services with HTTP(S) Endpoint, Aptible employs a zero downtime strategy whereby for a brief period, both new and old containers are running simultaneously. While the migrations in `before_release` are run before the new containers are added to the load balancing pool, this does mean any migrations not compatible with the old running code may result in noticeable errors or downtime during deployment. It is important that migrations are backwards compatible to avoid these errors. More on the release process [here](/core-concepts/apps/deploying-apps/releases/overview#services-with-endpoints).
*   Configure processes to run as PID 1 to handle signals properly
    *   Since Docker is essentially a process manager, it is important to properly configure Containers to handle signals. Docker (and by extension all Aptible platform features) will send signals to PID 1 in the container to instruct it to stop. If PID 1 is not in the process, or the process doesn't respond to SIGTERM well, users may notice undesirable effects when restarting, scaling, deploying your Apps, or when the container exceeds the memory limits. More on PID 1 [here](/how-to-guides/app-guides/define-services#advanced-pid-1-in-your-container-is-a-shell).
*   Use `exec` in the Procfile
    *   When users specify a Procfile, but do not have an ENTRYPOINT, the [commands are interpreted by a shell](/how-to-guides/app-guides/define-services#procfile-commands). Use `exec` to ensure the process assumes PID 1. More on PID 1 and `exec` [here](/how-to-guides/app-guides/define-services#advanced-pid-1-in-your-container-is-a-shell).

### Services

*   Use the APTIBLE\_CONTAINER\_SIZE variable where appropriate
    *   Some types of processes, particularly Java applications, require setting the size of a memory heap.  Users can use the environment variable set by Aptible to ensure the process knows what the container size is.  This helps avoid over-allocating memory and ensures users can quickly scale the application without having to set the memory amount manually in your App. Learn more about this variable [here](/core-concepts/scaling/memory-limits#how-do-i-know-the-memory-limit-for-a-container).
*   Host static assets externally and use consistent naming conventions
    *   There are two cases where the naming and or storage of static assets may cause issues:
        1.  If each container generates static assets within itself when it starts, randomly assigned static assets will cause errors for services scaled to >1 container
        2.  If assets are stored in the container image (as opposed to S3, for example), users may have issues during zero-downtime deployments where requests for static assets fail due to two incompatible code-bases running at the same time.
    *   Learn more about serving static assets in [this tutorial](/how-to-guides/app-guides/serve-static-assets)

### Databases

*   Upgrade all Database volumes to GP3
    *   Newly provisioned databases are automatically provisioned on GP3 volumes. The GP3 volume type provides a higher baseline of IO performance but, more importantly, allows ONLINE scaling of IOPs and throughput, so users can alleviate capacity issues without restarting the database. Users can upgrade existing databases with zero downtime using these [steps](https://www.aptible.com/changelog#content/changelog/easily-modify-databases-without-disruption-with-new-cli-command-aptible-db-modify.mdx). The volume type of existing databases can be confirmed at the top of each database page in the Aptible dashboard.

### Endpoints

*   Use strict runtime health checks
    *   By default, Aptible health checks only ensure a service is returning responses to HTTP requests, not that those requests are free of errors. By enabling strict health checks, Aptible will only route requests to containers if those containers return a 200 response to `/healthcheck`. Enabling strict health checks also allows users to configure the route Aptible checks to return healthy/unhealthy using the criteria established by the user. Enable strict runtime health checks using the steps [here](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/health-checks#strict-health-checks).

### Dependency Vulnerability Scanning

*   Use an image dependency vulnerability scanner before deploying to production.
    *   The built-in security scanner is designed for git-based deployments, where Aptible builds the image and users have no method to inspect it directly. It can only be inspected after being deployed. Aptible recommends scanning images before deploying to production. Using image-based deployment will be the easiest way to scan an image and integrate the scans into the CI/CD pipeline. Quay and ECS can scan images automatically and support alerting. Otherwise, users will need to scan the deployed staging image before deploying that commit to production.


# Best Practices Guide

Learn how to deploy your infrastructure with best practices for setting up your Aptible account

## Overview

This guide will provide all the essential information you need to confidently make key setup decisions for your Aptible platform. With our best practices, you'll be able to deploy your infrastructure with best practices for performance, reliability, and security.

## Resource Planning

### Stacks

An [Aptible Stack](/core-concepts/architecture/stacks) is the underlying virtualized infrastructure (EC2 instances, private network, etc.) on which resources (Apps, Databases) are deployed. Consider the following when planning and creating stacks:

*   Establish Network Boundaries

    *   Stacks provide network-level isolation of resources and are therefore used to protect production resources. Environments or apps used for staging, testing or other purposes that may be configured with less stringent security controls may have direct access to production resources if they are deployed in the same stack. There are also issues other than CPU/Memory limits, such as open file limits on the host, where it's possible for a misbehaving testing container to affect production resources. To prevent these scenarios, it is recommended to use stacks as network boundaries.
*   Use IP Filtering with [Stack IP addresses](/core-concepts/apps/connecting-to-apps/outbound-ips)

    *   Partners or vendors that use IP filtering may require users to provide them with the outbound IP addresses of the apps they interact with. There are instances where Aptible may need to fail over to other IP addresses to maintain outbound internet connectivity on a stack. It is important to add all Stack IP Addresses to the IP filter lists.

### Environments

[Environments](/core-concepts/architecture/environments) are used for access control, to control backup policy and to provide logical isolation.  Remember network isolation is established at the Stack level; Environments on the same Stack can talk to each other.  Environments are used to group resources by logging, retention, and access control needs as detailed below:

*   Group resources based on least-access principle

    *   Aptible uses Environments and Roles to [manage user access](/core-concepts/security-compliance/access-permissions).  Frequently, teams or employees do not require access to all resources.  It is good practice to identify the least access required for users or groups, and restrict access to that minimum set of permissions.

*   Group Databases based on backup retention needs

    *   Backup needs for databases can vary greatly. For example, backups for Redis databases used entirely as an in-memory cache or transient queue, or replica databases used by BI tools are not critical, or even useful, for disaster recovery. These types of databases can be moved to other Environments with a shorter backup retention configured, or without cross-region copies. More on Database Retention and Disposal [here](/core-concepts/managed-databases/managing-databases/database-backups#retention-and-disposal).

*   Group resources based on logging needs

    *   [Logs](/core-concepts/observability/logs/overview) are delivered separately for each environment. When users have access and retention needs that are specific to different classes of resources (staging versus production), using separate environments is an excellent way to deliver logs to different destinations or to uniquely tag logs.

*   Configure [Log Drains](/core-concepts/observability/logs/log-drains/overview) for all environments

    *   Reviewing the output of a process is a very important troubleshooting step when issues arise. Log Drains provide the output, and more: users can collect the request logs as recorded at the Endpoint, and may also capture Aptible SSH sessions to audit commands run in Ephemeral Containers.

*   Configure [Metric Drains](/core-concepts/observability/metrics/metrics-drains/overview) for all environments

*   Monitoring resource usage is a key step to detect issues as early as possible. While it is imperative to set up metric drains in production environments, there is also value in setting up metric drains for staging environments.

## Operational Practices

### Services

[Services](/core-concepts/apps/deploying-apps/services) are metadata that define how many Containers Aptible will start for an App, what Container Command they will run, their Memory Limits, and their CPU Limits. Here are some considerations to keep in mind when working with services:

*   [Scale services](/core-concepts/scaling/overview) horizontally where possible

*   Aptible recommends horizontally scaling all services to multiple containers to ensure high-availability. This will allow the app's services to handle container failures gracefully by routing traffic to healthy containers while the failed container is restarted. Horizontal scaling also ensures continued effectiveness in the case that performance needs to be scaled up. Aptible also recommend following this practice for at least one non-production environment because this will allow users to identify any issues with horizontal scaling (reliance on local session storage for example) in staging, rather than in production.

*   Avoid unnecessary tasks, commands and scripts in the ENTRYPOINT, CMD or [Procfile](/how-to-guides/app-guides/define-services).

    *   Aptible recommends users ensure containers do nothing but start the desired process such as the web server for example.  If the container downloads, installs or configures any software before running the desired process, this introduces both a chance for failure and a delay in starting the desired process.  These commands will run every time the container starts, including if the container restarts unexpectedly. Therefore, Aptible recommends ensuring the container starts serving requests immediately upon startup to limit the impact of such restarts.

### Endpoints

[Endpoints](/core-concepts/apps/connecting-to-apps/app-endpoints/overview) let users expose Apps on Aptible to clients over the public internet or the Stack's internal network. Here are some considerations to keep in mind when setting up endpoints:

*   TLS version

    *   Use the `SSL_PROTOCOLS_OVERRIDE` [setting](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/https-protocols#ssl_protocols_override-control-ssl--tls-protocols) to set the desired acceptable TLS version. While TLS 1.0 and 1.1 can provide great backward compatibility, it is standard practice to allow only `TLSv1.2`, and even `TLSv1.2 PFS` to pass many security scans.
*   SSL

    *   Take advantage of the `FORCE_SSL` [setting](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/https-redirect#force_ssl-in-detail). Aptible can handle HTTP->HTTPS redirects on behalf of the app, ensuring all clients connect securely without having to enable or write such a feature into each service.

### Dependency Vulnerability Scanning

*   Use an image dependency vulnerability scanner before deploying to production.

    *   The built-in security scanner is designed for git-based deployments (Dockerfile Deploy), where Aptible builds the image and users have no method to inspect it directly. It can only be inspected after being deployed. Aptible recommends that users scan images before deploying to production. Using image-based deployment (Direct Docker Image Deploy) will be the easiest way to scan images and integrate the scans into the CI/CD pipeline. Quay and ECS can scan images automatically and support alerting. Otherwise, users will want to scan the deployed staging image before deploying that commit to production.

### Databases

*   Create and use [least-privilege-required users](/core-concepts/managed-databases/connecting-databases/database-endpoints#least-privileged-access) on databases

    *   While using the built-in `aptible` user may be convenient, for Databases which support it (MySQL, PostgreSQL, Mongo, ES 7), Aptible recommends creating a separate user that is granted only the permissions required by the application. This has two primary benefits:

        1.  Limit the impact of security vulnerabilities because applications are not granted more permissions than they need

        2.  If the need to remediate a credential leak arises, or if a user's security policy dictates that the user rotate credentials periodically, the only way to rotate database credentials without any downtime is to create separate database users and update apps to use the newly created user's credentials.  Rotating the `aptible` user credential requires notifying Aptible Support to update the API to avoid breaking functionality such as replication and Database Tunnels and any Apps using the credentials will lose access to the Database.

## Monitoring

*   Set up monitoring for common errors:

    *   The "container exceeded memory allocation" is logged when a container exceeds its RAM allocation. While the metrics in the Dashboard are captured every minute, if a Container exceeds its RAM allocation very quickly and is then restarted, the metrics in the Dashboard may not reflect the usage spike. Aptible recommends referring to logs as the authoritative source of information to know when a container exceeds [the memory allocation](/core-concepts/scaling/memory-limits#memory-management).

    *   [Endpoint errors](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/endpoint-logs#common-errors) occur when an app does not respond to a request. The existence and frequency of these errors are key indicators of issues affecting end users. Aptible recommends setting up alerts when runtime health check requests are failing as this will notify users when a portion of the containers are impacted, rather than waiting for all containers to fail before noticing an issue.

*   Set up monitoring for database disk capacity and IOPS.

    *   While disk capacity issues almost always cause obviously fatal issues, IOPS capacity exhaustion can also be incredibly impactful on application performance. Aptible recommends setting up alerts when users see sustained IOPS consumption near the limit for the disk. This will allow users to skip right from fielding "the application is slow" complaints right to identifying the root cause.

*   Set up [application performance monitoring (APM)](/how-to-guides/observability-guides/setup-application-performance-monitoring) for applications.

    *   Tools like New Relic or Datadog's APM can give users with great insights into how well (or poorly) specific portions of an application are performing - both from an end user's perspective, and from a per-function perspective. Since they run in the codebase, these tools are often able to shed light for users on what specifically is wrong much more accurately than combing through logs or container metrics.

*   Set up external availability monitoring.

    *   The ultimate check of the availability of an application comes not from monitoring the individual pieces, but the system as a whole. Services like [Pingdom](https://www.pingdom.com/) can monitor uptime of an application, including discovering problems with services like DNS configuration, which fall outside of the scope of the Aptible platform.


# How to cancel my Aptible Account

To cancel your Deploy account and avoid any future charges, please follow these steps in order:

1.  Export any [database](/core-concepts/managed-databases/overview) data that you need.
    *   To export Aptible backups, [restore the backup](/core-concepts/managed-databases/managing-databases/database-backups#restoring-from-a-backup) to a new database first.
    *   Use the [`aptible db:tunnel` CLI command](/reference/aptible-cli/cli-commands/cli-db-tunnel) and whichever tool your database supports to dump the database to your computer.
2.  Delete [metric drains](/core-concepts/observability/metrics/metrics-drains/overview)
    *   [Metric drains](/core-concepts/observability/metrics/metrics-drains/overview) for an [environment](/core-concepts/architecture/environments) can be deleted by navigating to the environment's **Metric Drains** tab in the dashboard.
3.  Deprovision your [apps](/core-concepts/apps/overview) from the dashboard or with the [`aptible apps:deprovision`](/reference/aptible-cli/cli-commands/cli-apps-deprovision) CLI command.
    *   Deprovisioning an [app](/core-concepts/apps/overview) automatically deprovisions all of its [endpoints](/core-concepts/apps/connecting-to-apps/app-endpoints/overview) as well.
4.  Deprovision your [databases](/core-concepts/managed-databases/overview) from the dashboard or with the [`aptible db:deprovision`](/reference/aptible-cli/cli-commands/cli-db-deprovision) CLI command.
    *   Monthly and daily backups are automatically deleted when the [database](/core-concepts/managed-databases/overview) is deprovisioned.
5.  Delete [database backups](/core-concepts/managed-databases/managing-databases/database-backups)
    *   Use the **delete all on page** option to delete the final backups for your [databases](/core-concepts/managed-databases/overview).

        ❗️ Please note Aptible will no longer have a copy of your data when you delete your backups. Please create your own backup if you need to retain a copy of the data.
6.  Delete [log drains](/core-concepts/observability/logs/log-drains/overview)
    *   Log drains for an [environment](/core-concepts/architecture/environments) can be deleted by navigating to the environment's **Log Drains** tab in the dashboard.
7.  Deprovision the [environment](/core-concepts/architecture/environments) from the dashboard.
    *   You can deprovision environments once all the resources in that [environment](/core-concepts/architecture/environments) have been deprovisioned. If you have not deleted all resources, you will see a message advising you to delete any remaining resources before you can successfully deprovision the [environment](/core-concepts/architecture/environments).
8.  Submit a [support](/how-to-guides/troubleshooting/aptible-support) request to deprovision your [Dedicated Stack](/core-concepts/architecture/stacks#dedicated-stacks) and, if applicable, remove Premium or Enterprise Support.
    *   If this step is incomplete, you will incur charges until Aptible deprovisions the dedicated stack and removes paid support from your account. Aptible Support can only complete this step after your team submits a request.

> ❗️Please note you will likely receive one more invoice after deprovisioning for usage from the last invoice to the time of deprovisioning.


# How to create and deprovison dedicated stacks

Learn how to create and deprovision dedicated stacks

## Overview

[Dedicated stacks](/core-concepts/architecture/stacks#dedicated-stacks) automatically come with a [suite of security features](https://www.aptible.com/secured-by-aptible), high availability, regulatory practices (HIPAA BAAs), and advanced connectivity options, such as VPN and VPC Peering.

## Creating Dedicated Stacks

Dedicated can only be provisioned by [Aptible Support.](/how-to-guides/troubleshooting/aptible-support) You can request a dedicated stack from the Aptible Dashboard by:

*   Navigating to the **Stacks** page

*   Selecting **New Dedicated Stack**![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/deprovision-stack1.png)

*   Filling out the Request Dedicated Stack form![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/deprovision-stack2.png)

## Deprovisoning Stacks

<Info> A dedicated stack can only successfully be deprovisioned once all of the environments and their respective resources have been deprovisioned. See related guide: [How to deprovision each type of resource](/how-to-guides/platform-guides/delete-environment)</Info>

[Stacks](/core-concepts/architecture/stacks) can only be deprovisioned by contacting [Aptible Support.](/how-to-guides/troubleshooting/aptible-support) 


# How to create environments



Learn how to create an [environment](/core-concepts/architecture/environments)

## Using the Dashboard

Within the Aptible Dashboard, you can create an environment one of two ways:

*   Using the **Deploy** tool ![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/create-environment1.png)

*   From the **Environments** page by selecting **Create Environment**![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/create-environment2.png)


# How to delete environments



Learn how to delete/deprovision [environments](/core-concepts/architecture/environments)

## Using the Dashboard

> ⚠️ Ensure you understand the impact of deprovisioning each resource type and make any necessary preparations, such as exporting Database data, before proceeding

An environment can only be deprovisioned from the Dashboard by:

*   Navigating to the given environment

*   Selecting the **Settings** tab

*   Selecting **Deprovision Environment**![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/delete-environment1.png)

> 📘 An environment can only successfully be deprovisioned once all of the resources within that Environment have been deprovisioned. The following guide describes how to deprovision each type of resource.


# How to deprovision resources



First, review the [resource-specific restoration options](/how-to-guides/platform-guides/restore-resources) to understand the impact of deprovisioning each type of resource and make any necessary preparations, such as exporting Database data, before proceeding.

## Apps

Deprovisioning an App also deprovisions its [Endpoints](/core-concepts/apps/connecting-to-apps/app-endpoints/overview). [Apps](/core-concepts/apps/overview) can be deprovisioned using the [`aptible apps:deprovision`](/reference/aptible-cli/cli-commands/cli-apps-deprovision) CLI command or through the Dashboard:

*   Select the App

*   Select the **Deprovision** tab

*   Follow the prompt

## Database Backups

Automated [Backups](/core-concepts/managed-databases/managing-databases/database-backups) are deleted per the Environment's [backup retention policy](/core-concepts/managed-databases/managing-databases/database-backups#retention-and-disposal) when the Database is deprovisioned. Manual backups, created using the [`aptible db:backup`](/reference/aptible-cli/cli-commands/cli-db-backup) CLI command, must be deleted using the [`aptible backup:purge`](/reference/aptible-cli/cli-commands/cli-backup-purge) CLI command or through the Dashboard:

*   Select the **Backup Management** tab within the desired Environment.

*   Select "**Permanently remove this backup**" for backups marked as Manual.

## Databases

[Databases](/core-concepts/managed-databases/managing-databases/overview) can be deprovisioned using the [`aptible db:deprovision`](/reference/aptible-cli/cli-commands/cli-db-deprovision) CLI command or through the Dashboard:

*   Select the desired Database.

*   Select the **Deprovision** tab.

*   Follow the prompt.

## Log and Metric Drains

Delete Log and Metric Drains in the Dashboard:

*   Select the Log Drains or Metric Drains tabs within each Environment.

*   Select **Delete** on the top right of each drain.

## Environments

[Environments](/core-concepts/architecture/environments) can only be deprovisioned after all of the resources in the Environment have been deprovisioned. Environments can only be deprovisioned through the Dashboard:

*   Select the **Deprovision** tab within the Environment.

*   Follow the prompt.


# How to handle vulnerabilities found in security scans



[Security Scans](/core-concepts/security-compliance/security-scans) look for vulnerable OS packages installed in your Docker images by your Operating System’s package manager, so the solutions suggested below highlight the various ways you can manipulate these packages to mitigate the vulnerabilities.

## Mitigate by updating packages

## Rebuild your image

Since any found vulnerabilities were installed by the OS Package manager, we recommend first that you try the simplest approach possible and update all the packages in your Image. Rebuilding your image will often solve any vulnerabilities marked “Fix available”, as these are vulnerabilities for which the scanner has identified a newer version this package is available which remediates this vulnerability.

If you deploying via Git, you can use the command `aptible rebuild` to rebuild and deploy the new image:

```sql
aptible rebuild --app $HANDLE
```

If you are deploying via Docker Image, you will need to follow your established process to build, publish, and deploy the new image.

## Packages included in your parent image

The broadest thing you can try, assuming it does not introduce any compatibility issues for your application, is to update the parent image of your App: this is the one specified as the first line in your Dockerfile, for example:

```sql
FROM debian:8.2
```

Debian version 8.2 is no longer the latest revision of Debian 8, and may not have a specific newer package version available. You could update to `FROM debian:8.11` to get the latest version of this image, which may have upgraded packages in it, but by the time you read this FAQ there will be a newer still version available. So, you should prefer to use `FROM debian:8`, which is maintained to always be the latest Debian 8 image, as documented on the Docker Hub. This version tagging pattern is common on many images, so check the documentation of your parent image in order to choose the appropriate tag.

Finally, the vulnerability details might indicate a newer OS, eg Debian 10, includes a version with the vulnerability remediated. This change may be more impactful than those suggested above, given the types of changes that may occur between major versions of an operating system.

## Packages explicitly installed in your Dockerfile

You might also find that you have pinned a specific version of a package in your Dockerfile, either for compatibility or to prevent a regression of another vulnerability. For example:

```ruby
FROM debian: 8

RUN apt - get update &&\
apt - get - y install exim4 = 4.84.2 - 2 + deb8u5 exim4 - base=4.84.2 - 2 + deb8u5 &&\
rm - rf /var/lib/apt / lists/*
```

There exists a vulnerability (CVE-2020-1283) that is fixed in the newer `4.84.2-2+deb8u7` release of `exim4` . So, you would either want to test the newer version and specify it explicitly in your Dockerfile, or simply remove the explicit request for a particular version to be sure that exim4 is always kept up to date.

## Packages implicitly installed in your Dockerfile

Some packages will appear in the vulnerability scan that you don’t immediately recognize a reason they are installed. It is possible those are installed as a dependency of another package, and most package managers include tools for looking up reverse dependencies which you can use to determine which package(s) require the vulnerable package. For example, on Debian, you can use `apt-cache rdepends --installed $PACKAGE` .

## Mitigate by Removing Packages

If the scan lists a vulnerability in a package you do not require, you can simply remove it.

First, we suggest, as a best practice, to identify any packages that you have installed as a build-time dependency and remove them at the end of your Dockerfile when building is complete.

In your Dockerfile, you can track which packages are installed as a build dependency and simply uninstall them when you have completed that task:

```ruby
FROM debian:8

# Declare your build-time dependencies
ENV DEPS "make build-essential python-pip python-dev"

# Install them
RUN apt-get update &&\
    apt-get -y install ${DEPS}= &&\
    rm -rf /var/lib/apt/lists/*

# Build your application
RUN make build

# Remove the build dependencies now that you no longer need them
RUN apt-get -y --autoremove ${DEPS}
```

The above would potentially mitigate a vulnerability identified in `libmpc3`, which you only need as a dependency of `build-essential`. You would still need to determine if the vulnerability discovered affected your app through the use of `libmpc3`, even if you have later uninstalled it.

Finally, many parent images will include many unnecessary packages by default. Try the `-slim` tag to get an image with less software installed by default, for example, `python:3` contains a large number of packages that `python:3-slim` does not. Not all images have this option, and you will likely have to add specific dependencies back in your Dockerfile to keep your App working, but this can greatly reduce the surface area for vulnerability by reducing the number of installed packages.

## What next?

If there are no fixes available, and you can’t remove the package, you will need to analyze the vulnerability itself.

Does the package you have installed actually include the vulnerability? If the CVE information lists “not-affected” or “DNE” for your specific OS, there is likely no issue. For example, Ubuntu back ports security fixes in OpenSSL yet maintains a 1.0.x version number. This means a vulnerability that says it affects “OpenSSL versions before 1.1.0” does not automatically mean the `1.0.2g-1ubuntu4.6` version you likely have installed is actually vulnerable.

Does the vulnerability actually impact your use of the package? The vulnerability may be present in a function you do not use or in a service, your image is not actually running.

Is the vulnerability otherwise mitigated by your security posture? Many vulnerabilities can be remediated with simple steps like sanitizing input to your application or by not running or exposing unnecessary services.

If you’ve reached this point and the scanner has helped you identify a real vulnerability in your application, it’s time to decide on another mitigation strategy!


# How to achieve HIPAA compliance on Aptible

Learn how to achieve HIPAA compliance on Aptible, the leading platform for hosting HIPAA-compliant apps & databases

## Overview

[Aptible's story](/getting-started/introduction#our-story) began with a focus on serving digital health companies. As a result, the Aptible platform was designed with HIPAA compliance in mind. It automates and enforces all the necessary infrastructure security and compliance controls, ensuring the safe storage and processing of HIPAA-protected health information and more.

This guide will cover the essential steps for achieving HIPAA compliance on Aptible.

## HIPAA-Compliant Production Checklist

> Prerequisites: An Aptible account on Production or Enterprise plan.

1.  **Provision a dedicated stack**

    1.  [Dedicated stacks](/core-concepts/architecture/stacks#dedicated-stacks) live on isolated infrastructure and are designed to support deploying resources with higher requirements— such as HIPAA. Aptible automates and enforces **100%** of the necessary infrastructure security and compliance controls for HIPAA compliance. This includes but is not limited to:

        1.  Network Segregation (see: [stacks](/core-concepts/architecture/stacks#dedicated-stacks))

        2.  Platform Activity Logging (see: [activity](/core-concepts/observability/activity))

        3.  Automated Backups & Automated Backup Testing (see: [database backups](/core-concepts/managed-databases/managing-databases/database-backups))

        4.  Database Encryption at Rest (see: [database encryption](/core-concepts/managed-databases/managing-databases/database-encryption/overview))

        5.  End-to-end Encryption in Transit (see: [database encryption](/core-concepts/managed-databases/managing-databases/database-encryption/overview))

        6.  DDoS Protection (see: [DDoS Protection](/core-concepts/security-compliance/ddos-pid-limits))

        7.  Automatic Container Recovery (see: [container recovery](/core-concepts/architecture/containers/container-recovery))

        8.  Intrusion Detection (see: [HIDS](/core-concepts/security-compliance/hids))

        9.  Host Hardening

        10. Secure Infrastructure Access, Development, and Testing Practices

        11. 24/7 Site Reliability and Incident Response

        12. Infrastructure Penetration Tested
2.  **Execute a BAA with Aptible**

    1.  When you request your first dedicated stack, an Aptible team member will reach out to coordinate the execution of a Business Associate Agreement (BAA).

**After these steps are taken, you are ready to process PHI! 🎉**

Here are some optional steps you can take:

1.  Review your [Security & Compliance Dashboard](/core-concepts/security-compliance/security-compliance-dashboard)

    1.  Review the controls implemented for you, enhance your security posture by implementing additional controls, and share a detailed report with your customers.

2.  Show off your compliance with a Secured by Aptible HIPAA compliance badge![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/hipaa1.png)

3.  Set up log retention

    1.  Set up long-term log retention with the use of a [log drain](/core-concepts/observability/logs/log-drains/overview). All Aptible log drain integrations offer BAAs.

***

This document serves as a guide and does not replace professional legal advice. For detailed compliance questions, it is recommended to consult with legal experts or Aptible's support team.


# MedStack to Aptible Migration Guide

Learn how to migrate resources from MedStack to Aptible

# Overview

[Aptible](https://www.aptible.com/) is a PaaS (Platform as a Service) that provides developers with managed infrastructure and everything that they need to launch and scale apps that are secure, reliable, and compliant — with no need to manage infrastructure.

This guide will cover the differences between MedStack Control and Aptible and suggestions for how to migrate applications and resources.

# PaaS concepts

### Environment separation

In MedStack, environment separation is done using Clusters. In Aptible, data can be isolated using [Stacks](https://www.aptible.com/docs/core-concepts/architecture/stacks#stacks) and [Environments](https://www.aptible.com/docs/core-concepts/architecture/environments).

**Stacks**: A Stack in Aptible is most closely equivalent to a Cluster in MedStack. A Stack is an isolated network that contains the infrastructure required to run apps and databases on Aptible. A Shared Stack is a stack suitable for non-production workloads that do not contain PHI.

**Environments**: An Environment is a logical separation of resources. It can be used to group resources used in different stages of development (e.g., staging vs. prod) or to apply role-based permissions.

### Orchestration

In MedStack, orchestration is done via Docker Swarm. Aptible uses a built-in orchestration model that requires less management — you specify the size and number of containers to use for your application, and Aptible manages the allocation to underlying infrastructure nodes automatically. This means that you don’t have direct access to Nodes or resource pinning, but you don’t have to manage your resources in a way that requires access.

### Applications

In Aptible, you can **set up** applications via Git-based deploys where we build your Docker image based on your provided Dockerfile, or based on your pre-built Docker image, and define service name and command in a Procfile as needed. Configurations can be set in the UI or through the CLI.

To **deploy** the application, you can use `aptible deploy` or you can set up CI/CD for automated deployments from a repository.

To **scale** an application, you can use manual horizontal scaling (number of containers) and vertical scaling (size and profile of container). We also offer vertical and horizontal autoscaling, both available in beta.

### Databases and storage

MedStack is built on top of Azure. Aptible is built on top of AWS.

Our **managed database** offerings include support for PostgreSQL and MySQL, as well as other databases such as Redis, MongoDB, and [more](https://www.aptible.com/docs/core-concepts/managed-databases/overview). If you currently host any of the latter as database containers, you can host them as managed databases in Aptible.

Aptible doesn’t yet support **object storage**; for that, we recommend maintaining your storage in Azure and setting up connections from your hosted application in Aptible. For support for persistent volumes, please reach out to us.

### Downtime mitigation

Aptible’s [release process](https://www.aptible.com/docs/core-concepts/apps/deploying-apps/releases/overview#lifecycle) minimizes downtime while optimizing for container health. The platform runs [container health checks](https://www.aptible.com/docs/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/health-checks#health-check-lifecycle) during deployment and throughout the lifetime of the container.

### Metrics and logs

Aptible provides container [metrics](https://www.aptible.com/docs/core-concepts/observability/metrics/overview) and [logs](https://www.aptible.com/docs/core-concepts/observability/logs/overview) as part of the platform. You can view these within the Aptible UI, or you can set up [metrics](https://www.aptible.com/docs/core-concepts/observability/metrics/metrics-drains/overview) and [logs drains](https://www.aptible.com/docs/core-concepts/observability/logs/log-drains/overview) to your preferred destination.

# Compliance

**Compliance frameworks**: Aptible’s platform is designed to help businesses meet strict data privacy and security requirements. We offer built-in guardrails and infrastructure security controls that comply with the requirements of compliance frameworks such as HIPAA, HITRUST, PIPEDA, and [more](https://trust.aptible.com/). Compliance is built into how Aptible manages infrastructure, so no additional work is required to ensure that your application is compliant.

**Audit support**: We offer a [Security & Compliance dashboard](https://www.aptible.com/docs/core-concepts/security-compliance/security-compliance-dashboard/overview) that covers documentation and proof of infrastructure controls in the case of an audit.

**Security questionnaires**: In general, we don’t fill out security questionnaires on behalf of our customers. The Security & Compliance dashboard can be used as a resource to answer questionnaires. Our support team is available to answer specific one-off questions when needed.

# Pricing

MedStack’s pricing is primarily based on a platform fee with added pass-through infrastructure costs. Aptible’s pricing model differs slightly. Plan costs are mainly based on infrastructure usage, with a small platform fee for some plans.

Most companies will want to leverage our Production plan, which starts with a \$499/mo base fee and additional unit-based costs for resources.

For more details, see our [pricing page](https://www.aptible.com/pricing).

During the migration period, we will provide an extended free trial to allow you to leverage the necessary capabilities to try out and validate a migration of your services.

# Migrating a MedStack service to Aptible

This section walks through how to replicate and test your service on Aptible, prepare your database migration, and plan and execute a production migration plan.

### Create an Aptible account

*   Create an Aptible account ([https://app.aptible.com/signup](https://app.aptible.com/signup)). Use a company email so that you automatically qualify for a free trial.
*   Message Aptible support at [support@aptible.com](mailto:support@aptible.com) to let us know that you’re a MedStack customer and have created a trial account, and we will remove some customary resource limits from the free trial so that you can make a full deployment, validate for functionality, and estimate your pricing on Aptible.

### Replicate a MedStack staging service on Aptible

*   [Create an Environment](https://www.aptible.com/docs/how-to-guides/platform-guides/create-environment#how-to-create-environments) in one of the available Stacks in your account
*   Create required App(s): an Aptible App may contain one or more services that utilize the same Docker image
    *   An App with multiple services can be defined using the [Procfile](https://www.aptible.com/docs/how-to-guides/app-guides/define-services#step-01-providing-a-procfile) standard
        *   The Procfile file should be placed at **`/.aptible/Procfile`** in your pre-built Docker image
*   Add any pre or post-release commands to [.aptible.yml](https://www.aptible.com/docs/core-concepts/apps/deploying-apps/releases/aptible-yml):
    *   `before_release` is a common place to put commands like database migration tasks
    *   .aptible.yml should be placed in **`/.aptible/.aptible.yml`** in your pre-built Docker image
*   Set up config variables
    *   Aptible makes use of environment variables to configure your apps. These settings can be modified via the [Aptible CLI](https://www.aptible.com/docs/reference/aptible-cli/cli-commands/cli-config-set) via `aptible config:set` or via the Configuration tab of your App in the web dashboard
*   Add credentials for your Docker registry source
    *   Docker credentials can be [provided via the command line](https://www.aptible.com/docs/core-concepts/apps/deploying-apps/image/deploying-with-docker-image/overview#private-registry-authentication) as arguments with the `aptible deploy` command
    *   They can also be provided as secrets in your CI/CD workflow ([Github Actions Example](https://www.aptible.com/docs/how-to-guides/app-guides/how-to-deploy-aptible-ci-cd#deploying-with-docker))

### Deploy and validate your staging application

*   Deploy your application using:
    *   [`aptible deploy`](https://www.aptible.com/docs/reference/aptible-cli/cli-commands/cli-deploy#aptible-deploy) for Direct Docker Deployment using the Aptible CLI
    *   Github Actions ([example](https://www.aptible.com/docs/how-to-guides/app-guides/how-to-deploy-aptible-ci-cd#deploying-with-docker))
    *   Or, via git push if you are having us build your Docker Image by providing a Dockerfile in your git repo
*   Add Endpoint(s)
    *   An [Aptible Endpoint](https://www.aptible.com/docs/core-concepts/apps/connecting-to-apps/app-endpoints/overview) provides load balancer functionality for your App’s services.
    *   We support a [“default domain” endpoint](https://www.aptible.com/docs/core-concepts/apps/connecting-to-apps/app-endpoints/default-domain) where you can have an [on-aptible.com](http://on-aptible.com) domain used for your test services without configuring a custom domain.
    *   You can also configure [custom domain Endpoints](https://www.aptible.com/docs/core-concepts/apps/connecting-to-apps/app-endpoints/custom-domain#custom-domain), for which we can automatically provision certificates, or you can bring your own custom SSL certificates.
*   Validate your App(s)

### Prepare your database migration

*   Test the migration of your database to Aptible
    *   This can be done via dump and restore methods:
        *   PostgreSQL: using pg\_dump
        ```ruby
        pg_dump -h [source_host] -p [source_port] -U [source_user] -W [source_database] > source_db_dump.sql

        psql -h [destination_host] -p [destination_port] -U [destination_user] -W [destination_database] < source_db_dump.sql
        ```

### Complete your Aptible setup

*   Familiarize yourself with Aptible [activity](https://www.aptible.com/docs/core-concepts/observability/activity), [logs](https://www.aptible.com/docs/core-concepts/observability/logs/overview), [metrics](https://www.aptible.com/docs/core-concepts/observability/metrics/overview#metrics)
*   (Optional) Set up [log](https://www.aptible.com/docs/core-concepts/observability/logs/log-drains/overview#log-drains) and [metric drains](https://www.aptible.com/docs/core-concepts/observability/metrics/metrics-drains/overview)
*   Invite your team and [set up roles](https://www.aptible.com/docs/core-concepts/security-compliance/access-permissions)
*   [Contact Aptible Support](https://contact.aptible.com/) to validate your production migration plan and set up a [Dedicated Stack](https://www.aptible.com/docs/core-concepts/architecture/stacks#dedicated-stacks-isolated) to host your production resources.

### Plan, Test and Execute the Migration

*   Plan for the downtime required to migrate the database and perform DNS cutover for services behind load balancers to Aptible Endpoints. The total estimated downtime can be calculated by performing test database migrations and rehearsing manual migration steps.
*   Key Points to consider in the Migration plan:
    *   Be able to put app(s) in maintenance mode: before migrating databases for production systems, have a method available to ensure that no app services are connecting to the database for writes. Barring this, at least be able to scale app services to zero containers to take the app offline.
    *   Consider modifying the DNS TTL on the records to be modified to value of 5 minutes or less.
    *   Perform the database migration, and enable the Aptible app, potentially using a secondary [Default Domain Endpoint](https://www.aptible.com/docs/core-concepts/apps/connecting-to-apps/app-endpoints/default-domain) for testing, or using local /etc/hosts to override DNS temporarily.
    *   Once the validation is complete, make the DNS record change to point your domain records to the new Aptible destination(s).
    *   Monitor logs to ensure that requests transition fully to the Aptible Endpoint(s) (observe that requests cease at the MedStack Load Balancer, and appear in logs at the Aptible Endpoint).


# How to migrate environments

Learn how to migrate environments

## Migrating to a stack in the same region

It is possible to migrate environments from one [Stack](/core-concepts/architecture/stacks) to another so long as both stacks are in the same [Region](/core-concepts/architecture/stacks#supported-regions). The most common use case for this is migrating resources from a shared stack to a dedicated stack.

If you would like to migrate environments between stacks in the same region, please contact [Aptible Support](/how-to-guides/troubleshooting/aptible-support) with details on the environment name and the stacks to and from which you want the environment migrated.

## Migrating to a stack in a different region

It is not possible to migrate environments from a stack in a different region, for example from a us-west-1  stack to a stack in us-west-2 . To achieve this, you must redeploy your resources to a new environment.


# Minimize Downtime Caused by AWS Outages

Learn how to optimize your Aptible resource to reduce the potential downtime caused by AWS Outages

## Overview

Aptible is designed to provide a baseline level of tools and services to minimize downtime from AWS outages. This includes:

*   Automated configuration of [availability controls](https://www.aptible.com/secured-by-aptible/) designed to prevent outages

*   Expert SRE response to outages backed by [our 99.95% Uptime SLA](https://www.aptible.com/legal/service-level-agreement/) (Enterprise Plan only)

*   Simplification of additional downtime prevention measures (as described in the rest of this guide)

In this guide, we will cover into the various configurations and steps that can be implemented to enhance the Recovery Point Objective (RPO) and Recovery Time Objective (RTO). These improvements will assist in ensuring a more seamless and efficient recovery process in the event of any disruptions or disasters.

## Outage Notifications

If you think you are experiencing an outage, check Aptible's [Status Page](https://status.aptible.com/). We highly recommend subscribing to Aptible Status Page Notifications. If you still have questions, contact [Support](/how-to-guides/troubleshooting/aptible-support).

> **Recommended Action:**

> 🎯 [Subscribe to Aptible Status Page Notifications](https://status.aptible.com/)

## Understanding AWS Infrastructure

Aptible runs on AWS so it helps to have a basic understanding of AWS's concept of [Regions and Availability Zones (AZs)](https://aws.amazon.com/about-aws/global-infrastructure/regions_az/).

## Regions

AWS regions are physical locations where AWS data centers are clustered. Communication between regions has a much higher-latency compared to communication within the same region and the farther two regions are from one another, the higher the latency. This means that it's generally better to deploy resources that work together within the same region.

Aptible Stacks are deployed in a single region in order to ensure resources can communicate with minimal latency.

## Availability Zones

AWS regions are comprised of multiple Availability Zones (AZs). AZs are sets of discrete data centers with redundant power, networking, and connectivity in a region. As mentioned above, communication within a region, and therefore between AZs in the same region, is very low latency. This allows resources to be distributed across AZs, increasing their availability, while still allowing them to communicate with minimal latency.

Aptible Stacks are distributed across 2 to 4 AZs depending on the region they're in. This enables all Stacks to distribute resources configured for high availability across AZs.

## High Availability

High Availability (HA) refers to distributing resources across data centers to increase the likelihood that one of the resources will be available at any given point in time.

As described above, Aptible Stacks will automatically distribute resources across the AZs in their region in order to maximize availability. Specifically, it does this by:

*   Deploying the Containers for [Services scaled to multiple Containers](/core-concepts/scaling/overview#horizontal-scaling) across AZs.

*   Deploying [Database Replicas](/core-concepts/managed-databases/managing-databases/replication-clustering) to a different AZ than the source Database is deployed to.

This alone enables you to be able to handle most outages and doesn't require a lot of effort which is why we recommend scaling production Services to at least 2 Containers and creating replicas for production Databases in the [Best Practices Guide](https://www.aptible.com/docs/best-practices-guide).

## Failover

Failover is the process of switching from one resource to another, generally in response to an outage or other incident that renders the resource unavailable. Some resources support automated failover whereas others require some manual intervention.

For Apps, Aptible [HTTP(S) Endpoints](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/overview) perform [Runtime Health Checks](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/health-checks#runtime-health-checks) to determine the status of App Containers and only send traffic to those that are considered "healthy". This means that all HTTP(S) Endpoints on Services scaled to 2 or more Containers will automatically be prepared for most minor outages.

Most Database types support manual failover in the form of promoting a replica and updating all of the Apps that used the original Database to use the promoted replica, instead. [MongoDB](/core-concepts/managed-databases/supported-databases/mongodb) can dynamically failover between nodes in a cluster, similar to how HTTP(S) Endpoints only route traffic to "healthy" Containers, which enables them to handle minor outages without any action but can make multi-region failover more difficult. See the documentation for your [Database Type](/core-concepts/managed-databases/supported-databases/overview) for details on setting up replication and failing over to a replica.

## Configuration and Planning

Organizations should decide how much downtime they can tolerate for their resources as the more fault-proof a solution is, the more it costs. We recommend planning for most common outages as Aptible makes it fairly easy to do so.

## Coverage for most outages

*Maturity Level: Standard*

The majority of AWS outages are limited hardware or networking failures affecting a small number of machines. Frequently this affects only a single [Availability Zone](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-regions-availability-zones.html), as AZs are isolated by design to share the minimum common causes of failures. Aptible's SRE team is notified in the event of AWS outages and responds to restore service based on what AWS resources are available. Most outages are able to be resolved in under 30 minutes by action of either AWS or Aptible without user action being required.

### Apps

The strongest basic step for making Apps resilient to most outages is [scaling each Service](https://www.aptible.com/docs/best-practices-guide#services) to 2 or more Containers. Aptible automatically schedules Containers to be run on hosts in different availability zones. In an outage affecting a single availability zone, traffic will be served only to Containers which are reachable and passing [health checks](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/health-checks#release-health-checks). Optimizing your App image to minimize tasks on container startup (such as installing or configuring software which could be built into the image instead) will allow Containers to be restarted more quickly to replace unhealthy or unreachable Containers and restore full capacity of the Service.

> **Recommended Action:**

> 🎯 [Scale Apps to 2+ Containers](https://dashboard.aptible.com/controls/12/implementation?scope=4591%2C4115%2C2431%2C2279%2C1458%2C111%2C1\&sort=cumulativeMetrics.statusSort%3Aasc)

### Databases

The simplest form of recovery that's available to all Database types is restoring one of the [Database's Backups](/core-concepts/managed-databases/managing-databases/database-backups) to a new Database. However, Aptible automatically backups up Databases daily so the latest backup may be missing up to 24 hours of data so this approach is generally only recommended as a last resort.

[Replicas](/core-concepts/managed-databases/managing-databases/replication-clustering), on the other hand, continuously stream data from their source Database so they're usually not more than a few seconds behind at any point in time. This means that replicas can be failed over to in the event that the source Database is unavailable for an extended period of time with minimal data loss. As mentioned in the [High Availability](/how-to-guides/platform-guides/minimize-downtown-outages#high-availability) section, we recommend creating a replica for all production Databases that support replication. See the documentation for your [Database Type](/core-concepts/managed-databases/supported-databases/overview) for details on setting up replication and failing over to a replica.

> **Recommended Action:**

> 🎯 [Implement Database Replication and Clustering](https://dashboard.aptible.com/controls/14/implementation?scope=4591%2C4115%2C2431%2C2279%2C1458%2C111%2C1\&sort=cumulativeMetrics.statusSort%3Aasc)

## Coverage for major outages

*Maturity Level: Advanced*

Major outages are much more rare and cost more to prepare for. See the [pricing page](https://www.aptible.com/pricing-plans/) for the current costs for each resource type. As such, organizations should evaluate the cost of preparing for an outage like this against the likelihood and impact it would have on their business before implementing these solutions.

To date, there's only been one AWS regional outage that would require this level of planning to be prepared for.

### Stacks

Since Stacks are deployed in a single region, an additional dedicated Stack is required in order to be able to handle region-wide outages. Contact [Aptible Support](/how-to-guides/troubleshooting/aptible-support) if you'd like to provision an additional dedicated Stack.

When choosing what region to use as a backup, keep in mind that the further two regions are from each other the more latency there will be between them. Looking at the region that Aptible copies Backups to is a good starting point if you aren't sure.

You'll likely want to peer your two Stacks so that their resources can communicate with one another. In other words, this allows resources on one Stack can connect to Databases and Internal Endpoints on the other. This is also something that [Aptible Support](/how-to-guides/troubleshooting/aptible-support) can set up for you.

> **Recommended Action:**

> 🎯 [Request a backup Dedicated Stack to be provisioned and/or peered](http://contact.aptible.com/)

### Apps

For a major outage, Apps will require manual intervention to failover to a different Stack in a healthy region. If you need a new Dedicated Stack provisioned as above, deploying your App to the new Stack will be equivalent to deploying it from scratch. If you maintain a Dedicated Stack in another region to be prepared in advance for a regional failure, there are several things you can do to speed the failover process.

You can deploy your production App's code to a second Aptible App on the backup Stack. Keeping the code and configuration in sync with your production Stack will allow you to failover to this App more quickly. To save costs, you can also scale all Services on this backup App to 0 Containers. In this case, failover will require [scaling each Service](/core-concepts/scaling/overview) up from 0 before redirecting traffic to this App. Optimizing your App image to minimize startup time will speed up this process.

You will need to update DNS to point traffic toward Endpoints on the new App. Provisioning these Endpoints ahead of time will speed this process but will incur a small ongoing cost per Endpoint to have ready. Lowering DNS TTL will reduce failover time, and configuring these backup Endpoints with [custom certificates](/core-concepts/apps/connecting-to-apps/app-endpoints/custom-certificate) is suggested to avoid the effort required to keep [Managed TLS](/core-concepts/apps/connecting-to-apps/app-endpoints/managed-tls) certificates current on these Endpoints.

> **Recommended Action:**

> 🎯 [Deploy Apps to your backup Dedicated Stack](http://contact.aptible.com/)

> 🎯 [Provision Endpoints on your backup Dedicated Stack](/core-concepts/managed-databases/connecting-databases/database-endpoints)

### Databases

The options for preparing for a major outage are the same as for other outages, restore a [Backup](/core-concepts/managed-databases/managing-databases/database-backups) or failover to a [Replica](/core-concepts/managed-databases/managing-databases/replication-clustering). The main difference here is that the resulting Database would be on a Stack in a different region and you'd have to continue operating on this Stack indefinitely or fail back over to the original Stack once it was back online.

Additionally, Aptible currently does not allow you to specify what Environment to create the Replica in with the [`aptible db:replicate` CLI command](/reference/aptible-cli/cli-commands/cli-db-replicate) so Replicas are always created in the same Environment as the source Database. If you'd like to set up a Replica in another region, contact [Aptible Support](/how-to-guides/troubleshooting/aptible-support) for assistance.

> **Recommended Action:**

> 🎯 [Enable Cross-Region Copy Database Backups](/core-concepts/managed-databases/managing-databases/database-backups#retention-and-disposal)

> 🎯 [Request Replica(s) be moved to your backup Dedicated Stack](http://contact.aptible.com/)


# How to request HITRUST Inhertiance

Learn how to request HITRUST Inhertiance from Aptible

# Overview

Aptible makes achieving HITRUST a breeze with our Security & Compliance Dashboard and HITRUST Inhertiance.

<Tip>
  **What is HITRUST Inheritance?** Aptible is HITRUST CSF Certified. If you are pursuing your own HITRUST CSF Certification, you may request that Aptible assessment scores be incorporated into your own assessment. This process is referred to as HITRUST Inheritance.
</Tip>

While it varies per customer, approximately 30%-40% of controls can be fully inherited, and about 20%-30% of controls can be partially inherited.

## 01: Preparation

To comply with HITRUST, you must first:

*   Provision a [Dedicated Stack](/core-concepts/architecture/stacks) for all Environments that process PHI

*   Sign a BAA with Aptible. BAAs can be requested by contacting [Aptible Support](/how-to-guides/troubleshooting/aptible-support).

## 02: Requesting HITRUST Inheritance

<Info> HITRUST Inheritance is only available on the [Enterprise Plan](https://www.aptible.com/pricing). </Info>

The process for requesting [HITRUST Inheritance](/core-concepts/security-compliance/overview#hitrust-inheritance) from Aptible is as follows:

*   Navigate to [Aptible’s HITRUST Shared Responsibility Matrix](https://hitrustalliance.net/shared-responsibility-matrices) (SRM) to obtain a list of controls you can submit for HITRUST Inheritance. This document provides a list of all controls you can inherit from Aptible. To obtain the list of controls:

    *   Read and agree to the general terms and conditions stated in the HITRUST Shared Responsibility Matrix License agreement.

    *   Complete the form that appears, and you will receive an email within a few minutes after submission. Please check your spam folder if you don’t see the email after a few minutes.

    *   Click the link to the HITRUST Shared Responsibility Matrix for Aptible in the email, and the list of controls will download to your computer.

*   Using the list from the previous step, select which controls you would like to inherit and submit your request through MyCSF (Please note: Controls must be in “Submitted” status, not “Created”)

*   [Contact Aptible Support](/how-to-guides/troubleshooting/aptible-support) to let us know about your request in MyCSF. Note: This is the only way for us to communicate details to you about your request (including reasonings for rejections). Once you submit the inheritance request, our Support team will review and approve accordingly within MyCSF.

**Related resources:**

HITRUST’s Inheritance Program Fact
Navigating the MyCSF Portal (See 8.2.3 for more information on Submitting for Inheritance)


# How to navigate security questionnaires and audits

Learn how to approach responding to security questionnaires and audits on Aptible

## Overview

Aptible streamlines the process of addressing security questionnaires and audits with its pre-configured [Security & Compliance](/core-concepts/security-compliance/overview) features. This guide will help you effectively showcase your security and compliance status for Aptible resources.

## 01: Define the scope

Before diving into the response process, it's crucial to clarify the scope of your assessment. Determine between controls within the scope of Aptible (e.g., infrastructure implementation) and those that fall outside of the scope (e.g., employee training on compliance policies).

For HITRUST Audits, Aptible provides the option of HITRUST Inheritance, which is a valuable resource for demonstrating compliance within the defined scope. Refer to [How to Request HITRUST Inheritance from Aptible.](/how-to-guides/platform-guides/navigate-hitrust)

## 02: Gather resources

To ensure that you are well-prepared to answer questions and meet requirements, collect the most pertinent resources:

*   For inquiries or requirements related to your unique setup (e.g., implementing Multi-Factor Authentication or redundancy configurations), refer to your Security & Compliance Dashboard. The [Security and Compliance Dashboard](/core-concepts/security-compliance/security-compliance-dashboard/overview) provides an easy-to-consume view of all the HITRUST controls that are fully enforced and managed on your behalf. A printable report is available to share as needed.

*   For inquiries or requirements regarding Aptible's compliance (e.g., HITRUST/SOC 2 reports) or infrastructure setup (e.g., penetration testing and host hardening), refer to our comprehensive [trust.aptible.com](http://trust.aptible.com/) page. This includes a FAQ of security questions.

## 03: Contact Support as needed

Should you encounter any obstacles or require further assistance during this process:

*   If you are on the [Enterprise Plan](https://www.aptible.com/pricing), you have the option to request Aptible Support's assistance in completing an annual report when needed.

*   Don't hesitate to reach out to [Aptible Support](/how-to-guides/troubleshooting/aptible-support) for guidance.

## O4: Show off your compliance (optional)

Add a Secured by Aptible badge and link to the [Secured by Aptible](https://www.aptible.com/secured-by-aptible) page to show all the security & compliance controls implemented:

![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/navigate1.png)![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/navigate2.png)![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/navigate3.png)![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/navigate4.png)![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/secured_by_aptible_pipeda.png)


# Platform Guides

Explore guides for using the Aptible Platform

*   [How to achieve HIPAA compliance on Aptible](/how-to-guides/platform-guides/hipaa-compliance)

*   [How to create and deprovison dedicated stacks](/how-to-guides/platform-guides/create-deprovision-dedicated-stacks)

*   [How to create environments](/how-to-guides/platform-guides/create-environment)

*   [How to delete environments](/how-to-guides/platform-guides/delete-environment)

*   [How to deprovision resources](/how-to-guides/platform-guides/deprovision-resources)

*   [How to handle vulnerabilities found in security scans](/how-to-guides/platform-guides/handle-vulnerabilities-security-scans)

*   [How to migrate environments](/how-to-guides/platform-guides/migrate-environments)

*   [How to navigate security questionnaires and audits](/how-to-guides/platform-guides/navigate-security-questionnaire-audits)

*   [How to restore resources](/how-to-guides/platform-guides/restore-resources)

*   [How to upgrade or downgrade my plan](/how-to-guides/platform-guides/upgrade-downgrade-plan)

*   [How to set up Single Sign On (SSO)](/how-to-guides/platform-guides/setup-sso)

*   [Best Practices Guide](/how-to-guides/platform-guides/best-practices-guide)

*   [Advanced Best Practices Guide](/how-to-guides/platform-guides/advanced-best-practices-guide)

*   [How to navigate HITRUST Certification](/how-to-guides/platform-guides/navigate-hitrust)

*   [Minimize Downtime Caused by AWS Outages](/how-to-guides/platform-guides/minimize-downtown-outages)

*   [How to cancel my Aptible Account](/how-to-guides/platform-guides/cancel-aptible-account)

*   [How to reset my Aptible 2FA](/how-to-guides/platform-guides/reset-aptible-2fa)


# How to Re-invite Deleted Users



Users can be part of multiple organizations in Aptible. If you remove them from your specific organization, they will still exist in Aptible and can be members of other orgs.
This is why they will see “email is in use” when trying to create themselves as a new user.

Please re-send your invite to this user but instead of having them create a new user, have them log in using the link you sent. Please have them follow these steps exactly:

*   Click on the link to accept the invite
*   Instead of creating a new user, used the “sign in here” option
*   If your organization uses SSO, please have them sign in with password authentication because SSO will not work for them until they are a part of the organization. If they have 2FA set up and don’t have access to their device, please have them follow the steps [here](https://www.aptible.com/docs/how-to-guides/platform-guides/reset-aptible-2fa).

Once these steps are completed, they should appear as a Member in the Members page in the Org Settings. If your organization uses SSO, please share the [SSO login link](https://www.aptible.com/docs/core-concepts/security-compliance/authentication/sso#organization-login-id) from with the new user and have them attempt to login via SSO.


# How to reset my Aptible 2FA



When you enable 2FA, you will receive emergency backup codes to use if your device is lost, stolen, or temporarily unavailable. Keep these in a safe place. You can enter backup codes where you would typically enter the 2FA code generated by your device. You can only use each backup code once.

If you don't have your device and cannot access a backup code, you can work with an account owner to reset your 2FA:

Account Owner:

1.  Navigate to Settings > Members ![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/reset-2fa.png)

2.  Select Reset 2FA for your user

3.  Select Reset on the confirmation page ![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/reset-2fa-2.png)

User:

1.  Click the link in the 2FA reset email you receive. ![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/reset-2fa-3.png)

2.  Complete the reset on the confirmation page. ![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/reset-2fa-4.png)

3.  Log in with your credentials.

4.  Enable 2FA Authentication again in the Dashboard by navigating to Settings > Security Settings > Configure 2FA.

Account owners can reset 2FA for all other users, including other account owners, but cannot reset their own 2FA.


# How to restore resources



## Apps

It is not possible to restore an App, its [Configuration](/core-concepts/apps/deploying-apps/configuration), or its [Endpoints](/core-concepts/apps/connecting-to-apps/app-endpoints/overview) once deprovisioned. Instead, deploy a new App using the same [Image](/core-concepts/apps/deploying-apps/image/overview) and manually recreate the App's Configuration and any Endpoints.

## Database Backups

It is not possible to restore Database Backups once deleted. Aptible permanently deletes database backups when an account is closed. Users must export all essential data in Aptible before the account is closed.

## Databases

It is not possible to restore a Database, its [Endpoints](/core-concepts/managed-databases/connecting-databases/database-endpoints) or its [Replicas](/core-concepts/managed-databases/managing-databases/replication-clustering) once deprovisioned. Instead, create a new Database using the backed-up data from Database Backups via the [`aptible backup:restore`](/reference/aptible-cli/cli-commands/cli-backup-restore) CLI command or through the Dashboard:

*   Select the Backup Management tab within the desired environment.

*   Select "Restore to a New Database" for the relevant backup.

Then, recreate any Database Endpoints and Replicas. Restoring a Backup creates a new Database from the backed-up data. It does not replace or modify the Database the Backup was originally created from in any way. The new Database will have the same data, username, and password as the original did at the time the Backup was taken.

## Log and Metric Drains

Once deleted, it is not possible to restore log and metric drains. Create new drains instead.

## Environments

Once deleted, it is not possible to restore Environments.


# Provisioning with Entra Identity (SCIM)

Aptible supports SCIM 2.0 provisioning through Entra Identity using the Aptible SCIM integration. This setup enables you to automate user provisioning and de-provisioning for your organization.

With SCIM enabled, users won't have the option to leave your organization on their own and won't be able to change their account email or password. Only organization owners have permission to remove team members. Entra Identity administrators can use SCIM to manage user account details if they're associated with a domain your organization verified.

> 📘 Note

> You must be an Aptible organization owner to enable SCIM for your organization.

### Step 1: Create a SCIM Integration in Aptible

1.  **Log in to Aptible**: Sign in to your Aptible account with OrganizationOwner privileges.
2.  **Navigate to Provisioning**: Go to the 'Settings' section in your Aptible dashboard and select Provisioning.

![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/scim-app-ui.png)

3.  **Define Default Role**: Update the Default Aptible Role. New users created by SCIM will be automatically assigned to this role.
4.  **Generate SCIM Token**: Aptible will provide a SCIM token, which you will need for Entra Identity configuration. Save this token securely; it will only be displayed once.

> 📘 Note

> Please note that the SCIM token has a validity of one year.

5.  **Save the Changes**: Save the configuration.

### Step 2: Enable SCIM in Entra Identity

Entra Identity supports SCIM 2.0, allowing you to enable user provisioning directly through the Entra Identity portal.

1.  **Access the Entra Identity Portal**: Log in to your Entra Identity admin center.
2.  **Go to Enterprise Applications**: Navigate to Enterprise applications > All applications.
3.  **Add an Application**: Click on 'New application', then select 'Non-gallery application'. Enter a name for your custom application (i.e., "Aptible") and add it.
4.  **Setup SCIM**: In your custom application settings, go to the 'Provisioning' tab.
5.  **Configure SCIM**: Click on 'Get started' and select 'Automatic' for the Provisioning Mode.
6.  **Enter SCIM Connection Details**:
    *   **Tenant URL**: Enter `https://auth.aptible.com/scim_v2`.
    *   **Secret Token**: Paste the SCIM token you previously saved.
        ![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/entra-enable-scim.png)
7.  **Test Connection**: Test the SCIM connection to verify that the SCIM endpoint is functional and that the token is correct.
8.  **Save and Start Provisioning**: Save the settings and turn on provisioning to start syncing users.

### Step 3: Configure Attribute Mapping

Customize the attributes that Entra Identity will send to Aptible through SCIM:

1.  **Adjust the Mapping**: In the 'Provisioning' tab of your application, select 'Provision Microsoft Entra ID Users' to modify the attribute mappings.

![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/entra-attribute-configuration.png)

2.  **Edit Attribute Mapping**: Ensure to align with what Aptible expects, focusing on core attributes like **User Principal Name**, **Given Name**, and **Surname**.

3.  **Include required attributes**: Make sure to map essential attributes such as:
    *   **userPrincipalName** to **userName**
    *   **givenName** to **firstName**
    *   **surname** to **familyName**
    *   **Switch(\[IsSoftDeleted], , "False", "True", "True", "False")** to **active**
    *   **mailNickname** to **externalId**

![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/entra-attribute-mapping.png)

### Step 4: Test the SCIM Integration

1.  **Test User Provisioning**: Create a test user in Entra Identity and verify that the user is provisioned in Aptible.
2.  **Test User De-provisioning**: Deactivate or delete the test user in Entra Identity and confirm that the user is de-provisioned in Aptible.

By following these steps, you can successfully configure SCIM provisioning between Aptible and Entra Identity to automate your organization's user management.


# Provisioning with Okta (SCIM)

Aptible supports SCIM 2.0 provisioning through Okta using the Aptible SCIM integration. This setup enables you to automate user provisioning and de-provisioning for your organization.

With SCIM enabled, users won't have the option to leave your organization on their own, and won't be able to change their account email or password. Only organization owners have permission to remove team members. Only administrators in Okta have permission to use SCIM to change user account emails if they're associated with a domain your organization verified.

> 📘 Note

> You must be an Aptible organization owner to enable SCIM for your organization.

### Step 1: Create a SCIM Integration in Aptible

1.  **Log in to Aptible**: Sign in to your Aptible account with OrganizationOwner privileges.
2.  **Navigate to Provisioning**: Go to the 'Settings' section in your Aptible dashboard and select Provisioning

![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/scim-app-ui.png)

1.  **Define Default Role**: Update the Default Aptible Role. New Users created by SCIM will be automatically assigned to this Role.
2.  **Generate SCIM Token**: Aptible will provide a SCIM token, which you will need for the Okta configuration. Save this token securely; it will only be displayed once.

> 📘 Note

> Please note that the SCIM token has a validity of one year.

3.  **Save the Changes**: Save the configuration.

### Step 2: **Enable SCIM in Okta with the SCIM test app**

The [SCIM 2.0 test app (Header Auth)](https://www.okta.com/integrations/scim-2-0-test-app-header-auth/) is available in the Okta Integration Network, allowing you to enable user provisioning directly through Okta.

Prior to enabling SCIM in Okta, you must configure SSO for your Aptible account

To set up provisioning with Okta, do the following:

1.  Ensure you have the Aptible SCIM token generated in the previous step.
2.  Open your Okta admin console in a new tab.
3.  Go to **Applications**, and then select **Applications**.
4.  Select **Browse App Catalog**.

![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/okta-select-app.png)

5.  Search for "SCIM 2.0 Test App (Header Auth)". Select the app from the results, and then select **Add Integration**.

![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/okta-select-scim.png)

6.  In the **General Settings** tab, enter an app name you'll recognize later, and then select **Next**.
7.  In the **Sign-On Options** tab, select **Done**.
8.  In Okta, go to the newly created app, select **Provisioning**, then select **Configure API Integration**.

![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/okta-enable-scim.png)

9.  Select **Enable API integration**, and enter the following:
    *   **Base URL** - Enter `https://auth.aptible.com/scim_v2`.
    *   **API Token** - Enter your SCIM API key.

![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/okta-configure-scim.png)

10. Select **Test API Credentials**. If successful, a verification message will appear.

    > If verification is unsuccessful, confirm that you have SCIM enabled for your team in Aptible, are using the correct SCIM API key, and that your API key's status is ACTIVE in your team authentication settings. If you continue to face issues, contact Aptible support for assistance.
11. Select **Save**. Then you can configure the SCIM 2.0 test app (Header Auth).

## Configure the SCIM test app

After you enable SCIM in Okta with the SCIM 2.0 test app (Header Auth), you can configure the app. The SCIM 2.0 test app (Header Auth) supports the provisioning features listed in the SCIM provisioning overview. The app also supports updating group information from Aptible to your IdP.

To turn these features on or off, do the following:

1.  Go to the SCIM 2.0 test app (Header Auth) in Okta, select **Provisioning**, select **To App** on the left, then select **Edit**.

![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/okta-enable-crud.png)

2.  Select features to enable them or clear them to turn them off. Aptible supports the **Create users**, **Update User Attributes**, and **Deactivate Users** features. It doesn't support the **Sync Password** feature.

![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/okta-crud-enabled.png)

3.  Select **Save** to save your changes.

4.  Make sure only the **Username**, **Given name**, **Family name, and Display Name** attributes are mapped. Display Name is used if provided. Otherwise, the system will fall back to givenName and familyName. Other attributes are ignored if they're mapped.

![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/okta-attributes-mapping.png)

5.  Select **Assignments**, then assign relevant people and groups to the app. Learn how to [assign people and groups to an app in Okta](https://help.okta.com/en-us/content/topics/apps/apps-assign-applications.htm?cshid=ext_Apps_Apps_Page-assign).

![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/okta-initiate-assignments.png)

## Step 3: Validate the SCIM Integration

1.  **Validate User Provisioning**: Create a test user in Okta and verify that the user is provisioned in Aptible.
2.  **Validate User De-provisioning**: Deactivate the test user in Okta and verify that the user is de-provisioned in Aptible.

By following these steps, you can successfully configure SCIM provisioning between Aptible and Okta to automate your organization's user management.


# How to set up Single Sign On (SSO)

To use SSO, you must configure both the SSO provider and Aptible with metadata related to the SAML protocol. This documentation covers the process in general terms applicable to any SSO provider. Then, it covers in detail the setup process in Okta.

## Generic SSO Provider Configuration

To set up the SSO provider, it needs the following four pieces of information unique to Aptible. The values for each are available in your Organization's Single Sign On the settings page, accessible only by [Account Owners](/core-concepts/security-compliance/access-permissions), if you do not yet have SSO configured.

![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/sso1.png)

You should reference your SSO Provider's walkthrough for setting up a SAML application alongside this documentation.

*   [Okta](https://developer.okta.com/docs/guides/saml-application-setup/overview/)

*   [Google GSuite](https://support.google.com/a/answer/6087519)

*   [Auth0 (Aptible Guide)](/how-to-guides/platform-guides/setup-sso-auth0)

## Single Sign On URL

The SAML protocol relies on a series of redirects to pass information back and forth between the SSO provider and Aptible. The SSO provider needs the Aptible URLs set ahead of time to securely complete this process. This URL is also called the Assertion Consumer Service (ACS) or SAML Consume URL by some providers.

Google uses the term `SSO URL` to refer to the redirect URL on their server. This value is called the `ACS URL` in their guide.

This is the first URL provided on the Aptible settings page. It should end in `saml/consume`.

## Audience URI

This is a unique identifier used by the SSO provider to match incoming login requests to your specific account with them. This may also be referred to as the Service Provider (SP) Entity ID.

Google uses the term `Entity ID` to refer to this value in its guide.

This is the second value on the Aptible information page. It should end in `saml/metadata`

> 📘 This URL provides all the metadata needed by an SSO provider to setup SAML for your account with Aptible. If your SSO provider, has an option to use this metadata, you can provide this URL to automate setup. Neither Okta nor Google allow for setup this way.

## Name ID Format

SAML requires a special "name" field that uniquely identifies the same user in both the SSO Provider and Aptible. Aptible requires that this field be the user's email address. That is how users are uniquely identified in our system.

There are several standard formats for this field. If your SSO supports the `EmailAddress`, `emailAddress`, or `Email` formats, one of which should be selected. If not, the `Unspecified` format, should be used. If none of those are available, `Persistent` format is also acceptable.

Some SSO providers do not require manual setting of the Name ID format and will automatically assign one based on the attribute selected in the next step.

## Application Attribute or Name ID Attribute

This tells the SSO provider want information to include as the required Name ID. The information it stores about your users is generally called attributes but may also be called fields or other names. This **must be set so that is the same email address as used on the Aptible account**. Most SSO providers have an email attribute that can be selected here. If not, you may have to create a custom attribute in your SSO provider.

You may optionally configure the SSO provider to send additional attributes, such as the user's full name. Aptible currently ignores any additional attributes sent.

> ❗️ Warning

> If the email address sent by the SSO provider does not exactly match the email address associated with their Aptible account, the user will not be able to login via your SSO provider. If users are having issues logging in, you should confirm those email addresses match.

## Other configuration fields

Your SSO provider may have many other configuration fields. You should be able to leave these at their default settings. We provide some general guidance if you do want to customize your settings. However, your SSO provider's documentation should supersede any information here as these values can vary from provider to provider.

*   **Default RelayState or Start URL**: This allows you to set a default page on Aptible that your users will be taken to when logging in. We direct the user to the product they were using when they started logging in. You can override that behavior here if you want them to always start on a particular product.

*   **Encryption, Signature, Digest Algorithms**: Prefer options with `SHA-256` over those with `SHA-1`.

## Aptible SSO Configuration

Once your have completed the SSO provider configuration, they should provide you with **XML Metadata** either as a URL or via file download.

Return to the Single Sign On settings page for your Organization, where you copied the values for setting up your SSO provider. Then click on the "Configure an SSO Provider"

![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/sso2.png)

In the resulting modal box, enter either the URL or the XML contents of the file. You only need to enter one. If you enter both, Aptible will use the URL to retrieve the metadata. Aptible will then complete our setup automatically.

> 📘 Note

> Aptible only supports SSO configurations with a single certificate at this time. If you get an error when applying your configuration, check to see if it contains multiple `KeyDescriptor` elements. If you require multiple certificates please notify [Aptible Support](/how-to-guides/troubleshooting/aptible-support).

![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/sso3.png)

> ❗️ Warning

> When you retrieve the metadata, you should ensure the SSO provider's site is an HTTPS site. This ensure that the metadata is not tampered with during download. If an attacker could alter that metadata, they could substitute their own information and hi-jack your SSO configuration.

Once processing is complete, you should see data from your SSO provider. You can confirm these with the SSO provider's website to ensure they are correct.

You can optionally enable additional SSO feature within Aptible at this point:

## Okta Walkthrough

As a complement to the generic guide, we will present a detailed walkthrough for configuring Okta as an SSO provider to an Aptible Organization.

## Sign in to Okta with an admin account

*   Click Applications in the main menu.

*   Click Add Application and then Create New App.

## Setup a Web application with SAML 2.0

*   The default platform should be Web. If not, select that option.

*   Select SAML 2.0 as the Sign on method.

![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/sso4.png)

## Create SAML Integration

*   Enter `Aptible Deploy` or another name of your choice.

*   You may download and use our [logo](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/aptible_logo.png) for an image.

![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/sso5.png)

## Enter SAML Settings from Aptible Single Sign On Settings Page

*   Open the Organization settings in Aptible Dashboard

*   Select the Single Sign On settings in the sidebar

![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/sso6.png)

*   Copy and paste the Single Sign On URL

*   Copy and paste the Audience URI

*   Select `EmailAddress` for the Name ID format dropdown

*   Select `Email` in the Application username dropdown

*   Leave all other values as their defaults

*   Click Next

![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/sso7.png)

## Fill-in Okta's Feedback Page

*   Okta will prompt you for feedback on the SAML setup.

*   Select "I'm an Okta customer adding an internal app"

*   Optionally, provide additional feedback.

*   When complete, click Finish.

![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/sso8.png)

*   Copy the link for Identity Provider metadata

![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/sso9.png)

*   Open the Single Sign On settings page for your Organization in Aptible

*   Click "Configure an SSO Provider"

*   Paste the metadata URL into the box

![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/sso10.png)

## Assign Users to Aptible Deploy

*   Follow [Okta's guide to assign users](https://developer.okta.com/docs/guides/saml-application-setup/assign-users-to-the-app/) to the new application.

## Frequently Asked Questions

**What happens if my SSO provider suffers downtime?**

Users can continue to use their Aptible credentials to login even after SSO is enabled. If you also enabled [SSO enforcement](/core-concepts/security-compliance/authentication/sso#require-sso-for-access) then your Account Owners can still login with their Aptible credentials and disable enforcement until the SSO provider is back online.

**Does Aptible offer automated provisioning of SSO users?**

Aptible supports SCIM 2.0 provisioning. Please refer to our [Provisioning Guide](/core-concepts/security-compliance/authentication/scim).

**Does Aptible support Single Logout?**

We do not at this time. If this would be helpful for your Organization, please let us know.

**How can I learn more about SAML?**

There are many good references available on the Internet. We suggest the following starting points:

*   [Understanding SAML](https://developer.okta.com/docs/concepts/saml/)

*   [The Beer Drinker's Guide to SAML](https://duo.com/blog/the-beer-drinkers-guide-to-saml)

*   [Overview of SAML](https://developers.onelogin.com/saml)

*   [How SAML Authentication Works](https://auth0.com/blog/how-saml-authentication-works/)


# How to Set Up Single Sign-On (SSO) for Auth0

This guide provides detailed instructions on how to set up a custom SAML application in Auth0 for integration with Aptible.

## Prerequisites

*   An active Auth0 account
*   Administrative access to the Auth0 dashboard
*   Aptible Account Owner access to enable and configure SAML settings

## Creating Your Auth0 SAML Application

<Steps>
  <Step title="Accessing the Applications Dashboard">
    Log into your Auth0 dashboard. Navigate to **Applications** using the left navigation menu and click **Create Application**. Enter a name for your application (we suggest "Aptible"), select **Regular Web Applications**, and click **Create**.

    ![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/sso-auth0-create.png)
  </Step>

  <Step title="Enabling SAML2 WEB APP">
    Select the **Addons** tab and enable the **SAML2 WEB APP** add-on by toggling it on. Navigate to the **Usage** tab and download the Identity Provider Metadata or copy the link to it. Close this window—It will toggle back to off, which is expected. We will activate it later.

    ![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/sso-auth0-metadata.png)
  </Step>

  <Step title="Enable SAML Integration">
    Log into your Aptible dashboard as an Account Owner. Navigate to **Settings** and select **Single Sign-On**. Copy the following information; you will need it later:

    *   **Single Sign-On URL** (Assertion Consumer Service \[ACS] URL):\
        `https://auth.aptible.com/organizations/xxxxx-xxx-xxxx-xxxx-xxxxxxxxxxxx/saml/consume`

    ![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/sso-auth0-acs.png)
  </Step>

  <Step title="Upload Identity Provider Metadata">
    On the same screen, locate the option for **Metadata URL**. Copy the content of the metadata file you downloaded from Auth0 into **Metadata File XML Content**, or copy the link to the file into the **Metadata URL** field. Click **Save**. After the information has been successfully saved, copy the newly provided information:

    *   **Shortcut SSO login URL**:\
        `https://app.aptible.com/sso/xxxxx-xxx-xxxx-xxxx-xxxxxxxxxxxx`

    ![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/sso-auth0-shortcut.png)
  </Step>

  <Step title="Configuring SAML2 in Auth0">
    Return to the Auth0 SAML Application. In the Application under **Settings**, configure the following:

    *   **Application Login URI**:\
        `https://app.aptible.com/sso/xxxxx-xxx-xxxx-xxxx-xxxxxxxxxxxx`
        (this is the Aptible value of **Shortcut SSO login URL**).
    *   **Allowed Callback URLs**:\
        `https://auth.aptible.com/organizations/xxxxx-xxx-xxxx-xxxx-xxxxxxxxxxxx/saml/consume`
        (this is the Aptible value of **Single Sign-On URL - Assertion Consumer Service \[ACS] URL**).
    *   Scroll down to **Advanced Settings -> Grant Types**. Select the grant type appropriate for your Auth0 configuration. Save the changes. Re-enable the **SAML2 WEB APP** add-on by toggling it on. Switch to the **Settings** tab. Copy the following into the **Settings** space (ensure that nothing else remains there):

    ```json
    { 
      "nameIdentifierProbes": [ 
        "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" 
      ] 
    }
    ```

    ![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/sso-auth0-settings.png)
  </Step>

  <Step title="Finalize the Setup">
    Click on **Debug** — Ensure the opened page indicates "It works." Close this page, scroll down and select **Enable**.

    *   Ensure that the correct users have access to your app (specific to your setup). Save the changes.

    ![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/sso-auth0-itworks.png)
  </Step>
</Steps>

### Attribute Mapping

No additional attribute mapping is required for the integration to function.

### Testing the Login

Open a new incognito browser window. Open the link Aptible provided as **Shortcut SSO login URL**. Ensure that you will be able to login.


# How to upgrade or downgrade my plan

Learn how to upgrade and downgrade your Aptible plan

## Overview

Aptible offers a number of plans to designed to meet the needs of companies at all stages. This guide will walk you through modifying your Aptible plan.

## Upgrading Plans

### Production

Follow these steps to upgrade your plan to Production plan:

*   In the Aptible Dashboard, select your name at the top right

*   Select Billing Settings in the dropdown that appears

*   On the left, select Plan

*   Choose the plan you would like to upgrade to

### Enterprise

For Enterprise or Custom plans, [please get in touch with us.](https://www.aptible.com/contact)

## Downgrading Plans

Follow these steps to downgrade your plan:

*   In the Aptible dashboard, select your name at the top right

*   Select Billing Settings in the dropdown that appears

*   On the left, select Plan

*   Choose the plan you would like to downgrade to

> ⚠️ Please note that your active resources must match the limits of the plan you select for the downgrade to succeed. For example: if you downgrade to a plan that only includes up to 3GB RAM - you must scale your resources below 3GB RAM before you can successfully downgrade.


# Aptible Support



<Cardgroup cols={2}>
  <Card title="Troubleshooting Guides" icon="magnifying-glass" href="https://www.aptible.com/docs/common-erorrs">
    Hitting an Error? Read our troubleshooting guides for common errors

    <br />

    View guides -->
  </Card>

  <Card title="Contact Support" icon="comment" href="https://contact.aptible.com/">
    Have a question? Reach out to Aptible Support

    <br />

    Contact Support -->
  </Card>
</Cardgroup>

## **Best practices when opening a ticket**

*   **Add Detail:** Please provide as much detail as possible to help us resolve your issue quickly. When appropriate, please include the following:

    *   Relevant handles (App, Database, Environment, etc.)

    *   Logs or error messages

    *   The UTC timestamp when you experienced the issue

    *   Any commands or configurations you have tried so far

*   **Sanitize any sensitive information:** This includes [Database Credentials](/core-concepts/managed-databases/connecting-databases/database-credentials), SSH keys, passwords, tokens, and any confidential [Configuration](/core-concepts/apps/deploying-apps/configuration) variables you may use.

*   **Format your support requests:** To make it easier to parse important information, use backticks for monospacing or triple backticks for code blocks. We suggest using [private GitHub Gists](https://gist.github.com/) for long code blocks or stack traces.

*   **Set the appropriate priority:** This makes it easier for us to respond within the appropriate time frame.

## Ticket Priority

> 🏳️ High and Urgent Priority Support are only available on the [Premium & Enterprise Support plans.](https://www.aptible.com/pricing)

Users have the option to assign a priority level to their ticket submission, which is based on their [support plan](https://www.aptible.com/support-plans). The available priority levels include:

*   **Low** (You have a general development question, or you want to request a feature)

*   **Normal** (Non-critical functions of your application are behaving abnormally, or you have a time-sensitive development question)

*   **High** (Important functions of your production application are impaired or degraded)

*   **Urgent** (Your business is significantly impacted. Important functions your production application are unavailable)


# App Processing Requests Slowly



## Cause

If your app is processing requests slowly, it's possible that it is receiving more requests than it can efficiently handle at its current scale (due to hitting maxes with [CPU](/core-concepts/scaling/cpu-isolation) or [Memory](/core-concepts/scaling/memory-limits)).

## Resolution

First, consider deploying an [Application Performance Monitoring](/how-to-guides/observability-guides/setup-application-performance-monitoring) solution in your App in order to get a better understanding of why it's running slow.

Then, if needed, see [Scaling](/core-concepts/scaling/overview) for instructions on how to resize your App [Containers](/core-concepts/architecture/containers/overview).


# Application is Currently Unavailable



> 📘 If you have a [Custom Maintenance Page](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/maintenance-page#custom-maintenance-page) then you will see your maintenance page instead of *Application is currently unavailable*.

## Cause and Resolution

This page will be served by Aptible if your App fails to respond to a web request. There are several reasons why this might happen, each with different steps for resolution:

For further details about each specific occurrence, see [Endpoint Logs](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/endpoint-logs).

## The Service for your HTTP(S) Endpoint is scaled to zero

If there are no [Containers](/core-concepts/architecture/containers/overview) running for the [Service](/core-concepts/apps/deploying-apps/services) associated with your [HTTP(S) Endpoint](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/overview), this error page will be served. You will need to add at least one Container to your Service in order to serve requests.

## Your Containers are closing the connection without responding

Containers that have unexpectedly restarted will drop all requests that were running and will not respond to new requests until they have recovered. There are two reasons a Container would restart unexpectedly:

*   Your Container exceeded the [Memory Limit](/core-concepts/scaling/memory-limits) for your Service. You can tell if your Container has been restarted after exceeding its Memory Limit by looking for the message `container exceeded its memory allocation` in your [Logs](/core-concepts/observability/logs/overview). If your Container exceeded its Memory Limit, consider [Scaling](/core-concepts/scaling/overview) your Service.

*   Your Container exited unexpectedly for some reason other than a deploy, restart, or exceeding its Memory Limit. This is typically caused by a bug in your App or one of its dependencies. If your Container unexpectedly exits, you will see `container has exited` in your logs. Your logs may also have additional information that can help you determine why your container unexpectedly exited.

## Your App is taking longer than the Endpoint Timeout to serve requests

Clients will be served this error page if your App takes longer than the [Endpoint Timeout](/core-concepts/apps/connecting-to-apps/app-endpoints/overview#timeouts) to respond to their request. Your [Logs](/core-concepts/observability/logs/overview) may contain request logs that can help you identify specific requests that are exceeding the Endpoint Timeout. If it's acceptable for some of your requests take longer than your current Endpoint Timeout to process, you can increase the Endpoint Timeout by setting the `IDLE_TIMEOUT` [Configuration](/core-concepts/apps/deploying-apps/configuration) variable.

Hitting or exceeding resource limits may cause your App to respond to requests more slowly. Reviewing metrics from your Apps, either on the Aptible dashboard or from your [Metric Drains](/core-concepts/observability/metrics/metrics-drains/overview), can help you identify if you are hitting any resource bottlenecks. If you find that you are hitting or exceeding any resource limits, consider [Scaling](/core-concepts/scaling/overview) your App.

You should also consider deploying [Application Performance Monitoring](/how-to-guides/observability-guides/setup-application-performance-monitoring) for additional insight into why your application is responding slowly.

If you see the Aptible error page that says "This application crashed" consistently every time you [release](/core-concepts/apps/deploying-apps/releases/overview) your App (via Git push, `aptible deploy`, `aptible restart`, etc.), it's possible your App is responding to Aptible's [Release Health Checks](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/health-checks#release-health-checks), made via `GET /`, before the App is ready to serve other requests. Aptible's zero-downtime deployment process assumes that if your App responds to `GET /`, it is ready to respond successfully to other requests. If that assumption is not true, then your App cannot benefit from our zero-downtime approach, and you will see downtime accompanied by the Aptible error page after each release.

This situation can happen, for example, if your App runs a background process on startup, like precompiling static assets or loading a large data set, and blocks any requests (other than `GET /`) until this process is complete.

The best solution to this problem is to identify whatever background process is blocking requests and reconfigure your App to ensure this happens either (a) in your Dockerfile build or (b) in a startup script **before** your web server starts. Alternatively, you may consider enabling [Strict Health Checks](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/health-checks#strict-health-checks)] for your App, using a custom healthcheck request endpoint that only returns 200 when your App is actually ready to serve requests.

> 📘 Your [Endpoint Logs](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/endpoint-logs) will contain a specific error message for each of the above problems. You can identify the cause of each by referencing [Endpoint Common Errors](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/endpoint-logs#common-errors).


# App Logs Not Being Received



## Cause

There can be several causes why a [Log Drain](/core-concepts/observability/logs/log-drains/overview) would stop receiving logs from your app:

*   Your logging provider stopped accepting logs (e.g., because you are over quota)

*   Your app stopped emitting logs

*   The Log Drain crashed

## Resolution

You can start by restarting your Log Drain via the Dashboard. To do so, Navigate to the "Logging" Tab, then click on "Restart" next to the affected Log Drain.

If logs do not appear within a few minutes, the issue is likely somewhere else; contact [Aptible Support](/how-to-guides/troubleshooting/aptible-support) for assistance.


# aptible ssh Operation Timed Out



When connecting using [`aptible ssh`](/reference/aptible-cli/cli-commands/cli-ssh), you might encounter this error:

```
ssh: connect to host bastion-layer-$NAME.aptible.in port 1022: Operation timed out
```

## Cause

This issue is often caused by a firewall blocking traffic on port `1022` from your workstation to Aptible.

## Resolution

Try connecting from a different network or using a VPN (we suggest using [Cloak](https://www.getcloak.com/) if you need to quickly set up an ad-hoc VPN).

If that does not resolve your issue, contact [Aptible Support](/how-to-guides/troubleshooting/aptible-support).


# aptible ssh Permission Denied



If you get an error indicating `Permission denied (publickey)` when using [`aptible ssh`](/reference/aptible-cli/cli-commands/cli-ssh) (or [`aptible db:tunnel`](/reference/aptible-cli/cli-commands/cli-db-tunnel), [`aptible logs`](/reference/aptible-cli/cli-commands/cli-logs)), follow the instructions below.

This issue is caused by a bug in OpenSSH 7.8 that broke support for client certificates, which Aptible uses to authenticate [Ephemeral SSH Sessions](/core-concepts/apps/connecting-to-apps/ssh-sessions) sessions.

This only happens if you installed the [Aptible CLI](/reference/aptible-cli/cli-commands/overview) from source (as opposed to using the Aptible Toolbelt).

To fix the issue, follow the [Aptible CLI installation instructions](/reference/aptible-cli/cli-commands/overview) and make sure to install the CLI using the Aptible Toolbelt package download.


# before_release Commands Failed



## Cause

If any of the [`before_release`](/core-concepts/apps/deploying-apps/releases/aptible-yml#before-release) commands specified in your [`.aptible.yml`](/core-concepts/apps/deploying-apps/releases/aptible-yml) fails i.e. exits with a non-zero status code, Aptible will abort your deployment.

If you are using `before_release` commands for e.g. database migrations, this is usually what you want.

## Resolution

When this happens, the deploy logs will include the output of your `before_release` commands so that you can start there for debugging.

Alternatively, it's often a good idea to try running your `before_release` commands via a [`aptible ssh`](/reference/aptible-cli/cli-commands/cli-ssh) session in order to reproduce the issue.


# Build Failed Error



## Cause

This error is returned when you attempt a [Dockerfile Deploy](/how-to-guides/app-guides/deploy-from-git), but your [Dockerfile](/core-concepts/apps/deploying-apps/image/deploying-with-git/overview) could not be built successfully.

## Resolution

The logs returned when you hit this error include the full output from the Docker build that failed for your Dockerfile. Review the logs first to try and identify the root cause.

Since Aptible uses [Docker](https://www.docker.com/), you can also attempt to reproduce the issue locally by [installing Docker locally](https://docs.docker.com/installation/) and then running `docker build .` from your app repository.

Once your app builds locally with a given Dockerfile, you can commit all changes to the Dockerfile and push the repo to Aptible, where it should also build successfully.


# Connecting to MongoDB fails



If you are connecting to a [MongoDB](/core-concepts/managed-databases/supported-databases/mongodb) [Database](/core-concepts/managed-databases/managing-databases/overview) on Aptible, either through your app or a [Database Tunnel](/core-concepts/managed-databases/connecting-databases/database-tunnels), you might hit an error such as this one:

```sql
MongoDB shell version: 3.2.1
connecting to: 172.17.0.2:27017/db
2016-02-08T10:43:40.421+0000 E QUERY    [thread1] Error: network error while attempting to run command 'isMaster' on host '172.17.0.2:27017'  :
connect@src/mongo/shell/mongo.js:226:14
@(connect):1:6

exception: connect failed
```

## Cause

This error is usually caused by attempting to connect without SSL to a MongoDB server that requires it, which is the case on Aptible.

## Resolution

To solve the issue, connect to your MongoDB server over SSL.

## Clients

Connection URLs generated by Aptible include the `ssl=true` parameter, which should instruct your MongoDB client to connect over SSL. If your client does not connect over SSL despite this parameter, consult its documentation.

## CLI

> 📘 Make sure you use a hostname to connect to MongoDB databases when using a database tunnel. If you use an IP address for the host, certificate verification will fail. You can work with `--sslAllowInvalidCertificates` in your command line, but using a hostname is simpler and safer.

The MongoDB CLI client does not accept database URLs. Use the following to connect:

```bash
mongo --ssl \
        --username aptible --password "$PASSWORD" \
        --host "$HOST" --port "$PORT"
```


# Container Failed to Start Error



## Cause and Resolution

If you receive an error such as `Failed to start containers for ...`, this is usually indicative of one of the following issues:

*   The [Container Command](/core-concepts/architecture/containers/overview#container-command) does not exist in your container. In this case, you should fix your `CMD` directive or [Procfile](/how-to-guides/app-guides/define-services) to reference a command that does exist.

*   Your [Image](/core-concepts/apps/deploying-apps/image/overview) includes an `ENTRYPOINT`, but that `ENTRYPOINT` does not exist. In this case, you should fix your Image to use a valid `ENTRYPOINT`.

If neither is applicable to you, contact [Aptible Support](/how-to-guides/troubleshooting/aptible-support) for assistance.


# Deploys Take Too long



When Aptible builds your App, it must run each of the commands in your Dockerfile. We leverage Docker's built-in caching support, which is described in detail in [Docker's documentation.](https://docs.docker.com/articles/dockerfile_best-practices/#build-cache)

> 📘 [Shared Stacks](/core-concepts/architecture/stacks#shared-stacks) are more likely to miss the build cache than [Dedicated Stacks](/core-concepts/architecture/stacks#dedicated-stacks)

To take full advantage of Docker's build caching, you should organize the instructions in your Dockerfile so that the most time-consuming build steps are more likely to be cached. For many apps, the dependency installation step is the most time-consuming, so you'll want to (a) separate that process from the rest of your Dockerfile instructions and (b) ensure that it happens early in the Dockerfile.

We provide specific instructions and Dockerfile snippets for some package managers in our [How do I use Dockerfile caching to make builds faster?](/how-to-guides/app-guides/make-docker-deploys-faster) tutorials.

You can also switch to [Direct Docker Image Deploy](/how-to-guides/app-guides/migrate-dockerfile-to-direct-image-deploy) for full control over your build process.


# Enabling HTTP Response Streaming



## Problem

An Aptible user is attempting to stream HTTP responses from the server but notices that they are being buffered.

## Cause

By default, Aptible buffers requests at the proxy layer to protect against attacks that exploit slow uploads such as \[Slowloris]\(/docs/([https://en.wikipedia.org/wiki/Slowloris\_(computer\_security)](https://en.wikipedia.org/wiki/Slowloris_\(computer_security\))).

## Resolution

Aptible users can set the [`X-Accel-Buffering`](https://www.nginx.com/resources/wiki/start/topics/examples/x-accel/#x-accel-buffering) header to `no` to disable proxy buffering for these types of requests.

###### Enabling HTTP Response Streaming

*   [Problem](/how-to-guides/troubleshooting/common-errors-issues/enabling-http-response#problem)
*   [Cause](/how-to-guides/troubleshooting/common-errors-issues/enabling-http-response#cause)
*   [Resolution](/how-to-guides/troubleshooting/common-errors-issues/enabling-http-response#resolution)


# git Push "Everything up-to-date."



## Cause

This message means that the local branch you're pushing to Aptible is already at exactly the same revision as is currently deployed on Aptible.

## Resolution

*   If you've already pushed your code to Aptible and simply want to restart the app, you can do so by running the [`aptible restart`](/reference/aptible-cli/cli-commands/cli-restart) command. If you actually want to trigger a new build from the same code you've already pushed, you can use [`aptible rebuild`](/reference/aptible-cli/cli-commands/cli-rebuild) instead.

*   If you're pushing a branch other than `master`, you must still push to the remote branch named `master` in order to trigger a build. Assuming you've got a Git remote named `aptible`, you can do so with a command like the following `git push aptible local-branch:master`.


# git Push Permission Denied



When pushing to your [App](/core-concepts/apps/overview)'s [Git Remote](/how-to-guides/app-guides/deploy-from-git#git-remote), you may encounter a Permission denied error. Below are a few common reasons this may occur and steps to resolve them.

```sql
Pushing to git@beta.aptible.com:[environment]/[app].git
Permission denied (publickey).
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.
```

## Wrong SSH Key

If you attempt to authenticate with a [public SSH key](/core-concepts/security-compliance/authentication/ssh-keys) not registered with Aptible, Git Authentication will fail and raise this error.

To confirm whether Aptible’s Git server correctly authenticates you, use the ssh command below.

```
ssh -T git@beta.aptible.com test
```

On successful authentication, you'll see this message:

```
Hi [email]! Welcome to Aptible. Please use `git push` to connect.
```

On failure, you'll see this message instead:

```
git @beta.aptible.com: Permission denied(publickey).
```

## Resolution

The two most common causes for this error are that you haven't registered your [SSH Public Key](/core-concepts/security-compliance/authentication/ssh-keys) with Aptible or are using the wrong key to authenticate. 

From the SSH Keys page in your account settings (locate and click the Settings option on the bottom left of your Aptible Dashboard , then click the SSH Keys option), double-check you’ve registered an SSH key that matches the one you’re trying to use. If you’re still running into issues and have multiple public keys on your device, you may need to specify which key you want to use when connecting to Aptible. To do so, add the following to your local \~/.ssh/config file (you might need to create it):

```
Host beta.aptible.com
    IdentityFile /path/to/private/key
```

## Environment Permissions

If you don’t have the proper permissions for the Environment or because the Environment/App you’re pushing to doesn’t exist, you’ll also see the Permission denied (publickey) error above.

## Resolution

In the [Dashboard](http://app.aptible.com), check that you have the proper [permissions](/core-concepts/security-compliance/access-permissions) for the Environment you’re pushing to and that the Git Remote you’re using matches the App’s Git Remote.


# git Reference Error



You may encounter the following error messages when running a `git push` from a CI platform, such as Circle CI, Travis CI, Jenkins and others:

```bash
error: Could not read COMMIT_HASH
fatal: revision walk setup failed
fatal: reference is not a tree: COMMIT_HASH
! [remote rejected] master -> master (missing necessary objects)
! [remote rejected] master -> master (shallow update not allowed)
```

(Where `COMMIT_HASH` is a long hexadecimal number)

## Cause

These errors are all caused by pushing from a [shallow clone](https://www.perforce.com/blog/141218/git-beyond-basics-using-shallow-clones).

Shallow clones are often used by CI platforms to make builds faster, but you can't push from a shallow clone to another git repository, which is why this fails when you try pushing to Aptible.

## Resolution

To solve this problem, update your build script to run this command before pushing to Aptible:

```bash
git fetch --unshallow || true
```

If your CI platform uses an old version of git, `--unshallow` may not be available. In that case, you can try fetching a number of commits large enough to fetch all commits through to the repository root, thus unshallowing your repository:

```bash
git fetch --depth=1000000
```


# HTTP Health Checks Failed



## Cause

When your [App](/core-concepts/apps/overview) has one or more [HTTP(S) Endpoints](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/overview), Aptible automatically performs [Health Checks](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/health-checks) during your deploy to make sure your [Containers](/core-concepts/architecture/containers/overview) are properly responding to HTTP traffic.

If your containers are *not* responding to HTTP traffic, the health check fails.

These health checks are called [Release Health Checks](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/health-checks#release-health-checks).

## Resolution

There are several reasons why the health check might fail, each with its own fix:

If your app crashes immediately upon start-up, it's not healthy. In this case, Aptible will indicate that your Containers exited and report their [Container Command](/core-concepts/architecture/containers/overview#container-command) and exit code.

You'll need to identify why your Containers are exiting immediately. There are usually two possible causes:

*   There's a bug, and your container is crashing. If this is the case, it should be obvious from the logs. To proceed, fix the issue and try again.

*   Your container is starting a program that immediately daemonizes. In this case, your container will appear to have exited from Aptible's perspective. To proceed, make sure the program you're starting stays in the foreground and does not daemonize, then try again.

## App listens on incorrect host

If your app is listening on `localhost` (a.k.a `127.0.0.1`), then Aptible cannot connect to it, so the health check won't pass.

Indeed, your app is running in Containers, so if the app is listening on `127.0.0.1`, then it's only routable from within those Containers, and notably, it's not routable from the Endpoint.

To solve this issue, you need to make sure your app is listening on all interfaces. Most application servers let you do so by binding to `0.0.0.0`.

## App listens on the incorrect port

If your Containers are listening on a given port, but the Endpoint is trying to connect to a different port, the health check can't pass.

There are two possible scenarios here:

*   Your [Image](/core-concepts/apps/deploying-apps/image/overview) does not expose the port your app is listening on.

*   Your Image exposes multiple ports, but your Endpoint and your app are using different ports.

In either case, to solve this problem, you should make sure that:

*   The port your app is listening on is exposed by your image. For example, if your app listens on port `8000`, your :ref:`Dockerfile` *must* include the following directive: `EXPOSE 8000`.

*   Your Endpoint is using the same port as your app. By default, Aptible HTTP(S) Endpoints automatically select the lexicographically lowest port exposed by your image (e.g. if your image exposes port `443` and `80`, then the default is `443`), but you can select the port Aptible should use when creating the Endpoint and modify it at any time.

## App takes too long to come up

It's possible that your app Containers are is simply taking longer to finish booting up and start accepting traffic than Aptible is willing to wait.

Indeed, by default, Aptible waits for up to 3 minutes for your app to respond. However, you can increase that timeout by setting the `RELEASE_HEALTHCHECK_TIMEOUT` [Configuration](/core-concepts/apps/deploying-apps/configuration) variable on your app.

There is one particular error case worth mentioning here:

### Gunicorn and `[CRITICAL] WORKER TIMEOUT`

When starting a Python app using Gunicorn as your application server, the health check might fail with a repeated set of `[CRITICAL] WORKER TIMEOUT` errors.

These errors are generated by Gunicorn when your worker processes fail to boot within Gunicorn's timeout. When that happens, Gunicorn terminates the worker processes, then starts over.

By default, Gunicorn's timeout is 30 seconds. This means that if your app needs e.g., 35 seconds to boot, Gunicorn will repeatedly timeout and then restart it from scratch.

As a result, even though Aptible gives you 3 minutes to boot up (configurable with `RELEASE_HEALTHCHECK_TIMEOUT`), an app that needs 35 seconds to boot will time out on the Release Health Check because Gunicorn is repeatedly killing then restarting it.

Boot up may take longer than 30 seconds and hitting the timeout is common. Besides, you might have configured the timeout with a lower value (via the `--timeout` option).

There are two recommended strategies to address this problem:

*   **If you are using a synchronous worker in Gunicorn (the default)**, use Gunicorn's `--preload` flag. This option will cause Gunicorn to load your app **before** starting worker processes. As a result, when the worker processes are started, they don't need to load your app, and they can immediately start listening for requests instead (which won't time out).

*   **If you are using an asynchronous worker in Gunicorn**, increase your timeout using Gunicorn's `--timeout` flag.

> 📘 If neither of the options listed above satisfies you, you can also reduce your worker count using Gunicorn's `--workers` flag, or scale up your Container to make more resources available to them.

> We don't recommend these options to address boot-up timeouts because they affect your app beyond the boot-up stage, respectively by reducing the number of available workers and increasing your bill.

> That said, you should definitely consider making changes to your worker count or Container size if your app is performing poorly or [Metrics](/core-concepts/observability/metrics/overview) are reporting you're undersized: just don't do it *only* for the sake of making the Release Health Check pass.

## App is not expecting HTTP traffic

[HTTP(S) Endpoints](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/overview) expect your app to be listening for HTTP traffic. If you need to expose an app that's not expecting HTTP traffic, you shouldn't be using an HTTP(S) Endpoint.

Instead, you should consider [TLS Endpoints](/core-concepts/apps/connecting-to-apps/app-endpoints/tls-endpoints) and [TCP Endpoints](/core-concepts/apps/connecting-to-apps/app-endpoints/tcp-endpoints).


# MySQL Access Denied



## Cause

This error likely means that your [MySQL](/core-concepts/managed-databases/supported-databases/mysql) client is trying to connect without SSL, but MySQL [Databases](/core-concepts/managed-databases/managing-databases/overview) on Aptible require SSL.

## Resolution

Review our instructions for [Connecting to MySQL](/core-concepts/managed-databases/supported-databases/mysql#connecting-to-mysql). Contact [Aptible Support](/how-to-guides/troubleshooting/aptible-support) if you need further assistance.


# No CMD or Procfile in Image



### Cause

Aptible relies on your [Image's](/core-concepts/apps/deploying-apps/image/overview) `CMD` or the presence of a [Procfile](/how-to-guides/app-guides/define-services) in order to define [Services](/core-concepts/apps/deploying-apps/services) for your [App](/core-concepts/apps/overview).

If your App has neither, the deploy cannot succeed.

### Resolution

Add a `CMD` directive to your image, or add a Procfile in your repository.


# Operation Restricted to Availability Zone(s)



## Cause

Since there is varied support for container profiles per availability zone (AZ), [scaling](/core-concepts/scaling/overview) a database to a different [container profile](/core-concepts/scaling/container-profiles) may require moving the database to a different AZ. Moving a database to a different AZ requires a complete backup and restore of the underlying disk, which results in downtime of a few minutes up to even hours, depending on the size of the disk.

To protect your service from unexpected downtime, scaling to a container profile that requires an AZ move will result in an error and no change to your service. The error you see in logs will look something like:

```
ERROR -- : Operation restricted to availability zone(s) us-east-1e where m5 is not available. Disks cannot be moved to a different availability zone without a complete backup and restore.
```

## Resolution

If you still want to scale to a container profile that will result in an availability zone move, you can plan for the backup and restore by first looking at recent database backups and noting the time it took them to complete. You should expect roughly this amount of downtime for the **backup only**. You can speed up the backup portion of the move by creating a manual backup before running the operation since backups are incremental.

When restoring your database from a backup, you may initially experience slower performance. This slowdown occurs because each block on the restored volume is read for the first time from slower, long-term storage. This 'first-time' read is required for each block and affects different databases in various ways:

*   For large PostgreSQL databases with busy access patterns and longer-than-default checkpoint periods, you may face delays of several minutes or more. This is due to the need to read WAL files before the database becomes online and starts accepting connections.

*   Redis databases with persistence enabled could see delays in startup times as disk-based data must be read back into memory before the database is online and accepting connections.

*   Databases executing disk-intensive queries will experience slower initial query performance as the data blocks are first read from the volume.

Depending on the amount of data your database needs to load into memory to start serving connections, this part of the downtime could be significant and might take more than an hour for larger databases. If you're running a large or busy database, we strongly recommend testing this operation on a non-production instance to estimate the total downtime involved.

When you're ready to move, go to the Aptible Dashboard, find your database, go to the settings panel, and select the container profile you wish to migrate to in the "Restart Database with Disk Backup and Restore" panel. After acknowledging the warning about downtime, click the button and your container profile scaling operation will begin.


# Common Errors and Issues



Knowledge base for navigating common errors & issues:

*   [Enabling HTTP Response Streaming](/how-to-guides/troubleshooting/common-errors-issues/enabling-http-response)
*   [App Processing Requests Slowly](/how-to-guides/troubleshooting/common-errors-issues/app-processing-requests-slowly)
*   [Application is Currently Unavailable](/how-to-guides/troubleshooting/common-errors-issues/application-unavailable)
*   [before\_release Commands Failed](/how-to-guides/troubleshooting/common-errors-issues/before-released-commands-fail)
*   [Build Failed Error](/how-to-guides/troubleshooting/common-errors-issues/build-failed-error)
*   [Container Failed to Start Error](/how-to-guides/troubleshooting/common-errors-issues/container-failed-start-error)
*   [Deploys Take Too long](/how-to-guides/troubleshooting/common-errors-issues/deploys-take-long)
*   [git Reference Error](/how-to-guides/troubleshooting/common-errors-issues/git-reference-error)
*   [git Push "Everything up-to-date."](/how-to-guides/troubleshooting/common-errors-issues/git-push-everything-utd)
*   [HTTP Health Checks Failed](/how-to-guides/troubleshooting/common-errors-issues/http-health-check-failed)
*   [App Logs Not Being Received](/how-to-guides/troubleshooting/common-errors-issues/apps-logs-not-received)
*   [PostgreSQL Replica max\_connections](/how-to-guides/troubleshooting/common-errors-issues/postgresql-replica)
*   [Connecting to MongoDB fails](/how-to-guides/troubleshooting/common-errors-issues/connecting-mongodb-fails)
*   [MySQL Access Denied](/how-to-guides/troubleshooting/common-errors-issues/mysql-access-denied)
*   [No CMD or Procfile in Image](/how-to-guides/troubleshooting/common-errors-issues/no-cmd-procfile-image)
*   [git Push Permission Denied](/how-to-guides/troubleshooting/common-errors-issues/git-push-permission-denied)
*   [aptible ssh Permission Denied](/how-to-guides/troubleshooting/common-errors-issues/aptible-ssh-operation-timed-out)
*   [PostgreSQL Incomplete Startup Packet](/how-to-guides/troubleshooting/common-errors-issues/postgresql-incomplete)
*   [PostgreSQL SSL Off](/how-to-guides/troubleshooting/common-errors-issues/postgresql-ssl-off)
*   [Private Key Must Match Certificate](/how-to-guides/troubleshooting/common-errors-issues/private-key-match-certificate)
*   [aptible ssh Operation Timed Out](/how-to-guides/troubleshooting/common-errors-issues/aptible-ssh-operation-timed-out)
*   [SSL error ERR\_CERT\_AUTHORITY\_INVALID](/how-to-guides/troubleshooting/common-errors-issues/ssl-error-auth-invalid)
*   [SSL error ERR\_CERT\_COMMON\_NAME\_INVALID](/how-to-guides/troubleshooting/common-errors-issues/ssl-error-common-name-invalid)
*   [Unexpected Requests in App Logs](/how-to-guides/troubleshooting/common-errors-issues/unexpected-requests-app-logs)
*   [Operation Restricted to Availability Zone(s)](/how-to-guides/troubleshooting/common-errors-issues/operation-restricted-to-availability)


# PostgreSQL Incomplete Startup Packet



## Cause

When you add a [Database Endpoint](/core-concepts/managed-databases/connecting-databases/database-endpoints) to a [PostgreSQL](/core-concepts/managed-databases/supported-databases/postgresql) Database, Aptible automatically performs periodic TCP health checks to ensure the Endpoint can reach the Database.

These health checks consist of opening a TCP connection to the Database and closing it once that succeeds. As a result, PostgreSQL will log a `incomplete startup packet` error message every time the Endpoint performs a health check.

## Resolution

If you have a Database Endpoint associated with your PostgreSQL Database, you can safely ignore these messages. You might want to consider adding filtering rules in your logging provider to drop the messages entirely.


# PostgreSQL Replica max_connections



A PostgreSQL replica's `max_connections` setting must be greater than or equal to the primary's setting; if the value is increased on the primary before being changed on the replica it will result in the replica becoming inaccessible with the following error:

```
FATAL:  hot standby is not possible because max_connections = 1000 is a
lower setting than on the master server (its value was 2000)
```

Our SRE Team is alerted when a replica fails for this reason and will take action to correct the situation (generally by increasing `max_connections` on the replica and notifying the user).

To avoid this issue, you need to update `max_connections` on the replica Database to the higher value *before* updating the value on the primary.


# PostgreSQL SSL Off



## Cause

This error means that your [PostgreSQL](/core-concepts/managed-databases/supported-databases/postgresql) client is configured to connect to without SSL, but PostgreSQL [Databases](/core-concepts/managed-databases/managing-databases/overview) on Aptible require SSL.

## Resolution

Many PostgreSQL clients allow enforcing SSL by appending `?ssl=true` to the default database connection URL provided by Aptible.

For some clients or libraries, it may be necessary to set this in the configuration code.

If you have questions about enabling SSL for your app's PostgreSQL library, please contact [Aptible Support](/how-to-guides/troubleshooting/aptible-support).


# Private Key Must Match Certificate



## Cause

Your [Custom Certificate](/core-concepts/apps/connecting-to-apps/app-endpoints/custom-certificate) is malformed or incomplete, or the private key you uploaded is not the right one for the certificate you uploaded.

## Resolution

Review the instructions here: [Custom Certificate Format](/core-concepts/apps/connecting-to-apps/app-endpoints/custom-certificate#format).


# SSL error ERR_CERT_AUTHORITY_INVALID



## Cause

This error is usually caused by neglecting to include CA intermediate certificates when you upload a [Custom Certificate](/core-concepts/apps/connecting-to-apps/app-endpoints/custom-certificate) to Aptible.

## Resolution

Include CA intermediate certificate in your certificate bundle. See [Custom Certificate](/core-concepts/apps/connecting-to-apps/app-endpoints/custom-certificate) for instructions.


# SSL error ERR_CERT_COMMON_NAME_INVALID



## Cause and Resolution

This error usually indicates one of two things:

*   You created a CNAME to an [Endpoint](/core-concepts/apps/connecting-to-apps/app-endpoints/overview) configured to use a [Default Domain](/core-concepts/apps/connecting-to-apps/app-endpoints/default-domain). That won't work; use a [Custom Domain](/core-concepts/apps/connecting-to-apps/app-endpoints/custom-domain) instead.

*   The [Custom Certificate](/core-concepts/apps/connecting-to-apps/app-endpoints/custom-certificate) you provided for your Endpoint is not valid for the [Custom Domain](/core-concepts/apps/connecting-to-apps/app-endpoints/custom-domain) you're using. Get a valid certificate for the domain.


# Unexpected Requests in App Logs



When you expose an app to the Internet using [HTTP(S) Endpoints](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/overview) with [External Placement](/core-concepts/apps/connecting-to-apps/app-endpoints/overview#endpoint-placement) will likely receive traffic from sources other than your intended users.

Some of this traffic may make requests for non-existent or non-sensical resources.

## Cause

This is normal on the Internet, and there are various reasons it might happen:

*   An attacker is [fingerprinting you](http://security.stackexchange.com/questions/37839/strange-get-requests-to-my-apache-web-server)

*   An attacker is [probing you for vulnerabilities](http://serverfault.com/questions/215074/strange-stuff-in-apache-log)

*   A spammer is trying to get you to visit their site

*   Someone is mistakenly sending traffic to you

## Resolution

This traffic is usually harmless as long as your app does not expose major unpatched vulnerabilities.

So, the best thing you can do is to take a proactive security posture that includes secure code development practices, regular security assessment of your apps, and regular patching.


# aptible apps



This command lists [Apps](/core-concepts/apps/overview) in an [Environment](/core-concepts/architecture/environments).

# Synopsis

```
Usage:
  aptible apps

Options:
  [--environment=ENVIRONMENT]
```


# aptible apps:create



This command creates a new [App](/core-concepts/apps/overview).

# Synopsis

```
Usage:
  aptible apps:create HANDLE

Options:
  [--environment=ENVIRONMENT]

```


# aptible apps:deprovision



This command deprovisions an [App](/core-concepts/apps/overview).

# Synopsis

```
Usage:
  aptible apps:deprovision

Options:
      [--app=APP]
      [--environment=ENVIRONMENT]
  -r, [--remote=REMOTE]
```


# aptible apps:rename



This command renames [App](/core-concepts/apps/overview) handles. For the change to take effect, the App must be restarted.

# Synopsis

```
Usage:
  aptible apps:rename OLD_HANDLE NEW_HANDLE [--environment ENVIRONMENT_HANDLE]

Options:
  [--environment=ENVIRONMENT]
```


# aptible apps:scale



This command [scales](/core-concepts/scaling/overview) App [Services](/core-concepts/apps/deploying-apps/services) up or down.

# Synopsis

```
Usage:
  aptible apps:scale SERVICE [--container-count COUNT] [--container-size SIZE_MB] [--container-profile PROFILE]

Options:
      [--app=APP]
      [--environment=ENVIRONMENT]
  -r, [--remote=REMOTE]
      [--container-count=N]
      [--container-size=N]
      [--container-profile=PROFILE]
```

# Examples

```shell
aptible apps:scale --app "$APP_HANDLE" SERVICE \
        --container-count COUNT \
        --container-size SIZE_MB
```

#### Container Sizes (MB)

**All container profiles** support the following sizes: 512, 1024, 2048, 4096, 7168, 15360, 30720

The following profiles offer additional supported sizes:

*   **General Purpose (M) - Legacy, General Purpose(M) and Memory Optimized(R)** - **Legacy**: 61440, 153600, 245760
*   **Compute Optimized (C)**: 61440, 153600, 245760, 376832
*   **Memory Optimized (R)**: 61440, 153600, 245760, 376832, 507904, 770048


# aptible backup:list



This command lists all [Database Backups](/core-concepts/managed-databases/managing-databases/database-backups) for a given [Database](/core-concepts/managed-databases/overview).

## Synopsis

```
Usage:
  aptible backup:list DB_HANDLE

Options:
  [--environment=ENVIRONMENT]
  [--max-age=MAX_AGE]          # Limit backups returned (example usage: 1w, 1y, etc.)
                               # Default: 1mo

```

# Examples

```shell
aptible backup:list "$DB_HANDLE"
```


# aptible backup:orphaned



This command lists all [Final Database Backups](/core-concepts/managed-databases/managing-databases/database-backups#retention-and-disposal).

# Synopsis

```
Usage:
  aptible backup:orphaned

Options:
  [--environment=ENVIRONMENT]
  [--max-age=MAX_AGE]          # Limit backups returned (example usage: 1w, 1y, etc.)
                               # Default: 1y
```


# aptible backup:purge



This command permanently deletes a [Database Backup](/core-concepts/managed-databases/managing-databases/database-backups) and its copies.

# Synopsis

```
Usage:
  aptible backup:purge BACKUP_ID
```


# aptible backup:restore



This command is used to [restore from a Database Backup](/core-concepts/managed-databases/managing-databases/database-backups#restoring-from-a-backup). This command creates a new database: it **does not overwrite your existing database.** In fact, it doesn't interact with your existing database at all. Since this is a new Database, Databases are created with General Purpose Container Profile, which is the [default Container Profile.](/core-concepts/scaling/container-profiles#default-container-profile)

You'll need the ID of an existing [Backup](/core-concepts/managed-databases/managing-databases/database-backups) to use this command. You can find those IDs using the [`aptible backup:list`](/reference/aptible-cli/cli-commands/cli-backup-list) command or through the Dashboard.

<Warning> Warning: If you are restoring a Backup of a GP3 volume, the new Database will be provisioned with the base [performance characteristics](/core-concepts/scaling/database-scaling#throughput-performance): 3,000 IOPs and 125MB/s throughput. If the original Database's performance was scaled up, you may need to modify the restored Database if you wish to retain the performance of the source Database. </Warning>

# Synopsis

```
Usage:
  aptible backup:restore BACKUP_ID [--environment ENVIRONMENT_HANDLE] [--handle HANDLE] [--container-size SIZE_MB] [--disk-size SIZE_GB] [--container-profile PROFILE] [--iops IOPS] [--key-arn KEY_ARN]

Options:
  [--handle=HANDLE]            # a name to use for the new database
  [--environment=ENVIRONMENT]  # a different environment to restore to
  [--container-size=N]
  [--size=N]
  [--disk-size=N]
  [--key-arn=KEY_ARN]
  [--container-profile=PROFILE]
  [--iops=IOPS]
```

# Examples

## Restore a Backup

```shell
aptible backup:restore "$BACKUP_ID"
```

## Customize the new Database

You can also customize the new [Database](/core-concepts/managed-databases/overview) that will be created from the Backup:

```shell
aptible backup:restore "$BACKUP_ID" \
        --handle "$NEW_DATABASE_HANDLE" \
        --container-size "$CONTAINER_SIZE_MB" \
        --disk-size "$DISK_SIZE_GB"
```

If no handle is provided, it will default to `$DB_HANDLE-at-$BACKUP_DATE` where `$DB_HANDLE` is the handle of the Database the backup was taken from. Database handles must:

*   Only contain lowercase alphanumeric characters,`.`, `_`, or `-`
*   Be between 1 to 64 characters in length
*   Be unique within their [Environment](/core-concepts/architecture/environments)

Therefore, there are two situations where the default handle can be invalid:

*   The handle is longer than 64 characters. The default handle will be 23 characters longer than the original Database's handle.
*   The default handle is not unique within the Environment. Most likely, this would be caused by restoring the same backup to the same Environment multiple times.

## Restore to a different Environment

You can restore Backups across [Environments](/core-concepts/architecture/environments) as long as they are hosted on the same type of [Stack](/core-concepts/architecture/stacks). You can only restore Backups from a [Dedicated Stack](/core-concepts/architecture/stacks#dedicated-stacks) in another Dedicated Stack and backups from a Shared Stack in another Shared Stack. Since Environments are globally unique, you do not need to specify the Stack in your command:

```shell
aptible backup:restore "$BACKUP_ID" \
        --environment "$ENVIRONMENT_HANDLE"
```

#### Container Sizes (MB)

**General Purpose(M)**: 512, 1024, 2048, 4096, 7168, 15360, 30720, 61440, 153600, 245760


# aptible backup_retention_policy



This command shows the current
[backup retention policy](/core-concepts/managed-databases/managing-databases/database-backups#automatic-backups)
for an [Environment](/core-concepts/architecture/environments).

# Synopsis

```
Usage:
  aptible backup_retention_policy [ENVIRONMENT_HANDLE]

Show the current backup retention policy for the environment
```


# aptible backup_retention_policy:set



This command changes the
[backup retention policy](/core-concepts/managed-databases/managing-databases/database-backups#automatic-backups)
for an [Environment](/core-concepts/architecture/environments). Only the
specified attributes will be changed. The rest will reuse the current value.

# Synopsis

```
Usage:
  aptible backup_retention_policy:set [ENVIRONMENT_HANDLE] [--daily DAILY_BACKUPS] [--monthly MONTHLY_BACKUPS] [--yearly YEARLY_BACKUPS] [--make-copy|--no-make-copy] [--keep-final|--no-keep-final] [--force]

Options:
  [--daily=N]                        # Number of daily backups to retain
  [--monthly=N]                      # Number of monthly backups to retain
  [--yearly=N]                       # Number of yearly backups to retain
  [--make-copy], [--no-make-copy]    # If backup copies should be created
  [--keep-final], [--no-keep-final]  # If final backups should be kept when databases are deprovisioned
  [--force]                          # Do not prompt for confirmation if the new policy retains fewer backups than the current policy

Change the environment's backup retention policy
```


# aptible config



This command prints an App's [Configuration](/core-concepts/apps/deploying-apps/configuration) variables.

## Synopsis

```
Usage:
  aptible config

Options:
      [--app=APP]
      [--environment=ENVIRONMENT]
  -r, [--remote=REMOTE]
```

> ❗️\*\* Warning:\*\* The output of this command is shell escaped, meaning if you have included any special characters, they will be shown with an escape character. For instance, if you set `"foo=bar?"` it will be displayed by [`aptible config`](/reference/aptible-cli/cli-commands/cli-config) as `foo=bar\?`.

> If the values do not appear as you expect, you can further confirm how they are set using the JSON output\_format, or by inspecting the environment of your container directly using an [Ephemeral SSH Sessions](/core-concepts/apps/connecting-to-apps/ssh-sessions).

# Examples

```shell
aptible config --app "$APP_HANDLE"
```


# aptible config:add



This command is an alias to [`aptible config:set`](/reference/aptible-cli/cli-commands/cli-config-set).

# Synopsis

```javascript
Usage:
  aptible config:add [VAR1=VAL1] [VAR2=VAL2] [...]

Options:
      [--app=APP]
      [--environment=ENVIRONMENT]
  -r, [--remote=REMOTE]
```


# aptible config:get



This command prints a single value from the App's [Configuration](/core-concepts/apps/deploying-apps/configuration) variables.

# Synopsis

```
Usage:
  aptible config:get [VAR1]

Options:
      [--app=APP]
      [--environment=ENVIRONMENT]
  -r, [--remote=REMOTE]
```

# Examples

```shell
aptible config:get FORCE_SSL --app "$APP_HANDLE"
```


# aptible config:rm



This command is an alias to [`aptible config:unset`](/reference/aptible-cli/cli-commands/cli-config-unset).

## Synopsis

```
Usage:
  aptible config:rm [VAR1][VAR2][...]

Options:
 [--app=APP]
 [--environment= ENVIRONMENT]
  -r, [--remote=REMOTE]
```


# aptible config:set



This command sets [Configuration](/core-concepts/apps/deploying-apps/configuration) variables for an [App](/core-concepts/apps/overview).

# Synopsis

```
Usage:
  aptible config:set [VAR1=VAL1] [VAR2=VAL2] [...]

Options:
      [--app=APP]
      [--environment=ENVIRONMENT]
  -r, [--remote=REMOTE]
```

# Examples

## Setting variables

```shell
aptible config:set --app "$APP_HANDLE" \
        VARIABLE_1=VALUE_1 \
        VARIABLE_2=VALUE_2
```

## Setting a variable from a file

> 📘 Setting variables from a file is a convenient way to set complex variables that contain spaces, newlines, or other special characters.

```shell
# This will read file.txt and set it as VARIABLE

aptible config:set --app "$APP_HANDLE" \
        "VARIABLE=$(cat file.txt)"
```

> ❗️ Warning: When setting variables from a file using PowerShell, you need to use `Get-Content` with the `-Raw` option to preserve newlines.

```shell
aptible config:set --app "$APP_HANDLE" \
        VARIABLE=$(Get-Content file.txt -Raw)
```

## Deleting variables

To delete a variable, set it to an empty value:

```shell
aptible config:set --app "$APP_HANDLE" \
        VARIABLE=
```


# aptible config:unset



This command is used to remove [Configuration](/core-concepts/apps/deploying-apps/configuration) variables from an [App](/core-concepts/apps/overview).

> 📘 Tip

> You can also use [`aptible config:set`](/reference/aptible-cli/cli-commands/cli-config-set) to set and remove Configuration variables at the same time by passing an empty value:

```shell
aptible config:set --app "$APP_HANDLE" \
        VAR_TO_ADD=some VAR_TO_REMOVE=
```

# Examples

```shell
aptible config:unset --app "$APP_HANDLE" \
        VAR_TO_REMOVE
```

# Synopsis

```
Usage:
  aptible config:unset [VAR1] [VAR2] [...]

Options:
      [--app=APP]
      [--environment=ENVIRONMENT]
  -r, [--remote=REMOTE]

Remove an ENV variable from an app
```


# aptible db:backup



This command is used to create [Database Backups](/core-concepts/managed-databases/managing-databases/database-backups).

## Synopsis

```
Usage:
  aptible db:backup HANDLE

Options:
  [--environment=ENVIRONMENT]
```

# Examples

```shell
aptible db:backup "$DB_HANDLE"
```


# aptible db:clone



This command clones an existing Database.\
\
❗️ Warning: Consider using [`aptible backup:restore`](/reference/aptible-cli/cli-commands/cli-backup-restore) instead.

> `db:clone` connects to your existing Database to copy data out and imports it into your new Database.

> This means `db:clone` creates load on your existing Database, and can be slow or disruptive if you have a lot of data to copy. It might even fail if the new Database is underprovisioned, since this is a resource-intensive process.

> This also means `db:clone` only works for a subset of [Supported Databases](/core-concepts/managed-databases/supported-databases/overview) (those that allow for convenient import / export of data).

> In contrast, `backup:restore` instead uses a snapshot of your existing Database's disk, which means it doesn't affect your existing Database at all and supports all Aptible-supported Databases.

# Synopsis

```
Usage:
  aptible db:clone SOURCE DEST

Options:
  [--environment=ENVIRONMENT]
```


# aptible db:create



This command creates a new [Database](/core-concepts/managed-databases/overview) using the General Purpose container profile by default. The container profile can only be modified in the Aptible dashboard.

# Synopsis

```
Usage:
  aptible db:create HANDLE [--type TYPE] [--version VERSION] [--container-size SIZE_MB] [--container-profile PROFILE] [--disk-size SIZE_GB] [--iops IOPS] [--key-arn KEY_ARN]

Options:
  [--type=TYPE]
  [--version=VERSION]
  [--container-size=N]
  [--container-profile PROFILE]
                               # Default: m
  [--disk-size=N]
                               # Default: 10
  [--size=N]
  [--key-arn=KEY_ARN]
  [--iops=IOPS]
  [--environment=ENVIRONMENT]
```

# Examples

#### Create a new Database using a specific type

You can specify the type using the `--type` option. This parameter defaults to `postgresql`, but you can use any of Aptible's [Supported Databases](/core-concepts/managed-databases/supported-databases/overview).

For example, to create a [Redis](/core-concepts/managed-databases/supported-databases/redis) database:

```shell
aptible db:create --type redis
```

#### Create a new Database using a specific version

Use the `--version` flag in combination with `--type` to use a specific version:

```shell
aptible db:create --type postgresql --version 9.6
```

> 📘 Use the [`aptible db:versions`](/reference/aptible-cli/cli-commands/cli-db-versions) command to identify available versions.

#### Create a new Database with a custom Disk Size

```shell
aptible db:create --disk-size 20 "$DB_HANDLE"
```

#### Create a new Database with a custom Container Size

```shell
aptible db:create --container-size 2048 "$DB_HANDLE"
```

#### Container Sizes (MB)

**General Purpose(M)**: 512, 1024, 2048, 4096, 7168, 15360, 30720, 61440, 153600, 245760

#### Profiles

`m`: General purpose container \
`c`: Compute-optimized container \
`r`: Memory-optimized container


# aptible db:deprovision



This command is used to deprovision a [Database](/core-concepts/managed-databases/overview).

# Synopsis

```
Usage:
  aptible db:deprovision HANDLE

Options:
  [--environment=ENVIRONMENT]
```


# aptible db:dump



This command dumps a remote [PostgreSQL Database](/core-concepts/managed-databases/supported-databases/postgresql) to a file.\
\
Synopsis

```
Usage:
  aptible db:dump HANDLE [pg_dump options]

Options:
  [--environment=ENVIRONMENT]
```


# aptible db:execute



This command executes SQL against a [Database](/core-concepts/managed-databases/managing-databases/overview).

# Synopsis

```
Usage:
  aptible db:execute HANDLE SQL_FILE [--on-error-stop]

Options:
  [--environment=ENVIRONMENT]
  [--on-error-stop], [--no-on-error-stop]
```


# aptible db:list



This command lists [Databases](/core-concepts/managed-databases/overview) in an [Environment](/core-concepts/architecture/environments).

# Synopsis

```
Usage:
  aptible db:list

Options:
  [--environment=ENVIRONMENT]
```


# aptible db:modify



This command modifies existing [Databases](/core-concepts/managed-databases/managing-databases/overview). Running this command does not cause downtime.

# Synopsis

```
Usage:
  aptible db:modify HANDLE [--iops IOPS] [--volume-type [gp2, gp3]]

Options:
  [--environment=ENVIRONMENT]
  [--iops=N]
  [--volume-type=VOLUME_TYPE]

```

> 📘 The IOPS option only applies to GP3 volume.  If you currently have a GP2 volume and need more IOPS, simultaneously specify both the `--volume-type gp3` and `--iops NNNN` options.

> 📘 The maximum IOPS is 16,000, but you must meet a minimum ratio of 1 GB disk size per 500 IOPS.  For example, to reach 16,000 IOPS, you must have at least a 32 GB or larger disk.


# aptible db:reload



This command reloads a [Database](/core-concepts/managed-databases/managing-databases/overview) by replacing the running Database [Container](/core-concepts/architecture/containers/overview) with a new one.

<Tip> Reloading can be useful if your Database appears to be misbehaving.</Tip>

<Note> Using [`aptible db:reload`](/reference/aptible-cli/cli-commands/cli-db-reload) is faster than [`aptible db:restart`](/reference/aptible-cli/cli-commands/cli-db-restart), but it does not let you [resize](/core-concepts/scaling/database-scaling) your Database. </Note>

# Synopsis

```
Usage:
  aptible db:reload HANDLE

Options:
  [--environment=ENVIRONMENT]
```


# aptible db:rename



This command renames a [Database](/core-concepts/managed-databases/managing-databases/overview) handle. For this change to take effect, the Database must be restarted. After restart, the new Database handle will appear in log and metric drains.\
\
Synopsis

```
Usage:
  aptible db:rename OLD_HANDLE NEW_HANDLE [--environment ENVIRONMENT_HANDLE]

Options:
  [--environment=ENVIRONMENT]
```


# aptible db:replicate



This command creates a [Database Replica](/core-concepts/managed-databases/managing-databases/replication-clustering). All new Replicas are created with General Purpose Container Profile, which is the [default Container Profile.](/core-concepts/scaling/container-profiles#default-container-profile)

# Synopsis

```
Usage:
  aptible db:replicate HANDLE REPLICA_HANDLE [--container-size SIZE_MB] [--container-profile PROFILE]  [--disk-size SIZE_GB] [--iops IOPS] [--logical --version VERSION] [--key-arn KEY_ARN]

Options:
  [--environment=ENVIRONMENT]
  [--container-size=N]
  [--container-profile PROFILE]
                               # Default: m
  [--size=N]
  [--disk-size=N]
  [--logical], [--no-logical]
  [--version=VERSION]
  [--iops=IOPS]
  [--key-arn=KEY_ARN]
```

> 📘 The `--version` option is only supported for postgresql logical replicas.

# Examples

#### Create a replica with a custom Disk Size

```shell
aptible db:replicate "$DB_HANDLE" "$REPLICA_HANDLE" \
            --disk-size 20
```

#### Create a replica with a custom Container Size

```shell
aptible db:replicate "$DB_HANDLE" "$REPLICA_HANDLE" \
            --container-size 2048
```

#### Create a replica with a custom Container and Disk Size

```shell
aptible db:replicate "$DB_HANDLE" "$REPLICA_HANDLE" \
            --container-size 2048 \
            --disk-size 20
```

#### Create an upgraded replica for logical replication

```shell
aptible db:replicate "$DB_HANDLE" "$REPLICA_HANDLE" \
            --logical --version 12
```

#### Container Sizes (MB)

**General Purpose(M)**: 512, 1024, 2048, 4096, 7168, 15360, 30720, 61440, 153600, 245760

#### Profiles

`m`: General purpose container \
`c`: Compute-optimized container \
`r`: Memory-optimized container

# How Logical Replication Works

[`aptible db:replicate --logical`](/reference/aptible-cli/cli-commands/cli-db-replicate) should work in most cases. This section provides additional details details on how the CLI command works for debugging or if you'd like to know more about what the command does for you.

The CLI command uses the `pglogical` extension to set up logical replication between the existing Database and the new replica Database. At a high level, these are the steps the CLI command takes to setup logical replication for you:

1.  Update `max_worker_processes` on the replica based on the number of [PostgreSQL databases](https://www.postgresql.org/docs/current/managing-databases.html) being replicated. `pglogical` uses several worker processes per database so it can easily exhaust the default `max_worker_processes` if replicating more than a couple of databases.
2.  Recreate all roles (users) on the replica. `pglogical`'s copy of the source database structure includes assigning the same owner to each table and granting the same permissions. The roles must exist on the replica in order for this to work.
3.  For each PostgreSQL database on the source Database, excluding those that beginning with `template`:
    1.  Create the database on the replica with the `aptible` user as the owner.
    2.  Enable the `pglogical` extension on the source and replica database.
    3.  Create a `pglogical` subscription between the source and replica database. This will copy the source database's structure (e.g. schemas, tables, permissions, extensions, etc.).
    4.  Start the initial data sync. This will truncate and sync data for all tables in all schemas except for the `information_schema`, `pglogical`, and `pglogical_origin` schemas and schemas that begin with `pg_` (system schemas).

The replica does not wait for the initial data sync to complete before coming online. The time it takes to sync all of the data from the source Database depends on the size of the Database.

When run on the replica, the following query will list all tables that are not in the `replicating` state and, therefore, have not finished syncing the initial data from the source Database.

```postgresql
SELECT * FROM pglogical.local_sync_status WHERE NOT sync_status = 'r';
```


# aptible db:restart



This command restarts a [Database](/core-concepts/managed-databases/overview) and can be used to resize a Database.

<Tip> If you want to restart your Database in place without resizing it, consider using [`aptible db:reload`](/reference/aptible-cli/cli-commands/cli-db-reload) instead. [`aptible db:reload`](/reference/aptible-cli/cli-commands/cli-db-reload) is slightly faster than [`aptible db:restart`](/reference/aptible-cli/cli-commands/cli-db-restart).</Tip>

# Synopsis

```
Usage:
  aptible db:restart HANDLE [--container-size SIZE_MB] [--container-profile PROFILE]  [--disk-size SIZE_GB] [--iops IOPS] [--volume-type [gp2, gp3]]

Options:
  [--environment=ENVIRONMENT]
  [--container-size=N]
  [--container-profile PROFILE]
                               # Default: m
  [--disk-size=N]
  [--size=N]
  [--iops=N]
  [--volume-type=VOLUME_TYPE]
```

# Examples

#### Resize the Container

```shell
aptible db:restart "$DB_HANDLE" \
        --container-size 2048
```

#### Resize the Disk

```shell
aptible db:restart "$DB_HANDLE" \
        --disk-size 120
```

#### Resize Container and Disk

```shell
aptible db:restart "$DB_HANDLE" \
        --container-size 2048 \
        --disk-size 120
```

#### Container Sizes (MB)

**All container profiles** support the following sizes: 512, 1024, 2048, 4096, 7168, 15360, 30720

The following profiles offer additional supported sizes:

*   **General Purpose (M) - Legacy, General Purpose(M) and Memory Optimized(R)** - **Legacy**: 61440, 153600, 245760
*   **Compute Optimized (C)**: 61440, 153600, 245760, 376832
*   **Memory Optimized (R)**: 61440, 153600, 245760, 376832, 507904, 770048

#### Profiles

`m`: General purpose container \
`c`: Compute-optimized container \
`r`: Memory-optimized container


# aptible db:tunnel



This command creates [Database Tunnels](/core-concepts/managed-databases/connecting-databases/database-tunnels). If your [Database](/core-concepts/managed-databases/overview) exposes multiple [Database Credentials](/core-concepts/managed-databases/connecting-databases/database-credentials), you can specify which one you'd like to tunnel to.

## Synopsis

```
Usage:
  aptible db:tunnel HANDLE

Options:
  [--environment=ENVIRONMENT]
  [--port=N]
  [--type=TYPE]
```

# Examples

To tunnel using your Database's default Database Credential:

```shell
aptible db:tunnel "$DB_HANDLE"
```

To tunnel using a specific Database Credential:

```shell
aptible db:tunnel "$DB_HANDLE" --type "$CREDENTIAL_TYPE"
```


# aptible db:url



This command prints [Database Credentials](/core-concepts/managed-databases/connecting-databases/database-credentials) (which are displayed as Database URLs).

# Synopsis

```
Usage:
  aptible db:url HANDLE

Options:
  [--environment=ENVIRONMENT]
  [--type=TYPE]
```


# aptible db:versions



This command lists all available [Database](/core-concepts/managed-databases/managing-databases/overview) versions.\
\
This is useful for identifying available versions when creating a new Database.

# Synopsis

```
Usage:
  aptible db:versions
```


# aptible deploy



This command is used to deploy an App. This can be used for [Direct Docker Image Deploy](/how-to-guides/app-guides/migrate-dockerfile-to-direct-image-deploy) and/or for [Synchronizing Configuration and code changes](/how-to-guides/app-guides/synchronize-config-code-changes).

Docker image names are only supported in image:tag; sha256 format is not supported.

# Synopsis

```
Usage:
  aptible deploy [OPTIONS] [VAR1=VAL1] [VAR2=VAL2] [...]

Options:
      [--git-commitish=GIT_COMMITISH]                                  # Deploy a specific git commit or branch: the commitish must have been pushed to Aptible beforehand
      [--git-detach], [--no-git-detach]                                # Detach this app from its git repository: its Procfile, Dockerfile, and .aptible.yml will be ignored until you deploy again with git
      [--docker-image=APTIBLE_DOCKER_IMAGE]                            # Shorthand for APTIBLE_DOCKER_IMAGE=...
      [--private-registry-email=APTIBLE_PRIVATE_REGISTRY_EMAIL]        # Shorthand for APTIBLE_PRIVATE_REGISTRY_EMAIL=...
      [--private-registry-username=APTIBLE_PRIVATE_REGISTRY_USERNAME]  # Shorthand for APTIBLE_PRIVATE_REGISTRY_USERNAME=...
      [--private-registry-password=APTIBLE_PRIVATE_REGISTRY_PASSWORD]  # Shorthand for APTIBLE_PRIVATE_REGISTRY_PASSWORD=...
      [--app=APP]
      [--environment=ENVIRONMENT]
  -r, [--remote=REMOTE]
```


# aptible endpoints:database:create



This command creates a [Database Endpoint.](/core-concepts/managed-databases/connecting-databases/database-endpoints)

# Synopsis

```
Usage:
  aptible endpoints:database:create DATABASE

Options:
  [--environment=ENVIRONMENT]
  [--database=DATABASE]
  [--internal], [--no-internal]   # Restrict this Endpoint to internal traffic
  [--ip-whitelist=one two three]  # A list of IPv4 sources (addresses or CIDRs) to which to restrict traffic to this Endpoint
```

# Examples

#### Create a new Database Endpoint

```shell
aptible endpoints:database:create \
        --database "$DATABASE_HANDLE"
```

#### Create a new Database Endpoint with IP Filtering

```shell
aptible endpoints:database:create \
        --database "$DATABASE_HANDLE" \
        --ip-whitelist 1.1.1.1/1 2.2.2.2
```


# aptible endpoints:database:modify



This command modifies an existing [Database Endpoint.](/core-concepts/managed-databases/connecting-databases/database-endpoints)

# Synopsis

```
Usage:
  aptible endpoints:database:modify --database DATABASE ENDPOINT_HOSTNAME

Options:
  [--environment=ENVIRONMENT]
  [--database=DATABASE]
  [--ip-whitelist=one two three]  # A list of IPv4 sources (addresses or CIDRs) to which to restrict traffic to this Endpoint
  [--no-ip-whitelist]             # Disable IP Whitelist
```


# aptible endpoints:deprovision



This command deprovisions an [App Endpoint](/core-concepts/apps/connecting-to-apps/app-endpoints/overview) or a [Database Endpoint](/core-concepts/managed-databases/connecting-databases/database-endpoints).

# Synopsis

```
Usage:
  aptible endpoints:deprovision [--app APP | --database DATABASE] ENDPOINT_HOSTNAME

Options:
      [--app=APP]
      [--environment=ENVIRONMENT]
  -r, [--remote=REMOTE]
      [--database=DATABASE]
```

# Examples

The examples below `$ENDPOINT_HOSTNAME` reference the [Endpoint Hostname](/core-concepts/apps/connecting-to-apps/app-endpoints/custom-domain#endpoint-hostname) for the Endpoint you'd like to deprovision.

> 📘 Use the [`aptible endpoints:list`](/reference/aptible-cli/cli-commands/cli-endpoints-list) command to easily locate the [Endpoint Hostname](/core-concepts/apps/connecting-to-apps/app-endpoints/custom-domain#endpoint-hostname) for a given Endpoint.

#### Deprovision an App Endpoint

```shell
aptible endpoints:deprovision \
        --app "$APP_HANDLE" \
        "$ENDPOINT_HOSTNAME"
```

#### Deprovision a Database Endpoint

```shell
aptible endpoints:deprovision \
        --database "$DATABASE_HANDLE" \
        "$ENDPOINT_HOSTNAME"
```


# aptible endpoints:grpc:create



This command creates a new [gRPC Endpoint](/core-concepts/apps/connecting-to-apps/app-endpoints/grpc-endpoints).

# Synopsis

```
Usage:
  aptible endpoints:grpc:create [--app APP] SERVICE

Options:
      [--environment=ENVIRONMENT]
      [--app=APP]
  -r, [--remote=REMOTE]
      [--default-domain], [--no-default-domain]            # Enable Default Domain on this Endpoint
      [--port=N]                                           # A port to expose on this Endpoint   
      [--internal], [--no-internal]                        # Restrict this Endpoint to internal traffic
      [--ip-whitelist=one two three]                       # A list of IPv4 sources (addresses or CIDRs) to which to restrict traffic to this Endpoint
      [--certificate-file=CERTIFICATE_FILE]                # A file containing a certificate to use on this Endpoint
      [--private-key-file=PRIVATE_KEY_FILE]                # A file containing a private key to use on this Endpoint
      [--managed-tls], [--no-managed-tls]                  # Enable Managed TLS on this Endpoint
      [--managed-tls-domain=MANAGED_TLS_DOMAIN]            # A domain to use for Managed TLS
      [--certificate-fingerprint=CERTIFICATE_FINGERPRINT]  # The fingerprint of an existing Certificate to use on this Endpoint
```

# Examples

In all the examples below, `$SERVICE` represents the name of a [Service](/core-concepts/apps/deploying-apps/services) for the app you add an Endpoint to.

> 📘 If your app is using an [Implicit Service](/how-to-guides/app-guides/define-services#implicit-service-cmd), the service name is always `cmd`.

#### Create a new Endpoint using custom Container Ports and an existing [Custom Certificate](/core-concepts/apps/connecting-to-apps/app-endpoints/custom-certificate)

In the example below, `$CERTIFICATE_FINGERPRINT` is the SHA-256 fingerprint of a [Custom Certificate](/core-concepts/apps/connecting-to-apps/app-endpoints/custom-certificate) that exist in the same [Environment](/core-concepts/architecture/environments) as the App you are adding an Endpoint for.

> 📘 Tip: Use the Dashboard to easily locate the Certificate Fingerprint for a given Certificate.

> ❗️ Warning: Everything after the `--ports` argument is assumed to be part of the list of ports, so you need to pass it last.

```shell
aptible endpoints:grpc:create \
        "$SERVICE" \
        --app "$APP_HANDLE" \
        --certificate-fingerprint "$CERTIFICATE_FINGERPRINT" \
        --ports 8000 8001 8002 8003
```

#### More Examples

This command is fairly similar in usage to [`aptible endpoints:https:create`](/reference/aptible-cli/cli-commands/cli-endpoints-https-create). Review the examples there.


# aptible endpoints:grpc:modify



This command lets you modify [gRPC Endpoints](/core-concepts/apps/connecting-to-apps/app-endpoints/grpc-endpoints).

# Synopsis

```
Usage:
  aptible endpoints:grpc:modify [--app APP] ENDPOINT_HOSTNAME

Options:
      [--environment=ENVIRONMENT]
      [--app=APP]
  -r, [--remote=REMOTE]
      [--port=N]                                           # A port to expose on this Endpoint
      [--ip-whitelist=one two three]                       # A list of IPv4 sources (addresses or CIDRs) to which to restrict traffic to this Endpoint
      [--no-ip-whitelist]                                  # Disable IP Whitelist
      [--certificate-file=CERTIFICATE_FILE]                # A file containing a certificate to use on this Endpoint
      [--private-key-file=PRIVATE_KEY_FILE]                # A file containing a private key to use on this Endpoint
      [--managed-tls], [--no-managed-tls]                  # Enable Managed TLS on this Endpoint
      [--managed-tls-domain=MANAGED_TLS_DOMAIN]            # A domain to use for Managed TLS
      [--certificate-fingerprint=CERTIFICATE_FINGERPRINT]  # The fingerprint of an existing Certificate to use on this Endpoint
```

# Examples

The options available for this command are similar to those available for [`aptible endpoints:grpc:create`](/reference/aptible-cli/cli-commands/cli-endpoints-grpc-create). Review the examples there.


# aptible endpoints:https:create



This command created a new [HTTPS Endpoint](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/overview).

# Synopsis

```
Usage:
  aptible endpoints:https:create [--app APP] SERVICE

Options:
      [--environment=ENVIRONMENT]
      [--app=APP]
  -r, [--remote=REMOTE]
      [--default-domain], [--no-default-domain]            # Enable Default Domain on this Endpoint
      [--port=N]                                           # A port to expose on this Endpoint
      [--internal], [--no-internal]                        # Restrict this Endpoint to internal traffic
      [--ip-whitelist=one two three]                       # A list of IPv4 sources (addresses or CIDRs) to which to restrict traffic to this Endpoint
      [--certificate-file=CERTIFICATE_FILE]                # A file containing a certificate to use on this Endpoint
      [--private-key-file=PRIVATE_KEY_FILE]                # A file containing a private key to use on this Endpoint
      [--managed-tls], [--no-managed-tls]                  # Enable Managed TLS on this Endpoint
      [--managed-tls-domain=MANAGED_TLS_DOMAIN]            # A domain to use for Managed TLS
      [--certificate-fingerprint=CERTIFICATE_FINGERPRINT]  # The fingerprint of an existing Certificate to use on this Endpoint
```

# Examples

In all the examples below, `$SERVICE` represents the name of a [Service](/core-concepts/apps/deploying-apps/services) for the app you are adding an Endpoint to.

> 📘 If your app is using an [Implicit Service](/how-to-guides/app-guides/define-services#implicit-service-cmd), the service name is always `cmd`.

#### Create a new Endpoint using a new [Custom Certificate](/core-concepts/apps/connecting-to-apps/app-endpoints/custom-certificate)

In the example below, `$CERTIFICATE_FILE` is the path to a file containing a PEM-formatted certificate bundle, and `$PRIVATE_KEY_FILE` is the path to a file containing the matching private key (see [Format](/core-concepts/apps/connecting-to-apps/app-endpoints/custom-certificate#format) for more information).

```shell
aptible endpoints:https:create \
        --app "$APP_HANDLE" \
        --certificate-file "$CERTIFICATE_FILE" \
        --private-key-file "$PRIVATE_KEY_FILE" \
        "$SERVICE"
```

#### Create a new Endpoint using an existing [Custom Certificate](/core-concepts/apps/connecting-to-apps/app-endpoints/custom-certificate)

In the example below, `$CERTIFICATE_FINGERPRINT` is the SHA-256 fingerprint of a [Custom Certificate](/core-concepts/apps/connecting-to-apps/app-endpoints/custom-certificate) that exist in the same [Environment](/core-concepts/architecture/environments) as the App you are adding an Endpoint for.

> 📘 Tip: Use the Dashboard to easily locate the Certificate Fingerprint for a given Certificate.

```shell
aptible endpoints:https:create \
        --app "$APP_HANDLE" \
        --certificate-fingerprint "$CERTIFICATE_FINGERPRINT" \
        "$SERVICE"
```

#### Create a new Endpoint using [Managed TLS](/core-concepts/apps/connecting-to-apps/app-endpoints/managed-tls)

In the example below, `$YOUR_DOMAIN` is the domain you intend to use with your Endpoint.

After initial provisioning completes, the CLI will return the [Managed HTTPS Validation Records](/core-concepts/apps/connecting-to-apps/app-endpoints/managed-tls#managed-https-validation-records) you need to create in order to finalize the Endpoint.

Once you've created these records, use the [`aptible endpoints:renew`](/reference/aptible-cli/cli-commands/cli-endpoints-renew) to complete provisioning.

```shell
aptible endpoints:https:create \
        --app "$APP_HANDLE" \
        --managed-tls \
        --managed-tls-domain "$YOUR_DOMAIN"
        "$SERVICE"
```

#### Create a new Endpoint using a [Default Domain](/core-concepts/apps/connecting-to-apps/app-endpoints/default-domain)

```shell
aptible endpoints:https:create \
        --app "$APP_HANDLE" \
        --default-domain \
        "$SERVICE"
```

#### Create a new Endpoint using a custom Container Port and an existing Certificate

```shell
aptible endpoints:https:create \
        --app "$APP_HANDLE" \
        --certificate-fingerprint "$CERTIFICATE_FINGERPRINT" \
        --port 80 \
        "$SERVICE"
```


# aptible endpoints:https:modify



This command modifies an existing App [HTTP(S) Endpoint.](/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/overview)

> 📘 Tip: Use the [`aptible endpoints:list`](/reference/aptible-cli/cli-commands/cli-endpoints-list) command to easily locate the [Endpoint Hostname](/core-concepts/apps/connecting-to-apps/app-endpoints/custom-domain#endpoint-hostname) for a given Endpoint.

# Synopsis

```
Usage:
  aptible endpoints:https:modify [--app APP] ENDPOINT_HOSTNAME

Options:
      [--environment=ENVIRONMENT]
      [--app=APP]
  -r, [--remote=REMOTE]
      [--port=N]                                           # A port to expose on this Endpoint
      [--ip-whitelist=one two three]                       # A list of IPv4 sources (addresses or CIDRs) to which to restrict traffic to this Endpoint
      [--no-ip-whitelist]                                  # Disable IP Whitelist
      [--certificate-file=CERTIFICATE_FILE]                # A file containing a certificate to use on this Endpoint
      [--private-key-file=PRIVATE_KEY_FILE]                # A file containing a private key to use on this Endpoint
      [--managed-tls], [--no-managed-tls]                  # Enable Managed TLS on this Endpoint
      [--managed-tls-domain=MANAGED_TLS_DOMAIN]            # A domain to use for Managed TLS
      [--certificate-fingerprint=CERTIFICATE_FINGERPRINT]  # The fingerprint of an existing Certificate to use on this Endpoint
```

# Examples

The options available for this command are similar to those available for [`aptible endpoints:https:create`](/reference/aptible-cli/cli-commands/cli-endpoints-https-create). Review the examples there.


# aptible endpoints:list



This command lists the Endpoints for an [App](/core-concepts/apps/overview) or [Database](/core-concepts/managed-databases/overview).

# Synopsis

```
Usage:
  aptible endpoints:list [--app APP | --database DATABASE]

Options:
      [--app=APP]
      [--environment=ENVIRONMENT]
  -r, [--remote=REMOTE]
      [--database=DATABASE]
```

# Examples

#### List Endpoints for an App

```shell
aptible endpoints:list \
        --app "$APP_HANDLE"
```

#### List Endpoints for a Database

```shell
aptible endpoints:list \
        --database "$DATABASE_HANDLE"
```

#### Sample Output

```
Service: cmd
Hostname: elb-foobar-123.aptible.in
Status: provisioned
Type: https
Port: default
Internal: false
IP Whitelist: all traffic
Default Domain Enabled: false
Managed TLS Enabled: true
Managed TLS Domain: app.example.com
Managed TLS DNS Challenge Hostname: acme.elb-foobar-123.aptible.in
Managed TLS Status: ready
```

> 📘 The above block is repeated for each matching Endpoint.


# aptible endpoints:renew



This command triggers an initial renewal of a [Managed TLS](/core-concepts/apps/connecting-to-apps/app-endpoints/managed-tls) Endpoint after creating it using [`aptible endpoints:https:create`](/reference/aptible-cli/cli-commands/cli-endpoints-https-create) or [`aptible endpoints:tls:create`](/reference/aptible-cli/cli-commands/cli-endpoints-tls-create) and having set up the required [Managed HTTPS Validation Records](/core-concepts/apps/connecting-to-apps/app-endpoints/managed-tls#managed-https-validation-records).

> ⚠️ We recommend reviewing the documentation on [rate limits](/core-concepts/apps/connecting-to-apps/app-endpoints/managed-tls#rate-limits) before using this command automatically.\
> \
> 📘 You only need to do this once! After initial provisioning, Aptible automatically renews your Managed TLS certificates on a periodic basis.

# Synopsis

> 📘  Use the [`aptible endpoints:list`](/reference/aptible-cli/cli-commands/cli-endpoints-list) command to easily locate the [Endpoint Hostname](/core-concepts/apps/connecting-to-apps/app-endpoints/custom-domain#endpoint-hostname) for a given Endpoint.

```
Usage:
  aptible endpoints:renew [--app APP] ENDPOINT_HOSTNAME

Options:
      [--app=APP]
      [--environment=ENVIRONMENT]
  -r, [--remote=REMOTE]
```


# aptible endpoints:tcp:create



This command creates a new App [TCP Endpoint](/core-concepts/apps/connecting-to-apps/app-endpoints/tcp-endpoints).

# Synopsis

```
Usage:
  aptible endpoints:tcp:create [--app APP] SERVICE

Options:
      [--environment=ENVIRONMENT]
      [--app=APP]
  -r, [--remote=REMOTE]
      [--default-domain], [--no-default-domain]  # Enable Default Domain on this Endpoint
      [--ports=one two three]                    # A list of ports to expose on this Endpoint
      [--internal], [--no-internal]              # Restrict this Endpoint to internal traffic
      [--ip-whitelist=one two three]             # A list of IPv4 sources (addresses or CIDRs) to which to restrict traffic to this Endpoint
```

# Examples

In all the examples below, `$SERVICE` represents the name of a [Service](/core-concepts/apps/deploying-apps/services) for the Spp you are adding an Endpoint to.

> 📘 If your app is using an [Implicit Service](/how-to-guides/app-guides/define-services#implicit-service-cmd), the service name is always `cmd`.

#### Create a new Endpoint

```shell
aptible endpoints:tcp:create \
        --app "$APP_HANDLE" \
        "$SERVICE"
```

#### Create a new Endpoint using a [Default Domain](/core-concepts/apps/connecting-to-apps/app-endpoints/default-domain)

```shell
aptible endpoints:tcp:create \
        --app "$APP_HANDLE" \
        --default-domain \
        "$SERVICE"
```

#### Create a new Endpoint using a custom set of Container Ports

> ❗️ Warning

> The `--ports` argument accepts a list of ports, so you need to pass it last.

```shell
aptible endpoints:tcp:create \
        --app "$APP_HANDLE" \
        "$SERVICE" \
        --ports 8000 8001 8002 8003
```


# aptible endpoints:tcp:modify



This command modifies App [TCP Endpoints](/core-concepts/apps/connecting-to-apps/app-endpoints/tcp-endpoints).

# Synopsis

```
Usage:
  aptible endpoints:tcp:modify [--app APP] ENDPOINT_HOSTNAME

Options:
      [--environment=ENVIRONMENT]
      [--app=APP]
  -r, [--remote=REMOTE]
      [--ports=one two three]         # A list of ports to expose on this Endpoint
      [--ip-whitelist=one two three]  # A list of IPv4 sources (addresses or CIDRs) to which to restrict traffic to this Endpoint
      [--no-ip-whitelist]             # Disable IP Whitelist
```

# Examples

The options available for this command are similar to those available for [`aptible endpoints:tcp:create`](/reference/aptible-cli/cli-commands/cli-endpoints-tcp-create). Review the examples there.


# aptible endpoints:tls:create



This command creates a new [TLS Endpoint](/core-concepts/apps/connecting-to-apps/app-endpoints/tls-endpoints).

# Synopsis

```
Usage:
  aptible endpoints:tls:create [--app APP] SERVICE

Options:
      [--environment=ENVIRONMENT]
      [--app=APP]
  -r, [--remote=REMOTE]
      [--default-domain], [--no-default-domain]            # Enable Default Domain on this Endpoint
      [--ports=one two three]                              # A list of ports to expose on this Endpoint
      [--internal], [--no-internal]                        # Restrict this Endpoint to internal traffic
      [--ip-whitelist=one two three]                       # A list of IPv4 sources (addresses or CIDRs) to which to restrict traffic to this Endpoint
      [--certificate-file=CERTIFICATE_FILE]                # A file containing a certificate to use on this Endpoint
      [--private-key-file=PRIVATE_KEY_FILE]                # A file containing a private key to use on this Endpoint
      [--managed-tls], [--no-managed-tls]                  # Enable Managed TLS on this Endpoint
      [--managed-tls-domain=MANAGED_TLS_DOMAIN]            # A domain to use for Managed TLS
      [--certificate-fingerprint=CERTIFICATE_FINGERPRINT]  # The fingerprint of an existing Certificate to use on this Endpoint
```

# Examples

In all the examples below, `$SERVICE` represents the name of a [Service](/core-concepts/apps/deploying-apps/services) for the app you add an Endpoint to.

> 📘 If your app is using an [Implicit Service](/how-to-guides/app-guides/define-services#implicit-service-cmd), the service name is always `cmd`.

#### Create a new Endpoint using custom Container Ports and an existing [Custom Certificate](/core-concepts/apps/connecting-to-apps/app-endpoints/custom-certificate)

In the example below, `$CERTIFICATE_FINGERPRINT` is the SHA-256 fingerprint of a [Custom Certificate](/core-concepts/apps/connecting-to-apps/app-endpoints/custom-certificate) that exist in the same [Environment](/core-concepts/architecture/environments) as the App you are adding an Endpoint for.

> 📘 Tip: Use the Dashboard to easily locate the Certificate Fingerprint for a given Certificate.

> ❗️ Warning: Everything after the `--ports` argument is assumed to be part of the list of ports, so you need to pass it last.

```shell
aptible endpoints:tls:create \
        "$SERVICE" \
        --app "$APP_HANDLE" \
        --certificate-fingerprint "$CERTIFICATE_FINGERPRINT" \
        --ports 8000 8001 8002 8003
```

#### More Examples

This command is fairly similar in usage to [`aptible endpoints:https:create`](/reference/aptible-cli/cli-commands/cli-endpoints-https-create). Review the examples there.


# aptible endpoints:tls:modify



This command lets you modify [TLS Endpoints](/core-concepts/apps/connecting-to-apps/app-endpoints/tls-endpoints).

# Synopsis

```
Usage:
  aptible endpoints:tls:modify [--app APP] ENDPOINT_HOSTNAME

Options:
      [--environment=ENVIRONMENT]
      [--app=APP]
  -r, [--remote=REMOTE]
      [--ports=one two three]                              # A list of ports to expose on this Endpoint
      [--ip-whitelist=one two three]                       # A list of IPv4 sources (addresses or CIDRs) to which to restrict traffic to this Endpoint
      [--no-ip-whitelist]                                  # Disable IP Whitelist
      [--certificate-file=CERTIFICATE_FILE]                # A file containing a certificate to use on this Endpoint
      [--private-key-file=PRIVATE_KEY_FILE]                # A file containing a private key to use on this Endpoint
      [--managed-tls], [--no-managed-tls]                  # Enable Managed TLS on this Endpoint
      [--managed-tls-domain=MANAGED_TLS_DOMAIN]            # A domain to use for Managed TLS
      [--certificate-fingerprint=CERTIFICATE_FINGERPRINT]  # The fingerprint of an existing Certificate to use on this Endpoint
```

# Examples

The options available for this command are similar to those available for [`aptible endpoints:tls:create`](/reference/aptible-cli/cli-commands/cli-endpoints-tls-create). Review the examples there.


# aptible environment:ca_cert



# Synopsis

```
Usage:
  aptible environment:ca_cert

Options:
  [--environment=ENVIRONMENT]

Retrieve the CA certificate associated with the environment
```

> 📘 Since most Database clients will want you to provide a PEM formatted certificate as a file, you will most likely want to simply redirect the output of this command directly to a file, eg: "aptible environment:ca\_cert &> all-aptible-CAs.pem" or "aptible environment:ca\_cert --environment=production &> production-CA.pem".


# aptible environment:list



This command lists all [Environments.](/core-concepts/architecture/environments)

# Synopsis

```
Usage:
  aptible environment:list

Options:
  [--environment=ENVIRONMENT]
```


# aptible environment:rename



This command renames an [Environment](/core-concepts/architecture/environments) handle. You must restart all the Apps and Databases in this Environment for the changes to take effect.

# Synopsis

```
Usage:
  aptible environment:rename OLD_HANDLE NEW_HANDLE
```


# aptible help



This command displays available [commands](/reference/aptible-cli/cli-commands/overview) or one specific command.

# Synopsis

```
Usage:
  aptible help [COMMAND]
```


# aptible log_drain:create:datadog



This command lets you create a [Log Drain](/core-concepts/observability/logs/log-drains/overview) to forward your Container logs to Datadog.

> 📘 The `--url` option must be in the format of `https://http-intake.logs.datadoghq.com/v1/input/<DD_API_KEY>`. Refer to [https://docs.datadoghq.com/logs/log\_collection](https://docs.datadoghq.com/logs/log_collection) for more options.

> Please note, Datadog's documentation defaults to v2. Please use v1 Datadog documentation with Aptible.

# Synopsis

```
Usage:
  aptible log_drain:create:datadog HANDLE --url DATADOG_URL --environment ENVIRONMENT [--drain-apps true/false] [--drain_databases true/false] [--drain_ephemeral_sessions true/false] [--drain_proxies true/false]

Options:
  [--drain-apps], [--no-drain-apps]
                                                                 # Default: true
  [--drain-databases], [--no-drain-databases]
                                                                 # Default: true
  [--drain-ephemeral-sessions], [--no-drain-ephemeral-sessions]
                                                                 # Default: true
  [--drain-proxies], [--no-drain-proxies]
                                                                 # Default: true
  [--environment=ENVIRONMENT]
  [--url=URL]
```


# aptible log_drain:create:elasticsearch



This command lets you create a [Log Drain](/core-concepts/observability/logs/log-drains/overview) to forward your container logs to an [Elasticsearch Database](/core-concepts/managed-databases/supported-databases/elasticsearch) hosted on Aptible.

> 📘 You must choose a destination Elasticsearch Database that is within the same Environment as the Log Drain you are creating.

# Synopsis

```
Usage:
  aptible log_drain:create:elasticsearch HANDLE --db DATABASE_HANDLE --environment ENVIRONMENT [--drain-apps true/false] [--drain_databases true/false] [--drain_ephemeral_sessions true/false] [--drain_proxies true/false]

Options:
  [--drain-apps], [--no-drain-apps]
                                                                 # Default: true
  [--drain-databases], [--no-drain-databases]
                                                                 # Default: true
  [--drain-ephemeral-sessions], [--no-drain-ephemeral-sessions]
                                                                 # Default: true
  [--drain-proxies], [--no-drain-proxies]
                                                                 # Default: true
  [--environment=ENVIRONMENT]
  [--db=DB]
  [--pipeline=PIPELINE]
```


# aptible log_drain:create:https



This command lets you create a [Log Drain](/core-concepts/observability/logs/log-drains/overview) to forward your container logs to an [HTTPS destination](/core-concepts/observability/logs/log-drains/https-log-drains) of your choice.

> 📘 There are specific CLI commands for creating Log Drains for some specific HTTPS destinations, such as [Datadog](/reference/aptible-cli/cli-commands/cli-log-drain-create-datadog), [LogDNA](/reference/aptible-cli/cli-commands/cli-log-drain-create-logdna), and [SumoLogic](/reference/aptible-cli/cli-commands/cli-log-drain-create-sumologic).

# Synopsis

```
Usage:
  aptible log_drain:create:https HANDLE --url URL --environment ENVIRONMENT [--drain-apps true/false] [--drain_databases true/false] [--drain_ephemeral_sessions true/false] [--drain_proxies true/false]

Options:
  [--url=URL]
  [--drain-apps], [--no-drain-apps]
                                                                 # Default: true
  [--drain-databases], [--no-drain-databases]
                                                                 # Default: true
  [--drain-ephemeral-sessions], [--no-drain-ephemeral-sessions]
                                                                 # Default: true
  [--drain-proxies], [--no-drain-proxies]
                                                                 # Default: true
  [--environment=ENVIRONMENT]
```


# aptible log_drain:create:logdna



This command lets you create a [Log Drain](/core-concepts/observability/logs/log-drains/overview) to forward your container logs to LogDNA.

> 📘 The `--url` options must be given in the format of `https://logs.logdna.com/aptible/ingest/<INGESTION KEY>`. Refer to [https://docs.logdna.com/docs/aptible-logs](https://docs.logdna.com/docs/aptible-logs) for more options.

# Synopsis

```
Usage:
  aptible log_drain:create:logdna HANDLE --url LOGDNA_URL --environment ENVIRONMENT [--drain-apps true/false] [--drain_databases true/false] [--drain_ephemeral_sessions true/false] [--drain_proxies true/false]

Options:
  [--url=URL]
  [--drain-apps], [--no-drain-apps]
                                                                 # Default: true
  [--drain-databases], [--no-drain-databases]
                                                                 # Default: true
  [--drain-ephemeral-sessions], [--no-drain-ephemeral-sessions]
                                                                 # Default: true
  [--drain-proxies], [--no-drain-proxies]
                                                                 # Default: true
  [--environment=ENVIRONMENT]
```


# aptible log_drain:create:papertrail



This command lets you create a [Log Drain](/core-concepts/observability/logs/log-drains/overview) to forward your container logs to Papertrail.

> 📘 Note

> Add a new Log Destination in Papertrail (make sure to accept TCP + TLS connections and logs from unrecognized senders), then copy the host and port from the Log Destination.

# Synopsis

```
Usage:
  aptible log_drain:create:papertrail HANDLE --host PAPERTRAIL_HOST --port PAPERTRAIL_PORT --environment ENVIRONMENT [--drain-apps true/false] [--drain_databases true/false] [--drain_ephemeral_sessions true/false] [--drain_proxies true/false]

Options:
  [--host=HOST]
  [--port=PORT]
  [--drain-apps], [--no-drain-apps]
                                                                 # Default: true
  [--drain-databases], [--no-drain-databases]
                                                                 # Default: true
  [--drain-ephemeral-sessions], [--no-drain-ephemeral-sessions]
                                                                 # Default: true
  [--drain-proxies], [--no-drain-proxies]
                                                                 # Default: true
  [--environment=ENVIRONMENT]

Create a Papertrail Log Drain
```


# aptible log_drain:create:sumologic



This command lets you create a [Log Drain](/core-concepts/observability/logs/log-drains/overview) to forward your container logs to Sumo Logic.

> 📘 Note

> Create a new Hosted Collector in Sumo Logic using a HTTP source, then use provided the HTTP Source Address for the `--url` option.

# Synopsis

```
Usage:
  aptible log_drain:create:sumologic HANDLE --url SUMOLOGIC_URL --environment ENVIRONMENT [--drain-apps true/false] [--drain_databases true/false] [--drain_ephemeral_sessions true/false] [--drain_proxies true/false]

Options:
  [--url=URL]
  [--drain-apps], [--no-drain-apps]
                                                                 # Default: true
  [--drain-databases], [--no-drain-databases]
                                                                 # Default: true
  [--drain-ephemeral-sessions], [--no-drain-ephemeral-sessions]
                                                                 # Default: true
  [--drain-proxies], [--no-drain-proxies]
                                                                 # Default: true
  [--environment=ENVIRONMENT]

Create a Sumo Logic Drain
```


# aptible log_drain:create:syslog



This command lets you create a [Log Drain](/core-concepts/observability/logs/log-drains/overview) to forward your container logs to an [Syslog TCP+TLS destination](/core-concepts/observability/logs/log-drains/syslog-log-drains) of your choice.

> 📘 Note

> There are specific CLI commands for creating Log Drains for some specific Syslog destinations, such as [Papertrail](/reference/aptible-cli/cli-commands/cli-log-drain-create-papertrail).

# Synopsis

```
Usage:
  aptible log_drain:create:syslog HANDLE --host SYSLOG_HOST --port SYSLOG_PORT [--token TOKEN] --environment ENVIRONMENT [--drain-apps true/false] [--drain_databases true/false] [--drain_ephemeral_sessions true/false] [--drain_proxies true/false]

Options:
  [--host=HOST]
  [--port=PORT]
  [--token=TOKEN]
  [--drain-apps], [--no-drain-apps]
                                                                 # Default: true
  [--drain-databases], [--no-drain-databases]
                                                                 # Default: true
  [--drain-ephemeral-sessions], [--no-drain-ephemeral-sessions]
                                                                 # Default: true
  [--drain-proxies], [--no-drain-proxies]
                                                                 # Default: true
  [--environment=ENVIRONMENT]

Create a Papertrail Log Drain
```


# aptible log_drain:deprovision



# Synopsis

```
Usage:
  aptible log_drain:deprovision HANDLE --environment ENVIRONMENT

Options:
  [--environment=ENVIRONMENT]

Deprovisions a log drain
```


# aptible log_drain:list



This command lets you list the [Log Drains](/core-concepts/observability/logs/log-drains/overview) you have configured for your [Environments](/core-concepts/architecture/environments).

# Synopsis

```
Usage:
  aptible log_drain:list

Options:
  [--environment=ENVIRONMENT]
```


# aptible login



This command is used to login to Aptible from the CLI.\
\
Synopsis

```
Usage:
  aptible login

Options:
  [--email=EMAIL]
  [--password=PASSWORD]
  [--lifetime=LIFETIME]    # The duration the token should be valid for (example usage: 24h, 1d, 600s, etc.)
  [--otp-token=OTP_TOKEN]  # A token generated by your second-factor app
  [--sso=SSO]              # Use a token from a Single Sign On login on the dashboard
```


# aptible logs



This command lets you access real-time logs for an [App](/core-concepts/apps/overview) or [Database](/core-concepts/managed-databases/managing-databases/overview).

# Synopsis

```
Usage:
  aptible logs [--app APP | --database DATABASE]

Options:
      [--app=APP]
      [--environment=ENVIRONMENT]
  -r, [--remote=REMOTE]
      [--database=DATABASE]
```

# Examples

## App logs

```shell
aptible logs --app "$APP_HANDLE"
```

## Database logs

```shell
aptible logs --database "$DATABASE_HANDLE"
```


# aptible logs_from_archive



This command is used to retrieve container logs from your own [Disaster Log Archive](/core-concepts/observability/logs/s3-log-archives).

> ❗️ You must have enabled log archiving for your Dedicated Stack(s) in order to use this command.

# Synopsis

```
Usage:
  aptible logs_from_archive --bucket NAME --region REGION --stack NAME [ --decryption-keys ONE [OR MORE] ] [ --download-location LOCATION ] [ [ --string-matches ONE [OR MORE] ] | [ --app-id ID | --database-id ID | --endpoint-id ID | --container-id ID ] [ --start-date YYYY-MM-DD --end-date YYYY-MM-DD ] ] --bucket=BUCKET --region=REGION --stack=STACK

Options:
  --region=REGION                          # The AWS region your S3 bucket resides in
  --bucket=BUCKET                          # The name of your S3 bucket
  --stack=STACK                            # The name of the Stack to download logs from
  [--decryption-keys=one two three]        # The Aptible-provided keys for decryption. (Space separated if multiple)
  [--string-matches=one two three]         # The strings to match in log file names.(Space separated if multiple)
  [--app-id=N]                             # The Application ID to download logs for.
  [--database-id=N]                        # The Database ID to download logs for.
  [--endpoint-id=N]                        # The Endpoint ID to download logs for.
  [--container-id=CONTAINER_ID]            # The container ID to download logs for
  [--start-date=START_DATE]                # Get logs starting from this (UTC) date (format: YYYY-MM-DD)
  [--end-date=END_DATE]                    # Get logs before this (UTC) date (format: YYYY-MM-DD)
  [--download-location=DOWNLOAD_LOCATION]  # The local path place downloaded log files. If you do not set this option, the file names will be shown, but not downloaded.

Retrieves container logs from an S3 archive in your own AWS account. You must provide your AWS credentials via the environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY
```

> 📘 You can find resource ID's by looking at the URL of a resource on the Aptible Dashboard, or by using the [JSON output format](/reference/aptible-cli/cli-commands/overview#output-format) for the [`aptible db:list`](/reference/aptible-cli/cli-commands/cli-db-list) or [`aptible apps`](/reference/aptible-cli/cli-commands/cli-apps) commands.

> This command also allows retrieval of logs from deleted resources. Please contact [Aptible Support](/how-to-guides/troubleshooting/aptible-support) for assistance identifying the proper resource IDs of deleted resources.

# Examples

## Search for all archived logs for a specific Database

By default, no logs are downloaded. Matching file names are printed on the screen.

```shell
aptible logs_from_archive --database-id "$ID" \
        --stack "$STACK" \
        --region "$REGION" \
        --decryption-keys "$KEY"
```

## Search for archived logs for a specific Database within a specific date range

You can specify a date range in UTC to limit the search to logs emitted during a time period.

```shell
aptible logs_from_archive --database-id "$ID" --start-date "2022-08-30" --end-date "2022-10-03" \
        --stack "$STACK" \
        --region "$REGION" \
        --decryption-keys "$KEY"
```

## Download logs from a specific App to a local path

Once you have identified the files you wish to download, add the `--download-location` parameter to download the files to your local system.

> ❗️ Warning: Since container logs may include PHI or sensitive credentials, please choose the download location carefully.

```shell
aptible logs_from_archive --app-id "$ID" --download-location "$LOCAL_PATH" \
        --stack "$STACK" \
        --region "$REGION" \
        --decryption-keys "$KEY"
```

## Search for logs from a specific Container

You can search for logs for a specific container if you know the container ID.

```shell
aptible logs_from_archive --container-id "$ID" \
        --stack "$STACK" \
        --region "$REGION" \
        --decryption-keys "$KEY"
```


# aptible maintenance:apps



This command lists [Apps](/core-concepts/apps/overview) with pending maintenance.

# Synopsis

```
Usage:
  aptible maintenance:apps

Options:
  [--environment=ENVIRONMENT]
```


# aptible maintenance:dbs



This command lists [Databases](/core-concepts/managed-databases/overview) with pending maintenance.

# Synopsis

```
Usage:
  aptible maintenance:dbs

Options:
  [--environment=ENVIRONMENT]
```


# aptible metric_drain:create:datadog



This command lets you create a [Metric Drain](/core-concepts/observability/metrics/metrics-drains/overview) to forward your container metrics to [Datadog](/core-concepts/integrations/datadog).

You need to use the `--site` option to specify the [Datadog Site](https://docs.datadoghq.com/getting_started/site/) associated with your Datadog account. Valid options are `US1`, `US3`, `US5`, `EU1`, or `US1-FED`

# Synopsis

```
Usage:
  aptible metric_drain:create:datadog HANDLE --api_key DATADOG_API_KEY --site DATADOG_SITE --environment ENVIRONMENT

Options:
  [--api-key=API_KEY]
  [--site=SITE]
  [--environment=ENVIRONMENT]
```


# aptible metric_drain:create:influxdb



This command lets you create a [Metric Drain](/core-concepts/observability/metrics/metrics-drains/overview) to forward your container metrics to an [InfluxDB Database](/core-concepts/managed-databases/supported-databases/influxdb) hosted on Aptible.

> 📘 You must choose a destination InfluxDB Database that is within the same Environment as the Metric Drain you are creating.

# Synopsis

```
Usage:
  aptible metric_drain:create:influxdb HANDLE --db DATABASE_HANDLE --environment ENVIRONMENT

Options:
  [--db=DB]
  [--environment=ENVIRONMENT]
```


# aptible metric_drain:create:influxdb:custom



This command lets you create a [Metric Drain](/core-concepts/observability/metrics/metrics-drains/overview) to forward your container metrics to an InfluxDB database hosted outside Aptible.

> 📘 Only InfluxDB v1 destinations are supported.

# Synopsis

```
Usage:
  aptible metric_drain:create:influxdb:custom HANDLE --username USERNAME --password PASSWORD --url URL_INCLUDING_PORT --db INFLUX_DATABASE_NAME --environment ENVIRONMENT

Options:
  [--db=DB]
  [--username=USERNAME]
  [--password=PASSWORD]
  [--url=URL]
  [--environment=ENVIRONMENT]
```


# aptible metric_drain:deprovision



This command deprovisions a [Metric Drain](/core-concepts/observability/metrics/metrics-drains/overview).

# Synopsis

```
Usage:
  aptible metric_drain:deprovision HANDLE --environment ENVIRONMENT

Options:
  [--environment=ENVIRONMENT]
```


# aptible metric_drain:list



This command lets you list the [Metric Drains](/core-concepts/observability/metrics/metrics-drains/overview) you have configured for your [Environments](/core-concepts/architecture/environments).

# Synopsis

```
Usage:
  aptible metric_drain:list

Options:
  [--environment=ENVIRONMENT]
```


# aptible operation:cancel



This command cancels a running [Operation.](/core-concepts/architecture/operations)

# Synopsis

```
Usage:
  aptible operation:cancel OPERATION_ID
```


# aptible operation:follow



This command follows the logs of a running [Operation](/core-concepts/architecture/operations). Only the user that created an operation can successfully follow its logs via the CLI.

# Synopsis

```
Usage:
  aptible operation:follow OPERATION_ID
```


# aptible operation:logs



This command displays logs for a given [operation](/core-concepts/architecture/operations) performed within the last 90 days.

# Synopsis

```
Usage:
  aptible operation:logs OPERATION_ID
```


# aptible rebuild



This command rebuilds an [App](/core-concepts/apps/overview) and restarts its [Services](/core-concepts/apps/deploying-apps/services).

# Synopsis

```
Usage:
  aptible rebuild

Options:
      [--app=APP]
      [--environment=ENVIRONMENT]
  -r, [--remote=REMOTE]
```


# aptible restart



This command restarts an [App](/core-concepts/apps/overview) and all its associated [Services](/core-concepts/apps/deploying-apps/services).

# Synopsis

```
Usage:
  aptible restart

Options:
      [--simulate-oom], [--no-simulate-oom]  # Add this flag to simulate an OOM restart and test your app's response (not recommended on production apps).
      [--force]                              # Add this flag to use --simulate-oom in a production environment, which is not allowed by default.
      [--app=APP]
      [--environment=ENVIRONMENT]
  -r, [--remote=REMOTE]
```

# Examples

```shell
aptible restart --app "$APP_HANDLE"
```


# aptible services



This command lists all [Services](/core-concepts/apps/deploying-apps/services) for a given [App](/core-concepts/apps/overview).

# Synopsis

```
Usage:
  aptible services

Options:
      [--app=APP]
      [--environment=ENVIRONMENT]
  -r, [--remote=REMOTE]
```


# aptible services:settings



This command lets you configure [Services](/core-concepts/apps/deploying-apps/services) for a given [App](/core-concepts/apps/overview).

# Synopsis

```
Usage:
  aptible services:settings SERVICE [--force-zero-downtime|--no-force-zero-downtime] [--simple-health-check|--no-simple-health-check]

Options:
      [--app=APP]
      [--environment=ENVIRONMENT]
  -r, [--remote=REMOTE]
      [--force-zero-downtime|--no-force-zero-downtime]
      [--simple-health-check|--no-simple-health-check]
```

# Examples

```shell
aptible services:settings --app "$APP_HANDLE" SERVICE \
        --force-zero-downtime \
        --simple-health-check
```

#### Force Zero Downtime

For Services without endpoints, you can force a zero downtime deployment strategy, which enables healthchecks via Docker's healthcheck mechanism.

#### Simple Health Check

When enabled, instead of using Docker healthchecks, Aptible will ensure your container can stay up for 30 seconds before continuing the deployment.


# aptible ssh



This command creates [Ephemeral SSH Sessions](/core-concepts/apps/connecting-to-apps/ssh-sessions) to [Apps](/core-concepts/apps/overview) running on Aptible.

# Synopsis

```
Usage:
  aptible ssh [COMMAND]

Options:
      [--app=APP]
      [--environment=ENVIRONMENT]
  -r, [--remote=REMOTE]
      [--force-tty], [--no-force-tty]

Description:
  Runs an interactive command against a remote Aptible app

  If specifying an app, invoke via: aptible ssh [--app=APP] COMMAND
```

# Examples

```shell
aptible ssh --app "$APP_HANDLE"
```


# aptible version



This command prints the version of the Aptible CLI running.

# Synopsis

```
Usage:
  aptible version
```


# CLI Configurations

The Aptible CLI provides configuration options such as MFA support, customizing output format, and overriding configuration location.

## MFA support

To use hardware-based MFA (e.g., Yubikey) on Windows and Linux, manually install the libfido2 command line tools. You can find the latest installation release and installation instructions [here](https://developers.yubico.com/libfido2/).

For OSX users, installation via Homebrew will automatically include the libfido2 dependency.

## Output Format

The Aptible CLI supports two output formats: plain text and JSON. You can select your preferred output format by setting the `APTIBLE_OUTPUT_FORMAT` environment variable to `text` or `json`.

If the `APTIBLE_OUTPUT_FORMAT` variable is left unset (i.e., the default), the CLI will provide output as plain text.

> 📘 The Aptible CLI sends logging output to `stderr`, and everything else to `stdout` (this is the standard behavior for well-behaved UNIX programs).

> If you're calling the Aptible CLI from another program, make sure you don't merge the two streams (if you did, you'd have to filter out the logging output).

> Note that if you're simply using a shell such as Bash, the pipe operator (i.e. `|`) only pipes `stdout` through, which is exactly what you want here.

## Configuration location

The Aptible CLI normally stores its configuration (your Aptible authentication token and automatically generated SSH keys) in a hidden subfolder of your home directory: `~/.aptible`. To override this default location, you can specify a custom path by using the environment variable `APTIBLE_CONFIG_PATH`. Since the files in this path grant access to your Aptible account, protect them as if they were your password itself!


# Aptible CLI - Overview

Learn more about using the Aptible CLI for managing resources

# Overview

The Aptible CLI is a tool to help you manage your Aptible resources directly from the command line. You can use the Aptible CLI to do things like:

Create, modify, and delete Aptible resources
Deploy, restart, and scale Apps and Databases
View real-time logs
For an overview of what features the CLI supports, see the Feature Support Matrix.

# Install the Aptible CLI

<Tabs>
  <Tab title="MacOS">
    [](https://omnibus-aptible-toolbelt.s3.amazonaws.com/aptible/omnibus-aptible-toolbelt/master/gh-36/pkg/aptible-toolbelt-0.22.0%2B20241010193950-mac-os-x.10.15.7-1.pkg)Install v0.22.0 with **Homebrew**

    ```
    brew install --cask aptible
    ```
  </Tab>

  <Tab title="Windows">
    [Download v0.22.0 for Windows ↓](https://omnibus-aptible-toolbelt.s3.amazonaws.com/aptible/omnibus-aptible-toolbelt/master/gh-36/pkg/aptible-toolbelt-0.22.0%2B20241010192009~windows.6.3.9600-1-x64.msi)
  </Tab>

  <Tab title="Debian">
    [Download v0.22.0 for Debian ↓](https://omnibus-aptible-toolbelt.s3.amazonaws.com/aptible/omnibus-aptible-toolbelt/latest/aptible-toolbelt_latest_debian-9_amd64.deb)
  </Tab>

  <Tab title="Ubuntu">
    [Download v0.22.0 for Ubuntu ↓](https://omnibus-aptible-toolbelt.s3.amazonaws.com/aptible/omnibus-aptible-toolbelt/latest/aptible-toolbelt_latest_ubuntu-1604_amd64.deb)
  </Tab>

  <Tab title="CentOS">
    [Download v0.22.0 for CentOS ↓](https://omnibus-aptible-toolbelt.s3.amazonaws.com/aptible/omnibus-aptible-toolbelt/latest/aptible-toolbelt_latest_centos-7_amd64.rpm)
  </Tab>
</Tabs>

# Try the CLI

Take the CLI for a spin with these commands or [browse through all available commands.](https://www.aptible.com/docs/commands)

<CodeGroup>
  ```python Login to the CLI
  aptible login
  ```

  ```python View all commands
  aptible help
  ```

  ```python Create a new app
  aptible apps:create HANDLE --environment=ENVIRONMENT
  ```

  ```python List all databases
  aptible db:list
  ```
</CodeGroup>


# Aptible Metadata Variables



Aptible injects the following metadata keys as environment variables:

*   `APTIBLE_PROCESS_TYPE`

    *   Represents the name of the [Service](/core-concepts/apps/deploying-apps/services) this container belongs to. For example, if the [Procfile](/how-to-guides/app-guides/define-services) defines services like `web` and `worker`.

    *   Then, the containers for the web Service will run with `APTIBLE_PROCESS_TYPE=web`, and the containers for the worker Service will run with `APTIBLE_PROCESS_TYPE=worker`.

    *   If there is no Procfile and users choose to use an [Implicit Service](/how-to-guides/app-guides/define-services#implicit-service-cmd) instead, the variable is set to `APTIBLE_PROCESS_TYPE=cmd`.

*   `APTIBLE_PROCESS_INDEX`

    *   All containers for a given [Release](/core-concepts/apps/deploying-apps/releases/overview) of a Service are assigned a unique 0-based process index.

    *   For example, if your web service is [scaled](/core-concepts/scaling/overview) to 2 containers, one will have `APTIBLE_PROCESS_INDEX=0`, and the other will have `APTIBLE_PROCESS_INDEX=1`.

*   `APTIBLE_PROCESS_CONTAINER_COUNT`

    *   This variable is a companion to `APTIBLE_PROCESS_INDEX`, and represents the total count of containers on the service. Note that this will only be present in app service containers (not in pre\_release, ephemeral/ssh, or database containers).

*   `APTIBLE_CONTAINER_CPU_SHARE`

    *   Provides the vCPU share for the container, matching the ratios in our documentation for [­container profiles](/core-concepts/scaling/container-profiles). Format will be provided in the following format: 0.125, 0.5, 1.0, etc.

*   `APTIBLE_CONTAINER_PROFILE`

*   `APTIBLE_CONTAINER_SIZE`

    *   This variable represents the memory limit in MB of the Container. See [Memory Limits](/core-concepts/scaling/memory-limits) for more information.

*   `APTIBLE_LAYER`

    *   This variable represents whether the container is an [App](/core-concepts/apps/overview) or [Database](/core-concepts/managed-databases/managing-databases/overview) container using App or Database values.

*   `APTIBLE_GIT_REF`

*   `APTIBLE_ORGANIZATION_HREF`

    *   Aptible API URL representing the [Organization](/core-concepts/security-compliance/access-permissions) this container belongs to.

*   `APTIBLE_APP_HREF`

    *   Aptible API URL representing the [App](/core-concepts/apps/overview) this container belongs to, if any.

*   `APTIBLE_DATABASE_HREF`

    *   Aptible API URL representing the [Database](/core-concepts/managed-databases/managing-databases/overview) this container belongs to, if any.

*   `APTIBLE_SERVICE_HREF`

    *   Aptible API URL representing the Service this container belongs to, if any.

*   `APTIBLE_RELEASE_HREF`

    *   Aptible API URL representing the Release this container belongs to, if any.

*   `APTIBLE_EPHEMERAL_SESSION_HREF`

    *   Aptible API URL representing the current [Ephemeral SSH Sessions](/core-concepts/apps/connecting-to-apps/ssh-sessions) this container belongs to, if any.

*   `APTIBLE_USER_DOCUMENT`

    *   Aptible injects an expired JWT object with user information.
        *   The information available is id, email, name, etc.

    ```
    decode_base64_url() {
        local len=$((${#1} % 4))
        local result="$1"
        if [ $len -eq 2 ]; then result="$1"'=='
        elif [ $len -eq 3 ]; then result="$1"'=' 
        fi
        echo "$result" | tr '_-' '/+' | openssl enc -d -base64
    }

    decode_jwt(){
        decode_base64_url $(echo -n $2 | cut -d "." -f $1) | sed 's/{/\n&\n/g;s/}/\n&\n/g;s/,/\n&\n/g' | sed 's/^  */  /'
    }

    # Decode JWT header
    alias jwth="decode_jwt 1"

    # Decode JWT Payload
    alias jwtp="decode_jwt 2"
    ```

    You can use the above script to decode the expired JWT object using `jwtp $APTIBLE_USER_DOCUMENT`

*   `APTIBLE_RESOURCE_HREF`

    *   Aptible uses this variable internally. Do not depend on this value.

*   `APTIBLE_ALLOCATION`

    *   Aptible uses this variable internally. Do not depend on this value.


# Dashboard

Learn about navigating the Aptible Dashboard

# Overview

The [Aptible Dashboard](https://app.aptible.com/login) allows you to create, view, and manage your Aptible account, including resources, deployments, members, settings, and more.

# Getting Started

When you first sign up for Aptible, you will first be guided through your first deployment using one of our [starter templates](/getting-started/deploy-starter-template/overview) or your own [custom code](/getting-started/deploy-custom-code). Once you’ve done so, you will be routed to your account within Aptible Dashboard.

<Card title="Sign up for Aptible" icon="arrow-up-right-from-square" iconType="duotone" href="https://app.aptible.com/login" />

# Navigating the Dashboard

![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/dashboard1.png)

## Organization Selector

The organization selector enables you to switch between different Aptible accounts you belong to.

## Global Search

The global search feature enables you to search for all resources in your Aptible account. You can search by resource type, name, or ID, for the resources that you have access to.

# Resource pages

The Aptible Dashboard is organized to provide a view of resources categorized by type: stacks, environments, apps, databases, services, and endpoints. On each resource page, you have the ability to:

*   View the active resources to which you have access to with details such as estimated cost

*   Search for resources by name or ID

*   Create new resources

<CardGroup cols={2}>
  <Card title="Learn more about resources" icon="book" iconType="duotone" href="https://www.aptible.com/docs/platform" />

  <Card title="View resources in the dashboard" icon="arrow-up-right-from-square" iconType="duotone" href="https://app.aptible.com/apps" />
</CardGroup>

# Deployments

The Deployments page provides a view of all deployments initiated through the Deploy tool in the Aptible Dashboard. This view includes both successful deployments and those that are currently pending.

<CardGroup cols={2}>
  <Card title="Learn more about deployments" icon="book" iconType="duotone" href="https://www.aptible.com/docs/deploying-apps" />

  <Card title="View deployments in the dashboard" icon="arrow-up-right-from-square" iconType="duotone" href="https://app.aptible.com/deployments" />
</CardGroup>

# Activity

![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/dashboard2.png)

The Activity page provides a real-time view of operations in the last seven days. Through the Activity page, you can:

*   View operations for resources you have access to

*   Search operations by resource name, operation type, and user

*   View operation logs for debugging purposes

<Tip> **Troubleshooting with our team?** Link the Aptible Support team to the logs for the operation you are having trouble with </Tip>

<CardGroup cols={2}>
  <Card title="Learn more about activity" icon="book" iconType="duotone" href="https://www.aptible.com/docs/activity" />

  <Card title="View activity in the dashboard" icon="arrow-up-right-from-square" iconType="duotone" href="https://app.aptible.com/activity" />
</CardGroup>

# Security & Compliance

The Security & Compliance Dashboard provides a comprehensive view of the security controls that Aptible fully enforces and manages on your behalf and additional configurations you can implement. Through the Security & Compliance Dashboard, you can:

*   Review your overall compliance score or scores for specific frameworks like HIPAA and HITRUST

*   Review the details and status of all available controls

*   Share and export a summarized report

<CardGroup cols={2}>
  <Card title="Learn more about the Security & Compliance Dashboard" icon="book" iconType="duotone" href="https://www.aptible.com/docs/activity" />

  <Card title="View Security & Compliance in the dashboard" icon="arrow-up-right-from-square" iconType="duotone" href="https://dashboard.aptible.com/controls" />
</CardGroup>

# Deploy Tool

![](https://mintlify.s3-us-west-1.amazonaws.com/aptible/images/dashboard3.png)
The Deploy tool offers a guided experience to deploy code to a new Aptible environment. Through the Deploy tool, you can:

*   Configure your new environment

*   Deploy a [starter template](/getting-started/deploy-starter-template/overview) or your [custom code](/getting-started/deploy-custom-code)

*   Easily provision the necessary resources for your code: apps, databases, and endpoints

<CardGroup cols={2}>
  <Card title="Learn more about deploying with a starter template" icon="book" iconType="duotone" href="https://www.aptible.com/docs/quickstart-guides" />

  <Card title="Deploy from the dashboard" icon="arrow-up-right-from-square" iconType="duotone" href="https://app.aptible.com/create" />
</CardGroup>

# Settings

The Settings Dashboard allows you to view and manage organization and personal settings. Through the Settings Dashboard, you can:

*   Manage organization settings, such as:

    *   Creating and managing members

    *   Viewing and managing billing information

    *   Managing permissions

<Tip>  Most organization settings can only be viewed and managed by Account Owners. See [Roles & Permissions](/core-concepts/security-compliance/access-permissions) for more information.</Tip>

*   Manage personal settings, such as:

    *   Editing your profile details

    *   Creating and managing SSH Keys

    *   Managing your Security Settings

## Support

The Support tool empowers you to get help using the Aptible platform. With this tool, you can:

*   Create a ticket with the Aptible Support team

*   View recommended documentation related to your request

<CardGroup cols={2}>
  <Card title="Learn more about Aptible Support" icon="book" iconType="duotone" href="https://www.aptible.com/docs/support" />

  <Card title="Contact Aptible Support" icon="arrow-up-right-from-square" iconType="duotone" href="https://app.aptible.com/support" />
</CardGroup>


# Glossary



## Apps

On Aptible, an [app](/core-concepts/apps/overview) represents the deployment of your custom code. An app may consist of multiple Services, each running a unique command against a common codebase. Users may deploy Apps in one of 2 ways: via Dockerfile Deploy, in which you push a Git repository to Aptible and Aptible builds a Docker image on your behalf, or via Direct Docker Image Deploy, in which you deploy a Docker image you’ve built yourself outside of Aptible.

## App Endpoints

[App endpoints](/core-concepts/apps/connecting-to-apps/app-endpoints/overview) are load balancers that allow you to expose your Aptible apps to the public internet or your stack’s internal network. Aptible supports three types of app endpoints - HTTP(s), TLS, and TCP.

## Container Recovery

[Container recovery](/core-concepts/architecture/containers/container-recovery) is an Aptible-automated operation that restarts containers that have exited unexpectedly, i.e., outside of a deploy or restart operation.

## Containers

Aptible deploys all resources in Docker [containers](/core-concepts/architecture/containers/overview). Containers provide a consistent and isolated environment for applications to run, ensuring that they behave predictably and consistently across different computing environments.

## CPU Allocation

[CPU Allocation](/core-concepts/scaling/cpu-isolation) is amount of isolated CPU threads allocated to a given container.

## CPU Limit

The [CPU Limit](/core-concepts/scaling/container-profiles) is a type of [metric](/core-concepts/observability/metrics/overview) that emits the max available CPU of an app or database. With metric drains, you can monitor and set up alerts for when an app or database is approaching the CPU Limit.

## Database Endpoints

[Database endpoints](/core-concepts/managed-databases/connecting-databases/database-endpoints) are load balancers that allow you to expose your Aptible databases to the public internet.

## Databases

Aptible manages and pre-configures [databases](/core-concepts/managed-databases/managing-databases/overview) that provide data persistence. Aptible supports many database types, including PostgreSQL, Redis, Elasticsearch, InfluxDB, MYSQL, and MongoDB.

Aptible pre-configures databases with convenient features like automatic backups and encryption. Aptible offers additional functionality that simplifies infrastructure management, such as easy scaling with flexible container profiles, highly available replicas by default, and modifiable backup retention policies. These features empower users to easily handle and optimize their infrastructure without complex setup or extensive technical expertise.

Additionally, Aptible databases are managed and monitored by the Aptible SRE Team – including responding to capacity alerts and performing maintenance.

## Drains

[Log drains](/core-concepts/observability/logs/log-drains/overview) and [metric drain](/core-concepts/observability/metrics/metrics-drains/overview) allow you to connect to destinations where you can send the logs and metrics Aptible provides for your containers for long-term storage and historical review.

## Environments

[Environments](/core-concepts/architecture/environments) provide logical isolation of a group of resources, such as production and development environments. Account and Environment owners can customize user permissions per environment to ensure least-privileged access. Aptible also provides activity reports for all the operations performed per environment. Additionally, database backup policies are set on the environment level and conveniently apply to all databases within that environment.

## High Availability

High availability is an Aptible-automated configuration that provides redundancy by automatically distributing apps and databases to multiple availability zones (AZs). Apps are automatically configured with high availability and automatic failover when horizontally scaled to two or more containers. Databases are automatically configured with high availability using [replication and clustering](/core-concepts/managed-databases/managing-databases/replication-clustering).

## Horizontal Scaling

[Horizontal Scaling](/core-concepts/scaling/app-scaling#horizontal-scaling) is a scaling operation that modifies the number of containers of an app or database. Users can horizontally scale Apps on demand. Databases can be horizontally scaled using replication and clustering. When apps and databases are horizontally scaled to 2 or more containers, Aptible automatically deploys the containers in a high-availability configuration.

## Logs

[Logs](/core-concepts/observability/logs/overview) are the output of all containers sent to `stdout` and `stderr`. Aptible does not capture logs sent to files, so when you deploy your apps on Aptible, you should ensure you are logging to `stdout` or `stderr` and not to log files.

## Memory Limit

The [Memory Limit](/core-concepts/scaling/memory-limits) is a type of [metric](/core-concepts/observability/metrics/overview) that emits the max available RAM of an app or database container. Aptible kicks off memory management when a container exceeds its memory limit.

## Memory Management

[Memory Management](/core-concepts/scaling/memory-limits) is an Aptible feature that kicks off a process that results in container recovery when containers exceed their allocated memory.

## Metrics

Aptible captures and provides [metrics](/core-concepts/observability/metrics/overview) for your app and database containers that can be accessed in the dashboard, for short-term review, or through metric drains, for long-term storage and historical review.

## Operations

An [operation](/core-concepts/architecture/operations) is performed and logged for all changes to resources, environments, and stacks. Aptible provides activity reports of all operations in a given environment and an activity feed for all active resources.

## Organization

An [organization](/core-concepts/security-compliance/access-permissions#organization) represents a unique account on Aptible consisting of users and resources. Users can belong to multiple organizations.

## PaaS

Platform as a Service (PaaS) is a cloud computing service model, as defined by the National Institute of Standards and Technology (NIST), that provides a platform allowing customers to develop, deploy, and manage applications without the complexities of building and maintaining the underlying infrastructure. PaaS offers a complete development and deployment environment in the cloud, enabling developers to focus solely on creating software applications while the PaaS provider takes care of the underlying hardware, operating systems, and networking. PaaS platforms also handle application deployment, scalability, load balancing, security, and compliance measures.

## Resources

Resources refer to anything users can provision, deprovision, or restart within an Aptible environment, such as apps, databases, endpoints, log drains, and metric drains.

## Services

[Services](/core-concepts/apps/deploying-apps/services) define how many containers Aptible will start for your app, what [container command](/core-concepts/architecture/containers/overview#container-command) they will run, their Memory Limits, and their CPU Isolation. An app can have many services, but each service belongs to a single app.

## Stacks

[Stacks](/core-concepts/architecture/stacks) represent the underlying infrastructure used to deploy your resources and are how you define the network isolation for an environment or a group of environments. There are two types of stacks to create environments within:

*   Shared stacks: [Shared stacks](/core-concepts/architecture/stacks#shared-stacks) live on infrastructure that is shared among Aptible customers and are designed for deploying resources with lower requirements, such as deploying non-sensitive or test resources, and come with no additional costs.

*   Dedicated stacks: [Dedicated stacks](/core-concepts/architecture/stacks#dedicated-stacks) live on isolated infrastructure and are designed to support deploying resources with higher requirements–such as network isolation, flexible scaling options, VPN and VPC peering, 99.95% uptime guarantee, access to additional regions and more. Users can use dedicated stacks for both `production` and `development` environments. Dedicated Stacks are available on Production and Enterprise plans at an additional fee per dedicated stack.

## Vertical Scaling

[Vertical Scaling](/core-concepts/scaling/app-scaling#vertical-scaling) is a type of scaling operation that modifies the size (including CPU and RAM) of app or database containers. Users can vertically scale their containers manually or automatically (BETA).


# Interface Feature Availability Matrix



There are three supported methods for managing resources on Aptible:

*   [The Aptible Dashboard](/reference/dashboard)
*   The [Aptible CLI](/reference/aptible-cli/cli-commands/overview) client
*   The [Aptible Terraform Provider](https://registry.terraform.io/providers/aptible/aptible)

Currently, not every action is supported by every interface. This matrix describes which actions are supported by which interfaces.

## Key

*   ✅ - Supported

*   🔶 - Partial Support

*   ❌ - Not Supported

*   🚧 - In Progress

*   N/A - Not Applicable

## Matrix

|                                   |              Web             | CLI | Terraform       |
| :-------------------------------: | :--------------------------: | :-: | --------------- |
|    **User Account Management**    |               ✅              |  ❌  | ❌               |
|    **Organization Management**    |               ✅              |  ❌  | ❌               |
|   **Dedicated Stack Management**  |                              |     |                 |
|               Create              | 🔶 (can request first stack) |  ❌  | ❌               |
|                List               |               ✅              |  ❌  | ✅ (data source) |
|            Deprovision            |               ❌              |  ❌  | ❌               |
|     **Environment Management**    |                              |     |                 |
|               Create              |               ✅              |  ❌  | ✅               |
|                List               |               ✅              |  ✅  | ✅ (data source) |
|               Delete              |               ✅              |  ❌  | ✅               |
|               Rename              |               ✅              |  ✅  | ✅               |
|    Set Backup Retention Policy    |               ✅              |  ✅  | ✅               |
|         Get CA Certificate        |               ❌              |  ✅  | ❌               |
|         **App Management**        |                              |     |                 |
|               Create              |               ✅              |  ✅  | ✅               |
|                List               |               ✅              |  ✅  | N/A             |
|            Deprovision            |               ✅              |  ✅  | ✅               |
|               Rename              |               ✅              |  ✅  | ✅               |
|               Deploy              |               ✅              |  ✅  | ✅               |
|        Update Configuration       |               ✅              |  ✅  | ✅               |
|         Get Configuration         |               ✅              |  ✅  | ✅               |
|            SSH/Execute            |              N/A             |  ✅  | N/A             |
|              Rebuild              |               ❌              |  ✅  | N/A             |
|              Restart              |               ✅              |  ✅  | N/A             |
|               Scale               |               ✅              |  ✅  | ✅               |
|     Change Container Profiles     |               ✅              |  ✅  | ✅               |
|      **Database Management**      |                              |     |                 |
|               Create              |     🔶 (limited versions)    |  ✅  | ✅               |
|                List               |               ✅              |  ✅  | N/A             |
|            Deprovision            |               ✅              |  ✅  | ✅               |
|               Rename              |               ✅              |  ✅  | ✅               |
|               Modify              |               ❌              |  ✅  | ❌               |
|               Reload              |               ❌              |  ✅  | N/A             |
|           Restart/Scale           |               ✅              |  ✅  | ✅               |
|     Change Container Profiles     |               ✅              |  ❌  | ✅               |
|          Get Credentials          |               ✅              |  ✅  | ✅               |
|          Create Replicas          |               ❌              |  ✅  | ✅               |
|               Tunnel              |              N/A             |  ✅  | ❌               |
|   **Database Backup Management**  |                              |     |                 |
|               Create              |               ✅              |  ✅  | N/A             |
|                List               |               ✅              |  ✅  | N/A             |
|               Delete              |               ✅              |  ✅  | N/A             |
|              Restore              |               ✅              |  ✅  | N/A             |
|          Disable backups          |               ✅              |  ❌  | ❌               |
|      **Endpoint Management**      |                              |     |                 |
|               Create              |               ✅              |  ✅  | ✅               |
|                List               |               ✅              |  ✅  | N/A             |
|            Deprovision            |               ✅              |  ✅  | ✅               |
|               Modify              |               ✅              |  ✅  | ✅               |
|            IP Filtering           |               ✅              |  ✅  | ✅               |
|        Custom Certificates        |               ✅              |  ✅  | ❌               |
| **Custom Certificate Management** |                              |     |                 |
|               Create              |               ✅              |  ❌  | ❌               |
|                List               |               ✅              |  ❌  | N/A             |
|               Delete              |               ✅              |  ❌  | ❌               |
|      **Log Drain Management**     |                              |     |                 |
|               Create              |               ✅              |  ✅  | ✅               |
|                List               |               ✅              |  ✅  | N/A             |
|            Deprovision            |               ✅              |  ✅  | ✅               |
|    **Metric Drain Management**    |                              |     |                 |
|               Create              |               ✅              |  ✅  | ✅               |
|                List               |               ✅              |  ✅  | N/A             |
|            Deprovision            |               ✅              |  ✅  | ✅               |
|      **Operation Management**     |                              |     |                 |
|                List               |               ✅              |  ❌  | N/A             |
|               Cancel              |               ❌              |  ✅  | N/A             |
|                Logs               |               ✅              |  ✅  | N/A             |
|               Follow              |              N/A             |  ✅  | N/A             |


# Pricing

Learn about Aptible's pricing

# Aptible Hosted Pricing

The Aptible Hosted option allows organizations to provision infrastructure fully hosted by Aptible. This is ideal for organizations that prefer not to manage their own infrastructure and/or are looking to quickly get started. With this offering, the Aptible platform fee and infrastructure costs are wrapped into a simple, usage-based pricing model.

<CardGroup cols={3}>
  <Card title="Get started in minutes" icon="sparkles" iconType="duotone">
    Instantly deploy apps & databases
  </Card>

  <Card title="Simple pricing, fully on-demand" icon="play-pause" iconType="duotone">
    Pay-as-you-go, no contract required
  </Card>

  <Card title="Fast track compliance" icon="shield-halved" iconType="duotone">
    Infrastructure for ready for HIPAA, SOC 2, HITRUST & more
  </Card>
</CardGroup>

### On-Demand Pricing

|                            | Cost                                                    | Docs                                                                                      |
| -------------------------- | ------------------------------------------------------- | ----------------------------------------------------------------------------------------- |
| **Compute**                |                                                         |                                                                                           |
| General Purpose Containers | \$0.08/GB RAM/hour                                      | [→](/core-concepts/scaling/container-profiles)                                            |
| CPU-Optimized Containers   | \$0.10/GB RAM/hour                                      | [→](/core-concepts/scaling/container-profiles)                                            |
| RAM-Optimized Containers   | \$0.05/GB RAM/hour                                      | [→](/core-concepts/scaling/container-profiles)                                            |
| **Databases**              |                                                         |                                                                                           |
| Database Storage (Disk)    | \$0.20/GB/month                                         | [→](/core-concepts/scaling/database-scaling)                                              |
| Database IOPS              | \$0.01/IOPS after the first 3,000 IOPs/month (included) | [→](/core-concepts/scaling/database-scaling)                                              |
| Database Backups           | \$0.02/GB/month                                         | [→](/core-concepts/managed-databases/managing-databases/database-backups)                 |
| **Isolation**              |                                                         |                                                                                           |
| Shared Stack               | Free                                                    | [→](/core-concepts/architecture/stacks)                                                   |
| Dedicated Stack            | \$499/Stack/month                                       | [→](/core-concepts/architecture/stacks)                                                   |
| **Connectivity**           |                                                         | [→]()                                                                                     |
| Endpoints (Load Balancers) | \$0.06/endpoint/hour                                    | [→](/core-concepts/apps/connecting-to-apps/app-endpoints/overview#types-of-app-endpoints) |
| VPN                        | \$99/VPN peer/month                                     | [→](/core-concepts/integrations/network-integrations)                                     |
| **Security & Compliance**  |                                                         |                                                                                           |
| HIDS Reporting             | [Contact us]()                                          | [→](/core-concepts/security-compliance/hids)                                              |

### Enterprise and Volume Pricing

Aptible offers discounts for Enterprise and volume agreements. All agreements require a 12-month commitment. [Contact us to request a quote.](https://app.aptible.com/contact)

# Self Hosted Pricing

<Info>This offering is currently in limited release. [Request early access here](https://app.aptible.com/signup?cta=early-access).</Info>

The Self Hosted offering allows companies to host the Aptible platform directly within their own AWS accounts. This is ideal for organizations that already existing AWS usage or organizations interested in host their own infrastructure. With this offering, you pay Aptible a platform fee, and your infrastructure costs are paid directly to AWS.

<CardGroup cols={3}>
  <Card title="Unified Infrastructure" icon="badge-check" iconType="duotone">
    Manage your AWS infrastructure in your own account
  </Card>

  <Card title="Infrastructure costs paid directly to AWS" icon="aws" iconType="duotone">
    Leverage AWS discount and credit programs
  </Card>

  <Card title="Full access to AWS tools" icon="unlock" iconType="duotone">
    Unlock full access to tools and services within AWS marketplace
  </Card>
</CardGroup>

### On-Demand and Enterprise Pricing

All pricing for our Self Hosted offering is custom. This allows us to tailor agreements designed for organizations of all sizes.

# Support Plans

All Aptible customers receive access to email support with our Customer Reliability team. Our support plans give you additional access to things like increased targetted response times, 24x7 urgent support, Slack support, and a designated technical resources from the Aptible team.

<CardGroup cols={3}>
  <Card title="Standard" icon="signal-fair">
    **\$0/mo**

    Standard support with our technical experts. Recommended for the average production workload.
  </Card>

  <Card title="Premium" icon="signal-good">
    **\$499/mo**

    Faster response times with our technical experts. Recommended for average production workloads, with escalation ability.
  </Card>

  <Card title="Enterprise" icon="signal-strong">
    **Custom**

    Dedicated team of technical experts. Recommended for critical production workloads that require 24x7 support. Includes a Technical Account Manager and Slack support.
  </Card>
</CardGroup>

|                                | Standard        | Premium                                       | Enterprise                                    |
| ------------------------------ | --------------- | --------------------------------------------- | --------------------------------------------- |
| Get Started                    | Included        | [Contact us](https://app.aptible.com/contact) | [Contact us](https://app.aptible.com/contact) |
| **Target Response Time**       |                 |                                               |                                               |
| Low Priority                   | 2 Business Days | 2 Business Days                               | 2 Business Days                               |
| Normal Priority                | 1 Business Day  | 1 Business Day                                | 1 Business Day                                |
| High Priority                  | 1 Business Day  | 3 Business Hours                              | 3 Business Hours                              |
| Urgent Priority                | 1 Business Day  | 3 Business Hours                              | 1 Calendar Hour                               |
| **Support Options**            |                 |                                               |                                               |
| Email and Zendesk Support      | ✔️              | ✔️                                            | ✔️                                            |
| Slack Support (for Low/Normal) | -               | -                                             | ✔️                                            |
| 24/7 Support (for Urgent)      | -               | -                                             | ✔️                                            |
| Production Readiness Reviews   | -               | -                                             | ✔️                                            |
| Architectural Reviews          | -               | -                                             | ✔️                                            |
| Technical Account Manager      | -               | -                                             | ✔️                                            |

<Note>Aptible is committed to best-in-class uptime for all customers regardless of support plan. Aptible will make reasonable efforts to ensure your services running in Dedicated Environments are available with a Monthly Uptime Percentage of at least 99.95%. This means that we guarantee our customers will experience no more than 21.56 min/month of Unavailability.\
Unavailability, for app services and databases, is when our customer's service or database is not running or not reachable due to Aptible's fault. Details on our commitment to uptime and company level SLAs can be found [here](https://www.aptible.com/legal/service-level-agreement). The following Support plans and their associated target response times are for roadblocks that customers may run into while Aptible Services are up and running as expected.</Note>

# FAQ

<AccordionGroup>
  <Accordion title="Does Aptible offer free trials?">
    Yes. There is a 30 day free trial for launching a new project on Aptible hosted resources upon signup if you sign up with a business email.
    <Tip> Didn't receive a trial by default? [Contact us!](https://www.aptible.com/contact) </Tip>
    At this time, we are accepting requests for early access to use Aptible to launch a platform in your existing cloud accounts. Early access customers will get proof of concept/value periods.
  </Accordion>

  <Accordion title="What’s the difference between the Aptible Hosted and Self Hosted options?">
    Hundreds of the fastest growing startups and scaling companies have used **Aptible’s hosted platform** for a decade. In this option, Aptible hosts and manages your resources, abstracting away all the complexity of interacting with an underlying cloud provider and ensuring resources are provisioned properly.

    Aptible also manages **existing resources hosted in your own cloud account**. This means that you integrate Aptible with your cloud accounts and Aptible helps your platform engineering team create a platform on top of the infrastructure you already have. In this option, you control and pay for your own cloud accounts, while Aptible helps you analyze and standardize your cloud resources.
  </Accordion>

  <Accordion title="How can I upgrade my support plan?">
    [Contact us](https://app.aptible.com/contact) to ugprade your support plan.
  </Accordion>

  <Accordion title="How do I manage billing details such as payment information or invoices?">
    See our [Billing & Payments](/core-concepts/billing-payments) page for more information.
  </Accordion>

  <Accordion title="Does Aptible offer a startup program?">
    Yes, see our [Startup Program page for more information](https://www.aptible.com/startup).
  </Accordion>
</AccordionGroup>


# Terraform



## Overview

The [Aptible Terraform provider](https://registry.terraform.io/providers/aptible/aptible) allows you to manage your Aptible resources directly from Terraform - enabling infrastructure as code (IaC) instead of manually initiating Operations from the Aptible Dashboard of Aptible CLI. You can use the Aptible Terraform to automate the process of setting up new Environments, including:

*   Creating, scaling, modifying, and deprovisioning Apps and Databases

*   Creating and deprovisioning Log Drains and Metric Drains (including the [Aptible Terraform Metrics Module](https://registry.terraform.io/modules/aptible/metrics/aptible/latest), which provisions built Grafana dashboards with alerting)

*   Creating, modifying, and provisioning App Endpoints and Database Endpoints

For an overview of what actions the Aptible Terraform Provider supports, see the [Feature Support Matrix](/reference/interface-feature#feature-support-matrix).

## Using the Aptible Terraform Provider

### Environment definition

Environments are defined as data sources and should point toward a pre-existing environment that the Terraform user already has access to:

```perl
data "aptible_environment" "example" {
  handle = "terraform-example-environment"
}
```

### Deployment and managing Docker images

[Direct Docker Image Deployment](/how-to-guides/app-guides/migrate-dockerfile-to-direct-image-deploy) is currently the only deployment method supported with Terraform. If you'd like to use Terraform to deploy your Apps and you're currently using [Dockerfile Deployment](/how-to-guides/app-guides/deploy-from-git) you'll need to switch. See [Migrating from Dockerfile Deploy](/how-to-guides/app-guides/migrate-dockerfile-to-direct-image-deploy) for tips on how to do so.

If you’re already using Direct Docker Image Deployment, managing this is pretty easy. Set your Docker repo, registry username, and registry password as the configuration variables `APTIBLE_DOCKER_IMAGE`, `APTIBLE_PRIVATE_REGISTRY_USERNAME`, and `APTIBLE_PRIVATE_REGISTRY_PASSWORD`.

```perl
resource "aptible_app" "example-app" {
    env_id         = data.aptible_environment.example.env_id
    handle         = "example-app"
    config = {
        "APTIBLE_DOCKER_IMAGE": "",
        "APTIBLE_PRIVATE_REGISTRY_USERNAME": "",
        "APTIBLE_PRIVATE_REGISTRY_PASSWORD": "",
    }
}
```

<Warning> Please ensure you have the correct image, username, and password set every time you run `terraform apply`. If you are deploying outside of Terraform, you will also need to keep your Terraform configuration up to date. See [Terraform's refresh Terraform configuration documentation](https://developer.hashicorp.com/terraform/cli/commands/refresh) for more information.</Warning>

<Tip> For a step-by-step tutorial in deploying a metric drain with Terraform, please visit our [Terraform Metric Drain Deployment Guide](/how-to-guides/app-guides/deploy-metric-drain-with-terraform)</Tip>

## Managing Services

### Managing Services

The service `process_type` should match what's contained in your Procfile. Otherwise, service container sizes and container counts cannot be defined and managed individually.

```perl
resource "aptible_app" "example-app" {
  env_id         = data.aptible_environment.example.env_id
  handle         = "exmaple-app"
  config = {
    "APTIBLE_DOCKER_IMAGE": "",
    "APTIBLE_PRIVATE_REGISTRY_USERNAME": "",
    "APTIBLE_PRIVATE_REGISTRY_PASSWORD": "",
  }
  service {
    process_type           = "sidekiq"
    container_count        = 1
    container_memory_limit = 1024
  }
  service {
    process_type           = "web"
    container_count        = 2
    container_memory_limit = 4096
  }
}
```

### Referencing Resources in Configurations

Resources can easily be referenced in configurations when using Terraform. Here is an example of an App configuration that references Databases:

```perl
resource "aptible_app" "example-app" {
    env_id = data.aptible_environment.example.env_id
    handle = "example-app"
    config = {
        "REDIS_URL": aptible_database.example-redis-db.default_connection_url,
        "DATABASE_URL": aptible_database.example-pg-db.default_connection_url,
    }
    service {
        process_type           = "cmd"
        container_count        = 1
        container_memory_limit = 1024
    }
}

resource "aptible_database" "example-redis-b" {
  env_id         = data.aptible_environment.example.env_id
  handle         = "example-redis-db"
  database_type  = "redis"
  container_size = 512
  disk_size      = 10
  version        = "5.0"
}

resource "aptible_database" "example-pg-db" {
  env_id         = data.aptible_environment.example.env_id
  handle         = "example-pg-db"
  database_type  = "postgresql"
  container_size = 1024
  disk_size      = 10
  version        = "12"
}
```

Some apps use the port, hostname, username, and password broken apart rather than as a standalone connection URL. Terraform can break those apart, or you can add some logic in your app or container entry point to achieve this. This also works with endpoints. For example:

```perl
resource "aptible_app" "example-app" {
  env_id = data.aptible_environment.example.env_id
  handle = "example-app"
  config = {
    "ANOTHER_APP_URL": aptible_endpoint.example-endpoint.virtual_domain,
  }
  service {
    process_type = "cmd"
    container_count = 1
    container_memory_limit = 1024
  }
}

resource "aptible_app" "another-app" {
  env_id = data.aptible_environment.example.env_id
  handle = "another-app"
  config = {}
  service {
    process_type = "cmd"
    container_count = 1
    container_memory_limit = 1024
  }
}

resource "aptible_endpoint" "example-endpoint" {
  env_id         = data.aptible_environment.example.env_id
  default_domain = true
  internal       = true
  platform       = "alb"
  process_type   = "cmd"
  endpoint_type  = "https"
  resource_id    = aptible_app.another-app.app_id
  resource_type  = "app"
  ip_filtering   = []
}
```

The value `aptible_endpoint.example-endpoint.virtual_domain` will be the domain used to access the Endpoint (so `app-0000.on-aptible.com` or `www.example.com`).

<Note> If your Endpoint uses a wildcard certificate/domain, `virtual_domain` would be something like `*.example.com` which is not a valid domain name. Therefore, when using a wildcard domain, you should provide the subdomain you want your application to use to access the Endpoint, like `www.example.com`, rather than relying solely on the Endpoint's `virtual_domain`.</Note>

## Circular Dependencies

One potential risk of relying on URLs to be set in App configurations is circular dependencies. This happens when your App uses the Endpoint URL in its configuration, but the Endpoint cannot be created until the App exists. Terraform does not have a graceful way of handling circular dependencies. While this approach won't work for default domains, the easiest option is to define a variable that can be referenced in both the Endpoint resource and the App configuration:

```perl
variable "example_domain" {
  description = "The domain name"
  type        = string
  default     = "www.example.com"
}

resource "aptible_app" "example-app" {
  env_id = data.aptible_environment.example.env_id
  handle = "example-app"
  config = {
    "ANOTHER_APP_URL": var.example_domain,
  }
  service {
    process_type = "cmd"
    container_count = 1
    container_memory_limit = 1024
  }
}

resource "aptible_endpoint" "example-endpoint" {
  env_id         = data.aptible_environment.example.env_id
  endpoint_type  = "https"
  internal       = false
  managed        = true
  platform       = "alb"
  process_type   = "cmd"
  resource_id    = aptible_app.example-app.app_id
  resource_type  = "app"
  domain         = var.example_domain
  ip_filtering   = []
}
```

## Managing DNS

While Aptible does not directly manage your DNS, we do provide you the information you need to manage DNS. For example, if you are using Cloudflare for your DNS, and you have an endpoint called `example-endpoint`, you would be able to create the record:

```perl
resource "cloudflare_record" "example_app_dns" {
  zone_id = cloudflare_zone.example.id
  name    = "www.example"
  type    = "CNAME"
  value   = aptible_endpoint.example-endpoint.id
  ttl     = 60
}
```

And for the Managed HTTPS [dns-01](/core-concepts/apps/connecting-to-apps/app-endpoints/managed-tls#dns-01) verification record:

```perl
resource "cloudflare_record" "example_app_acme" {
  zone_id = cloudflare_zone.example.id
  name    = "_acme-challange.www.example"
  type    = "CNAME"
  value   = "acme.${aptible_endpoint.example-endpoint.id}"
  ttl     = 60
}
```

## Secure/Sensitive Values

You can use Terraform to mark values as secure. These values are redacted in the output of `terraform plan` and `terraform apply`.

```perl

variable "shhh" {
  description = "A sensitive value"
  type        = string
  sensitive   = true
}

resource "aptible_app" "example-app" {
  env_id = data.aptible_environment.example.env_id
  handle = "example-app"
  config = {
    "SHHH": var.shhh,
  }
  service {
    process_type = "cmd"
    container_count = 1
    container_memory_limit = 1024
  }
}
```

When you run `terraform state show` these values will also be marked as sensitive. For example:

```perl
resource "aptible_app" "example-app" {
    app_id   = 000000
    config   = {
        "SHHH" = (sensitive)
    }
    env_id   = 4749
    git_repo = "git@beta.aptible.com:terraform-example-environment/example-app.git"
    handle   = "example-app"
    id       = "000000"

    service {
        container_count        = 1
        container_memory_limit = 1024
        process_type           = "cmd"
    }
}
```

## Spinning down Terraform Resources

Resources created using Terraform should not be deleted through the Dashboard or CLI. Deleting through the Dashboard or CLI does not update the Terraform state which will result in errors the next time you run terraform plan or terraform apply. Instead, use terraform plan -destroy to see which resources will be destroyed and then use terraform destroy to destroy those resources.

If a Terraform-created resource is deleted through the Dashboard or CLI, use the terraform state rm [command](https://developer.hashicorp.com/terraform/cli/commands/state/rm) to remove the deleted resource from the Terraform state file. The next time you run terraform apply, the resource will be recreated to reflect the configuration.