Add library/: one-command Dockerized Koha home library (WIP)
Compose stack (MariaDB + Koha built from the Koha project's Debian packages), headless bootstrap replacing the web installer, seeded item types and LoC Z39.50 server, and an install.sh that installs Docker, generates passwords and waits for the site. End-to-end testing in progress. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013wi3ZSot4XbUViwRFgLpRf
This commit is contained in:
@@ -0,0 +1,4 @@
|
|||||||
|
# Generated by install.sh - contains passwords
|
||||||
|
.env
|
||||||
|
# Extra CA certificates dropped in for building behind a proxy
|
||||||
|
koha/certs/*.crt
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
name: library
|
||||||
|
|
||||||
|
services:
|
||||||
|
db:
|
||||||
|
image: mariadb:10.11
|
||||||
|
container_name: library-db
|
||||||
|
restart: unless-stopped
|
||||||
|
environment:
|
||||||
|
MARIADB_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
|
||||||
|
MARIADB_DATABASE: koha_library
|
||||||
|
MARIADB_USER: koha_library
|
||||||
|
MARIADB_PASSWORD: ${DB_PASSWORD}
|
||||||
|
command: ["--character-set-server=utf8mb4", "--collation-server=utf8mb4_unicode_ci", "--innodb-buffer-pool-size=128M"]
|
||||||
|
volumes:
|
||||||
|
- db-data:/var/lib/mysql
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 20
|
||||||
|
|
||||||
|
koha:
|
||||||
|
build:
|
||||||
|
context: ./koha
|
||||||
|
args:
|
||||||
|
KOHA_SUITE: ${KOHA_SUITE:-stable}
|
||||||
|
image: library-koha:local
|
||||||
|
container_name: library-koha
|
||||||
|
restart: unless-stopped
|
||||||
|
depends_on:
|
||||||
|
db:
|
||||||
|
condition: service_healthy
|
||||||
|
environment:
|
||||||
|
TZ: ${TZ:-UTC}
|
||||||
|
KOHA_DB_HOST: db
|
||||||
|
KOHA_DB_PASS: ${DB_PASSWORD}
|
||||||
|
KOHA_ADMIN_USER: ${ADMIN_USER:-admin}
|
||||||
|
KOHA_ADMIN_PASS: ${ADMIN_PASSWORD}
|
||||||
|
KOHA_LIBRARY_NAME: ${LIBRARY_NAME:-My Library}
|
||||||
|
ports:
|
||||||
|
- "${OPAC_PORT:-8080}:80"
|
||||||
|
- "${STAFF_PORT:-8081}:8081"
|
||||||
|
volumes:
|
||||||
|
- koha-data:/var/lib/koha
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
db-data:
|
||||||
|
koha-data:
|
||||||
Executable
+126
@@ -0,0 +1,126 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# One-command setup for a self-hosted home library (Koha) on Ubuntu/Debian.
|
||||||
|
#
|
||||||
|
# sudo ./install.sh # install Docker if needed, build, start
|
||||||
|
# sudo ./install.sh --status # show URLs and container health
|
||||||
|
# sudo ./install.sh --update # rebuild with the latest Koha and restart
|
||||||
|
# sudo ./install.sh --stop | --start
|
||||||
|
#
|
||||||
|
# Optional environment variables:
|
||||||
|
# LIBRARY_NAME="Smith Family Library" name shown on the catalogue
|
||||||
|
# OPAC_PORT=8080 STAFF_PORT=8081 preferred host ports (next free is used)
|
||||||
|
# EXTRA_CA=/path/to/proxy-ca.crt trust an extra CA while building
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
cd "$HERE"
|
||||||
|
|
||||||
|
c_info() { printf '\033[0;34m[INFO]\033[0m %s\n' "$*"; }
|
||||||
|
c_ok() { printf '\033[0;32m[ OK ]\033[0m %s\n' "$*"; }
|
||||||
|
c_warn() { printf '\033[1;33m[WARN]\033[0m %s\n' "$*"; }
|
||||||
|
c_err() { printf '\033[0;31m[FAIL]\033[0m %s\n' "$*" >&2; }
|
||||||
|
|
||||||
|
[ "$(id -u)" = 0 ] || { c_err "Run with sudo: sudo $0 $*"; exit 1; }
|
||||||
|
RUN_USER="${SUDO_USER:-root}"
|
||||||
|
|
||||||
|
# --- Docker -------------------------------------------------------------------
|
||||||
|
ensure_docker() {
|
||||||
|
if command -v docker >/dev/null 2>&1 && docker compose version >/dev/null 2>&1; then
|
||||||
|
c_ok "Docker $(docker --version | awk '{print $3}' | tr -d ,) with Compose is installed"
|
||||||
|
else
|
||||||
|
c_info "Installing Docker (official get.docker.com script)..."
|
||||||
|
command -v curl >/dev/null 2>&1 || { apt-get update -qq && apt-get install -y -qq curl ca-certificates; }
|
||||||
|
curl -fsSL https://get.docker.com | sh
|
||||||
|
docker compose version >/dev/null 2>&1 || apt-get install -y -qq docker-compose-plugin
|
||||||
|
c_ok "Docker installed"
|
||||||
|
fi
|
||||||
|
systemctl enable --now docker >/dev/null 2>&1 || true
|
||||||
|
if [ "$RUN_USER" != root ] && ! id -nG "$RUN_USER" | tr ' ' '\n' | grep -qx docker; then
|
||||||
|
usermod -aG docker "$RUN_USER" && c_info "Added $RUN_USER to the docker group (log out/in to use docker without sudo)"
|
||||||
|
fi
|
||||||
|
docker info >/dev/null 2>&1 || { c_err "The Docker daemon is not running."; exit 1; }
|
||||||
|
}
|
||||||
|
|
||||||
|
port_in_use() { ss -tlnH "sport = :$1" 2>/dev/null | grep -q .; }
|
||||||
|
free_port() { local p="$1"; while port_in_use "$p"; do p=$((p + 1)); done; echo "$p"; }
|
||||||
|
rand() { head -c 64 /dev/urandom | base64 | tr -dc 'A-Za-z0-9' | head -c "$1"; }
|
||||||
|
lan_ip() { hostname -I 2>/dev/null | awk '{print $1}'; }
|
||||||
|
|
||||||
|
dc() { docker compose --project-directory "$HERE" "$@"; }
|
||||||
|
|
||||||
|
show_status() {
|
||||||
|
[ -f .env ] || { c_err "Not installed yet - run: sudo ./install.sh"; exit 1; }
|
||||||
|
# shellcheck disable=SC1091
|
||||||
|
. ./.env
|
||||||
|
local ip; ip="$(lan_ip)"; ip="${ip:-localhost}"
|
||||||
|
dc ps
|
||||||
|
echo
|
||||||
|
echo " Catalogue (public): http://$ip:$OPAC_PORT"
|
||||||
|
echo " Staff interface: http://$ip:$STAFF_PORT"
|
||||||
|
echo " Staff login: $ADMIN_USER / $ADMIN_PASSWORD (also stored in $HERE/.env)"
|
||||||
|
echo
|
||||||
|
}
|
||||||
|
|
||||||
|
case "${1:-}" in
|
||||||
|
--status) show_status; exit 0 ;;
|
||||||
|
--stop) dc stop; exit 0 ;;
|
||||||
|
--start) dc start; exit 0 ;;
|
||||||
|
--update)
|
||||||
|
ensure_docker
|
||||||
|
dc build --pull --no-cache koha
|
||||||
|
dc up -d
|
||||||
|
show_status; exit 0 ;;
|
||||||
|
"" ) ;;
|
||||||
|
*) c_err "Unknown option: $1"; exit 1 ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
ensure_docker
|
||||||
|
|
||||||
|
# --- Settings (.env is created once and never overwritten) ------------------------
|
||||||
|
if [ ! -f .env ]; then
|
||||||
|
c_info "Generating settings and passwords..."
|
||||||
|
TZ_NOW="$(cat /etc/timezone 2>/dev/null || timedatectl show -p Timezone --value 2>/dev/null || echo UTC)"
|
||||||
|
umask 077
|
||||||
|
cat > .env << ENVEOF
|
||||||
|
# Generated by install.sh - keep this file private.
|
||||||
|
LIBRARY_NAME="${LIBRARY_NAME:-My Library}"
|
||||||
|
TZ=${TZ_NOW}
|
||||||
|
OPAC_PORT=$(free_port "${OPAC_PORT:-8080}")
|
||||||
|
STAFF_PORT=$(free_port "${STAFF_PORT:-8081}")
|
||||||
|
ADMIN_USER=admin
|
||||||
|
ADMIN_PASSWORD=$(rand 16)
|
||||||
|
DB_ROOT_PASSWORD=$(rand 32)
|
||||||
|
DB_PASSWORD=$(rand 32)
|
||||||
|
KOHA_SUITE=stable
|
||||||
|
ENVEOF
|
||||||
|
umask 022
|
||||||
|
[ "$RUN_USER" = root ] || chown "$RUN_USER" .env
|
||||||
|
else
|
||||||
|
c_info "Re-using existing .env"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "${EXTRA_CA:-}" ]; then
|
||||||
|
cp "$EXTRA_CA" koha/certs/extra-ca.crt
|
||||||
|
c_info "Trusting extra CA during the build: $EXTRA_CA"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# --- Build and start ---------------------------------------------------------------
|
||||||
|
c_info "Building the Koha image (first time: 5-10 minutes, downloads ~1 GB)..."
|
||||||
|
dc build
|
||||||
|
c_info "Starting..."
|
||||||
|
dc up -d
|
||||||
|
|
||||||
|
# --- Wait until the site answers ---------------------------------------------------
|
||||||
|
# shellcheck disable=SC1091
|
||||||
|
. ./.env
|
||||||
|
c_info "First start installs the database - waiting for the staff interface..."
|
||||||
|
for i in $(seq 1 120); do
|
||||||
|
if curl -fsS -o /dev/null "http://127.0.0.1:$STAFF_PORT/" 2>/dev/null; then READY=1; break; fi
|
||||||
|
if ! docker ps --format '{{.Names}}' | grep -qx library-koha; then c_err "library-koha stopped - see: docker logs library-koha"; exit 1; fi
|
||||||
|
sleep 5
|
||||||
|
done
|
||||||
|
[ "${READY:-0}" = 1 ] || { c_err "Timed out - see: docker logs -f library-koha"; exit 1; }
|
||||||
|
|
||||||
|
c_ok "Your library is running."
|
||||||
|
echo
|
||||||
|
show_status
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
# Koha (open-source library system) built from the Koha project's own Debian
|
||||||
|
# packages - no third-party Koha images involved.
|
||||||
|
#
|
||||||
|
# KOHA_SUITE stable (default) | oldstable | unstable
|
||||||
|
# KEEP_TRANSLATIONS no (default) trims ~650 MB of non-English .po files;
|
||||||
|
# set "yes" if you want to install other languages later
|
||||||
|
FROM debian:bookworm-slim
|
||||||
|
|
||||||
|
ARG KOHA_SUITE=stable
|
||||||
|
ARG KEEP_TRANSLATIONS=no
|
||||||
|
ENV DEBIAN_FRONTEND=noninteractive \
|
||||||
|
LANG=C.UTF-8
|
||||||
|
|
||||||
|
RUN apt-get update \
|
||||||
|
&& apt-get install -y --no-install-recommends ca-certificates curl gnupg tzdata
|
||||||
|
|
||||||
|
# Optional: drop extra CA certificates (*.crt) into ./certs/ before building if
|
||||||
|
# you are behind a TLS-inspecting proxy. Empty by default.
|
||||||
|
COPY certs/ /usr/local/share/ca-certificates/extra/
|
||||||
|
RUN update-ca-certificates
|
||||||
|
|
||||||
|
RUN curl -fsSL https://debian.koha-community.org/koha/gpg.asc | gpg --dearmor -o /usr/share/keyrings/koha.gpg \
|
||||||
|
&& echo "deb [signed-by=/usr/share/keyrings/koha.gpg] https://debian.koha-community.org/koha ${KOHA_SUITE} main bookworm" \
|
||||||
|
> /etc/apt/sources.list.d/koha.list \
|
||||||
|
&& apt-get update \
|
||||||
|
&& apt-get install -y --no-install-recommends koha-common mariadb-client \
|
||||||
|
&& a2enmod rewrite headers proxy_http cgi deflate >/dev/null \
|
||||||
|
&& a2dissite 000-default >/dev/null 2>&1 || true \
|
||||||
|
&& if [ "$KEEP_TRANSLATIONS" != "yes" ]; then rm -rf /usr/share/koha/misc/translator/po; fi \
|
||||||
|
&& rm -rf /var/lib/apt/lists/* /usr/share/doc/*
|
||||||
|
|
||||||
|
COPY bootstrap.pl entrypoint.sh /opt/koha-init/
|
||||||
|
COPY seed/ /opt/koha-init/seed/
|
||||||
|
RUN chmod 0755 /opt/koha-init/entrypoint.sh && chmod -R a+rX /opt/koha-init
|
||||||
|
|
||||||
|
EXPOSE 80 8081
|
||||||
|
VOLUME ["/var/lib/koha"]
|
||||||
|
HEALTHCHECK --interval=30s --timeout=10s --start-period=300s --retries=5 \
|
||||||
|
CMD curl -fsS -o /dev/null http://127.0.0.1:80/ && curl -fsS -o /dev/null http://127.0.0.1:8081/ || exit 1
|
||||||
|
ENTRYPOINT ["/opt/koha-init/entrypoint.sh"]
|
||||||
Executable
+111
@@ -0,0 +1,111 @@
|
|||||||
|
#!/usr/bin/perl
|
||||||
|
# Headless replacement for Koha's web installer + onboarding wizard.
|
||||||
|
# Run as the instance user: koha-shell -c "perl bootstrap.pl" <instance>
|
||||||
|
#
|
||||||
|
# Mirrors what /cgi-bin/koha/installer/install.pl does step by step (so a
|
||||||
|
# future Koha upgrade keeps working), then seeds a home-library setup.
|
||||||
|
use Modern::Perl;
|
||||||
|
use C4::Context;
|
||||||
|
use C4::Installer;
|
||||||
|
use Koha;
|
||||||
|
use Koha::Libraries;
|
||||||
|
use Koha::Patrons;
|
||||||
|
use Koha::Patron::Categories;
|
||||||
|
|
||||||
|
$| = 1;
|
||||||
|
my $seed_dir = $ENV{KOHA_SEED_DIR} || '/opt/koha-init/seed';
|
||||||
|
my $admin_pass = $ENV{KOHA_ADMIN_PASS};
|
||||||
|
die "KOHA_ADMIN_PASS not set\n" unless defined $admin_pass && length $admin_pass;
|
||||||
|
my %env = (
|
||||||
|
admin_user => $ENV{KOHA_ADMIN_USER} || 'admin',
|
||||||
|
admin_pass => $admin_pass,
|
||||||
|
library => $ENV{KOHA_LIBRARY_NAME} || 'My Library',
|
||||||
|
);
|
||||||
|
|
||||||
|
my $installer = C4::Installer->new();
|
||||||
|
my $dbh = C4::Context->dbh;
|
||||||
|
my $intranet = C4::Context->config('intranetdir');
|
||||||
|
my $data = "$intranet/installer/data/mysql";
|
||||||
|
|
||||||
|
# Already installed? (the entrypoint checks too; this is a safety net)
|
||||||
|
my ($tables) = $dbh->selectrow_array(
|
||||||
|
"SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = DATABASE()");
|
||||||
|
if ($tables) { say "bootstrap: database already has $tables tables - nothing to do."; exit 0; }
|
||||||
|
|
||||||
|
say "bootstrap: loading database schema...";
|
||||||
|
if ( my $err = $installer->load_db_schema() ) { die "schema load failed: $err\n"; }
|
||||||
|
|
||||||
|
$installer->set_marcflavour_syspref('marc21');
|
||||||
|
|
||||||
|
# Same ordering rules the web installer applies (sysprefs first, userflags last).
|
||||||
|
my @files = (
|
||||||
|
sort( glob("$data/en/mandatory/*.sql"), glob("$data/en/mandatory/*.yml") ),
|
||||||
|
sort( glob("$data/en/marcflavour/marc21/mandatory/*.yml"), glob("$data/en/marcflavour/marc21/mandatory/*.sql") ),
|
||||||
|
);
|
||||||
|
# Optional data worth having: matching rules, "Fast add" framework (a short
|
||||||
|
# cataloguing form - title/author/ISBN/call number/barcode), MARC-coded values.
|
||||||
|
for my $f (qw(
|
||||||
|
marcflavour/marc21/optional/marc21_default_matching_rules.yml
|
||||||
|
marcflavour/marc21/optional/marc21_sample_fastadd_framework.yml
|
||||||
|
optional/marc21_holdings_coded_values.yml
|
||||||
|
optional/marc21_relatorterms.yml
|
||||||
|
optional/auth_val.yml
|
||||||
|
optional/csv_profiles.yml
|
||||||
|
)) {
|
||||||
|
push @files, "$data/en/$f" if -f "$data/en/$f";
|
||||||
|
}
|
||||||
|
|
||||||
|
say "bootstrap: loading ", scalar(@files), " framework / data files...";
|
||||||
|
my ( undef, $list ) = $installer->load_sql_in_order( 'en', [], @files );
|
||||||
|
for my $lvl (@$list) {
|
||||||
|
for my $f ( @{ $lvl->{fwklist} } ) {
|
||||||
|
say " ! $f->{fwkname}: $f->{error}" if $f->{error};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$installer->set_version_syspref();
|
||||||
|
$installer->set_languages_syspref('en');
|
||||||
|
|
||||||
|
# ---- Home-library seed data (YAML in the same format Koha ships) ----------
|
||||||
|
for my $y (sort glob("$seed_dir/*.yml")) {
|
||||||
|
my $err = $installer->load_sql($y);
|
||||||
|
say " seed $y: ", ( $err ? "ERROR $err" : 'ok' );
|
||||||
|
}
|
||||||
|
|
||||||
|
# ---- Library, patron categories, owner account ----------------------------
|
||||||
|
Koha::Library->new({
|
||||||
|
branchcode => 'HOME', branchname => $env{library},
|
||||||
|
})->store unless Koha::Libraries->find('HOME');
|
||||||
|
|
||||||
|
for my $c ( [ 'OWNER', 'Owner / librarian', 'S' ], [ 'FRIEND', 'Friend / borrower', 'A' ] ) {
|
||||||
|
Koha::Patron::Category->new({
|
||||||
|
categorycode => $c->[0], description => $c->[1], category_type => $c->[2],
|
||||||
|
enrolmentperiod => 999, overduenoticerequired => 0,
|
||||||
|
})->store unless Koha::Patron::Categories->find( $c->[0] );
|
||||||
|
}
|
||||||
|
|
||||||
|
my $admin = Koha::Patron->new({
|
||||||
|
cardnumber => 'ADMIN', surname => 'Librarian', userid => $env{admin_user},
|
||||||
|
branchcode => 'HOME', categorycode => 'OWNER', flags => 1, # 1 = superlibrarian
|
||||||
|
})->store;
|
||||||
|
$admin->set_password({ password => $env{admin_pass}, skip_validation => 1 });
|
||||||
|
|
||||||
|
# ---- Preferences ----------------------------------------------------------
|
||||||
|
my %prefs = (
|
||||||
|
autoBarcode => 'incremental', # new items get a barcode automatically
|
||||||
|
itemcallnumber => '082ab', # Dewey call number copied from the MARC record
|
||||||
|
OpenLibraryCovers => 1, # cover images in the catalogue
|
||||||
|
OPACSearchForTitleIn => '',
|
||||||
|
BiblioDefaultView => 'normal',
|
||||||
|
OpacPublic => 1,
|
||||||
|
opacuserlogin => 0, # catalogue is browse-only; no patron logins needed
|
||||||
|
OpacMaintenance => 0,
|
||||||
|
ExpireReservesMaxPickUpDelay => 0,
|
||||||
|
AllowOfflineCirculation => 0,
|
||||||
|
marcflavour => 'MARC21',
|
||||||
|
LibraryName => $env{library},
|
||||||
|
timezone => $ENV{TZ} || 'UTC',
|
||||||
|
);
|
||||||
|
C4::Context->set_preference( $_, $prefs{$_} ) for sort keys %prefs;
|
||||||
|
|
||||||
|
say "bootstrap: done. Staff login: $env{admin_user}";
|
||||||
Executable
+80
@@ -0,0 +1,80 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Container entrypoint: (re)creates the Koha instance config from environment
|
||||||
|
# variables on every start, installs the database on the first start, then runs
|
||||||
|
# Apache in the foreground. All durable state lives in MariaDB and /var/lib/koha.
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
INST="${KOHA_INSTANCE:-library}"
|
||||||
|
DB_HOST="${KOHA_DB_HOST:-db}"
|
||||||
|
DB_NAME="${KOHA_DB_NAME:-koha_library}"
|
||||||
|
DB_USER="${KOHA_DB_USER:-koha_library}"
|
||||||
|
: "${KOHA_DB_PASS:?KOHA_DB_PASS is required}"
|
||||||
|
: "${KOHA_ADMIN_PASS:?KOHA_ADMIN_PASS is required}"
|
||||||
|
STAFF_PORT=8081
|
||||||
|
export TZ="${TZ:-UTC}"
|
||||||
|
|
||||||
|
log() { echo "[koha-init] $*"; }
|
||||||
|
|
||||||
|
# --- 1. memcached (Koha caches sysprefs and sessions in it) -----------------
|
||||||
|
memcached -u memcache -m 64 -d
|
||||||
|
cron
|
||||||
|
|
||||||
|
# --- 2. wait for MariaDB ----------------------------------------------------
|
||||||
|
log "waiting for database at $DB_HOST..."
|
||||||
|
for i in $(seq 1 120); do
|
||||||
|
mariadb -h "$DB_HOST" -u "$DB_USER" -p"$KOHA_DB_PASS" "$DB_NAME" -e 'select 1' >/dev/null 2>&1 && break
|
||||||
|
[ "$i" = 120 ] && { log "database never became ready"; exit 1; }
|
||||||
|
sleep 2
|
||||||
|
done
|
||||||
|
|
||||||
|
# --- 3. instance config (regenerated each time a container is created) ------
|
||||||
|
if [ ! -d "/etc/koha/sites/$INST" ]; then
|
||||||
|
log "creating Koha instance '$INST'..."
|
||||||
|
sed -i \
|
||||||
|
-e 's|^DOMAIN=.*|DOMAIN=""|' \
|
||||||
|
-e 's|^INTRASUFFIX=.*|INTRASUFFIX=""|' \
|
||||||
|
-e "s|^INTRAPORT=.*|INTRAPORT=\"$STAFF_PORT\"|" \
|
||||||
|
/etc/koha/koha-sites.conf
|
||||||
|
echo "$INST:$DB_USER:$KOHA_DB_PASS:$DB_NAME:$DB_HOST" > /etc/koha/passwd
|
||||||
|
koha-create --use-db --dbhost "$DB_HOST" --timezone "$TZ" \
|
||||||
|
--memcached-servers 127.0.0.1:11211 "$INST" 2>&1 | grep -v AH00558 || true
|
||||||
|
|
||||||
|
# No RabbitMQ in this stack: workers fall back to polling the database.
|
||||||
|
CONF="/etc/koha/sites/$INST/koha-conf.xml"
|
||||||
|
perl -0pi -e 's|\s*<message_broker>.*?</message_broker>||s' "$CONF"
|
||||||
|
|
||||||
|
# Serve both interfaces through Plack (much faster than plain CGI).
|
||||||
|
SITE="/etc/apache2/sites-available/$INST.conf"
|
||||||
|
sed -i \
|
||||||
|
-e 's|^\(\s*\)Include /etc/koha/apache-shared-opac.conf|\1Include /etc/koha/apache-shared-opac-plack.conf|' \
|
||||||
|
-e 's|^\(\s*\)Include /etc/koha/apache-shared-intranet.conf|\1Include /etc/koha/apache-shared-intranet-plack.conf|' \
|
||||||
|
-e 's|^#\s*Include /etc/koha/apache-shared-opac-plack.conf||' \
|
||||||
|
-e 's|^#\s*Include /etc/koha/apache-shared-intranet-plack.conf||' "$SITE"
|
||||||
|
koha-plack --enable "$INST" >/dev/null
|
||||||
|
grep -q '^ServerName' /etc/apache2/apache2.conf || echo 'ServerName localhost' >> /etc/apache2/apache2.conf
|
||||||
|
fi
|
||||||
|
chown -R "$INST-koha:$INST-koha" "/var/lib/koha/$INST" "/var/log/koha/$INST" 2>/dev/null || true
|
||||||
|
|
||||||
|
# --- 4. install or upgrade the database -------------------------------------
|
||||||
|
TABLES=$(mariadb -N -h "$DB_HOST" -u "$DB_USER" -p"$KOHA_DB_PASS" "$DB_NAME" \
|
||||||
|
-e "select count(*) from information_schema.tables where table_schema='$DB_NAME'")
|
||||||
|
if [ "$TABLES" = "0" ]; then
|
||||||
|
log "first start: installing Koha (about a minute)..."
|
||||||
|
koha-shell -c "KOHA_ADMIN_USER='${KOHA_ADMIN_USER:-admin}' KOHA_ADMIN_PASS='$KOHA_ADMIN_PASS' KOHA_LIBRARY_NAME='${KOHA_LIBRARY_NAME:-My Library}' TZ='$TZ' perl /opt/koha-init/bootstrap.pl" "$INST"
|
||||||
|
FIRST_RUN=1
|
||||||
|
else
|
||||||
|
log "existing database found - applying any pending upgrades..."
|
||||||
|
koha-upgrade-schema "$INST" || log "WARNING: koha-upgrade-schema reported a problem (see output above)"
|
||||||
|
FIRST_RUN=0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# --- 5. search index (Zebra) ------------------------------------------------
|
||||||
|
koha-plack --restart "$INST" >/dev/null 2>&1 || koha-plack --start "$INST" >/dev/null 2>&1 || true
|
||||||
|
koha-worker --restart "$INST" >/dev/null 2>&1 || true
|
||||||
|
if [ "$FIRST_RUN" = 1 ] || [ ! -e "/var/lib/koha/$INST/biblios/register" ]; then
|
||||||
|
log "building search index..."
|
||||||
|
koha-rebuild-zebra -f -b -a -v "$INST" >/dev/null 2>&1 || koha-rebuild-zebra -f -v "$INST" || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
log "ready - library catalogue on :80, staff interface on :$STAFF_PORT"
|
||||||
|
exec apache2ctl -D FOREGROUND
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
---
|
||||||
|
description:
|
||||||
|
- "Item types for a home library: books, movies, music, games"
|
||||||
|
tables:
|
||||||
|
- itemtypes:
|
||||||
|
translatable: [ description ]
|
||||||
|
multiline: []
|
||||||
|
rows:
|
||||||
|
- { itemtype: BOOK, description: "Book", rentalcharge: 0, notforloan: 0, imageurl: "bridge/book.png", summary: "" }
|
||||||
|
- { itemtype: DVD, description: "Movie (DVD/Blu-ray)", rentalcharge: 0, notforloan: 0, imageurl: "bridge/dvd.png", summary: "" }
|
||||||
|
- { itemtype: CD, description: "Music (CD/vinyl)", rentalcharge: 0, notforloan: 0, imageurl: "bridge/sound.png", summary: "" }
|
||||||
|
- { itemtype: GAME, description: "Game", rentalcharge: 0, notforloan: 0, imageurl: "bridge/computer_file.png", summary: "" }
|
||||||
|
- { itemtype: OTHER, description: "Other", rentalcharge: 0, notforloan: 0, imageurl: "bridge/kit.png", summary: "" }
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
---
|
||||||
|
description:
|
||||||
|
- "Public Z39.50 servers used by Cataloging > Z39.50/SRU search"
|
||||||
|
tables:
|
||||||
|
- z3950servers:
|
||||||
|
translatable: [ servername ]
|
||||||
|
multiline: []
|
||||||
|
rows:
|
||||||
|
- { host: "lx2.loc.gov", port: 210, db: LCDB, userid: "", password: "", servername: "LIBRARY OF CONGRESS", checked: 1, rank: 1, syntax: USMARC, encoding: utf8, recordtype: biblio }
|
||||||
Reference in New Issue
Block a user