Skip to content

Instantly share code, notes, and snippets.

@themightychris
Created October 22, 2019 20:40
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save themightychris/a10cf1a4d7b787987014b474f9988688 to your computer and use it in GitHub Desktop.
Save themightychris/a10cf1a4d7b787987014b474f9988688 to your computer and use it in GitHub Desktop.
Habitat plan.sh for Laravel application
#!{{pkgPathFor "core/bash"}}/bin/bash -e
if [ -f '{{pkg.svc_var_path}}/key' ]; then
APP_KEY="$(cat '{{pkg.svc_var_path}}/key')"
fi
APP_DEBUG='{{#if cfg.app.debug}}true{{/if}}'
APP_ENV='{{#if cfg.app.env}}{{cfg.app.env}}{{else}}production{{/if}}'
APP_URL='{{cfg.app.url}}'
# configure access to bound database member
DB_CONNECTION='{{cfg.db.connection}}'
DB_DATABASE='{{cfg.db.database}}'
{{~ #eachAlive bind.database.members as |member|}}
{{~ #if @first}}
# for psql client
PGHOST="{{member.sys.ip}}"
PGPORT="{{member.cfg.port}}"
PGUSER="{{member.cfg.superuser_name}}"
PGPASSWORD="{{member.cfg.superuser_password}}"
# for Laravel application
DB_HOST="${PGHOST}"
DB_PORT="${PGPORT}"
DB_USERNAME="${PGUSER}"
DB_PASSWORD="${PGPASSWORD}"
{{~ /if}}
{{~/eachAlive}}
# configure email
MAIL_DRIVER="{{cfg.mail.driver}}"
MAIL_HOST="{{cfg.mail.host}}"
MAIL_PORT="{{cfg.mail.port}}"
MAIL_USERNAME="{{cfg.mail.username}}"
MAIL_PASSWORD="{{cfg.mail.password}}"
MAIL_ENCRYPTION="{{cfg.mail.encryption}}"
[app]
debug = true
url = "http://localhost"
env = "local"
[admin]
email = ""
[db]
connection = "pgsql"
database = "myapp"
[mail]
driver = "smtp"
host = "smtp.mailtrap.io"
port = 2525
username = ""
password = ""
encryption = ""
[error]
reporting = "E_ALL"
[extensions.opcache]
enabled=true
zend=true
[extensions.sqlsrv]
enabled=true
[extensions.pdo_sqlsrv]
enabled=true
#!{{pkgPathFor "core/bash"}}/bin/bash -e
exec 2>&1
echo "Initializing storage/cache/config"
pushd "{{pkg.svc_var_path}}" > /dev/null
{
mkdir -vp \
"./cache" \
"./storage/app/public" \
"./storage/framework"/{cache/data,sessions,views} \
"./storage/logs"
if [ ! -f "./key" ]; then
echo "Generating app key with artisan"
artisan key:generate --show > "./key" || {
{
echo "Failed to generate ./key";
cat "./key" | sed 's/^/\t/';
rm -v "./key";
} 2>&1 | sed 's/^/\t/' | >&2 cat
exit 1;
}
fi
set -a
. "{{pkg.svc_config_path}}/env"
set +a
artisan event:cache
artisan view:cache
artisan config:cache
chown -R "{{pkg.svc_user}}":"{{pkg.svc_group}}" ./{cache,storage}
}
popd > /dev/null
echo "Initializing database"
createdb "${DB_DATABASE}" || true
artisan migrate --force
pkg_name=myapp
pkg_origin=myorigin
pkg_version="0.1.0"
pkg_maintainer="Chris Alfano <chris@jarv.us>"
pkg_build_deps=(
core/composer
core/node
core/yarn
jarvus/toml-merge
)
pkg_deps=(
core/bash
core/postgresql11-client
emergence/php7
emergence/php7-mssql
jarvus/libfcgi
)
pkg_bin_dirs=(bin)
pkg_binds=(
[database]="port superuser_name superuser_password"
)
pkg_exports=(
[port]=network.port
[server_snippet]=server.snippet
)
do_setup_environment() {
set_buildtime_env COMPOSER_ALLOW_SUPERUSER "1"
set_runtime_env PHPRC "${pkg_svc_config_install_path}"
set_runtime_env APP_STORAGE "${pkg_svc_var_path}/storage"
set_runtime_env APP_SERVICES_CACHE "${pkg_svc_var_path}/cache/services.php"
set_runtime_env APP_PACKAGES_CACHE "${pkg_svc_var_path}/cache/packages.php"
set_runtime_env APP_CONFIG_CACHE "${pkg_svc_var_path}/cache/config.php"
set_runtime_env APP_ROUTES_CACHE "${pkg_svc_var_path}/cache/routes.php"
set_runtime_env APP_EVENTS_CACHE "${pkg_svc_var_path}/cache/events.php"
}
do_before() {
# adjust PHP_EXTENSION_DIR after env is initially built
set_runtime_env -f PHP_EXTENSION_DIR "${pkg_svc_config_install_path}/extensions-${PHP_ZEND_API_VERSION}"
}
do_unpack() {
pushd "${PLAN_CONTEXT}/.." > /dev/null
mkdir -v "${CACHE_PATH}/"
build_line "Copying app manifests build directory"
cp -v composer.{lock,json} \
package{,-lock}.json \
yarn.lock \
webpack.mix.js \
"${CACHE_PATH}/" || :
build_line "Copying artisan command build directory"
cp -v artisan "${CACHE_PATH}/"
build_line "Copying app directories build directory"
cp -r {app,bootstrap,config,database,public,resources,routes} \
"${CACHE_PATH}/" || :
popd > /dev/null
}
do_build() {
pushd "${CACHE_PATH}" > /dev/null
build_line "Cleaning sources"
rm -vr bootstrap/cache/*.php \
public/{js,css,fonts/ \
public/mix-manifest.json || :
build_line "Patching artisan command"
sed -e "s#\#\!/usr/bin/env php#\#\!$(pkg_path_for php7)/bin/php#" --in-place artisan
build_line "Installing PHP dependencies"
composer install \
--ignore-platform-reqs \
--no-interaction \
--no-plugins \
--no-scripts \
--prefer-dist
build_line "Installing Node.js dependencies"
yarn install
build_line "Fixing node_modules/.bin interpreters"
find -L "./node_modules/.bin" -type f -executable \
-print \
-exec bash -c 'sed -e "s#\#\!/usr/bin/env node#\#\!$1/bin/node#" --in-place "$(readlink -f "$2")"' _ "$(pkg_path_for node)" "{}" \;
build_line "Building frontend with Node.js"
yarn production
popd > /dev/null
}
do_install() {
pushd "${CACHE_PATH}" > /dev/null
cp -r . "${pkg_prefix}/web"
cat <<EOF > "${pkg_prefix}/bin/artisan"
#!$(pkg_path_for bash)/bin/sh -e
if [ -f "${pkg_svc_config_path}/env" ]; then
set -a
. "${pkg_svc_config_path}/env"
set +a
fi
$(pkg_path_for php7)/bin/php "${pkg_prefix}/web/artisan" \$@
chown -R "${pkg_svc_user}":"${pkg_svc_group}" "${pkg_svc_var_path}/cache"
EOF
chmod -v 755 "${pkg_prefix}/bin/artisan"
popd > /dev/null
}
do_build_config() {
do_default_build_config
build_line "Merging php7 config"
cp -nrv "$(pkg_path_for emergence/php7)"/{config_install,config,hooks} "${pkg_prefix}/"
toml-merge \
"$(pkg_path_for emergence/php7)/default.toml" \
"${PLAN_CONTEXT}/default.toml" \
> "${pkg_prefix}/default.toml"
}
do_strip() {
return 0
}
@MillerAdulu
Copy link

Hi,

How would you bind the Laravel application to the database? When I run the hab svc load <origin>/<art>, it runs fine. Then when I check the logs using sup-log I get:

app.default(SR): Initializing app.default hook[init]:(HK): + ln -fs app app.default hook[init]:(HK): ln: failed to create symbolic link './app': Permission denied app.default hook[init]:(HK): + exec app(HK): Initialization failed! 'init' exited with status code 1

I would like to connect to a postgreSQL database instance.

Also may you happen to know whether the core/postgresql11 package writes to a file to maintain state in case of an update or restart.

@themightychris
Copy link
Author

@MillerAdulu look up the Habitat docs on service binding, in this case you'd start postgres first and then run something like hab svc load myorigin/myapp --bind=database: postgres11.default

Persistent data is generally stored under /hab/svc/*/data/ but beware that when you mount those paths to persist volumes you'll need to go in manually and chown them to hab:hab so the services can write to them

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment