Switch to using Docker

This commit refactors all code in this project to make use of docker.
This has not yet been documented properly.
This commit is contained in:
Tom Wiesing 2020-06-26 12:54:47 +02:00
parent 9ece280e72
commit 76ef5d8e68
No known key found for this signature in database
GPG key ID: DC1F29F2BC78AB15
43 changed files with 943 additions and 545 deletions

39
distillery/.env.sample Normal file
View file

@ -0,0 +1,39 @@
# All WissKi and Drupal Installations are contained within a single directory.
# The name of each subfolder corresponds to the appropriate domain name.
# This variable determines the subfolder to place installations into.
DRUPAL_ROOT=/var/www/factory
# Furthermore, several docker-compose files are created to manage global services and the system itself.
# These will be placed into a folder, set its' path here.
COMPOSER_ROOT=/var/www/deploy
# The system can support setting up certificate(s) automatically.
# It can be enabled by setting an email for certbot certificates.
# This email address can be configured here.
CERTBOT_EMAIL=
# Each Drupal instance requires a corresponding system user, database users and databases.
# These are also set by the appropriate domain name.
# To differentiate them from other users of the system, these names can be prefixed.
# The prefix to use can be configured here.
# When changing these please consider that no system user may exist that has the same name as a mysql user.
# This is a MariaDB restriction.
MYSQL_USER_PREFIX=mysql-factory-
MYSQL_DATABASE_PREFIX=mysql-factory-
GRAPHDB_USER_PREFIX=graphdb-factory-
GRAPHDB_REPO_PREFIX=graphdb-factory-
# In addition to the filesystem the WissKI distillery requires a single SQL table.
# It uses this database to store a list of installed things
DISTILLERY_BOOKKEEPING_DATABASE=distillery
DISTILLERY_BOOKKEEPING_TABLE=distillery
# Each created Drupal Instance corresponds to a single domain name.
# These domain names should either be a complete domain name or a sub-domain of a default domain.
# This setting configures the default domain-name to create subdomains of.
DEFAULT_DOMAIN=localhost.kwarc.info
# Various components use password-based-authentication.
# These passwords are generated automatically.
# This variable can be used to determine their length.
PASSWORD_LENGTH=64

61
distillery/lib/00_init.sh Normal file
View file

@ -0,0 +1,61 @@
#!/bin/bash
set -e
# This is a library file.
# It should be 'source'd only, if it is not we bail out here.
if [[ "$0" = "$BASH_SOURCE" ]]; then
echo "This file should not be executed directly, it should be 'source'd only. "
exit 1;
fi
# Check that we are running on a linux system, to prevent accidentally running on Windows or Mac.
# Ideally we would want to explicitly limit to Debian / Ubuntu but at this point that's not needed.
OS="$(uname -s)"
case "${OS}" in
Linux*) :;;
*) echo "This script must be run under Linux. "; exit 1;;
esac
# To prevent accidentally messing up permissions, we need to always run as root.
# Check that the uid is 0, and otherwise bail out.
if [[ $EUID -ne 0 ]]; then
echo "This script should be run as root, use 'sudo' if in doubt. "
exit 1;
fi
# We enable shell aliases, to allow us to setup utility functions much more easily.
# To be safe that we don't have any other ones in the environment, we first unalias everything.
unalias -a
shopt -s expand_aliases
# Setup some basic input/output functions
function log_info() {
echo -e "\033[1m$1\033[0m"
}
function log_ok() {
echo -e "\033[0;32m$1\033[0m"
}
function log_warn() {
echo -e "\033[1;33m$1\033[0m"
}
function log_error() {
echo -e "\033[0;31m$1\033[0m"
}
if [ -n "$DISABLE_LOG" ]; then
function log_info() {
true
}
function log_ok() {
true
}
function log_warn() {
true
}
function log_error() {
true
}
fi

168
distillery/lib/10_config.sh Normal file
View file

