diff --git a/.env.sample b/.env.sample index ec8eecd..d47c2da 100644 --- a/.env.sample +++ b/.env.sample @@ -1,8 +1,69 @@ +# recipe vars TYPE=fab-manager - -DOMAIN=fab-manager.example.com - -## Domain aliases -#EXTRA_DOMAINS=', `www.fab-manager.example.com`' - +COMPOSE_FILE="compose.yml" +#COMPOSE_FILE="compose.yml:compose.smtp.yml" +TIMEOUT=300 LETS_ENCRYPT_ENV=production + +# secret versions +SECRET_DB_PASSWORD_VERSION=v1 +SECRET_ADMIN_INIT_PASSWORD_VERSION=v1 # length=64 charset=default,safespecial +SECRET_SECRET_KEY_BASE_VERSION=v1 # length=128 +SECRET_SMTP_PASSWORD_VERSION=v1 + +# customize +## General +DOMAIN=fab-manager.example.com +ADMIN_INIT_EMAIL=test@test.de + +## Locale (This is an easy way to set all the locale/date/currency/timezone variables in one place. They are defined in the entrypoint. If you don't want to use it, clear this value and set the manual variables below) +FAB_MANAGER_LOCALE_PACK=en +TIME_ZONE=UTC + +# default Fab Manager +SLOT_DURATION=60 +FEATURE_TOUR_DISPLAY=once +DISK_SPACE_MB_ALERT=1024 + +## Mail +DELIVERY_METHOD=file +SMTP_ADDRESS=smtp-relay.brevo.com +SMTP_PORT=587 +SMTP_USER_NAME= +SMTP_AUTHENTICATION=plain +SMTP_ENABLE_STARTTLS_AUTO=true +SMTP_OPENSSL_VERIFY_MODE= +SMTP_TLS=false + + +## Openlab +OPENLAB_BASE_URI=https://openprojects.fab-manager.com +OPENLAB_SSL_VERIFY=true + +## Upload Sizes +### 5242880 = 5 megabytes +MAX_IMPORT_SIZE=5242880 +### 10485760 = 10 megabytes +MAX_IMAGE_SIZE=10485760 +### 20971520 = 20 megabytes +MAX_CAO_SIZE=20971520 +### 5242880 = 5 megabytes +MAX_SUPPORTING_DOCUMENT_FILE_SIZE=5242880 + + +# Manual Locales/ Date Time (unset FAB_MANAGER_LOCALE_PACK if you want to use those) +## Manual Locales +RAILS_LOCALE=en +APP_LOCALE=en +MOMENT_LOCALE=en +SUMMERNOTE_LOCALE=en-US +ANGULAR_LOCALE=en-us +FULLCALENDAR_LOCALE=en +INTL_LOCALE=en-US +INTL_CURRENCY=USD +POSTGRESQL_LANGUAGE_ANALYZER=english + +WEEK_STARTING_DAY=monday +D3_DATE_FORMAT=%m/%d/%Y +UIB_DATE_FORMAT=MM/dd/yyyy +EXCEL_DATE_FORMAT=MM/dd/yyyy diff --git a/README.md b/README.md index 85c3a33..892a38f 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,15 @@ # fab-manager -> One line description of the recipe +> Fab-manager is the Fab Lab management solution. It provides a comprehensive, web-based, open-source tool to simplify your administrative tasks, and document your marker's projects.Please visit fab-manager.com for more information about this software and its features. * **Category**: Apps -* **Status**: 0 -* **Image**: [`fab-manager`](https://hub.docker.com/r/fab-manager), 4, upstream -* **Healthcheck**: No -* **Backups**: No -* **Email**: No +* **Status**: 3 +* **Image**: [`fab-manager`](https://hub.docker.com/r/sleede/fab-manager), 4, upstream +* **Healthcheck**: Yes +* **Backups**: Yes +* **Email**: Yes * **Tests**: No * **SSO**: No @@ -21,4 +21,6 @@ * `abra app config ` * `abra app deploy ` +The default admin login will be initially created with the email that is specified in the `ADMIN_INIT_EMAIL` env. + For more, see [`docs.coopcloud.tech`](https://docs.coopcloud.tech). diff --git a/abra.sh b/abra.sh new file mode 100644 index 0000000..4c24a67 --- /dev/null +++ b/abra.sh @@ -0,0 +1,19 @@ +export DATABASE_CONFIG_VERSION=v1 +export APP_ENTRYPOINT_VERSION=v3 +export AUTH_PROVIDER_VERSION=v1 +export ELASTIC_SEARCH_CONFIG_VERSION=v1 +export ELASTIC_SEARCH_LOG_CONFIG_VERSION=v1 +export PG_BACKUP_VERSION=v1 + +# since supervisors log in the default app image doesn't get redirected to stdout, we need a function to get the log +function getSupervisorErrorLog() +{ + cat /var/log/supervisor/worker-stderr.log +} + +# since supervisors log in the default app image doesn't get redirected to stdout, we need a function to get the log +function getSupervisorStandardLog() +{ + cat /var/log/supervisor/worker-stdout.log +} + diff --git a/compose.smtp.yml b/compose.smtp.yml new file mode 100644 index 0000000..81fe04b --- /dev/null +++ b/compose.smtp.yml @@ -0,0 +1,30 @@ +--- +version: "3.8" + + + +x-mail-env: &mail-env + DELIVERY_METHOD: ${DELIVERY_METHOD} + SMTP_ADDRESS: ${SMTP_ADDRESS} + SMTP_PORT: ${SMTP_PORT} + SMTP_USER_NAME: ${SMTP_USER_NAME} + SMTP_AUTHENTICATION: ${SMTP_AUTHENTICATION} + SMTP_ENABLE_STARTTLS_AUTO: ${SMTP_ENABLE_STARTTLS_AUTO} + SMTP_OPENSSL_VERIFY_MODE: ${SMTP_OPENSSL_VERIFY_MODE} + SMTP_TLS: ${SMTP_TLS} + + + +services: + app: + environment: + *mail-env + secrets: + - smtp_password + + + +secrets: + smtp_password: + name: ${STACK_NAME}_smtp_password_${SECRET_SMTP_PASSWORD_VERSION} + external: true \ No newline at end of file diff --git a/compose.yml b/compose.yml index a2c3805..ae847e1 100644 --- a/compose.yml +++ b/compose.yml @@ -1,32 +1,277 @@ --- version: "3.8" +x-db-env: &db-env + POSTGRES_PASSWORD_FILE: /run/secrets/db_password + POSTGRES_DB: fablab_production + POSTGRES_USER: postgres + POSTGRES_USERNAME: postgres + +x-redis-env: &redis-env + REDIS_URL: redis://${STACK_NAME}_redis:6379 + REDIS_HOST: ${STACK_NAME}_redis + REDIS_PORT: 6379 + +x-elastic-env: &elastic-env + ES_JAVA_OPTS: -Xms512m -Xmx512m -Dlog4j2.formatMsgNoLookups=true + + +x-environment: &default-env + <<: [*db-env, *redis-env] + REDIS_URL: redis://${STACK_NAME}_redis:6379 + REDIS_HOST: ${STACK_NAME}_redis + REDIS_PORT: 6379 + LETS_ENCRYPT_ENV: ${LETS_ENCRYPT_ENV} + RAILS_ENV: production + RACK_ENV: production + POSTGRES_HOST: ${STACK_NAME}_db + ELASTICSEARCH_HOST: ${STACK_NAME}_elasticsearch + SLOT_DURATION: ${SLOT_DURATION} + FEATURE_TOUR_DISPLAY: ${FEATURE_TOUR_DISPLAY} + DEFAULT_HOST: ${DOMAIN} + DEFAULT_PROTOCOL: http + DELIVERY_METHOD: ${DELIVERY_METHOD} + SMTP_ADDRESS: ${SMTP_ADDRESS} + SMTP_PORT: ${SMTP_PORT} + SMTP_USER_NAME: ${SMTP_USER_NAME} + SMTP_PASSWORD: ${SMTP_PASSWORD} + SMTP_AUTHENTICATION: ${SMTP_AUTHENTICATION} + SMTP_ENABLE_STARTTLS_AUTO: ${SMTP_ENABLE_STARTTLS_AUTO} + SMTP_OPENSSL_VERIFY_MODE: ${SMTP_OPENSSL_VERIFY_MODE} + SMTP_TLS: ${SMTP_TLS} + FAB_MANAGER_LOCALE_PACK: ${FAB_MANAGER_LOCALE_PACK} + RAILS_LOCALE: ${RAILS_LOCALE} + APP_LOCALE: ${APP_LOCALE} + MOMENT_LOCALE: ${MOMENT_LOCALE} + SUMMERNOTE_LOCALE: ${SUMMERNOTE_LOCALE} + ANGULAR_LOCALE: ${ANGULAR_LOCALE} + FULLCALENDAR_LOCALE: ${FULLCALENDAR_LOCALE} + INTL_LOCALE: ${INTL_LOCALE} + INTL_CURRENCY: ${INTL_CURRENCY} + POSTGRESQL_LANGUAGE_ANALYZER: ${POSTGRESQL_LANGUAGE_ANALYZER} + TIME_ZONE: ${TIME_ZONE} + WEEK_STARTING_DAY: ${WEEK_STARTING_DAY} + D3_DATE_FORMAT: ${D3_DATE_FORMAT} + UIB_DATE_FORMAT: ${UIB_DATE_FORMAT} + EXCEL_DATE_FORMAT: ${EXCEL_DATE_FORMAT} + OPENLAB_BASE_URI: ${OPENLAB_BASE_URI} + OPENLAB_SSL_VERIFY: ${OPENLAB_SSL_VERIFY} + LOG_LEVEL: debug + RAILS_LOG_TO_STDOUT: "true" + DISK_SPACE_MB_ALERT: ${DISK_SPACE_MB_ALERT} + ADMINSYS_EMAIL: ${ADMIN_INIT_EMAIL} + ALLOW_INSECURE_HTTP: "true" + ENABLE_SENTRY: "false" + MAX_IMPORT_SIZE: ${MAX_IMPORT_SIZE} + MAX_IMAGE_SIZE: ${MAX_IMAGE_SIZE} + MAX_CAO_SIZE: ${MAX_CAO_SIZE} + MAX_SUPPORTING_DOCUMENT_FILE_SIZE: ${MAX_SUPPORTING_DOCUMENT_FILE_SIZE} + ADMIN_INIT_EMAIL: ${ADMIN_INIT_EMAIL} + SECRET_KEY_BASE_FILE: /run/secrets/secret_key_base + + + services: app: - image: nginx:1.20.0 + image: sleede/fab-manager:release-v6.3.44 + environment: *default-env + entrypoint: /entrypoint.sh + command: "" + configs: + - source: app_entrypoint + target: /entrypoint.sh + mode: 0555 + - source: database_config + target: /usr/src/app/config/database.yml + volumes: + - fabmanager_packs:/usr/src/app/public/packs + - fabmanager_uploads:/usr/src/app/public/uploads + - fabmanager_invoices:/usr/src/app/invoices + - fabmanager_payment_schedules:/usr/src/app/payment_schedules + - fabmanager_exports:/usr/src/app/exports + - fabmanager_imports:/usr/src/app/imports + - fabmanager_supporting_document_files:/usr/src/app/supporting_document_files + - fabmanager_log:/var/log/supervisor + - fabmanager_plugins:/usr/src/app/plugins + - fabmanager_accounting:/usr/src/app/accounting + - fabmanager_auth:/usr/src/app/authconfig + depends_on: + - db + - redis + secrets: + - db_password + - secret_key_base + - admin_init_password networks: - proxy + - db deploy: + update_config: + failure_action: rollback + order: start-first + rollback_config: + order: start-first restart_policy: + max_attempts: 3 condition: on-failure + window: 240s labels: - "traefik.enable=true" - - "traefik.http.services.${STACK_NAME}.loadbalancer.server.port=80" + - "traefik.http.services.${STACK_NAME}.loadbalancer.server.port=3000" - "traefik.http.routers.${STACK_NAME}.rule=Host(`${DOMAIN}`${EXTRA_DOMAINS})" - "traefik.http.routers.${STACK_NAME}.entrypoints=web-secure" - "traefik.http.routers.${STACK_NAME}.tls.certresolver=${LETS_ENCRYPT_ENV}" - ## Redirect from EXTRA_DOMAINS to DOMAIN - #- "traefik.http.routers.${STACK_NAME}.middlewares=${STACK_NAME}-redirect" - #- "traefik.http.middlewares.${STACK_NAME}-redirect.headers.SSLForceHost=true" - #- "traefik.http.middlewares.${STACK_NAME}-redirect.headers.SSLHost=${DOMAIN}" - - "coop-cloud.${STACK_NAME}.version=" + - "coop-cloud.${STACK_NAME}.version=1.0.0+v6.3.44" + - "backupbot.backup=${ENABLE_BACKUPS:-true}" healthcheck: - test: ["CMD", "curl", "-f", "http://localhost"] + test: ["CMD", "curl", "-f", "http://localhost:3000"] interval: 30s timeout: 10s - retries: 10 + retries: 15 start_period: 1m + db: + image: postgres:16.8 + volumes: + - postgres_data:/var/lib/postgresql/data + environment: + <<: *db-env + POSTGRES_HOST_AUTH_METHOD: trust + secrets: + - db_password + networks: + - db + configs: + - source: pg_backup + target: /pg_backup.sh + mode: 0555 + deploy: + update_config: + failure_action: rollback + order: start-first + rollback_config: + order: start-first + restart_policy: + max_attempts: 3 + condition: on-failure + window: 60s + labels: + backupbot.backup: "${ENABLE_BACKUPS:-true}" + backupbot.backup.pre-hook: "/pg_backup.sh backup" + backupbot.backup.volumes.postgres_data.path: "backup.sql" + backupbot.restore.post-hook: '/pg_backup.sh restore' + healthcheck: + test: [ "CMD-SHELL", "pg_isready" ] + interval: 10s + timeout: 5s + retries: 10 + redis: + image: redis:7.4-alpine + environment: + <<: *redis-env + volumes: + - redis_data:/data + networks: + - db + deploy: + update_config: + failure_action: rollback + order: start-first + rollback_config: + order: start-first + restart_policy: + max_attempts: 3 + condition: on-failure + window: 60s + healthcheck: + test: ["CMD", "redis-cli", "ping"] + + + + elasticsearch: + image: elasticsearch:5.6 + environment: + <<: *elastic-env + ulimits: + memlock: + soft: -1 + hard: -1 + networks: + - db + configs: + - source: elastic_search_config + target: /usr/share/elasticsearch/config/elasticsearch.yml + - source: elastic_search_log_config + target: /usr/share/elasticsearch/config/log4j2.properties.tmpl + volumes: + - elasticsearch_data:/usr/share/elasticsearch/data + deploy: + update_config: + failure_action: rollback + order: start-first + rollback_config: + order: start-first + restart_policy: + max_attempts: 3 + condition: on-failure + window: 60s + labels: + - "backupbot.backup=${ENABLE_BACKUPS:-true}" + healthcheck: + test: ["CMD-SHELL", "curl --silent --fail localhost:9200/_cluster/health || exit 1"] + interval: 30s + timeout: 30s + retries: 3 + networks: proxy: external: true + db: + +volumes: + fabmanager_packs: + fabmanager_uploads: + fabmanager_invoices: + fabmanager_payment_schedules: + fabmanager_exports: + fabmanager_imports: + fabmanager_supporting_document_files: + fabmanager_log: + fabmanager_plugins: + fabmanager_accounting: + fabmanager_auth: + postgres_data: + redis_data: + elasticsearch_data: + +secrets: + db_password: + external: true + name: ${STACK_NAME}_db_password_${SECRET_DB_PASSWORD_VERSION} + secret_key_base: + external: true + name: ${STACK_NAME}_secret_key_base_${SECRET_SECRET_KEY_BASE_VERSION} + admin_init_password: + external: true + name: ${STACK_NAME}_admin_init_password_${SECRET_ADMIN_INIT_PASSWORD_VERSION} + +configs: + app_entrypoint: + name: ${STACK_NAME}_app_entrypoint_${APP_ENTRYPOINT_VERSION} + file: entrypoint.sh.tmpl + template_driver: golang + database_config: + name: ${STACK_NAME}_database_config_${DATABASE_CONFIG_VERSION} + file: database_config.yml.tmpl + template_driver: golang + elastic_search_config: + name: ${STACK_NAME}_elastic_search_config_config_${ELASTIC_SEARCH_CONFIG_VERSION} + file: elasticsearch.yml.tmpl + template_driver: golang + elastic_search_log_config: + name: ${STACK_NAME}_elastic_search_log_config_config_${ELASTIC_SEARCH_LOG_CONFIG_VERSION} + file: log4j2.properties.tmpl + template_driver: golang + pg_backup: + name: ${STACK_NAME}_pg_backup_${PG_BACKUP_VERSION} + file: pg_backup.sh \ No newline at end of file diff --git a/database_config.yml.tmpl b/database_config.yml.tmpl new file mode 100644 index 0000000..c365922 --- /dev/null +++ b/database_config.yml.tmpl @@ -0,0 +1,30 @@ +# For staging & production environments, copy this file to database.yml +# For development & test environments, you can use this file OR config/database.yml.default + +default: &default + adapter: postgresql + encoding: unicode + pool: 25 + username: <%= ENV["POSTGRES_USERNAME"] %> + password: {{ secret "db_password"}} + host: <%= ENV["POSTGRES_HOST"] %> + +development: + <<: *default + database: fablab_development + +# Warning: The database defined as "test" will be erased and +# re-generated from your development database when you run "rails". +# Do not set this db to the same as development or production. +test: + <<: *default + database: fablab_test + +staging: + <<: *default + database: fablab_staging + + +production: + <<: *default + database: fablab_production \ No newline at end of file diff --git a/elasticsearch.yml.tmpl b/elasticsearch.yml.tmpl new file mode 100644 index 0000000..7c2ac1a --- /dev/null +++ b/elasticsearch.yml.tmpl @@ -0,0 +1,4 @@ +http.host: 0.0.0.0 +script.inline: true +script.engine.groovy.inline.update: true +path.repo: /usr/share/elasticsearch \ No newline at end of file diff --git a/entrypoint.sh.tmpl b/entrypoint.sh.tmpl new file mode 100644 index 0000000..9643ea3 --- /dev/null +++ b/entrypoint.sh.tmpl @@ -0,0 +1,204 @@ +#!/bin/bash + +set -e + +file_env() { + # 3wc: Load $VAR_FILE into $VAR - useful for secrets. See + # https://medium.com/@adrian.gheorghe.dev/using-docker-secrets-in-your-environment-variables-7a0609659aab + local var="$1" + local fileVar="${var}_FILE" + local def="${2:-}" + + if [ "${!var:-}" ] && [ "${!fileVar:-}" ]; then + echo >&2 "error: both $var and $fileVar are set (but are exclusive)" + exit 1 + fi + local val="$def" + if [ "${!var:-}" ]; then + val="${!var}" + elif [ "${!fileVar:-}" ]; then + val="$(< "${!fileVar}")" + fi + export "$var"="$val" + unset "$fileVar" +} + +file_env "SECRET_KEY_BASE" +file_env "SMTP_PASSWORD" + + + +db_setup() { + echo "Database 'fablab_production' is empty, running db setup." + bundle exec rails db:create + bundle exec rails db:schema:load + ADMIN_EMAIL="$ADMIN_INIT_EMAIL" ADMIN_PASSWORD="$(cat /run/secrets/admin_init_password)" bundle exec rake db:seed +} + + +wait_for_postgres() { + local retries=30 + local count=0 + + >&2 echo "Waiting for PostgreSQL..." + + until PGPASSWORD=$(cat /run/secrets/db_password) psql -U "$POSTGRES_USER" -h "$POSTGRES_HOST" -c '\l' &> /dev/null; do + count=$((count+1)) + if [ "$count" -ge "$retries" ]; then + >&2 echo "Postgres is still unavailable after $retries attempts - exiting" + exit 1 + fi + >&2 echo "Postgres is unavailable - sleeping" + sleep 1 + done + + >&2 echo "Postgres is up - continuing" +} + +wait_for_redis() { + local retries=30 + local count=0 + until redis-cli -h "$REDIS_HOST" -p "$REDIS_PORT" ping | grep -q "PONG"; do + count=$((count+1)) + if [ "$count" -ge "$retries" ]; then + >&2 echo "Redis is still unavailable after $retries attempts - exiting" + exit 1 + fi + >&2 echo "Redis is unavailable - sleeping" + sleep 1 + done + >&2 echo "Redis is up - continuing" +} + +wait_for_elasticsearch() { + local retries=30 # Number of attempts before timeout + local count=0 + + >&2 echo "Waiting for Elasticsearch..." + + until curl -s -o /dev/null -w "%{http_code}" "http://$ELASTICSEARCH_HOST:9200" | grep -q "200"; do + count=$((count+1)) + if [ "$count" -ge "$retries" ]; then + >&2 echo "Elasticsearch is still unavailable after $retries attempts - exiting" + exit 1 + fi + >&2 echo "Elasticsearch is unavailable - sleeping" + sleep 1 + done + + >&2 echo "Elasticsearch is up - continuing" +} + + + +echo "generate binstubs" + +yes|bundle exec rails app:update:bin + +echo "install redis tools" +apt-get update && apt-get install redis-tools -y + +echo "set Env Variables" + +if [[ -z "${FAB_MANAGER_LOCALE_PACK}" ]]; then + echo "FAB_MANAGER_LOCALE_PACK is not set or is empty, Manual locale env is used" +else + echo "FAB_MANAGER_LOCALE_PACK is set to '${FAB_MANAGER_LOCALE_PACK}'." + + case "${FAB_MANAGER_LOCALE_PACK}" in + "en") + echo "English locale selected." + export RAILS_LOCALE=en + export APP_LOCALE=en + export MOMENT_LOCALE=en + export SUMMERNOTE_LOCALE=en-US + export ANGULAR_LOCALE=en-us + export FULLCALENDAR_LOCALE=en + export INTL_LOCALE=en-US + export INTL_CURRENCY=USD + export POSTGRESQL_LANGUAGE_ANALYZER=english + export WEEK_STARTING_DAY=monday + export D3_DATE_FORMAT=%m/%d/%Y + export UIB_DATE_FORMAT=MM/dd/yyyy + export EXCEL_DATE_FORMAT=MM/dd/yyyy + ;; + "fr") + echo "French locale selected." + export RAILS_LOCALE=fr + export APP_LOCALE=fr + export MOMENT_LOCALE=fr + export SUMMERNOTE_LOCALE=fr-FR + export ANGULAR_LOCALE=fr-fr + export FULLCALENDAR_LOCALE=fr + export INTL_LOCALE=fr-FR + export INTL_CURRENCY=EUR + export POSTGRESQL_LANGUAGE_ANALYZER=french + export WEEK_STARTING_DAY=monday + export D3_DATE_FORMAT=%d/%m/%y + export UIB_DATE_FORMAT=dd/MM/yyyy + export EXCEL_DATE_FORMAT=dd/mm/yyyy + ;; + "de") + echo "German locale selected." + export RAILS_LOCALE=de + export APP_LOCALE=de + export MOMENT_LOCALE=de + export SUMMERNOTE_LOCALE=de-DE + export ANGULAR_LOCALE=de-de + export FULLCALENDAR_LOCALE=de + export INTL_LOCALE=de-DE + export INTL_CURRENCY=EUR + export POSTGRESQL_LANGUAGE_ANALYZER=german + export WEEK_STARTING_DAY=monday + export D3_DATE_FORMAT=%d/%m/%Y + export UIB_DATE_FORMAT=dd/MM/yyyy + export EXCEL_DATE_FORMAT=dd/mm/yyyy + ;; + *) + echo "Unknown locale Pack: ${!VAR_NAME}. Manual locale env is used" + ;; + esac + + + + + +fi + +wait_for_postgres +wait_for_elasticsearch +wait_for_redis + +echo "initialising fab-manager!" + + # handle auth_provider.yml + [ -f /usr/src/app/authconfig/auth_provider.yml ] || touch /usr/src/app/authconfig/auth_provider.yml + ln -s /usr/src/app/authconfig/auth_provider.yml /usr/src/app/config/auth_provider.yml + + bundle install + + # running this code instaed of db:prepare in docker_start.sh in loomio container + # as postgres container creates empty db, somehow db:prepare cannot cope. + # therefore we run db:setup or db:migrate individually + if PGPASSWORD=$(cat /run/secrets/db_password) psql -U "$POSTGRES_USER" -h "$POSTGRES_HOST" -lqt | cut -d \| -f 1 | grep -wq "fablab_production"; then + echo "database fablab_production exists." + + # check if the database contains tables + TABLE_COUNT=$(PGPASSWORD=$(cat /run/secrets/db_password) psql -U "$POSTGRES_USER" -h "$POSTGRES_HOST" -d "fablab_production" -t -c "SELECT count(*) FROM information_schema.tables WHERE table_schema = 'public';") + + if [ "$TABLE_COUNT" -eq 0 ]; then + db_setup + else + echo "database 'fablab_production' not empty, running migrations." + bundle exec rails db:migrate + fi + else + db_setup + fi + + bundle exec rake assets:precompile + bundle exec rake fablab:es:build_stats + +echo "finished initialising fab-manager, starting supervisor!" + +/usr/bin/supervisord -c /etc/supervisor/conf.d/fabmanager.conf diff --git a/log4j2.properties.tmpl b/log4j2.properties.tmpl new file mode 100644 index 0000000..46877d0 --- /dev/null +++ b/log4j2.properties.tmpl @@ -0,0 +1,9 @@ +status = error + +appender.console.type = Console +appender.console.name = console +appender.console.layout.type = PatternLayout +appender.console.layout.pattern = [%d{ISO8601}][%-5p][%-25c{1.}] %marker%m%n + +rootLogger.level = info +rootLogger.appenderRef.console.ref = console diff --git a/pg_backup.sh b/pg_backup.sh new file mode 100644 index 0000000..e83074d --- /dev/null +++ b/pg_backup.sh @@ -0,0 +1,34 @@ +#!/bin/bash + +set -e + +BACKUP_FILE='/var/lib/postgresql/data/backup.sql' + +function backup { + export PGPASSWORD=$(cat /run/secrets/db_password) + pg_dump -U ${POSTGRES_USER} ${POSTGRES_DB} > $BACKUP_FILE +} + +function restore { + cd /var/lib/postgresql/data/ + restore_config(){ + # Restore allowed connections + cat pg_hba.conf.bak > pg_hba.conf + su postgres -c 'pg_ctl reload' + } + # Don't allow any other connections than local + cp pg_hba.conf pg_hba.conf.bak + echo "local all all trust" > pg_hba.conf + su postgres -c 'pg_ctl reload' + trap restore_config EXIT INT TERM + + # Recreate Database + psql -U ${POSTGRES_USER} -d postgres -c "DROP DATABASE ${POSTGRES_DB} WITH (FORCE);" + createdb -U ${POSTGRES_USER} ${POSTGRES_DB} + psql -U ${POSTGRES_USER} -d ${POSTGRES_DB} -1 -f $BACKUP_FILE + + trap - EXIT INT TERM + restore_config +} + +$@ diff --git a/release/1.0.0+v6.3.44 b/release/1.0.0+v6.3.44 new file mode 100644 index 0000000..6c9353e --- /dev/null +++ b/release/1.0.0+v6.3.44 @@ -0,0 +1 @@ +Initial recipie release \ No newline at end of file