Creating your Own Installation Script

Any user may propose a script in the language of their choice allowing users to install their application. This script will be run with the permissions for the account where installation took place and must start with a YAML format comment.

Scripts comprise two parts:

  • the YAML format dataset for configuring the site and requesting the information required by the script (the FORM_* variables) from the user. It can be split into four:

    • site: refer to the API documentation that restates all of the possible options.
    • database: mysql, postgresql, couchdb, rabbitmq.
    • requirements: specify limiting requirements which blocks their installation on certain plans.
    • form: all of the variables requested from the user creating the site. Example: site title, administrator ID, e-mail address, administrator's name, etc.
  • the actual script.

Environment variables

Variables Description Example
USER Account name foo
HOME Account root for the script /home/foo/example/
APPLICATION_NAME Application name
INSTALL_URL Site address foo.example.net/test
INSTALL_URL_PATH Site root (base URL) /test
INSTALL_URL_HOSTNAME Site host name foo.example.net
INSTALL_PATH_RELATIVE Relative path from the account root (without final slash) example
INSTALL_PATH Absolute path (without final slash) /home/foo/example
DATABASE_USERNAME Database connection user (managed automatically) foo_*
DATABASE_PASSWORD User password for database connection (managed automatically)
DATABASE_NAME Site database (managed automatically) foo_*
DATABASE_HOST Host name for database server connection mysql-foo.alwaysdata.net (base MySQL)
SMTP_HOST Host name for mail sending server connection smtp-foo.alwaysdata.net
RESELLER_DOMAIN Root domain used by the hosting provider alwaysdata.net
FORM_* Other variables explicitly requested from the user in the "form" section in the YAML dataset
PORT Specific port for User program, Node.js, Elixir, .NET or Deno type sites
:: or IP Specific port for User program, Node.js, Elixir, .NET or Deno type sites (prefer :: to IP)

If other variables are needed, open a support ticket.

Notes and tips

  • The script needs to start with set -e to stop it when it fails,
  • Specify the version of the language used (PHP, Python, Ruby, Node.js and Elixir). This is recommended to avoid being dependent on the default account configuration,
  • The root directory specified by the user (INSTALL_PATH) serves as the root for a script (an export HOME= is run by default),
  • To make an installation script public, you must specify the disk condition in the requirements,
  • It is preferable to request a minimum amount of information to avoid making the script an exhaustive one. Users may change the configuration of their application later on.
  • To add an optional form field, set the required option to false. If the user does not specify anything, the field remains blank,
  • Labels and regex_text are translatables. Depending on the language chosen in its alwaysdata administration interface, the user can have the form questions in the specified languages.

Note

To make a script accessible to alwaysdata platform users, check the box to make it public. Any script marked as public must be maintained and will at least be checked by the alwaysdata team.

Tip

A deposit URL may be provided to make maintenance easier. In this case, once the changes are pushed to the deposit all that remains is to update the application via the button provided.

Example - Drupal installation script

#!/bin/bash

# Declare site in YAML, as documented on the documentation: https://help.alwaysdata.com/en/marketplace/build-application-script/
# site:
#     type: php
#     path: '{INSTALL_PATH_RELATIVE}/web'
#     php_version: '8.3'
# database:
#     type: mysql
# requirements:
#     disk: 140
# form:
#     language:
#         type: choices
#         label:
#             en: Language
#             fr: Langue
#         choices:
#             de: Deutsch
#             en: English
#             es: Español
#             fr: Français
#             it: Italiano
#     site_name:
#         label:
#             en: Site name
#             fr: Nom du site
#         max_length: 255
#     email:
#         type: email
#         label:
#             en: Email
#             fr: Email
#         max_length: 255
#     admin_username:
#         label:
#             en: Administrator username
#             fr: Nom d'utilisateur de l'administrateur
#         regex: ^[ a-zA-Z0-9.@_-]+$
#         regex_text:
#             en: "It must include at least 5 characters which can be uppercase, lowercase, numbers, spaces, and special characters: .@_-."
#             fr: "Il doit comporter au moins 5 caractères qui peuvent être des majuscules, des minuscules, des chiffres, des espaces et les caractères spéciaux : .@_-."
#         min_length: 5
#         max_length: 255
#     admin_password:
#         type: password
#         label:
#             en: Administrator password
#             fr: Mot de passe de l'administrateur
#         min_length: 5
#         max_length: 255

set -e

# https://www.drupal.org/docs/system-requirements

# Download & install dependencies
COMPOSER_CACHE_DIR=/dev/null composer2 create-project drupal/recommended-project

cd recommended-project

sed -i "/\"require\": {/a \ \ \ \ \ \ \ \ \"drush/drush\": \"^12.1\"," composer.json

COMPOSER_CACHE_DIR=/dev/null composer2 update

# Install
# CLI: https://drushcommands.com
echo "y" | php vendor/drush/drush/drush.php si --db-url=mysql://"$DATABASE_USERNAME":"$DATABASE_PASSWORD"@"$DATABASE_HOST"/"$DATABASE_NAME" --account-name="$FORM_ADMIN_USERNAME" --account-pass="$FORM_ADMIN_PASSWORD" --account-mail="$FORM_EMAIL" --site-name="$FORM_SITE_NAME" --locale="$FORM_LANGUAGE"

# Handle subdirectories base URL
if [ "$INSTALL_URL_PATH" != "/" ]
then
    sed -i "s|# RewriteBase /$|RewriteBase $INSTALL_URL_PATH|" web/.htaccess
fi

# Clean install environment
cd
rm -rf .config .local .subversion
shopt -s dotglob
mv recommended-project/* .

The disk:140 condition specifies that the Drupal installation requires 140 MB of disk space. The free offer is therefore too tight. Use the regex_text condition to explain the regex with words.