@ -0,0 +1,168 @@
#!/bin/bash
set -e
# This is a library file.
# It should be 'source'd only, if it is not we bail out here.
if [[ "$0" = "$BASH_SOURCE" ]]; then
echo "This file should not be executed directly, it should be 'source'd only. "
exit 1;
fi
# The Path to the configuration file.
CONFIG_FILE="$SCRIPT_DIR/.env"
# Check that the configuration file exists.
# If it does not, throw an error
log_info " => Reading configuration file"
if ! [ -f "$CONFIG_FILE" ]; then
log_error ""
log_error "Missing configuration, provide a '.env' file"
exit 1
fi
# 'source' in the configuration file.
# Ideally we would want to make sure to prevent code-executation within the .env file
# But for the moment let's not.
source "$CONFIG_FILE"
# Next, validate all the configuration settings.
# is_valid_slug checks if it's argument is a valid 'slug'.
# A slug is any non-empty string of alphanumeric characters or '-'s.
# The first character of a slug may not be a dash.
function is_valid_slug() {
if [[ "$1" =~ ^[a-zA-Z0-9][-a-zA-Z0-9]*$ ]]; then
return 0;
else
return 1;
fi;
}
# is_valid_abspath checks if it's argument is an absolute path.
function is_valid_abspath() {
if [[ "$1" =~ ^\/(.+)\/([^/]+)$ ]]; then
return 0;
else
return 1;
fi;
}
# 'is_valid_domain' checks if a number is a valid domain.
# A domain consists of at least one slug, seperated by '.'s.
# Each token is a slug.
function is_valid_domain() {
if [[ "$1" =~ ^([a-zA-Z0-9][-a-zA-Z0-9]*\.)*[a-zA-Z0-9][-a-zA-Z0-9]*$ ]]; then
return 0;
else
return 1;
fi;
}
# 'is_valid_number' checks if a value is a valid number.
function is_valid_number() {
if [[ "$1" =~ ^[1-9][0-9]*$ ]]; then
return 0;
else
return 1;
fi;
}
# 'is_valid_email' checks if a value is a valid email address
function is_valid_email() {
if [[ "$1" =~ ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$ ]]; then
return 0;
else
return 1;
fi
}
# The 'DRUPAL_ROOT' variable must be an absolute path.
if ! is_valid_abspath "$DRUPAL_ROOT"; then
log_error "Variable 'DRUPAL_ROOT' is missing or not a valid path. ";
log_info "Please verify that it is set correctly in '.env'. ";
log_info "Please ensure that it does not end in '/'. ";
exit 1;
fi
# The 'COMPOSER_ROOT' variable must be an absolute path.
if ! is_valid_abspath "$COMPOSER_ROOT"; then
log_error "Variable 'COMPOSER_ROOT' is missing or not a valid path. ";
log_info "Please verify that it is set correctly in '.env'. ";
log_info "Please ensure that it does not end in '/'. ";
exit 1;
fi
# The 'MYSQL_USER_PREFIX' variable must be a valid slug.
if ! is_valid_slug "$MYSQL_USER_PREFIX"; then
log_error "Variable 'MYSQL_USER_PREFIX' is missing or not a valid slug. ";
log_info "Please verify that it is set correctly in '.env'. ";
exit 1;
fi
# The 'MYSQL_DATABASE_PREFIX' variable must be a valid slug.
if ! is_valid_slug "$MYSQL_DATABASE_PREFIX"; then
log_error "Variable 'MYSQL_DATABASE_PREFIX' is missing or not a valid slug. ";
log_info "Please verify that it is set correctly in '.env'. ";
exit 1;
fi
# The 'DISTILLERY_BOOKKEEPING_DATABASE' variable must be a valid slug.
if ! is_valid_slug "$DISTILLERY_BOOKKEEPING_DATABASE"; then
log_error "Variable 'DISTILLERY_BOOKKEEPING_DATABASE' is missing or not a valid slug. ";
log_info "Please verify that it is set correctly in '.env'. ";
exit 1;
fi
# The 'DISTILLERY_BOOKKEEPING_TABLE' variable must be a valid slug.
if ! is_valid_slug "$DISTILLERY_BOOKKEEPING_TABLE"; then
log_error "Variable 'DISTILLERY_BOOKKEEPING_TABLE' is missing or not a valid slug. ";
log_info "Please verify that it is set correctly in '.env'. ";
exit 1;
fi
# The 'GRAPHDB_USER_PREFIX' variable must be a valid slug.
if ! is_valid_slug "$GRAPHDB_USER_PREFIX"; then
log_error "Variable 'DATABASE_PREFIX' is missing or not a valid slug. ";
log_info "Please verify that it is set correctly in '.env'. ";
exit 1;
fi
# The 'GRAPHDB_REPO_PREFIX' variable must be a valid slug.
if ! is_valid_slug "$GRAPHDB_REPO_PREFIX"; then
log_error "Variable 'GRAPHDB_REPO_PREFIX' is missing or not a valid slug. ";
log_info "Please verify that it is set correctly in '.env'. ";
exit 1;
fi
# The 'DEFAULT_DOMAIN' variable must be a valid domain.
if ! is_valid_domain "$DEFAULT_DOMAIN"; then
log_error "Variable 'DEFAULT_DOMAIN' is missing or not a valid domain. ";
log_info "Please verify that it is set correctly in '.env'. ";
exit 1;
fi
# The 'CERTBOT_EMAIL' variable should either be empty or a valid email
if [ -n "$CERTBOT_EMAIL" ]; then
if ! is_valid_email "$CERTBOT_EMAIL"; then
log_error "Variable 'CERTBOT_EMAIL' is not a valid email address. ";
log_info "Please verify that it is set correctly in '.env' or remove it completly. ";
exit 1;
fi;
fi
# The 'PASSWORD_LENGTH' variable must be a valid number.
if ! is_valid_number "$PASSWORD_LENGTH"; then
log_error "Variable 'PASSWORD_LENGTH' is missing or not a valid number. ";
log_info "Please verify that it is set correctly in '.env'. ";
exit 1;
fi
# paths to composer things
COMPOSER_WEB_DIR="$COMPOSER_ROOT/core/web"
COMPOSER_TRIPLESTORE_DIR="$COMPOSER_ROOT/core/triplestore"
COMPOSER_SQL_DIR="$COMPOSER_ROOT/core/sql"
COMPOSER_INSTANCES_DIR="$COMPOSER_ROOT/instances"
log_ok "Read and validated configuration file. "

86
distillery/lib/20_sql.sh Normal file
View file

@ -0,0 +1,86 @@
#!/bin/bash
set -e
# This is a library file.
# It should be 'source'd only, if it is not we bail out here.
if [[ "$0" = "$BASH_SOURCE" ]]; then
echo "This file should not be executed directly, it should be 'source'd only. "
exit 1;
fi
###
### General SQL functions
###
# wait_for_sql waits for the sql database to be ready
function wait_for_sql() {
log_info "Waiting for database to start ..."
_wait_for_sql_internal
log_ok "Database responded to query "
}
function _wait_for_sql_internal() {
timeout=30
times=1
until dockerized_mysql -e 'show databases;' > /dev/null 2>&1; do
((times=times+1))
if [ "$times" -gt $timeout ]; then
log_error "Database timed out after ${timeout} seconds(s). "
fi;
echo -n "."
sleep 1
done
}
# 'dockerized_mysql' runs an sql command in the sql docker container
function dockerized_mysql() {
pushd "$COMPOSER_SQL_DIR" > /dev/null
docker exec -i `docker-compose ps -q sql` mysql "$@"
retval=$?
popd > /dev/null
return $retval
}
# 'dockerized_mysql' runs an sql command in the sql docker container interactively
function dockerized_mysql_interactive() {
pushd "$COMPOSER_SQL_DIR" > /dev/null
docker exec -ti `docker-compose ps -q sql` mysql "$@"
retval=$?
popd > /dev/null
return $retval
}
###
### Bookkeeping sql
###
# 'sql_bookkeep_exists' checks if a given site already exists
function sql_bookkeep_exists() {
COUNT=$(dockerized_mysql -D "$DISTILLERY_BOOKKEEPING_DATABASE" -e "SELECT COUNT(*) FROM \`$DISTILLERY_BOOKKEEPING_TABLE\` WHERE slug=\"$1\"; " | tail -n +2)
if [ "$COUNT" = "1" ]; then
return 0;
else
return 1;
fi;
}
# 'sql_bookkeep_insert' inserts a new pair of values into the sql database
function sql_bookkeep_insert() {
dockerized_mysql -D "$DISTILLERY_BOOKKEEPING_DATABASE" -e "INSERT INTO \`$DISTILLERY_BOOKKEEPING_TABLE\`($1) VALUES ($2) ;"
}
# 'sql_bookkeep_delete' removes a slug into the bookeeping table
function sql_bookeep_delete() {
dockerized_mysql -D "$DISTILLERY_BOOKKEEPING_DATABASE" -e "DELETE FROM \`$DISTILLERY_BOOKKEEPING_TABLE\` WHERE slug=\"$1\";"
}
# 'sql_bookkeep_load' reads from the bookkeeping table
function sql_bookkeep_load() {
dockerized_mysql -D "$DISTILLERY_BOOKKEEPING_DATABASE" -e "SELECT $2 FROM \`$DISTILLERY_BOOKKEEPING_TABLE\` WHERE slug=\"$1\";"
}
# 'sql_bookkeep_list' lists all slugs from the bookkeeping table
function sql_bookkeep_list() {
dockerized_mysql -D "$DISTILLERY_BOOKKEEPING_DATABASE" -e "SELECT slug FROM \`$DISTILLERY_BOOKKEEPING_TABLE\`; " | tail -n +2
}

