Files
DocumentServer-v-9.2.0/run-document-server.sh
Yajbir Singh db4b0e3625
Some checks failed
check / markdownlint (push) Has been cancelled
check / spellchecker (push) Has been cancelled
updated
2025-12-11 16:38:53 +05:30

393 lines
11 KiB
Bash

#!/bin/bash
# ONLYOFFICE DocumentServer Startup Script
# This script initializes and starts all required services
umask 0022
# ============================================
# HARDCODED CONFIGURATION
# ============================================
COMPANY_NAME=${COMPANY_NAME:-onlyoffice}
PRODUCT_NAME=${PRODUCT_NAME:-documentserver}
# Database Configuration
DB_TYPE=${DB_TYPE:-postgres}
DB_HOST=${DB_HOST:-localhost}
DB_PORT=${DB_PORT:-5432}
DB_NAME=${DB_NAME:-onlyoffice}
DB_USER=${DB_USER:-onlyoffice}
DB_PWD=${DB_PWD:-onlyoffice}
# Redis Configuration
REDIS_SERVER_HOST=${REDIS_SERVER_HOST:-localhost}
REDIS_SERVER_PORT=${REDIS_SERVER_PORT:-6379}
REDIS_ENABLED=${REDIS_ENABLED:-true}
# RabbitMQ Configuration
AMQP_SERVER_HOST=${AMQP_SERVER_HOST:-localhost}
AMQP_SERVER_PORT=${AMQP_SERVER_PORT:-5672}
AMQP_SERVER_USER=${AMQP_SERVER_USER:-guest}
AMQP_SERVER_PWD=${AMQP_SERVER_PWD:-guest}
AMQP_SERVER_PROTO=${AMQP_SERVER_PROTO:-amqp}
# JWT Configuration
JWT_ENABLED=${JWT_ENABLED:-false}
JWT_SECRET=${JWT_SECRET:-secret}
JWT_HEADER=${JWT_HEADER:-Authorization}
JWT_IN_BODY=${JWT_IN_BODY:-false}
# Other settings
WOPI_ENABLED=${WOPI_ENABLED:-false}
GENERATE_FONTS=${GENERATE_FONTS:-true}
PLUGINS_ENABLED=${PLUGINS_ENABLED:-true}
DS_LOG_LEVEL=${DS_LOG_LEVEL:-WARN}
NGINX_WORKER_PROCESSES=${NGINX_WORKER_PROCESSES:-1}
# ============================================
# DIRECTORIES
# ============================================
APP_DIR="/var/www/${COMPANY_NAME}/documentserver"
DATA_DIR="/var/www/${COMPANY_NAME}/Data"
PRIVATE_DATA_DIR="${DATA_DIR}/.private"
LOG_DIR="/var/log/${COMPANY_NAME}"
DS_LOG_DIR="${LOG_DIR}/documentserver"
LIB_DIR="/var/lib/${COMPANY_NAME}"
DS_LIB_DIR="${LIB_DIR}/documentserver"
CONF_DIR="/etc/${COMPANY_NAME}/documentserver"
PG_ROOT="/var/lib/postgresql"
PGDATA="${PG_ROOT}/${PG_VERSION:-16}/main"
REDIS_DATA="/var/lib/redis"
RABBITMQ_DATA="/var/lib/rabbitmq"
# ============================================
# FUNCTIONS
# ============================================
start_process() {
"$@" &
CHILD=$!
wait "$CHILD"
CHILD=""
}
clean_exit() {
[[ -z "$CHILD" ]] || kill -s SIGTERM "$CHILD" 2>/dev/null
/usr/bin/documentserver-prepare4shutdown.sh 2>/dev/null || true
exit
}
trap clean_exit SIGTERM SIGQUIT SIGABRT SIGINT
waiting_for_db() {
echo "Waiting for database connection..."
local RETRY=0
local MAX_RETRY=30
while ! PGPASSWORD="${DB_PWD}" psql -h "${DB_HOST}" -p "${DB_PORT}" -U "${DB_USER}" -d "${DB_NAME}" -c "SELECT 1" >/dev/null 2>&1; do
RETRY=$((RETRY + 1))
if [ $RETRY -ge $MAX_RETRY ]; then
echo "ERROR: Database connection failed after ${MAX_RETRY} attempts"
exit 1
fi
echo " Attempt ${RETRY}/${MAX_RETRY}..."
sleep 2
done
echo "Database connection established!"
}
waiting_for_amqp() {
echo "Waiting for RabbitMQ connection..."
local RETRY=0
local MAX_RETRY=30
while ! nc -z "${AMQP_SERVER_HOST}" "${AMQP_SERVER_PORT}" 2>/dev/null; do
RETRY=$((RETRY + 1))
if [ $RETRY -ge $MAX_RETRY ]; then
echo "ERROR: RabbitMQ connection failed after ${MAX_RETRY} attempts"
exit 1
fi
echo " Attempt ${RETRY}/${MAX_RETRY}..."
sleep 2
done
echo "RabbitMQ connection established!"
}
waiting_for_redis() {
echo "Waiting for Redis connection..."
local RETRY=0
local MAX_RETRY=30
while ! nc -z "${REDIS_SERVER_HOST}" "${REDIS_SERVER_PORT}" 2>/dev/null; do
RETRY=$((RETRY + 1))
if [ $RETRY -ge $MAX_RETRY ]; then
echo "ERROR: Redis connection failed after ${MAX_RETRY} attempts"
exit 1
fi
echo " Attempt ${RETRY}/${MAX_RETRY}..."
sleep 2
done
echo "Redis connection established!"
}
create_postgresql_cluster() {
echo "Creating PostgreSQL cluster..."
sudo -u postgres /usr/lib/postgresql/${PG_VERSION:-16}/bin/initdb -D "${PGDATA}"
# Configure pg_hba.conf to trust local connections
# This avoids password authentication issues between services running in the same container
echo "local all onlyoffice trust" > "${PGDATA}/pg_hba.conf"
echo "local all all peer" >> "${PGDATA}/pg_hba.conf"
echo "host all all 127.0.0.1/32 trust" >> "${PGDATA}/pg_hba.conf"
echo "host all all ::1/128 trust" >> "${PGDATA}/pg_hba.conf"
}
create_postgresql_db() {
echo "Creating PostgreSQL database..."
sudo -u postgres psql -c "CREATE USER ${DB_USER} WITH password '${DB_PWD}';" 2>/dev/null || true
sudo -u postgres psql -c "CREATE DATABASE ${DB_NAME} OWNER ${DB_USER};" 2>/dev/null || true
}
create_postgresql_tbl() {
echo "Creating database tables..."
PGPASSWORD="${DB_PWD}" psql -h "${DB_HOST}" -p "${DB_PORT}" -U "${DB_USER}" -d "${DB_NAME}" \
-f "${APP_DIR}/server/schema/postgresql/createdb.sql" 2>/dev/null || true
}
update_ds_settings() {
echo "Updating DocumentServer settings..."
local JSON="${CONF_DIR}/local.json"
# Create local.json with all settings
cat > "${JSON}" << EOF
{
"services": {
"CoAuthoring": {
"sql": {
"type": "${DB_TYPE}",
"dbHost": "${DB_HOST}",
"dbPort": "${DB_PORT}",
"dbName": "${DB_NAME}",
"dbUser": "${DB_USER}",
"dbPass": "${DB_PWD}"
},
"redis": {
"host": "${REDIS_SERVER_HOST}",
"port": ${REDIS_SERVER_PORT}
},
"pubsub": {
"maxNumberOfReceivers": "infinity"
},
"token": {
"enable": {
"request": {
"inbox": ${JWT_ENABLED},
"outbox": ${JWT_ENABLED}
},
"browser": ${JWT_ENABLED}
},
"inbox": {
"header": "${JWT_HEADER}",
"inBody": ${JWT_IN_BODY}
},
"outbox": {
"header": "${JWT_HEADER}",
"inBody": ${JWT_IN_BODY}
}
},
"secret": {
"inbox": {
"string": "${JWT_SECRET}"
},
"outbox": {
"string": "${JWT_SECRET}"
},
"session": {
"string": "${JWT_SECRET}"
}
}
}
},
"rabbitmq": {
"url": "${AMQP_SERVER_PROTO}://${AMQP_SERVER_USER}:${AMQP_SERVER_PWD}@${AMQP_SERVER_HOST}:${AMQP_SERVER_PORT}"
},
"wopi": {
"enable": ${WOPI_ENABLED}
}
}
EOF
chown ds:ds "${JSON}"
chmod 644 "${JSON}"
}
# ============================================
# MAIN STARTUP SEQUENCE
# ============================================
echo "============================================"
echo "ONLYOFFICE DocumentServer Startup"
echo "============================================"
echo "Database: ${DB_HOST}:${DB_PORT}/${DB_NAME}"
echo "Redis: ${REDIS_SERVER_HOST}:${REDIS_SERVER_PORT}"
echo "RabbitMQ: ${AMQP_SERVER_HOST}:${AMQP_SERVER_PORT}"
echo "JWT Enabled: ${JWT_ENABLED}"
echo "============================================"
# Create log directories
for i in converter docservice metrics adminpanel; do
mkdir -p "$DS_LOG_DIR/$i" && touch "$DS_LOG_DIR/$i"/{out,err}.log
done
mkdir -p "${DS_LOG_DIR}-example" && touch "${DS_LOG_DIR}-example"/{out,err}.log
# Create app directories
for i in ${DS_LIB_DIR}/App_Data/cache/files ${DS_LIB_DIR}/App_Data/docbuilder ${DS_LIB_DIR}-example/files; do
mkdir -p "$i"
done
# Create data directory
mkdir -p "${DATA_DIR}"
mkdir -p "${PRIVATE_DATA_DIR}"
# Set permissions
chown ds:ds "${DATA_DIR}"
for i in ${DS_LOG_DIR} ${DS_LOG_DIR}-example ${LIB_DIR}; do
chown -R ds:ds "$i"
chmod -R 755 "$i"
done
# Array to track local services that need to be started
LOCAL_SERVICES=()
# Handle database
if [ "${DB_HOST}" = "localhost" ]; then
echo "Starting local PostgreSQL..."
chown -R postgres:postgres ${PG_ROOT}
chmod -R 700 ${PG_ROOT}
if [ ! -d "${PGDATA}" ]; then
create_postgresql_cluster
PG_NEW_CLUSTER=true
fi
LOCAL_SERVICES+=("postgresql")
fi
# Handle RabbitMQ
if [ "${AMQP_SERVER_HOST}" = "localhost" ]; then
echo "Starting local RabbitMQ..."
chown -R rabbitmq:rabbitmq ${RABBITMQ_DATA}
chmod -R go=rX,u=rwX ${RABBITMQ_DATA}
if [ -f ${RABBITMQ_DATA}/.erlang.cookie ]; then
chmod 400 ${RABBITMQ_DATA}/.erlang.cookie
fi
rm -rf /var/run/rabbitmq
LOCAL_SERVICES+=("rabbitmq-server")
fi
# Handle Redis
if [ "${REDIS_ENABLED}" = "true" ] && [ "${REDIS_SERVER_HOST}" = "localhost" ]; then
echo "Starting local Redis..."
chown -R redis:redis ${REDIS_DATA}
chmod -R 750 ${REDIS_DATA}
LOCAL_SERVICES+=("redis-server")
fi
# Start local services
for i in ${LOCAL_SERVICES[@]}; do
echo "Starting service: $i"
service $i start
done
# Wait for and initialize database
if [ "${DB_HOST}" = "localhost" ]; then
sleep 3
if [ "${PG_NEW_CLUSTER}" = "true" ]; then
create_postgresql_db
create_postgresql_tbl
fi
else
waiting_for_db
# Check if tables exist, if not create them
PGPASSWORD="${DB_PWD}" psql -h "${DB_HOST}" -p "${DB_PORT}" -U "${DB_USER}" -d "${DB_NAME}" \
-c "SELECT 1 FROM doc_changes LIMIT 1" 2>/dev/null || create_postgresql_tbl
fi
# Wait for other services
waiting_for_amqp
if [ "${REDIS_ENABLED}" = "true" ]; then
waiting_for_redis
fi
# Update DocumentServer configuration
update_ds_settings
# Configure nginx
echo "Configuring Nginx..."
NGINX_ONLYOFFICE_PATH="${CONF_DIR}/nginx"
NGINX_ONLYOFFICE_CONF="${NGINX_ONLYOFFICE_PATH}/ds.conf"
ln -sf ${NGINX_ONLYOFFICE_PATH}/ds.conf.tmpl ${NGINX_ONLYOFFICE_CONF}
# Install plugins if enabled
if [ "${PLUGINS_ENABLED}" = "true" ]; then
echo "Installing plugins..."
start_process documentserver-pluginsmanager.sh -r false --update=\"${APP_DIR}/sdkjs-plugins/plugin-list-default.json\" >/dev/null 2>&1 || true
echo "Plugins installed."
fi
# Configure ds-example if enabled
if [ "${DS_EXAMPLE}" = "true" ]; then
echo "Enabling test example service..."
cat > /etc/supervisor/conf.d/ds-example.conf <<EOF
[program:ds-example]
command=/var/www/onlyoffice/documentserver-example/example
directory=/var/www/onlyoffice/documentserver-example
user=ds
autostart=true
autorestart=true
startsecs=5
stopwaitsecs=10
killasgroup=true
stopasgroup=true
stdout_logfile=/var/log/${COMPANY_NAME}/documentserver-example/out.log
stderr_logfile=/var/log/${COMPANY_NAME}/documentserver-example/err.log
stdout_logfile_maxbytes=10MB
stderr_logfile_maxbytes=10MB
environment=NODE_ENV="production-linux",NODE_CONFIG_DIR="/var/www/onlyoffice/documentserver-example/config"
EOF
# Create log directory for example
mkdir -p /var/log/${COMPANY_NAME}/documentserver-example
chown -R ds:ds /var/log/${COMPANY_NAME}/documentserver-example
fi
# Start supervisor (manages DocService, Converter, etc.)
echo "Starting Supervisor..."
service supervisor start
# Start cron for log rotation
service cron start
# Flush cache
start_process documentserver-flush-cache.sh -r false 2>/dev/null || true
# Start nginx
echo "Starting Nginx..."
service nginx start
# Generate fonts if enabled
if [ "${GENERATE_FONTS}" = "true" ]; then
echo "Generating fonts..."
start_process documentserver-generate-allfonts.sh false >/dev/null 2>&1 || true
echo "Fonts generated."
fi
# Compress static files
start_process documentserver-static-gzip.sh false >/dev/null 2>&1 || true
echo "============================================"
echo "ONLYOFFICE DocumentServer is ready!"
echo "Access at: http://localhost"
if [ "${JWT_ENABLED}" = "true" ]; then
echo "JWT Secret: ${JWT_SECRET}"
fi
echo "============================================"
# Keep container running and tail logs
exec tail -F ${DS_LOG_DIR}/docservice/out.log ${DS_LOG_DIR}/converter/out.log 2>/dev/null