Files
myoffice_public/proxmox/install-in-ct.sh
T

228 lines
6.6 KiB
Bash

#!/usr/bin/env bash
# Runs inside the MyOffice LXC: PostgreSQL + ASP.NET Core runtime + app from Gitea Release.
# No Docker, no nginx, no git, no SDK, no Node.
#
# Env (from proxmox/myoffice.sh):
# APP_DIR, PUBLIC_URL, API_PORT, ASSETS_DIR
# GITEA_URL, GITEA_OWNER, GITEA_REPO, RELEASE_TAG, RELEASE_ASSET_URL, GITEA_TOKEN
set -euo pipefail
APP_DIR="${APP_DIR:-/opt/myoffice}"
API_DIR="${APP_DIR}/api"
ASSETS_DIR="${ASSETS_DIR:-/tmp/myoffice-proxmox}"
PUBLIC_URL="${PUBLIC_URL:-}"
API_PORT="${API_PORT:-9100}"
PG_DB="myoffice"
PG_USER="myoffice"
PG_PASS="myoffice"
SKIP_FETCH="${SKIP_FETCH:-0}"
export DEBIAN_FRONTEND=noninteractive
export API_DIR
# Avoid perl locale warnings in minimal LXC (host may export unsupported LC_*).
export LANG=C.UTF-8
export LC_ALL=C.UTF-8
unset LANGUAGE LC_TIME LC_MESSAGES 2>/dev/null || true
msg() { echo -e " ==> $*"; }
# TEMPORARY: map Gitea hostname → nginx LAN (override with GITEA_HOSTS_IP= to disable)
ensure_gitea_hosts() {
if [[ -z "${GITEA_HOSTS_IP:-}" ]]; then
return 0
fi
local hn="${GITEA_HOSTS_NAME:-mygit.ase.com.ua}"
sed -i "/[[:space:]]${hn}\$/d" /etc/hosts
echo "${GITEA_HOSTS_IP} ${hn}" >> /etc/hosts
msg "hosts: ${GITEA_HOSTS_IP} ${hn}"
}
as_postgres() {
# Script runs as root in CT; sudo is not installed.
# cd away from /root — postgres cannot access it (harmless but noisy otherwise).
if command -v runuser >/dev/null 2>&1; then
(cd /tmp && runuser -u postgres -- "$@")
else
(cd /tmp && su -s /bin/bash postgres -c "$(printf '%q ' "$@")")
fi
}
detect_public_url() {
if [[ -n "$PUBLIC_URL" ]]; then
PUBLIC_URL=$(echo "$PUBLIC_URL" | sed 's:/*$::')
return 0
fi
local ip
ip=$(ip -4 -o addr show eth0 2>/dev/null | awk '{print $4}' | cut -d/ -f1 | head -1 || true)
if [[ -z "$ip" ]]; then
ip=$(hostname -I 2>/dev/null | awk '{print $1}')
fi
if [[ -z "$ip" ]]; then
echo "Could not detect CT IP. Set PUBLIC_URL." >&2
exit 1
fi
PUBLIC_URL="http://${ip}:${API_PORT}"
}
install_base() {
msg "Installing base packages"
apt-get update -y
apt-get install -y ca-certificates curl gnupg locales postgresql postgresql-contrib
sed -i 's/^# *en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen 2>/dev/null || true
locale-gen en_US.UTF-8 >/dev/null 2>&1 || true
update-locale LANG=en_US.UTF-8 >/dev/null 2>&1 || true
}
install_aspnet_runtime() {
if command -v dotnet >/dev/null 2>&1 && dotnet --list-runtimes 2>/dev/null | grep -q 'Microsoft.AspNetCore.App 10\.'; then
msg "ASP.NET Core 10 runtime already installed"
return 0
fi
msg "Installing ASP.NET Core 10 runtime"
curl -fsSL https://packages.microsoft.com/config/debian/12/packages-microsoft-prod.deb -o /tmp/packages-microsoft-prod.deb
dpkg -i /tmp/packages-microsoft-prod.deb
apt-get update -y
apt-get install -y aspnetcore-runtime-10.0
}
setup_postgres() {
msg "Configuring PostgreSQL"
systemctl enable --now postgresql
if ! as_postgres psql -tAc "SELECT 1 FROM pg_roles WHERE rolname='${PG_USER}'" | grep -q 1; then
as_postgres psql -c "CREATE USER ${PG_USER} WITH PASSWORD '${PG_PASS}';"
else
as_postgres psql -c "ALTER USER ${PG_USER} WITH PASSWORD '${PG_PASS}';"
fi
if ! as_postgres psql -tAc "SELECT 1 FROM pg_database WHERE datname='${PG_DB}'" | grep -q 1; then
as_postgres psql -c "CREATE DATABASE ${PG_DB} OWNER ${PG_USER};"
fi
as_postgres psql -c "GRANT ALL PRIVILEGES ON DATABASE ${PG_DB} TO ${PG_USER};"
as_postgres psql -d "$PG_DB" -c "GRANT ALL ON SCHEMA public TO ${PG_USER};" || true
msg "PostgreSQL ready (db/user/pass=${PG_DB})"
}
write_runtime_config() {
mkdir -p "$API_DIR"
if [[ ! -f "$API_DIR/appsettings.Production.json" ]]; then
cat >"$API_DIR/appsettings.Production.json" <<EOF
{
"DatabaseProvider": "npgsql",
"Kestrel": {
"EndPoints": {
"Http": {
"Url": "http://*:${API_PORT}"
}
}
},
"FrontEnd": {
"Host": "${PUBLIC_URL}"
},
"Cors": {
"AllowedOrigins": [
"${PUBLIC_URL}"
]
},
"OpenIddict": {
"UseEphemeralKeys": true,
"AllowHttp": true
}
}
EOF
fi
if [[ ! -f "$API_DIR/appsettings.shared.Production.json" ]]; then
cat >"$API_DIR/appsettings.shared.Production.json" <<EOF
{
"ConnectionStrings": {
"npgsql": "Host=127.0.0.1;Port=5432;Database=${PG_DB};Username=${PG_USER};Password=${PG_PASS}"
}
}
EOF
fi
}
fetch_app() {
if [[ "$SKIP_FETCH" == "1" ]]; then
msg "SKIP_FETCH=1 — not downloading release"
return 0
fi
local fetch_script="${ASSETS_DIR}/fetch-release.sh"
if [[ ! -f "$fetch_script" ]]; then
fetch_script="${APP_DIR}/proxmox/fetch-release.sh"
fi
if [[ ! -f "$fetch_script" ]]; then
echo "Missing fetch-release.sh (looked in ASSETS_DIR and ${APP_DIR}/proxmox)." >&2
exit 1
fi
# shellcheck disable=SC1090
source "$fetch_script"
download_and_extract
}
install_systemd() {
msg "Configuring systemd unit myoffice-api"
local unit_src="${ASSETS_DIR}/myoffice-api.service"
if [[ ! -f "$unit_src" ]]; then
unit_src="${APP_DIR}/proxmox/myoffice-api.service"
fi
if [[ ! -f "$unit_src" ]]; then
echo "Missing myoffice-api.service" >&2
exit 1
fi
sed -e "s|__API_DIR__|${API_DIR}|g" -e "s|__API_PORT__|${API_PORT}|g" \
"$unit_src" >/etc/systemd/system/myoffice-api.service
mkdir -p "${APP_DIR}/proxmox"
if [[ -d "$ASSETS_DIR" ]]; then
cp -a "${ASSETS_DIR}/." "${APP_DIR}/proxmox/"
fi
chmod +x "${APP_DIR}/proxmox/"*.sh 2>/dev/null || true
cat >"${APP_DIR}/proxmox/env" <<EOF
PUBLIC_URL=${PUBLIC_URL}
API_PORT=${API_PORT}
APP_DIR=${APP_DIR}
GITEA_URL=${GITEA_URL:-}
GITEA_OWNER=${GITEA_OWNER:-}
GITEA_REPO=${GITEA_REPO:-myoffice_public}
RELEASE_TAG=${RELEASE_TAG:-latest}
RELEASE_ASSET_URL=${RELEASE_ASSET_URL:-}
GITEA_HOSTS_IP=${GITEA_HOSTS_IP:-}
GITEA_HOSTS_NAME=${GITEA_HOSTS_NAME:-mygit.ase.com.ua}
EOF
# TEMPORARY hosts also persisted above in env; already applied at start via ensure_gitea_hosts
systemctl daemon-reload
systemctl enable myoffice-api
if [[ -f "${API_DIR}/MyOffice.Web.dll" ]]; then
systemctl restart myoffice-api
else
systemctl stop myoffice-api 2>/dev/null || true
msg "App DLL missing — service not started"
fi
}
print_done() {
echo
echo " MyOffice CT is ready:"
echo " Public URL ${PUBLIC_URL}"
echo " Listen 0.0.0.0:${API_PORT} (proxy this from your nginx LXC)"
echo " Postgres 127.0.0.1:5432 db/user/pass=${PG_DB}"
echo " App dir ${API_DIR}"
echo
echo " Update later: ${APP_DIR}/proxmox/update.sh"
echo " Demo login: user_UAH@user_UAH.userUAH / user_UAH"
echo
}
detect_public_url
ensure_gitea_hosts
install_base
install_aspnet_runtime
setup_postgres
write_runtime_config
fetch_app
install_systemd
print_done