67
distillery/lib/30_slug.sh Normal file
View file

@ -0,0 +1,67 @@
#!/bin/bash
set -e
# This is a library file.
# It should be 'source'd only, if it is not we bail out here.
if [[ "$0" = "$BASH_SOURCE" ]]; then
echo "This file should not be executed directly, it should be 'source'd only. "
exit 1;
fi
# This file reads a single slug command line option.
# This is validated when 'require_slug_argument' is called.
function require_slug_argument() {
# The 'SLUG' argument must be a valid slug.
if ! is_valid_slug "$SLUG"; then
log_error "Argument 'SLUG' is missing or not a valid slug. ";
log_info "Please provide it via the command line. ";
exit 1;
fi
log_info " => Deriving configuration for '$SLUG'. "
echo "Domain Name: $INSTANCE_DOMAIN"
echo "Base Directory: $INSTANCE_BASE_DIR"
echo "MySQL User: $MYSQL_USER"
echo "MySQL Database: $MYSQL_DATABASE"
echo "GraphDB User: $GRAPHDB_USER"
echo "GraphDB Repository: $GRAPHDB_REPO"
}
# Read the slug argument.
# We also read it in for scripts where it is not required, and will only use it if that is the case.
SLUG="$1"
# Compute the domain name for this instance.
# Also lowercase the domain name for consistency.
INSTANCE_DOMAIN="$SLUG.$DEFAULT_DOMAIN"
INSTANCE_DOMAIN="$(echo "$INSTANCE_DOMAIN" | tr '[:upper:]' '[:lower:]')"
# Next we need a username base.
# This will be used as a username across the system (linux), MySQL and GraphDB.
# For this we can only allow [0-9a-zA-Z-], hence we have to escape.
# In most cases, the only characters that require escaping are '.'s.
# Hence we replace '.' with '-'s.
# We replace the other two characters that require escaping (_ and -)s with --u and --s respectively.
# Because no two dots can ever follow each other in the INSTANCE_DOMAIN, this is guaranteed collision free.
# We also have to do the '-' replacement first, to prevent escaped other characters from being escaped twice.
USERNAME_BASE="$SLUG"
USERNAME_BASE="${USERNAME_BASE//-/--d}"
USERNAME_BASE="${USERNAME_BASE//_/--u}"
USERNAME_BASE="${USERNAME_BASE//./-}"
# Generate the user and database names for the various systems
MYSQL_USER="${MYSQL_USER_PREFIX}${USERNAME_BASE}"
MYSQL_DATABASE="${MYSQL_DATABASE_PREFIX}${USERNAME_BASE}"
GRAPHDB_USER="${GRAPHDB_USER_PREFIX}${USERNAME_BASE}"
GRAPHDB_REPO="${GRAPHDB_REPO_PREFIX}${USERNAME_BASE}"
# Compute the base directory for the files that will live on disk.
INSTANCE_BASE_DIR="$COMPOSER_INSTANCES_DIR/$INSTANCE_DOMAIN"
INSTANCE_DATA_DIR="$INSTANCE_BASE_DIR/data/"
if [ -n "$CERTBOT_EMAIL" ]; then
LETSENCRYPT_HOST="$INSTANCE_DOMAIN"
LETSENCRYPT_EMAIL="$CERTBOT_EMAIL"
fi;

View file

