App cloning

How to clone my running application to new application in aptible??

Is my application a good fit for Aptible?

Broadly speaking, if your Application is already containerized, and aligns well with the [Twelve-Factor App]( model, you will likely find Deploy's features to be familiar and in-line with your expectations. However, the Deploy platform's architecture is opinionated and is not suitable for _every_ type of application. > πŸ“˜ Tip > > You do not need to host 100% of your infrastructure on Aptible Deploy to realize the benefits of the platform. If some of your applications are not compatible, Deploy can be used in conjunction with other SaaS services, or privately hosted services via [Integrations]( # Containerization Deploy _only_ supports running Docker Containers. Most applications you have written yourself will be easy to containerize, if they are not already. However, software distributed by a 3rd party may be harder to meet this requirement. Some tell-tale signs an application won't be possible or easy to run on Deploy: - **VMDK, VDI, or VDH files** - Deploy does not support running software in virtual machines. - **Amazon Machine Images (AMIs)** - Deploy does not support running software directly on EC2 instances. - **EXE or MSI files** - Deploy does not support Microsoft Windows software. # Operating System Aptible Deploy supports Docker images with operating systems based upon the Linux kernel, such as Debian, Ubuntu, CentOS, RedHat, Alpine, etc. Windows-based Docker images cannot be run on Deploy. # Transport Protocol All services you host on Deploy must be explicitly exposed via [Endpoints](, which only support exposing TCP-based services. You will not be able to serve UDP services from Deploy. You may still connect _to_ UDP services (such as DNS, SNMP, etc) from Applications hosted on Deploy. # Data Persistence With the notable exception of Database data, the filesystem for your Containers is ephemeral. This means that every time your containers are recycled, any data you stored on the filesystem will be gone. As a result, you should make sure you never use the filesystem for data you need to retain long term. Instead, this data should be stored in a [Database]( or in a third-party storage solution, such as AWS S3. Applications that rely on persistent local storage, or a volume shared between multiple containers, will need to be re-architected.

How do I check when a Database's SSL certificate expires?

Retrieving information about a Database's SSL certificate can be accomplished using the same tools that you'd use to retrieve any website's certificate from the command line. The main difference is how you connect to the Database since, unlike websites, it's not publicly accessible over the internet. The simplest way to connect to the Database is to create a [Database Tunnel]( from your local computer. Then you can use an SSL client such as `openssl` to retrieve the certificate. For Redis Database tunnels SSL must be explicity enabled by setting the tunnel's `--type` to `redis+ssl` e.g. ``` aptible db:tunnel $DB_HANDLE --type redis+ssl ``` The following `openssl` command should work for all Database types except MySQL and PostgreSQL. ``` echo | openssl s_client -connect$TUNNEL_PORT 2>/dev/null | openssl x509 -noout -dates ``` Which will print something along the lines of. ``` notBefore=Jan 27 00:00:00 2018 GMT notAfter=Feb 2 23:59:59 2021 GMT ``` MySQL and PostgreSQL handle encryption in a way that `openssl` does not support by default so the above method cannot be used. However, unlike other Database types, Databases of these two types generate a new certificate whenever they are reloaded or restarted. This certificate is valid for several years so there is very little chance that the certificate will expire before the Database is restarted.

Access app name within container

How can I access the name of the current aptible app within my container? I see from that aptible injects an env var called $APTIBLE_APP_HREF, but inside the container I'm not sure how to get an app name from that.

How should I handle vulnerabilities found in Security Scans?

[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 in order 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 are using a [Dockerfile Deploy]( you can use the command [`aptible rebuild`]( to rebuild and deploy the new image: ```shell aptible rebuild --app $HANDLE ``` If you are using [Direct Docker Image Deploy](, 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 : ```dockerfile 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: ```dockerfile 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 which 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: ```dockerfile 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!

Connecting to MySQL on Aptible Deploy using PHP

On Aptible Deploy, [MySQL]( Databases enforce SSL, but use a self-signed certificate. Here is how you can configure PHP to connect over SSL. # Using PDO ```php // Assuming you have set $hostname, $username, $password, $db, and $port $url = "mysql:host=$hostname;port=$port;dbname=$db;charset=utf8"; new PDO( $url, $username, $password, array( PDO::MYSQL_ATTR_SSL_CIPHER => 'DHE-RSA-AES256-SHA', PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT => false ) ); ``` # Using `mysqli` ```php // Assuming you have set $hostname, $username, $password, $db, and $port $link = mysqli_init(); mysqli_real_connect( $link, $hostname, $username, $password, $db, $port, NULL, MYSQLI_CLIENT_SSL | MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT ); ```

How can I whitelist my App's IP?

See [Outbound IP Addresses](

Can I use Whenever to run scheduled tasks (cron jobs) on Aptible Deploy?

The best way to use Whenever with Aptible Deploy is to use Whenever to generate a `crontab`, then execute that `crontab` using Supercronic To do so, add the `whenever` gem to your `Gemfile`, then add a `config/schedule.rb` file to your app repository. Here is an example `config/schedule.rb` that schedules `bundle exec rake db:awesome` to run every day at 2 AM: ```ruby every, at: '2:00 am' do command 'bundle exec rake db:awesome' end ``` Finally, follow the instructions under [How do I run scheduled tasks (cron jobs) on Aptible Deploy?](, except that instead of writing the `crontab` and copying it to your image, you should use `whenever` to generate it: ```dockerfile RUN whenever > /app/crontab ```

Does Aptible Deploy provide a Web Application Firewall (WAF) solution?

Aptible Deploy does not have a WAF solution built-in but it is possible to use them with Deploy-hosted [Apps]( However, WAFs are not required for HIPAA compliance nor are they perfect. If they are configured too leniently, they may miss malicious requests and, if they're too strict, they may block legitimate requests. For these reasons, we recommend using other methods to protect against request-based attacks. # Mitigating Request-Based Attacks ## SQL Injection Using an Object-Relational Mapping (ORM) when interacting with [Databases]( will mitigate SQL injection attacks. The ORM will handle escaping string parameters so the Database can distinguish between SQL and parameters. ## Cross-Site Request Forgery Many frameworks guard against CSRF attacks. If you're not using a framework or yours does not provide this protection you can implement a [token based]( approach to mitigate this risk. ## Cross-Site Scripting XSS attacks can be mitigated by avoiding inserting untrusted data in dangerous places in HTML such as script tags, comments, and attribute names, escaping the data when putting it in the body of a tag, and avoiding running untrusted scripts. There are also some libraries and frameworks that handle these concerns. # WAF Placement Like all reverse-proxies used with Deploy-hosted [Apps](, there are three main locations where a WAF can be deployed: - Inside the same container as the App - In its own dedicated App or Service - Outside of Aptible Deploy Each placement has some considerations on how to prevent users from circumventing the WAF and accessing the [App]( directly. ## Inside the App Container When a WAF is deployed in the same container as the [App]( it's proxying, the [Endpoint]( for this App has to target the port the WAF is listening on and the WAF must forward the request to the App. This method ensures that all internal and external traffic must pass through the WAF in order to access the App and will scale with the App. However, it also increases the complexity of Apps and requires that the WAF be installed in all [App Images]( that utilize it. ## Dedicated Service When deploying the WAF in its own dedicated [Service](, an [External Endpoint]( must be created on the WAF Service and [Internal Endpoints]( must be created on the Service(s) that the WAF is proxying. Users will connect to the WAF via the External Endpoint and the WAF will connect to the Service(s) via the Internal Endpoints. This method prevents having to install the WAF in every [App Image]( and a single WAF [Service]( can serve multiple Services simultaneously. The downside is that that WAF won't scale with the Services, another [App]( on the Stack could circumvent the WAF and access an [Internal Endpoint]( directly, and it can create a single point of failure for multiple Services though this can be mitigated by [scaling the WAF horizontally]( ## Outside Aptible Deploy Forcing users to connect to an [App]( through a WAF deployed outside of Aptible Deploy is a little more tricky. An [External Endpoint]( can still be used to allow the WAF to connect to the services it's proxying but [IP Filtering]( will need to be used to only allow access from the WAF. Otherwise, users could access the [Endpoint]( directly and circumvent the WAF. An [Internal Endpoint]( may also be used but the WAF will have to access it via a [Network Integration]( There are many off-the-shelf products that can be used with this method but if they're processing PHI a BAA will be required for HIPAA compliance. Unlike using a dedicated [Service]( on Aptible Deploy, [Apps]( on the same [Stack]( will still have to route requests through the WAF in order to access the underlying App.

How do I use shared_preload_libraries in my PostgreSQL Database?

Some [PostgreSQL]( extensions need to be added to shared_preload_libraries before they can be used in your Database. `pg_stat_statements` is one commonly-used library with this property. You can use `ALTER SYSTEM SET` in your Database to make this change - for example using libraries `foo` and `bar`: ```postgresql ALTER SYSTEM SET shared_preload_libraries = foo,bar; ``` Attempting to run `CREATE EXTENSION foo` before adding `foo` to shared_preload_libraries will return the following: `ERROR: foo is not in shared_preload_libraries`. Changes made with `ALTER SYSTEM SET` will persist through [`aptible db:restart`]( operations. > ❗️ Warning > > When specifying more than one library in shared_preload_libraries, the values must be unquoted or quoted individually: > > ```postgresql > -- These are valid options: > ALTER SYSTEM SET shared_preload_libraries = foo,bar; > ALTER SYSTEM SET shared_preload_libraries = 'foo','bar'; > -- This will result in an error: > ALTER SYSTEM SET shared_preload_libraries = 'foo,bar'; > ``` > > This is because PostgreSQL supports library names containing commas, so it interprets the final line as a single library '"foo,bar"'.

How do I restrict Users to access only specific Apps?

To restrict users to particular [Apps]( (or [Databases](, split those resources into separate [Environments](

How do I install private Ruby / Node / ... dependencies for my app?

Often, an app may have private dependencies (e.g., Ruby gems or Node packages) that must be downloaded and installed at runtime. We recommend hosting these private dependencies on GitHub and downloading them via GitHub "personal access tokens." To create a personal access token, first log in to GitHub as a user with access to the repo(s) hosting the private dependencies your app requires. (Ideally, this should be a "robot user" with privileges restricted to read-only access, and only for the required repos.) Then, navigate to the [Personal Access Tokens]( page, and create a token with `repo` scope. Now, let's say that your newly-generated token is ``` 988881adc9fc3655077dc2d4d757d480b5ea0e11 ``` To reference a Ruby gem dependency using this token, you'd add an entry like the following to your `Gemfile`. For the example, we've assumed that the gem is named `mygem`, and hosted on GitHub as `myorg/mygem`: ```ruby gem 'mygem', git: 'https://[email protected]/myorg/mygem.git' ``` To reference a Node (NPM) package using this token, you'd an entry like the following to your `package.json`. For the example, we've assumed that the package is named `mypkg`, and hosted on GitHub as `myorg/mypkg`: ```json { "mypkg": "git+https://988881adc9fc3655077dc2d4d757d480b5ea0e11:[email protected]/myorg/mypkg.git" } ``` Finally, note that you can also leverage [Direct Docker Image Deploy](, and inject private dependencies in your Docker build context as you see fit.

My app requires a specific OS package. How do I install it?

Aptible Deploy is OS-agnostic, so installing an OS package is mainly a matter of updating your [Dockerfile]( to install it using your OS package manager. For example, if your app requires ImageMagick and you're using a Debian or Ubuntu based image, you'd add the following directive to your Dockerfile: ```dockerfile RUN apt-get update \ && apt-get install -y imagemagick \ && rm -rf /var/lib/apt/lists/* ```

How do I place my app in maintenance mode?

If you need to perform e.g. complex database migrations and need to take your app offline while this completes, scale all of your App's services to zero (see: [Scaling]( If clients connect while your app is down, a configurable [Maintenance Page]( will be served.

Why is Load Average shown on the Dashboard Metrics but isn't included by Metric Drains?

Load average can be a useful diagnostic metric, but our assessment is that there are downsides of the implementation detail that outweigh the benefits of providing load average in [Metric Drains]( # How Load Average is Calculated When measuring load average at the host level, the metric is computed by the Kernel, which keeps track of it whenever it updates the state of a process. In particular, this means the load average provided by the Kernel is not subject to sampling bias since it is kept up to date every time a task changes state. Unfortunately, the same is not true of cgroup (container-level) load average, since the kernel does not track load average on a per-cgroup basis. Instead, we use the [Control Groupstats]( netlink API, which provides us with the number of sleeping, running, etc. tasks, needed to compute load average. Aptible Deploy polls this API periodically in order to calculate and present a load average metric on the Dashboard that's comparable to the expected load average measurement. # Sampling Bias Since we released load average in the Dashboard, we have come to the realization that this approach is unfortunately very much subject to sampling bias. This means that if you happen to poll the API while a task in uninterruptible sleep, load average will jump even if the task stayed in that state for a microsecond. Unless Deploy were to poll very, very frequently (which would ultimately have a performance impact), load average ends up being a very noisy and fairly misleading metric. It's worth noting that it's only noisy in one direction: if your container is actually very busy, the load average will properly reflect this, but other times the load average will jump for no reason. This sampling bias, unfortunately, makes load average fairly useless from an alerting perspective (if not actively misleading) and only mildly useful from an investigative perspective. We've seen many cases where load average is high in a container where everything was actually perfectly fine. # Security Concerns Finally, the aforementioned netlink API would require running Metric Drains as privileged containers, which we avoid doing for security reasons.

What kinds of isolation can Aptible Deploy 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 Deploy 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 Deploy platform. The [Reference Architecture Diagram]( helps illustrate some of the following concepts. # Infrastructure All Aptible Deploy 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]( and [Databases]( # Network/Stack An Aptible Deploy each [Stack]( is an AWS Virtual Private Cloud provisioned with EC2, ELB, and EBS assets and Aptible Deploy platform software. When you provision a [Dedicated Stack]( on Aptible Deploy, you receive your own VPC, meaning you receive your own private and public subnets, isolated from other Aptible Deploy customers.. You can provide further network level isolation between your own [Apps]( and [Databases]( by provisioning Additional [Dedicated Stacks]( # Host The Aptible Deploy layers where you [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 Deploy customer using those EC2 virtual servers. The AWS hypervisor enforces isolation between EC2 hosts running on the same underlying hardware. Within a Stack, the EC2 hosts are organized into Aptible Deploy 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 Deploy 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 Deploy [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 Deploy uses Docker to build and run your App and Database [Containers]( 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](

How can I request HITRUST inheritance for Aptible Deploy?

Aptible Deploy is HITRUST CSF Certified. If you are pursuing your own HITRUST CSF Certification, you may request that Aptible Deploy's assessment scores be incorporated into your own assessment, reducing the time and cost of your own HITRUST CSF Validated assessment. To get started, first contact [Aptible Support]( to request the list of controls you may inherit. Then, follow HITRUST's instructions for [Inheriting a Requirement Statement]( Once you generate the inheritance request, our support team will review and approve the request in MyCSF.

How do I import my existing Heroku PostgreSQL database?

Once you have provisioned and deployed a copy of your app on Aptible, there are a few final steps to migrate from Heroku's managed PostgreSQL service. Before you begin, make sure that `wget` and the PostgreSQL client tools (`psql` and `pg_restore`) are available in your app's Docker image. If your Docker image is based on Ubuntu, you can do this by adding the following lines to your [Dockerfile]( then deploying your app: ```dockerfile RUN apt-get update \ && apt-get -y install wget postgresql-client postgresql-contrib \ && rm -rf /var/lib/apt/lists/* ``` Now, to perform the migration: 1. First, put your Heroku app into maintenance mode: ```shell heroku maintenance:on -a $HEROKU_APP_HANDLE ``` 2. Then, manually trigger a backup of your Heroku database: ```shell heroku pgbackups:capture -a $HEROKU_APP_HANDLE ``` 3. View the list of backups, noting the ID for the backup you just created: ```shell heroku pgbackups -a $HEROKU_APP_HANDLE ``` 4. Get the URL for your backup: ```shell heroku pgbackups:url $BACKUP_ID -a $HEROKU_APP_HANDLE ``` 5. Open an [Ephemeral SSH Session]( to your app: ```shell aptible ssh --app $APTIBLE_APP_HANDLE ``` 6. Download the backup file, using the URL from Step 4: ```shell wget $BACKUP_URL -O backup.dump ``` 7. Identify the host, port and password for your Aptible PostgreSQL database, and run the following command to restore from the backup (replacing `$HOST` and `$PORT` with your Aptible PostgreSQL database's host and port). You will be prompted for the database password: ```shell pg_restore --clean --no-acl --no-owner \ -h "$HOST" -p "$PORT" -d db -U aptible -W backup.dump ```

How do I set environment variables for my app?

Your [App]('s [Configuration]( is available as environment variables in your App [Containers]( To set new environment variables, use the [`aptible config:set`]( command.

How can I download a backup of an Aptible Deploy database?

To download a [Database Backup]( 1. [Restore the backup to a new database]( 2. Use the [`aptible db:tunnel`]( command and use whatever tool your database supports to dump the restored database. > πŸ“˜ Tip > > Your restored database will count towards your container and disk usage, so deprovision it when you are done and you no longer need it.