@ -0,0 +1,49 @@
#!/bin/bash
set -e
# This is a library file.
# It should be 'source'd only, if it is not we bail out here.
if [[ "$0" = "$BASH_SOURCE" ]]; then
echo "This file should not be executed directly, it should be 'source'd only. "
exit 1;
fi
RESOURCE_DIR="$SCRIPT_DIR/resources"
TEMPLATE_DIR="$RESOURCE_DIR/templates/"
# load_template will load a template $1 from the template directory
# and replace ${$2} with $3, ${$4} with $5 etc.
# echoes out the replaced template
function load_template() {
# read the template then remove the argument
TEMPLATE=`cat "$TEMPLATE_DIR/$1"`
shift 1;
# while we have a variable to substiute
while [ ! -z "$1" ]
do
# do the substitution
TEMPLATE="${TEMPLATE//\$\{$1\}/$2}"
shift 2
done;
# finally echo out the template
echo "$TEMPLATE"
}
# install_resource_dir will copy over a resource directory
# to a destination path recursively.
function install_resource_dir() {
from="$RESOURCE_DIR/$1"
to=$2
# copythe template files
for filename in "$from"/*; do
dest="$to/`basename "${filename}"`"
echo "Writing \"$dest\""
cp -r "$filename" "$dest"
done
}
# path where common apache files will be installed.
WISSKI_COMMON_PATH="/etc/apache2/conf/wisski"

View file

@ -0,0 +1,16 @@
#!/bin/bash
set -e
# This is a library file.
# It should be 'source'd only, if it is not we bail out here.
if [[ "$0" = "$BASH_SOURCE" ]]; then
echo "This file should not be executed directly, it should be 'source'd only. "
exit 1;
fi
# Set a few variables to point to the debian frontend
export DEBIAN_FRONTEND=noninteractive
# This file just sets a few utility functions to be used by the code.
# randompw generates a random password as per the configuration file.
alias randompw="cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w $PASSWORD_LENGTH | head -n 1"

22
distillery/lib/lib.sh Normal file
View file

@ -0,0 +1,22 @@
#!/bin/bash
set -e
# This file will load all the library functions needed by the various scripts.
# It should be 'source'd only, if it is not we bail out here.
if [[ "$0" = "$BASH_SOURCE" ]]; then
echo "This file should not be executed directly, it should be 'source'd only. "
exit 1;
fi
# Set variables for the script_dir and the lib_dir
SCRIPT_DIR="$(pwd)"
LIB_DIR="$SCRIPT_DIR/lib"
# Next, we load a bunch of utility functions stored in lib/lib_<number>_<system>.sh
# These contain functionality used in the various scripts.
source "$LIB_DIR/00_init.sh";
source "$LIB_DIR/10_config.sh";
source "$LIB_DIR/20_sql.sh";
source "$LIB_DIR/30_slug.sh";
source "$LIB_DIR/40_templates.sh";
source "$LIB_DIR/50_utils.sh";

14
distillery/mysql.sh Normal file
View file

@ -0,0 +1,14 @@
#!/bin/bash
set -e
# disable the log
DISABLE_LOG=1
# read the lib/shared.sh
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
cd "$DIR"
source "$DIR/lib/lib.sh"
# wait for sql to come up
wait_for_sql > /dev/null
dockerized_mysql_interactive "$@"

107
distillery/provision.sh Normal file
View file

@ -0,0 +1,107 @@
# To install a new system:
# This script will provision a new Drupal instance and make it available to apache.
# Usage: sudo ./provision.sh $SLUG
# In case the installation fails, it will bail out and leave you with an incomplete installation.
# To delete an incomplete installation, use the ./purge.sh script, or try fixing the error manually.
set -e
# read the lib/shared.sh and read the slug argument.
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
cd "$DIR"
source "$DIR/lib/lib.sh"
require_slug_argument
# wait for sql to be awake
wait_for_sql
# check if the site exists
if sql_bookkeep_exists "$SLUG"; then
log_error "=> Site '$SLUG' already exists in bookeeping table. "
echo "Refusing to work"
exit 1;
fi
# Randomly generate the database name and user we will configure.
# Use the 'randompw' alias for this.
log_info " => Generating new MySQL password"
MYSQL_PASSWORD="$(randompw)"
# Initialize the SQL database with those credentials.
log_info " => Intializing new SQL database '${MYSQL_DATABASE}' and user '$MYSQL_USER'. "
dockerized_mysql -e "CREATE DATABASE \`${MYSQL_DATABASE}\`;"
dockerized_mysql -e "CREATE USER \`${MYSQL_USER}\`@'%' IDENTIFIED BY '${MYSQL_PASSWORD}';"
dockerized_mysql -e "GRANT ALL PRIVILEGES ON \`${MYSQL_DATABASE}\`.* TO \`${MYSQL_USER}\`@\`%\`;"
dockerized_mysql -e "FLUSH PRIVILEGES;"
# Create a new repository for GraphDB.
# Use the template for this.
log_info " => Generating new GraphDB repository '$GRAPHDB_REPO'"
load_template "repository/graphdb-repo.ttl" "GRAPHDB_REPO" "${GRAPHDB_REPO}" "INSTANCE_DOMAIN" "${INSTANCE_DOMAIN}" | \
curl -X POST \
http://127.0.0.1:7200/rest/repositories \
--header 'Content-Type: multipart/form-data' \
-F "config=@-"
# Generate a random password for the GraphDB user
log_info " => Generating a new GraphDB password"
GRAPHDB_PASSWORD="$(randompw)"
# Create the user and grant them access to the creatd database.
log_info " => Creating GraphDB user '$GRAPHDB_USER'"
load_template "repository/graphdb-user.json" "GRAPHDB_USER" "${GRAPHDB_USER}" "GRAPHDB_REPO" "${GRAPHDB_REPO}" | \
curl -X POST \
"http://127.0.0.1:7200/rest/security/user/${GRAPHDB_USER}" \
--header 'Content-Type: application/json' \
--header 'Accept: text/plain' \
--header "X-GraphDB-Password: $GRAPHDB_PASSWORD" \
-d @-
log_info " => Creating local directory '$INSTANCE_BASE_DIR'"
mkdir -p "$INSTANCE_BASE_DIR"
mkdir -p "$INSTANCE_DATA_DIR"
mkdir -p "$INSTANCE_DATA_DIR/.composer"
mkdir -p "$INSTANCE_DATA_DIR/data"
# Generate some more random credentials, this time for drupal.
# We again make use of the randompw alias.
log_info " => Generating new drupal credentials"
DRUPAL_USER="admin"
DRUPAL_PASS="$(randompw)"
# TODO: copy over docker-compose into the right directory
log_info " => Creating instance directory"
install_resource_dir "compose/runtime" "$INSTANCE_BASE_DIR"
# Log all the details into the bookeeping database
log_info "=> Storing configuration in bookkeeping table"
sql_bookkeep_insert \
"slug,filesystem_base,sql_database,sql_user,sql_password,graphdb_repository,graphdb_user,graphdb_password" \
"\"${SLUG}\",\"${INSTANCE_BASE_DIR}\",\"${MYSQL_DATABASE}\",\"${MYSQL_USER}\",\"${MYSQL_PASSWORD}\",\"${GRAPHDB_REPO}\",\"${GRAPHDB_USER}\",\"${GRAPHDB_PASSWORD}\""
log_info " => Writing configuration file"
load_template "runtime-config/environment" \
"REAL_PATH" "${INSTANCE_DATA_DIR}" \
"VIRTUAL_HOST" "${INSTANCE_DOMAIN}" \
"LETSENCRYPT_HOST" "${LETSENCRYPT_HOST}" \
"LETSENCRYPT_EMAIL" "${LETSENCRYPT_EMAIL}" \
> "$INSTANCE_BASE_DIR/.env"
log_info " => Running and building image"
cd "$INSTANCE_BASE_DIR"
docker-compose build --pull
docker-compose pull
log_info " => Running provision script"
docker-compose run --rm runtime /bin/bash -c "sudo PATH=\$PATH -u www-data /bin/bash /provision_container.sh \
\"${INSTANCE_DOMAIN}\" \
\"${MYSQL_DATABASE}\" \"${MYSQL_USER}\" \"${MYSQL_PASSWORD}\" \
\"${GRAPHDB_REPO}\" \"${GRAPHDB_USER}\" \"${GRAPHDB_PASSWORD}\" \
\"${DRUPAL_USER}\" \"${DRUPAL_PASS}\" \
\"${USE_DRUPAL_9}\""
log_info " => Starting container"
docker-compose up -d

67
distillery/purge.sh Normal file
View file

@ -0,0 +1,67 @@
# To install a new system:
# This script will provision a new Drupal instance and make it available to apache.
# Usage: sudo ./provision.sh $SLUG
# In case the installation fails, it will bail out and leave you with an incomplete installation.
# To delete an incomplete installation, use the ./purge.sh script, or try fixing the error manually.
set -e
# read the lib/shared.sh and read the slug argument.
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
cd "$DIR"
source "$DIR/lib/lib.sh"
require_slug_argument
# wait for sql to be awake
wait_for_sql
while true; do
log_info " => I'm about to delete the '$SLUG' site from this system. "
read -p "This can not be undone. Please type 'y' to continue: " yn
case $yn in
[Yy]* ) break;;
* ) echo "Abort. "; exit 1;;
esac
done
# check if the site exists
if ! sql_bookkeep_exists "$SLUG"; then
log_error "=> Site '$SLUG' does not exist in bookeeping table. "
echo "I'll try to cleanup with the current defaults. "
echo "This may or may not work. "
else
# Read all the configuration from the database
log_info " => Reading components from database"
read -r INSTANCE_BASE_DIR MYSQL_DATABASE MYSQL_USER GRAPHDB_REPO GRAPHDB_USER <<< "$(sql_bookkeep_load "${SLUG}" "filesystem_base,sql_database,sql_user,graphdb_repository,graphdb_user" | tail -n +2)"
fi
# stop the running system container
if [ -d "$INSTANCE_BASE_DIR" ] ; then
log_info "=> Stopping running system"
cd "$INSTANCE_BASE_DIR"
docker-compose down -v || true
fi;
cd
# delete the mysql database.
log_info " => Deleting MySQL database '$MYSQL_DATABASE' and user '$MYSQL_USER'. "
dockerized_mysql -e "DROP DATABASE IF EXISTS \`${MYSQL_DATABASE}\`;"
dockerized_mysql -e "DROP USER IF EXISTS \`${MYSQL_USER}\`@\`%\`;"
dockerized_mysql -e "FLUSH PRIVILEGES;"
# Clear the GraphDB repository.
log_info " => Deleting GraphDB user '$GRAPHDB_USER'"
curl -X DELETE http://127.0.0.1:7200/rest/security/user/$GRAPHDB_USER/
log_info " => Deleting GraphDB repository '$GRAPHDB_REPO'"
curl -X DELETE http://127.0.0.1:7200/rest/repositories/$GRAPHDB_REPO/
# Delete the directory
log_info " => Deleting '$INSTANCE_BASE_DIR'"
rm -rf "$INSTANCE_BASE_DIR"
log_info " => Clearing bookkeeping record"
sql_bookeep_delete "$SLUG" || true
log_info " => '$SLUG' has been purged. "

View file

@ -0,0 +1 @@
data/

View file

@ -0,0 +1,6 @@
# Ignore everything
*
# allow the following files:
!conf/*
!scripts/*

View file

@ -0,0 +1,27 @@
#######################
# Meta Settings
#######################
# Real path for volumes to be stored
REAL_PATH=/var/www/example.slug
#######################
### Web Server settings
#######################
# the hostname for the website
VIRTUAL_HOST=example.com
# optional letsencrypt support
# when blank, ignore
LETSENCRYPT_HOST=
LETSENCRYPT_EMAIL=
### SQL settings
MYSQL_HOST=mysql
MYSQL_USER=user
MYSQL_PASS=pass
### GraphDB settings
GRAPHDB_HOST=graphdb
GRAPHDB_USER=user
GRAPHDB_PASS=pass

View file

@ -0,0 +1,75 @@
FROM php:7-apache-buster
WORKDIR /var/www
# install and enable the various required php extension
RUN apt-get update && apt-get install -y \
libcurl4-openssl-dev curl \
libpng-dev \
libicu-dev \
libxml2-dev \
libssh2-1-dev \
sudo \
zip unzip \
default-mysql-client \
&& \
docker-php-source extract && \
docker-php-ext-install \
curl \
gd \
intl \
soap \
mysqli \
opcache \
pdo_mysql \
xml \
xmlrpc \
&& \
pecl install ssh2-1.2 && \
docker-php-ext-enable \
curl \
gd \
intl \
mysqli \
opcache \
pdo_mysql \
soap \
ssh2 \
mysqli \
xml \
xmlrpc \
&& \
docker-php-source delete
# enable the apache rewrite mod
RUN a2enmod rewrite
# install composer and add it to path
RUN curl -sS https://getcomposer.org/installer | php && \
mv composer.phar /usr/local/bin/composer
ENV PATH "/usr/local/bin:/var/www/data/project/vendor/bin:$PATH"
# remove default configuration
RUN rm /etc/apache2/sites-available/*.conf && \
rm /etc/apache2/sites-enabled/*.conf
# Add wisski configuration
ADD conf/ports.conf /etc/apache2/ports.conf
ADD conf/wisski.conf /etc/apache2/sites-available/wisski.conf
RUN a2ensite wisski
# volumes for composer
VOLUME /var/www/.composer
VOLUME /var/www/data
# increase the php memory limit to 2g
RUN echo 'memory_limit=2G' > /usr/local/etc/php/conf.d/memory-limit.ini
# Add and configure the entrypoint
ADD scripts/entrypoint.sh /entrypoint.sh
ENTRYPOINT [ "/entrypoint.sh" ]
CMD ["apache2-foreground"]
# Add the provision script
ADD scripts/provision_container.sh /provision_container.sh
# expose port 8080
EXPOSE 8080

View file

@ -0,0 +1,4 @@
# This file configures where apache should listen.
# Because we are running as a limited user, we want to listen on a high port.
# For this we use port 8080
Listen 8080

View file

@ -0,0 +1,22 @@
<VirtualHost *:8080>
# the document root -- /var/www/data/project/web
DocumentRoot /var/www/data/project/web
<Directory /var/www/data/project/web>
# add types for .owl and .rdf
AddType application/rdf+xml .owl
AddType application/rdf+xml .rdf
# Rewrite the 'ontology' directory
ReWriteRule ^(ontology/[^/]+/).+ $1 [R=303,L]
ReWriteRule ^(ontology/[^/]+)/$ sites/default/files/$1.owl [L]
# Allow overrides of symlinks
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
ErrorLog /dev/stderr
CustomLog /dev/stdout combined
</VirtualHost>

View file

@ -0,0 +1,24 @@
version: "3.7"
services:
runtime:
build: .
restart: always
environment:
# port and hostname for this image to use
VIRTUAL_HOST: ${VIRTUAL_HOST}
VIRTUAL_PORT: 8080
# optional letsencrypt email
LETSENCRYPT_HOST: ${LETSENCRYPT_HOST}
LETSENCRYPT_EMAIL: ${LETSENCRYPT_EMAIL}
# the volumes to
volumes:
- ${REAL_PATH}/.composer:/var/www/.composer
- ${REAL_PATH}/data:/var/www/data
networks:
default:
external:
name: distillery

View file

@ -0,0 +1,11 @@
#!/bin/bash
# This script contains
# chown the volumes to make sure they can be read and written by the limited user
chown www-data:www-data /var/www
chown www-data:www-data /var/www/.composer
chown www-data:www-data /var/www/data/
# run the original entrypoint
docker-php-entrypoint "$@"

View file

@ -0,0 +1,126 @@
#!/bin/bash
set -e
function log_info() {
echo -e "\033[1m$1\033[0m"
}
function log_ok() {
echo -e "\033[0;32m$1\033[0m"
}
log_info " => Reading configuration variables"
INSTANCE_DOMAIN="$1"
echo "INSTANCE_DOMAIN=$INSTANCE_DOMAIN"
shift 1
MYSQL_DATABASE="$1"
echo "MYSQL_DATABASE=$MYSQL_DATABASE"
MYSQL_USER="$2"
echo "MYSQL_USER=$MYSQL_USER"
MYSQL_PASSWORD="$3"
echo "MYSQL_PASSWORD=$MYSQL_PASSWORD"
shift 3
GRAPHDB_REPO="$1"
echo "GRAPHDB_REPO=$GRAPHDB_REPO"
GRAPHDB_USER="$2"
echo "GRAPHDB_USER=$GRAPHDB_USER"
GRAPHDB_PASSWORD="$3"
echo "GRAPHDB_PASSWORD=$GRAPHDB_PASSWORD"
shift 3
DRUPAL_USER="$1"
echo "DRUPAL_USER=$DRUPAL_USER"
DRUPAL_PASS="$2"
echo "DRUPAL_PASS=$DRUPAL_PASS"
shift 2
USE_DRUPAL_9="$1"
echo "USE_DRUPAL_9=$USE_DRUPAL_9"
shift 1
log_info " => Preparing installation environment"
BASE_DIR="/var/www/data"
COMPOSER_DIR="$BASE_DIR/project"
WEB_DIR="$COMPOSER_DIR/web"
ONTOLOGY_DIR="$WEB_DIR/sites/default/files/ontology"
log_info " => Creating '$COMPOSER_DIR'"
mkdir -p "$COMPOSER_DIR"
cd "$COMPOSER_DIR"
function drupal_sites_permission_workaround() {
chmod -R u+w "$WEB_DIR/sites/" || true
}
# Create a new composer project.
log_info " => Creating composer project"
if [ -z "${USE_DRUPAL_9}" ]; then
composer create-project 'drupal/recommended-project:^8.9.0' .
else
composer create-project 'drupal/recommended-project:^9.0.0' .
fi
# Install drush so that we can automate a lot of things
log_info " => Installing 'drush'"
composer require drush/drush
# Use 'drush' to run the site-installation.
# Here we need to use the username, password and database creds we made above.
log_info " => Running drupal installation scripts"
drush site-install standard --yes --site-name=${INSTANCE_DOMAIN} \
--account-name=$DRUPAL_USER --account-pass=$DRUPAL_PASS \
--db-url=mysql://${MYSQL_USER}:${MYSQL_PASSWORD}@sql/${MYSQL_DATABASE}
drupal_sites_permission_workaround
# create a directory for ontologies.
log_info " => Creating '$ONTOLOGY_DIR'"
mkdir -p "$ONTOLOGY_DIR"
# Install the Wisski packages.
log_info " => Installing Wisski packages"
cd "$COMPOSER_DIR"
# install the development version when requested
if [ -z "${USE_DRUPAL_9}" ]; then
composer require 'drupal/wisski'
else
composer require 'drupal/wisski:2.x-dev'
fi
drupal_sites_permission_workaround
composer require drupal/inline_entity_form
drupal_sites_permission_workaround
composer require drupal/imagemagick
drupal_sites_permission_workaround
composer require drupal/image_effects
drupal_sites_permission_workaround
composer require drupal/colorbox
log_info " => Enable Wisski modules"
drush pm-enable --yes wisski_core wisski_linkblock wisski_pathbuilder wisski_adapter_sparql11_pb wisski_salz
drupal_sites_permission_workaround
log_info " => Provisioning is now complete. "
log_ok "Your installation details are as follows:"
function printdetails() {
echo "URL: http://$INSTANCE_DOMAIN"
echo "Username: $DRUPAL_USER"
echo "Password: $DRUPAL_PASS"
log_info " => Your GraphDB details (for WissKI Salz) are: "
echo "Read URL: http://triplestore:7200/repositories/$GRAPHDB_REPO"
echo "Write URL: http://triplestore:7200/repositories/$GRAPHDB_REPO/statements"
echo "Username: $GRAPHDB_USER"
echo "Password: $GRAPHDB_PASSWORD"
echo "Writable: yes"
echo "Default Graph URI: http://$INSTANCE_DOMAIN/#"
echo "Ontology Paths: (empty)"
echo "SameAs property: http://www.w3.org/2002/07/owl#sameAs"
}
printdetails

View file

@ -0,0 +1,32 @@
version: "3.7"
services:
sql:
image: mariadb
volumes:
- "./data/:/var/lib/mysql"
environment:
# This combination of environment variables will configure a passwordless root user
# that can only connect to the container from 'localhost'.
# This means we can only connect using 'docker-compose exec sql mysql -C '...' '.
- "MYSQL_ALLOW_EMPTY_PASSWORD=yes"
- "MYSQL_ROOT_HOST=localhost"
restart: always
phpmyadmin:
image: phpmyadmin/phpmyadmin
environment:
- "PMA_HOST=sql"
- "HIDE_PHP_VERSION=true"
# phpmyadmin running on localhost:8080 so that we can easily access the system graphically.
# By default no admin account is created, so initial shell access to make one is needed.
ports:
- 127.0.0.1:8080:80
depends_on:
- sql
restart: always
networks:
default:
external:
name: distillery

View file

@ -0,0 +1,60 @@
# This Dockerfile contains instructions to compile and run GraphDB inside a Docker container.
# It is roughly based on https://github.com/Ontotext-AD/graphdb-docker/blob/master/free-edition/Dockerfile
# but has been modified for performance and security.
# This image is intended to be built like:
# docker build --build-arg graphdb_src=graphdb.zip .
# We first make a base image to base further builds on.
# We don't use alpine here, as that uses significantly slower musl instead of glibc.
FROM adoptopenjdk/openjdk11:debian-slim as base
# Create a user called graphdb
RUN useradd -ms /bin/bash graphdb
# make a base images, to add the sources to.
FROM base as sources
# install unzip
RUN apt-get update && apt-get install -y unzip
# add the source file (by default graphdb.zip) to the image
ARG src=graphdb.zip
ADD ${src} /graphdb.zip
# unpack it into a temporary directory
RUN unzip "$src" -d "/unpack/"
# Move it into /opt/graphdb, and chown it to graphdb
RUN mv "/unpack"/* /opt/graphdb
RUN chown -R graphdb:graphdb /opt/graphdb
# finally make an image that will run
FROM base as final
# add the entrypoint script
ADD entrypoint.sh /entrypoint.sh
# copy over the sources
COPY --from=sources /opt/graphdb /opt/graphdb
# set environment variables for graphdb_home and path
ENV GRAPHDB_HOME=/opt/graphdb
ENV PATH=$GRAPHDB_HOME/bin:$PATH
# expose a port
EXPOSE 7200
# setup a healthcheck, that checks if the server is up.
RUN apt-get update && apt-get install -y curl
HEALTHCHECK --interval=30s --timeout=30s --start-period=5s --retries=3 CMD curl --fail 127.0.0.1:7200/rest/repositories || exit 1
# Add volumes for data, work and logs as these might be accessible from the outside.
# To add your own configuration, manually mount a config file into /opt/graphdb/work
VOLUME /opt/graphdb/data
VOLUME /opt/graphdb/work
VOLUME /opt/graphdb/logs
# setup command and entrypoint
CMD ["-Dgraphdb.home=/opt/graphdb"]
ENTRYPOINT ["/bin/bash", "/entrypoint.sh"]

View file

@ -0,0 +1,17 @@
version: "3.7"
services:
triplestore:
build: .
ports:
- "127.0.0.1:7200:7200"
volumes:
- './data/data:/opt/graphdb/data'
- './data/work:/opt/graphdb/work'
- './data/logs:/opt/graphdb/logs'
restart: always
networks:
default:
external:
name: distillery

View file

@ -0,0 +1,13 @@
#!/bin/bash
set -e
# Because we want to run graphdb as a limited user
# we need to make sure that the volumes are writable.
# Because of that, we 'chown'
chown graphdb:graphdb /opt/graphdb/data
chown graphdb:graphdb /opt/graphdb/work
chown graphdb:graphdb /opt/graphdb/logs
# switch to the graphdb user, and run graphdb
su graphdb -c "/opt/graphdb/bin/graphdb $@"

View file

@ -0,0 +1,45 @@
version: "3.7"
services:
nginx-proxy:
image: nginxproxy/nginx-proxy:alpine
ports:
- "80:80"
- "443:443"
volumes:
- "vhost:/etc/nginx/vhost.d"
- "htpasswd:/etc/nginx/htpasswd"
- "html:/usr/share/nginx/html"
- "/var/run/docker.sock:/tmp/docker.sock:ro"
- "certs:/etc/nginx/certs"
labels:
com.github.jrcs.letsencrypt_nginx_proxy_companion.nginx_proxy: true
restart: always
networks:
- default
letsencrypt-nginx-proxy-companion:
image: jrcs/letsencrypt-nginx-proxy-companion
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
- "htpasswd:/etc/nginx/htpasswd"
- "vhost:/etc/nginx/vhost.d"
- "html:/usr/share/nginx/html"
- "/var/run/docker.sock:/tmp/docker.sock:ro"
- "certs:/etc/nginx/certs"
restart: always
networks:
- default
depends_on:
- nginx-proxy
volumes:
vhost:
html:
certs:
htpasswd:
networks:
default:
external:
name: distillery

View file

@ -0,0 +1,28 @@
-- create the database if it doesn't exist yet
CREATE DATABASE IF NOT EXISTS `${DATABASE}`;
-- use the database we just created
USE `${DATABASE}`;
-- create the bookkeeping table
CREATE TABLE IF NOT EXISTS `${TABLE}`(
-- automatically created fields
pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
created DATETIME DEFAULT CURRENT_TIMESTAMP,
-- slug of the website
slug TEXT NOT NULL UNIQUE,
-- local file path
filesystem_base TEXT NOT NULL,
-- sql access credentials
sql_database TEXT NOT NULL,
sql_user TEXT NOT NULL,
sql_password TEXT NOT NULL,
-- graphdb credentials
graphdb_repository TEXT NOT NULL,
graphdb_user TEXT NOT NULL,
graphdb_password TEXT NOT NULL
);

View file

@ -0,0 +1,57 @@
# This file is used to initialize a new GraphDB repository.
# In this file the variables ${GRAPHDB_REPO} and ${INSTANCE_DOMAIN} will be replaced.
# All other variables will be left untouched.
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>.
@prefix rep: <http://www.openrdf.org/config/repository#>.
@prefix sr: <http://www.openrdf.org/config/repository/sail#>.
@prefix sail: <http://www.openrdf.org/config/sail#>.
@prefix owlim: <http://www.ontotext.com/trree/owlim#>.
[] a rep:Repository ;
rep:repositoryID "${GRAPHDB_REPO}" ;
rdfs:label "${INSTANCE_DOMAIN}" ;
rep:repositoryImpl [
rep:repositoryType "graphdb:FreeSailRepository" ;
sr:sailImpl [
sail:sailType "graphdb:FreeSail" ;
owlim:owlim-license "" ;
owlim:base-URL "http://${INSTANCE_DOMAIN}/#" ;
owlim:defaultNS "" ;
owlim:entity-index-size "10000000" ;
owlim:entity-id-size "32" ;
owlim:imports "" ;
owlim:repository-type "file-repository" ;
owlim:ruleset "empty" ;
owlim:storage-folder "storage" ;
owlim:enable-context-index "false" ;
owlim:cache-memory "80m" ;
owlim:tuple-index-memory "80m" ;
owlim:enablePredicateList "false" ;
owlim:predicate-memory "0%" ;
owlim:fts-memory "0%" ;
owlim:ftsIndexPolicy "never" ;
owlim:ftsLiteralsOnly "true" ;
owlim:in-memory-literal-properties "false" ;
owlim:enable-literal-index "true" ;
owlim:index-compression-ratio "-1" ;
owlim:check-for-inconsistencies "false" ;
owlim:disable-sameAs "false" ;
owlim:enable-optimization "true" ;
owlim:transaction-mode "safe" ;
owlim:transaction-isolation "true" ;
owlim:query-timeout "0" ;
owlim:query-limit-results "0" ;
owlim:throw-QueryEvaluationException-on-timeout "false" ;
owlim:useShutdownHooks "true" ;
owlim:read-only "false" ;
owlim:nonInterpretablePredicates "http://www.w3.org/2000/01/rdf-schema#label;http://www.w3.org/1999/02/22-rdf-syntax-ns#type;http://www.ontotext.com/owlim/ces#gazetteerConfig;http://www.ontotext.com/owlim/ces#metadataConfig" ;
]
].

View file

@ -0,0 +1,8 @@
{
"username": "${GRAPHDB_USER}",
"grantedAuthorities": [
"ROLE_USER",
"READ_REPO_${GRAPHDB_REPO}",
"WRITE_REPO_${GRAPHDB_REPO}"
]
}

View file

@ -0,0 +1,17 @@
#######################
# Meta Settings
#######################
# Real path for volumes to be stored
REAL_PATH=${REAL_PATH}
#######################
### Web Server settings
#######################
# the hostname for the website
VIRTUAL_HOST=${VIRTUAL_HOST}
# optional letsencrypt support
# when blank, ignore
LETSENCRYPT_HOST=${LETSENCRYPT_HOST}
LETSENCRYPT_EMAIL=${LETSENCRYPT_EMAIL}

View file

@ -0,0 +1,89 @@
#!/bin/bash
set -e
# read the lib/shared.sh
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
cd "$DIR"
source "$DIR/lib/lib.sh"
# Read the 'GRAPHDB_ZIP' argument from the command line.
# If it's not set, throw an error.
GRAPHDB_ZIP=$1
if [ -z "$GRAPHDB_ZIP" ]; then
log_error "Usage: system_install.sh GRAPHDB_ZIP"
exit 1;
fi;
# print some general info on the screen
log_info "=> Preparing system to become a WissKI Distillery"
echo "This script will install or upgrade this system to become a WissKI distillery. "
echo "It is idempotent and can safely be run multiple times. "
sleep 5
# Install default system upgrades.
log_info "=> Installing system updates"
apt-get update
apt-get upgrade -y
# install docker dependencies.
log_info "=> Installing docker installer dependencies"
apt-get update
apt-get install -y curl
# install docker using an automated script.
log_info "=> Installing docker"
curl -fsSL https://get.docker.com -o - | /bin/sh
# install docker-compose dependencies.
log_info "=> Install docker-compose installer dependencies"
apt-get update
apt-get install -y python3-pip
# install docker-compose.
log_info "=> Installing docker-compose"
pip3 install --upgrade docker-compose
log_info "=> Creating docker-compose directories"
mkdir -p "$COMPOSER_INSTANCES_DIR"
mkdir -p "$COMPOSER_WEB_DIR"
mkdir -p "$COMPOSER_TRIPLESTORE_DIR"
mkdir -p "$COMPOSER_SQL_DIR"
log_info "=> Creating 'distillery' network"
docker network create distillery || true
log_info "=> Creating 'docker-compose' files for the 'web'. "
install_resource_dir "compose/web" "$COMPOSER_WEB_DIR"
# copy over the directory
log_info "=> Creating 'docker-compose' files for the 'triplestore'. "
install_resource_dir "compose/triplestore" "$COMPOSER_TRIPLESTORE_DIR"
# copy the graphdb.zip
echo "Writing \"$COMPOSER_TRIPLESTORE_DIR/graphdb.zip\""
cp "$GRAPHDB_ZIP" "$COMPOSER_TRIPLESTORE_DIR/graphdb.zip"
# create data (volume) location
mkdir -p "$COMPOSER_TRIPLESTORE_DIR/data/data/"
mkdir -p "$COMPOSER_TRIPLESTORE_DIR/data/work/"
mkdir -p "$COMPOSER_TRIPLESTORE_DIR/data/logs/"
# copy over the sql resource directory, then ensure the data diretory for sql exists.
log_info "=> Creating 'docker-compose' files for the 'sql'. "
install_resource_dir "compose/sql" "$COMPOSER_SQL_DIR"
mkdir -p "$COMPOSER_SQL_DIR/data/"
# Run all the updates via system_update.sh
log_info " => Running 'system_update.sh'"
bash "$SCRIPT_DIR/system_update.sh"
log_info "=> Waiting for sql to come up"
wait_for_sql
log_info "=> Creating '$DISTILLERY_BOOKKEEPING_DATABASE' database and '$DISTILLERY_BOOKKEEPING_TABLE' table"
load_template "bookkeeping/create.sql" "DATABASE" "$DISTILLERY_BOOKKEEPING_DATABASE" "TABLE" "$DISTILLERY_BOOKKEEPING_TABLE" | \
dockerized_mysql
log_info "=> System installation finished, ready to distill. "

View file

@ -0,0 +1,31 @@
#!/bin/bash
set -e
# read the lib/shared.sh
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
cd "$DIR"
source "$DIR/lib/lib.sh"
# update_stack fully updates a docker-compose stack in the given location.
function update_stack() {
cd "$1"
docker-compose pull
docker-compose build --pull
docker-compose up -d
}
log_info "=> Rebuilding and restarting 'web' stack"
update_stack "$COMPOSER_WEB_DIR"
# build and start the triplestore
log_info "=> Rebuilding and restarting 'triplestore' stack"
update_stack "$COMPOSER_TRIPLESTORE_DIR"
# build and start the triplestore
log_info "=> Rebuilding and restarting 'sql' stack"
update_stack "$COMPOSER_SQL_DIR"
# TODO: Iterate over all the instance
# and a pull_and_update
log_info "=> System up-to-date. "