{"id":459638,"date":"2025-05-14T15:00:17","date_gmt":"2025-05-14T15:00:17","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=459638"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=459638","title":{"rendered":"<span>BookStack: \u043c\u043e\u0439 \u043e\u043f\u044b\u0442 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f open-source \u0431\u0430\u0437\u044b \u0437\u043d\u0430\u043d\u0438\u0439<\/span>"},"content":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<h4>\u041f\u043e\u0447\u0435\u043c\u0443 \u044f \u0432\u044b\u0431\u0440\u0430\u043b \u0438\u043c\u0435\u043d\u043d\u043e BookStack<\/h4>\n<p>\u041c\u044b \u0432 \u043a\u043e\u043c\u0430\u043d\u0434\u0435 \u0434\u0430\u0432\u043d\u043e \u0438\u0441\u043a\u0430\u043b\u0438 \u0443\u0434\u043e\u0431\u043d\u044b\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u0434\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0442\u0435\u0445\u043d\u0438\u0447\u0435\u0441\u043a\u043e\u0439 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 \u0438 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0439. \u041f\u0440\u043e\u0431\u043e\u0432\u0430\u043b\u0438 \u0432\u0441\u0451 \u043f\u043e\u0434\u0440\u044f\u0434 \u2014 \u043e\u0442 Wiki.js \u0434\u043e Confluence. \u041d\u043e \u0442\u043e \u0441\u0430\u043d\u043a\u0446\u0438\u0438, \u0442\u043e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u043f\u0435\u0440\u0435\u0433\u0440\u0443\u0436\u0435\u043d, \u0442\u043e \u043a\u0430\u0441\u0442\u043e\u043c\u0438\u0437\u0430\u0446\u0438\u044f \u0441\u0442\u0440\u0430\u0434\u0430\u0435\u0442. \u0412 \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u043c\u043e\u043c\u0435\u043d\u0442 \u044f \u043d\u0430\u0442\u043a\u043d\u0443\u043b\u0441\u044f \u043d\u0430 <a href=\"https:\/\/www.bookstackapp.com\/\" rel=\"noopener noreferrer nofollow\">BookStack<\/a> \u2014 \u043b\u0451\u0433\u043a\u0443\u044e, \u0441\u0438\u043c\u043f\u0430\u0442\u0438\u0447\u043d\u0443\u044e open-source \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0443 \u043d\u0430 Laravel. \u0420\u0435\u0448\u0438\u043b \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c. \u0412 \u0438\u0442\u043e\u0433\u0435 \u2014 \u0440\u0430\u0437\u0432\u0435\u0440\u043d\u0443\u043b, \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u043b, \u0438 \u0442\u0435\u043f\u0435\u0440\u044c \u043e\u043d\u0430 \u0443 \u043d\u0430\u0441 \u0432 \u043f\u0440\u043e\u0434\u0435.<\/p>\n<p>\u0420\u0430\u0441\u0441\u043a\u0430\u0436\u0443, \u043a\u0430\u043a \u044d\u0442\u043e \u0431\u044b\u043b\u043e.<\/p>\n<h3>\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 BookStack \u043d\u0430 Ubuntu 24.04 (\u0447\u0435\u0440\u0435\u0437 \u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0439 \u0441\u043a\u0440\u0438\u043f\u0442)<\/h3>\n<p>\u0421\u0430\u043c\u044b\u0439 \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0438 \u0431\u044b\u0441\u0442\u0440\u044b\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u0440\u0430\u0437\u0432\u0435\u0440\u043d\u0443\u0442\u044c BookStack \u2014 \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f <strong>\u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u043c bash-\u0441\u043a\u0440\u0438\u043f\u0442\u043e\u043c<\/strong>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0438\u0440\u0443\u0435\u0442 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0443 \u0432\u0441\u0435\u0445 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439 \u0438 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044e. \u042f \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u043b \u044d\u0442\u043e \u043d\u0430 <strong>\u0447\u0438\u0441\u0442\u043e\u0439 Ubuntu 24.04<\/strong> \u2014 \u0432\u0441\u0451 \u0437\u0430\u0440\u0430\u0431\u043e\u0442\u0430\u043b\u043e \u0431\u0435\u0437 \u043f\u0440\u043e\u0431\u043b\u0435\u043c.<\/p>\n<h4>1. \u041f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0430 \u0441\u0438\u0441\u0442\u0435\u043c\u044b<\/h4>\n<p>\u041f\u0435\u0440\u0435\u0434 \u043d\u0430\u0447\u0430\u043b\u043e\u043c \u0443\u0431\u0435\u0434\u0438\u0442\u0435\u0441\u044c, \u0447\u0442\u043e \u0443 \u0432\u0430\u0441:<\/p>\n<ul>\n<li>\n<p>Ubuntu 24.04 (\u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f)<\/p>\n<\/li>\n<li>\n<p>\u041f\u0440\u0430\u0432\u0430 root \u0438\u043b\u0438 <code>sudo<\/code><\/p>\n<\/li>\n<li>\n<p>\u0418\u043d\u0442\u0435\u0440\u043d\u0435\u0442-\u0434\u043e\u0441\u0442\u0443\u043f \u0434\u043b\u044f \u0441\u043a\u0430\u0447\u0438\u0432\u0430\u043d\u0438\u044f \u0441\u043a\u0440\u0438\u043f\u0442\u0430<\/p>\n<\/li>\n<\/ul>\n<p>\u041e\u0431\u043d\u043e\u0432\u0438\u043c \u043f\u0430\u043a\u0435\u0442\u044b:<\/p>\n<pre><code class=\"bash\">sudo apt update &amp;&amp; sudo apt upgrade -y<\/code><\/pre>\n<p>\u0421\u043a\u0440\u0438\u043f\u0442 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 Ubuntu 24.04:<\/p>\n<pre><code class=\"bash\"># \u0421\u043a\u0430\u0447\u0430\u0442\u044c \u0441\u043a\u0440\u0438\u043f\u0442 wget https:\/\/codeberg.org\/bookstack\/devops\/raw\/branch\/main\/scripts\/installation-ubuntu-24.04.sh  # \u0421\u0434\u0435\u043b\u0430\u0442\u044c \u0435\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u043d\u044f\u0435\u043c\u044b\u043c chmod a+x installation-ubuntu-24.04.sh  # \u0417\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0441\u043a\u0440\u0438\u043f\u0442 \u0441 \u043f\u0440\u0430\u0432\u0430\u043c\u0438 \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u0430 sudo .\/installation-ubuntu-24.04.sh<\/code><\/pre>\n<div class=\"tm-iframe_temp\" data-src=\"https:\/\/embedd.srv.habr.com\/iframe\/682182578f844fa824a8a309\" data-style=\"\" id=\"682182578f844fa824a8a309\" width=\"\"><\/div>\n<p>\u0427\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442 \u0441\u043a\u0440\u0438\u043f\u0442: <br \/><a href=\"https:\/\/codeberg.org\/bookstack\/devops\/src\/branch\/main\/scripts\/installation-ubuntu-24.04.sh\" rel=\"noopener noreferrer nofollow\">\u0421\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u0441\u043a\u0440\u0438\u043f\u0442<\/a>  <\/p>\n<pre><code class=\"bash\">#!\/bin\/bash  echo \"This script installs a new BookStack instance on a fresh Ubuntu 24.04 server.\" echo \"This script does not ensure system security.\" echo \"\"  # \u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043f\u0443\u0442\u0438 \u0434\u043b\u044f \u0444\u0430\u0439\u043b\u0430 \u043b\u043e\u0433\u0430 \u0434\u043b\u044f \u043e\u0442\u043b\u0430\u0434\u043a\u0438 LOGPATH=$(realpath \"bookstack_install_$(date +%s).log\")  # \u041f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f, \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u044e\u0449\u0435\u0433\u043e \u0441\u043a\u0440\u0438\u043f\u0442 SCRIPT_USER=\"${SUDO_USER:-$USER}\"  # \u041f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 IP-\u0430\u0434\u0440\u0435\u0441\u0430 \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u043c\u0430\u0448\u0438\u043d\u044b CURRENT_IP=$(ip addr | grep 'state UP' -A4 | grep 'inet ' | awk '{print $2}' | cut -f1  -d'\/')  # \u0413\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u043f\u0430\u0440\u043e\u043b\u044f \u0434\u043b\u044f \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445 DB_PASS=\"$(head \/dev\/urandom | tr -dc A-Za-z0-9 | head -c 13)\"  # \u041a\u0430\u0442\u0430\u043b\u043e\u0433 \u0434\u043b\u044f \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 BookStack BOOKSTACK_DIR=\"\/var\/www\/bookstack\"  # \u041f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0434\u043e\u043c\u0435\u043d\u0430 \u0438\u0437 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u0432 (\u0437\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u043e\u0437\u0436\u0435, \u0435\u0441\u043b\u0438 \u043d\u0435 \u0443\u043a\u0430\u0437\u0430\u043d\u043e) DOMAIN=$1  # \u041f\u0440\u0435\u0434\u043e\u0442\u0432\u0440\u0430\u0449\u0435\u043d\u0438\u0435 \u0438\u043d\u0442\u0435\u0440\u0430\u043a\u0442\u0438\u0432\u043d\u044b\u0445 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u0445 export DEBIAN_FRONTEND=noninteractive  # \u0412\u044b\u0432\u043e\u0434 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043e\u0431 \u043e\u0448\u0438\u0431\u043a\u0435 \u0432 \u043a\u043e\u043c\u0430\u043d\u0434\u043d\u0443\u044e \u0441\u0442\u0440\u043e\u043a\u0443 \u0438 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u0435 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b # \u0422\u0430\u043a\u0436\u0435 \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0432 \u0444\u0430\u0439\u043b \u043b\u043e\u0433\u0430 function error_out() {   echo \"ERROR: $1\" | tee -a \"$LOGPATH\" 1&gt;&amp;2   exit 1 }  # \u0412\u044b\u0432\u043e\u0434 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0433\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0432 \u043a\u043e\u043c\u0430\u043d\u0434\u043d\u0443\u044e \u0441\u0442\u0440\u043e\u043a\u0443 \u0438 \u0444\u0430\u0439\u043b \u043b\u043e\u0433\u0430 function info_msg() {   echo \"$1\" | tee -a \"$LOGPATH\" }  # \u0412\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u043e\u043a \u043f\u0435\u0440\u0435\u0434 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u043e\u0439, \u0447\u0442\u043e\u0431\u044b \u0438\u0437\u0431\u0435\u0436\u0430\u0442\u044c \u043d\u0430\u0440\u0443\u0448\u0435\u043d\u0438\u044f \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0439 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0432\u0435\u0431-\u0441\u0435\u0440\u0432\u0435\u0440\u0430 function run_pre_install_checks() {   # \u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430, \u0437\u0430\u043f\u0443\u0449\u0435\u043d \u043b\u0438 \u0441\u043a\u0440\u0438\u043f\u0442 \u043e\u0442 \u0438\u043c\u0435\u043d\u0438 root, \u0438 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u0435, \u0435\u0441\u043b\u0438 \u043d\u0435\u0442   if [[ $EUID -gt 0 ]]   then     error_out \"This script must be ran with root\/sudo privileges\"   fi    # \u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430, \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d \u043b\u0438 Apache, \u0438 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u0435, \u0435\u0441\u043b\u0438 \u043e\u043d \u0443\u0436\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d   if [ -d \"\/etc\/apache2\/sites-enabled\" ]   then     error_out \"This script is intended for a fresh server install, existing apache config found, aborting install\"   fi    # \u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430, \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u0430 \u043b\u0438 MySQL, \u0438 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u0435, \u0435\u0441\u043b\u0438 \u0434\u0430\u043d\u043d\u044b\u0435 MySQL \u0443\u0436\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0442   if [ -d \"\/var\/lib\/mysql\" ]   then     error_out \"This script is intended for a fresh server install, existing MySQL data found, aborting install\"   fi }  # \u041f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0434\u043e\u043c\u0435\u043d\u0430 \u0438\u0437 \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u043d\u043e\u0433\u043e \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430 \u0438\u043b\u0438 \u0437\u0430\u043f\u0440\u043e\u0441 \u0432\u0432\u043e\u0434\u0430 \u0434\u043e\u043c\u0435\u043d\u0430 \u0443 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f function run_prompt_for_domain_if_required() {   if [ -z \"$DOMAIN\" ]   then     info_msg \"\"     info_msg \"Enter the domain (or IP if not using a domain) you want to host BookStack on and press [ENTER].\"     info_msg \"Examples: my-site.com or docs.my-site.com or ${CURRENT_IP}\"     read -r DOMAIN   fi    # \u0417\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u0435 \u0441 \u043e\u0448\u0438\u0431\u043a\u043e\u0439, \u0435\u0441\u043b\u0438 \u0434\u043e\u043c\u0435\u043d \u043d\u0435 \u0443\u043a\u0430\u0437\u0430\u043d   if [ -z \"$DOMAIN\" ]   then     error_out \"A domain must be provided to run this script\"   fi }  # \u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0445 \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u044b\u0445 \u043f\u0430\u043a\u0435\u0442\u043e\u0432 function run_package_installs() {   apt update   apt install -y git unzip apache2 curl mysql-server-8.0 php8.3 \\   php8.3-fpm php8.3-curl php8.3-mbstring php8.3-ldap php8.3-xml php8.3-zip php8.3-gd php8.3-mysql }  # \u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445 function run_database_setup() {   # \u0423\u0431\u0435\u0434\u0438\u0442\u044c\u0441\u044f, \u0447\u0442\u043e \u0441\u043b\u0443\u0436\u0431\u0430 \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445 \u0437\u0430\u043f\u0443\u0449\u0435\u043d\u0430   systemctl start mysql-server.service   sleep 3    # \u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0439 \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445, \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0438 \u043f\u0440\u0430\u0432 \u0434\u043e\u0441\u0442\u0443\u043f\u0430   mysql -u root --execute=\"CREATE DATABASE bookstack;\"   mysql -u root --execute=\"CREATE USER 'bookstack'@'localhost' IDENTIFIED WITH mysql_native_password BY '$DB_PASS';\"   mysql -u root --execute=\"GRANT ALL ON bookstack.* TO 'bookstack'@'localhost';FLUSH PRIVILEGES;\" }  # \u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430 BookStack function run_bookstack_download() {   cd \/var\/www || exit   git clone https:\/\/github.com\/BookStackApp\/BookStack.git --branch release --single-branch bookstack }  # \u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 Composer function run_install_composer() {   EXPECTED_CHECKSUM=\"$(php -r 'copy(\"https:\/\/composer.github.io\/installer.sig\", \"php:\/\/stdout\");')\"   php -r \"copy('https:\/\/getcomposer.org\/installer', 'composer-setup.php');\"   ACTUAL_CHECKSUM=\"$(php -r \"echo hash_file('sha384', 'composer-setup.php');\")\"    if [ \"$EXPECTED_CHECKSUM\" != \"$ACTUAL_CHECKSUM\" ]   then       &gt;&amp;2 echo 'ERROR: Invalid composer installer checksum'       rm composer-setup.php       exit 1   fi    php composer-setup.php --quiet   rm composer-setup.php    # \u041f\u0435\u0440\u0435\u043c\u0435\u0449\u0435\u043d\u0438\u0435 Composer \u0432 \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u0443\u044e \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0443   mv composer.phar \/usr\/local\/bin\/composer }  # \u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439 BookStack \u0447\u0435\u0440\u0435\u0437 Composer function run_install_bookstack_composer_deps() {   cd \"$BOOKSTACK_DIR\" || exit   export COMPOSER_ALLOW_SUPERUSER=1   php \/usr\/local\/bin\/composer install --no-dev --no-plugins }  # \u041a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f BookStack function run_update_bookstack_env() {   cd \"$BOOKSTACK_DIR\" || exit   cp .env.example .env   sed -i.bak \"s@APP_URL=.*\\$@APP_URL=http:\/\/$DOMAIN@\" .env   sed -i.bak 's\/DB_DATABASE=.*$\/DB_DATABASE=bookstack\/' .env   sed -i.bak 's\/DB_USERNAME=.*$\/DB_USERNAME=bookstack\/' .env   sed -i.bak \"s\/DB_PASSWORD=.*\\$\/DB_PASSWORD=$DB_PASS\/\" .env   # \u0413\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u043a\u043b\u044e\u0447\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f   php artisan key:generate --no-interaction --force }  # \u0412\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u043f\u0435\u0440\u0432\u043e\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u044b\u0445 \u043c\u0438\u0433\u0440\u0430\u0446\u0438\u0439 \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445 BookStack function run_bookstack_database_migrations() {   cd \"$BOOKSTACK_DIR\" || exit   php artisan migrate --no-interaction --force }  # \u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u043f\u0440\u0430\u0432 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a \u0444\u0430\u0439\u043b\u0430\u043c \u0438 \u043f\u0430\u043f\u043a\u0430\u043c # \u0423\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442 \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043a\u0430\u043a \u0432\u043b\u0430\u0434\u0435\u043b\u044c\u0446\u0430 \u0438 \u0433\u0440\u0443\u043f\u043f\u0443 www-data \u043a\u0430\u043a \u0432\u043b\u0430\u0434\u0435\u043b\u044c\u0446\u0430 \u0433\u0440\u0443\u043f\u043f\u044b, # \u0437\u0430\u0442\u0435\u043c \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0433\u0440\u0443\u043f\u043f\u0435 \u043f\u0440\u0430\u0432\u0430 \u043d\u0430 \u0437\u0430\u043f\u0438\u0441\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0445 \u043a\u0430\u0442\u0430\u043b\u043e\u0433\u043e\u0432. # \u0421\u043a\u0440\u044b\u0432\u0430\u0435\u0442 \u0444\u0430\u0439\u043b `.env`, \u0447\u0442\u043e\u0431\u044b \u043e\u043d \u043d\u0435 \u0431\u044b\u043b \u0432\u0438\u0434\u0435\u043d \u0434\u0440\u0443\u0433\u0438\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\u043c \u0432 \u0441\u0438\u0441\u0442\u0435\u043c\u0435. function run_set_application_file_permissions() {   cd \"$BOOKSTACK_DIR\" || exit   chown -R \"$SCRIPT_USER\":www-data .\/   chmod -R 755 .\/   chmod -R 775 bootstrap\/cache public\/uploads storage   chmod 740 .env    # \u0423\u043a\u0430\u0437\u0430\u043d\u0438\u0435 git \u0438\u0433\u043d\u043e\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043f\u0440\u0430\u0432 \u0434\u043e\u0441\u0442\u0443\u043f\u0430   git config core.fileMode false }  # \u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 Apache \u0441 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u043c\u0438 \u043c\u043e\u0434\u0443\u043b\u044f\u043c\u0438 \u0438 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0435\u0439 function run_configure_apache() {   # \u0412\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0445 \u043c\u043e\u0434\u0443\u043b\u0435\u0439 \u0438 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 Apache   a2enmod rewrite proxy_fcgi setenvif   a2enconf php8.3-fpm    # \u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0439 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 Apache \u0434\u043b\u044f BookStack   cat &gt;\/etc\/apache2\/sites-available\/bookstack.conf &lt;&lt;EOL &lt;VirtualHost *:80&gt;   ServerName ${DOMAIN}    ServerAdmin webmaster@localhost   DocumentRoot \/var\/www\/bookstack\/public\/    &lt;Directory \/var\/www\/bookstack\/public\/&gt;       Options -Indexes +FollowSymLinks       AllowOverride None       Require all granted       &lt;IfModule mod_rewrite.c&gt;           &lt;IfModule mod_negotiation.c&gt;               Options -MultiViews -Indexes           &lt;\/IfModule&gt;            RewriteEngine On            # Handle Authorization Header           RewriteCond %{HTTP:Authorization} .           RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]            # Redirect Trailing Slashes If Not A Folder...           RewriteCond %{REQUEST_FILENAME} !-d           RewriteCond %{REQUEST_URI} (.+)\/$           RewriteRule ^ %1 [L,R=301]            # Handle Front Controller...           RewriteCond %{REQUEST_FILENAME} !-d           RewriteCond %{REQUEST_FILENAME} !-f           RewriteRule ^ index.php [L]       &lt;\/IfModule&gt;   &lt;\/Directory&gt;    ErrorLog \\${APACHE_LOG_DIR}\/error.log   CustomLog \\${APACHE_LOG_DIR}\/access.log combined  &lt;\/VirtualHost&gt; EOL    # \u041e\u0442\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0441\u0430\u0439\u0442\u0430 Apache \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0438 \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 BookStack   a2dissite 000-default.conf   a2ensite bookstack.conf    # \u041f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a Apache \u0434\u043b\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043d\u043e\u0432\u043e\u0439 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438   systemctl restart apache2   # \u0423\u0431\u0435\u0434\u0438\u0442\u044c\u0441\u044f, \u0447\u0442\u043e \u0441\u043b\u0443\u0436\u0431\u0430 php-fpm \u0437\u0430\u043f\u0443\u0449\u0435\u043d\u0430   systemctl start php8.3-fpm.service }  info_msg \"This script logs full output to $LOGPATH which may help upon issues.\" sleep 1  run_pre_install_checks run_prompt_for_domain_if_required info_msg \"\" info_msg \"Installing using the domain or IP \\\"$DOMAIN\\\"\" info_msg \"\" sleep 1  info_msg \"[1\/9] Installing required system packages... (This may take several minutes)\" run_package_installs &gt;&gt; \"$LOGPATH\" 2&gt;&amp;1  info_msg \"[2\/9] Preparing MySQL database...\" run_database_setup &gt;&gt; \"$LOGPATH\" 2&gt;&amp;1  info_msg \"[3\/9] Downloading BookStack to ${BOOKSTACK_DIR}...\" run_bookstack_download &gt;&gt; \"$LOGPATH\" 2&gt;&amp;1  info_msg \"[4\/9] Installing Composer (PHP dependency manager)...\" run_install_composer &gt;&gt; \"$LOGPATH\" 2&gt;&amp;1  info_msg \"[5\/9] Installing PHP dependencies using composer...\" run_install_bookstack_composer_deps &gt;&gt; \"$LOGPATH\" 2&gt;&amp;1  info_msg \"[6\/9] Creating and populating BookStack .env file...\" run_update_bookstack_env &gt;&gt; \"$LOGPATH\" 2&gt;&amp;1  info_msg \"[7\/9] Running initial BookStack database migrations...\" run_bookstack_database_migrations &gt;&gt; \"$LOGPATH\" 2&gt;&amp;1  info_msg \"[8\/9] Setting BookStack file &amp; folder permissions...\" run_set_application_file_permissions &gt;&gt; \"$LOGPATH\" 2&gt;&amp;1  info_msg \"[9\/9] Configuring apache server...\" run_configure_apache &gt;&gt; \"$LOGPATH\" 2&gt;&amp;1  info_msg \"----------------------------------------------------------------\" info_msg \"Setup finished, your BookStack instance should now be installed!\" info_msg \"- Default login email: admin@admin.com\" info_msg \"- Default login password: password\" info_msg \"- Access URL: http:\/\/$CURRENT_IP\/ or http:\/\/$DOMAIN\/\" info_msg \"- BookStack install path: $BOOKSTACK_DIR\" info_msg \"- Install script log: $LOGPATH\" info_msg \"---------------------------------------------------------------\"<\/code><\/pre>\n<h4>\u0417\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438<\/h4>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 BookStack \u0431\u0443\u0434\u0435\u0442 \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d \u043f\u043e IP-\u0430\u0434\u0440\u0435\u0441\u0443 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 (\u0438\u043b\u0438 \u0434\u043e\u043c\u0435\u043d\u0443, \u0435\u0441\u043b\u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043d). \u041f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e:<\/p>\n<ul>\n<li>\n<p>\u041b\u043e\u0433\u0438\u043d: <a href=\"mailto:admin@admin.com\" rel=\"noopener noreferrer nofollow\"><code>admin@admin.com<\/code><\/a><\/p>\n<\/li>\n<li>\n<p>\u041f\u0430\u0440\u043e\u043b\u044c: <code>password<\/code> (\u0435\u0433\u043e \u043d\u0430\u0434\u043e \u0441\u043c\u0435\u043d\u0438\u0442\u044c \u0441\u0440\u0430\u0437\u0443 \u0436\u0435!)<\/p>\n<\/li>\n<\/ul>\n<p>\u0415\u0441\u043b\u0438 \u0445\u043e\u0442\u0438\u0442\u0435 \u043f\u043e\u043c\u0435\u043d\u044f\u0442\u044c URL, \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0438, \u044f\u0437\u044b\u043a, \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0438 \u043f\u0440\u043e\u0447\u0435\u0435 \u2014 \u0432\u0441\u0451 \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0432 <code>.env<\/code> \u0444\u0430\u0439\u043b\u0435 \u043f\u043e \u043f\u0443\u0442\u0438 <code>\/var\/www\/bookstack\/.env<\/code>.<\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440:<\/p>\n<pre><code class=\"bash\">APP_URL=http:\/\/10.50.10.188 APP_LANG=ru FILE_UPLOAD_SIZE_LIMIT=50<\/code><\/pre>\n<p> \u041f\u043e\u0441\u043b\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 \u043d\u0435 \u0437\u0430\u0431\u0443\u0434\u044c\u0442\u0435:  <\/p>\n<pre><code class=\"bash\">php artisan config:clear php artisan cache:clear<\/code><\/pre>\n<h4>\u041a\u0430\u043a \u0443\u0441\u0442\u0440\u043e\u0435\u043d\u0430 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0432 BookStack \u0438 \u043f\u043e\u0447\u0435\u043c\u0443 \u043e\u043d\u0430 \u0443\u0434\u043e\u0431\u043d\u0430\u044f<\/h4>\n<p>\u0412\u0441\u0451 \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u043e \u043f\u043e \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u0443 \u00ab\u043a\u0430\u043a \u0432 \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u0445 \u043a\u043d\u0438\u0433\u0430\u0445\u00bb. \u0415\u0441\u0442\u044c <strong>\u041f\u043e\u043b\u043a\u0438<\/strong>, <strong>\u041a\u043d\u0438\u0433\u0438<\/strong>, <strong>\u0413\u043b\u0430\u0432\u044b<\/strong> \u0438 <strong>\u0421\u0442\u0440\u0430\u043d\u0438\u0446\u044b<\/strong>. \u041c\u043d\u0435 \u044d\u0442\u043e \u0441\u0440\u0430\u0437\u0443 \u0437\u0430\u0448\u043b\u043e \u2014 \u043b\u0435\u0433\u043a\u043e \u043e\u0431\u044a\u044f\u0441\u043d\u0438\u0442\u044c \u043a\u043e\u043b\u043b\u0435\u0433\u0430\u043c, \u0433\u0434\u0435 \u0447\u0442\u043e \u043b\u0435\u0436\u0438\u0442.<\/p>\n<p>\u0423 \u043d\u0430\u0441, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440:<\/p>\n<ul>\n<li>\n<p>\u041f\u043e\u043b\u043a\u0430 <code>DevOps<\/code><\/p>\n<ul>\n<li>\n<p>\u041a\u043d\u0438\u0433\u0430 <code>CI\/CD<\/code><\/p>\n<ul>\n<li>\n<p>\u0413\u043b\u0430\u0432\u0430 <code>GitLab<\/code><\/p>\n<ul>\n<li>\n<p>\u0421\u0442\u0440\u0430\u043d\u0438\u0446\u0430 <code>\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0434\u0435\u043f\u043b\u043e\u0439<\/code><\/p>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/acc\/877\/037\/acc877037e59f28813894f14bd2e5d76.gif\" alt=\"\" title=\"\" width=\"1703\" height=\"878\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/acc\/877\/037\/acc877037e59f28813894f14bd2e5d76.gif 780w,&#10;       https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/acc\/877\/037\/acc877037e59f28813894f14bd2e5d76.gif 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<p>\u0420\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0431\u044b\u0441\u0442\u0440\u043e, \u0438\u0441\u043a\u0430\u0442\u044c \u0443\u0434\u043e\u0431\u043d\u043e, \u0435\u0441\u0442\u044c \u0434\u0430\u0436\u0435 \u0441\u0441\u044b\u043b\u043a\u0438 \u043d\u0430 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0435 \u0430\u0431\u0437\u0430\u0446\u044b.<\/p>\n<h4>\u041f\u043e\u0447\u0435\u043c\u0443 \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440\u044b \u2014 \u044d\u0442\u043e \u043a\u0430\u0439\u0444<\/h4>\n<p>\u0414\u0432\u0430 \u0440\u0435\u0436\u0438\u043c\u0430:<\/p>\n<ul>\n<li>\n<p>\u0414\u043b\u044f \u043a\u043e\u043b\u043b\u0435\u0433, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0435 \u043b\u044e\u0431\u044f\u0442 \u0440\u0430\u0437\u043c\u0435\u0442\u043a\u0443 \u2014 WYSIWYG.<\/p>\n<\/li>\n<li>\n<p>\u0414\u043b\u044f \u043c\u0435\u043d\u044f \u2014 Markdown. \u041f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0430 \u043f\u043e\u0434\u0441\u0432\u0435\u0442\u043a\u0438 \u043a\u043e\u0434\u0430, live preview, \u0432\u0441\u0442\u0430\u0432\u043a\u0430 \u0441\u043d\u0438\u043f\u043f\u0435\u0442\u043e\u0432 \u2014 \u043e\u0447\u0435\u043d\u044c \u0443\u0434\u043e\u0431\u043d\u043e.<\/p>\n<\/li>\n<\/ul>\n<h4>\u0411\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u044c, \u043f\u0440\u0430\u0432\u0430 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u0438 \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u0438<\/h4>\n<p>BookStack \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0433\u0438\u0431\u043a\u043e \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f\u043e\u043c. \u0423 \u043d\u0430\u0441, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043e\u0442\u0434\u0435\u043b \u043f\u0440\u043e\u0434\u0430\u0436 \u043c\u043e\u0436\u0435\u0442 \u0447\u0438\u0442\u0430\u0442\u044c, \u043d\u043e \u043d\u0435 \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c, \u0430 \u0442\u0435\u0445\u043e\u0442\u0434\u0435\u043b \u0438\u043c\u0435\u0435\u0442 \u043f\u043e\u043b\u043d\u044b\u0439 \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u0441\u0432\u043e\u0438\u043c \u0440\u0430\u0437\u0434\u0435\u043b\u0430\u043c.<\/p>\n<p>\u0410\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044e \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u043b\u0438 \u0447\u0435\u0440\u0435\u0437 GitHub \u2014 \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u043b\u0435\u0433\u043a\u043e, \u0432 \u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0439 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 \u0432\u0441\u0451 \u0435\u0441\u0442\u044c.<\/p>\n<h4>\u0427\u0442\u043e \u0435\u0449\u0451 \u043a\u0440\u0443\u0442\u043e<\/h4>\n<ul>\n<li>\n<p>\u0415\u0441\u0442\u044c REST API \u2014 \u043c\u043e\u0436\u043d\u043e \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0441\u0442\u0440\u0430\u043d\u0438\u0446<\/p>\n<\/li>\n<li>\n<p>\u0415\u0441\u0442\u044c dark mode \u2014 \u043a\u043e\u043b\u043b\u0435\u0433\u0438 \u043a\u0430\u0439\u0444\u0443\u044e\u0442 \ud83d\ude42<\/p>\n<\/li>\n<li>\n<p>\u0420\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0448\u0443\u0441\u0442\u0440\u043e \u0434\u0430\u0436\u0435 \u043d\u0430 \u0441\u043b\u0430\u0431\u043e\u043c VPS<\/p>\n<\/li>\n<\/ul>\n<h4>\u0412\u044b\u0432\u043e\u0434<\/h4>\n<p>\u0415\u0441\u043b\u0438 \u0432\u044b \u0438\u0449\u0435\u0442\u0435 \u043f\u0440\u043e\u0441\u0442\u0443\u044e, \u0443\u0434\u043e\u0431\u043d\u0443\u044e \u0438 \u043a\u0440\u0430\u0441\u0438\u0432\u0443\u044e \u0431\u0430\u0437\u0443 \u0437\u043d\u0430\u043d\u0438\u0439 \u2014 \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0439\u0442\u0435 BookStack. \u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u0437\u0430\u043d\u0438\u043c\u0430\u0435\u0442 10 \u043c\u0438\u043d\u0443\u0442, \u0430 \u043f\u043e\u043b\u044c\u0437\u044b \u2014 \u043c\u043e\u0440\u0435. \u0423 \u043d\u0430\u0441 \u044d\u0442\u043e \u0441\u0442\u0430\u043b must-have \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u0432 \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0435.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/909222\/\"> https:\/\/habr.com\/ru\/articles\/909222\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<h4>\u041f\u043e\u0447\u0435\u043c\u0443 \u044f \u0432\u044b\u0431\u0440\u0430\u043b \u0438\u043c\u0435\u043d\u043d\u043e BookStack<\/h4>\n<p>\u041c\u044b \u0432 \u043a\u043e\u043c\u0430\u043d\u0434\u0435 \u0434\u0430\u0432\u043d\u043e \u0438\u0441\u043a\u0430\u043b\u0438 \u0443\u0434\u043e\u0431\u043d\u044b\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u0434\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0442\u0435\u0445\u043d\u0438\u0447\u0435\u0441\u043a\u043e\u0439 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 \u0438 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0439. \u041f\u0440\u043e\u0431\u043e\u0432\u0430\u043b\u0438 \u0432\u0441\u0451 \u043f\u043e\u0434\u0440\u044f\u0434 \u2014 \u043e\u0442 Wiki.js \u0434\u043e Confluence. \u041d\u043e \u0442\u043e \u0441\u0430\u043d\u043a\u0446\u0438\u0438, \u0442\u043e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u043f\u0435\u0440\u0435\u0433\u0440\u0443\u0436\u0435\u043d, \u0442\u043e \u043a\u0430\u0441\u0442\u043e\u043c\u0438\u0437\u0430\u0446\u0438\u044f \u0441\u0442\u0440\u0430\u0434\u0430\u0435\u0442. \u0412 \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u043c\u043e\u043c\u0435\u043d\u0442 \u044f \u043d\u0430\u0442\u043a\u043d\u0443\u043b\u0441\u044f \u043d\u0430 <a href=\"https:\/\/www.bookstackapp.com\/\" rel=\"noopener noreferrer nofollow\">BookStack<\/a> \u2014 \u043b\u0451\u0433\u043a\u0443\u044e, \u0441\u0438\u043c\u043f\u0430\u0442\u0438\u0447\u043d\u0443\u044e open-source \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0443 \u043d\u0430 Laravel. \u0420\u0435\u0448\u0438\u043b \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c. \u0412 \u0438\u0442\u043e\u0433\u0435 \u2014 \u0440\u0430\u0437\u0432\u0435\u0440\u043d\u0443\u043b, \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u043b, \u0438 \u0442\u0435\u043f\u0435\u0440\u044c \u043e\u043d\u0430 \u0443 \u043d\u0430\u0441 \u0432 \u043f\u0440\u043e\u0434\u0435.<\/p>\n<p>\u0420\u0430\u0441\u0441\u043a\u0430\u0436\u0443, \u043a\u0430\u043a \u044d\u0442\u043e \u0431\u044b\u043b\u043e.<\/p>\n<h3>\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 BookStack \u043d\u0430 Ubuntu 24.04 (\u0447\u0435\u0440\u0435\u0437 \u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0439 \u0441\u043a\u0440\u0438\u043f\u0442)<\/h3>\n<p>\u0421\u0430\u043c\u044b\u0439 \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0438 \u0431\u044b\u0441\u0442\u0440\u044b\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u0440\u0430\u0437\u0432\u0435\u0440\u043d\u0443\u0442\u044c BookStack \u2014 \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f <strong>\u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u043c bash-\u0441\u043a\u0440\u0438\u043f\u0442\u043e\u043c<\/strong>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0438\u0440\u0443\u0435\u0442 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0443 \u0432\u0441\u0435\u0445 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439 \u0438 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044e. \u042f \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u043b \u044d\u0442\u043e \u043d\u0430 <strong>\u0447\u0438\u0441\u0442\u043e\u0439 Ubuntu 24.04<\/strong> \u2014 \u0432\u0441\u0451 \u0437\u0430\u0440\u0430\u0431\u043e\u0442\u0430\u043b\u043e \u0431\u0435\u0437 \u043f\u0440\u043e\u0431\u043b\u0435\u043c.<\/p>\n<h4>1. \u041f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0430 \u0441\u0438\u0441\u0442\u0435\u043c\u044b<\/h4>\n<p>\u041f\u0435\u0440\u0435\u0434 \u043d\u0430\u0447\u0430\u043b\u043e\u043c \u0443\u0431\u0435\u0434\u0438\u0442\u0435\u0441\u044c, \u0447\u0442\u043e \u0443 \u0432\u0430\u0441:<\/p>\n<ul>\n<li>\n<p>Ubuntu 24.04 (\u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f)<\/p>\n<\/li>\n<li>\n<p>\u041f\u0440\u0430\u0432\u0430 root \u0438\u043b\u0438 <code>sudo<\/code><\/p>\n<\/li>\n<li>\n<p>\u0418\u043d\u0442\u0435\u0440\u043d\u0435\u0442-\u0434\u043e\u0441\u0442\u0443\u043f \u0434\u043b\u044f \u0441\u043a\u0430\u0447\u0438\u0432\u0430\u043d\u0438\u044f \u0441\u043a\u0440\u0438\u043f\u0442\u0430<\/p>\n<\/li>\n<\/ul>\n<p>\u041e\u0431\u043d\u043e\u0432\u0438\u043c \u043f\u0430\u043a\u0435\u0442\u044b:<\/p>\n<pre><code class=\"bash\">sudo apt update &amp;&amp; sudo apt upgrade -y<\/code><\/pre>\n<p>\u0421\u043a\u0440\u0438\u043f\u0442 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 Ubuntu 24.04:<\/p>\n<pre><code class=\"bash\"># \u0421\u043a\u0430\u0447\u0430\u0442\u044c \u0441\u043a\u0440\u0438\u043f\u0442 wget https:\/\/codeberg.org\/bookstack\/devops\/raw\/branch\/main\/scripts\/installation-ubuntu-24.04.sh  # \u0421\u0434\u0435\u043b\u0430\u0442\u044c \u0435\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u043d\u044f\u0435\u043c\u044b\u043c chmod a+x installation-ubuntu-24.04.sh  # \u0417\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0441\u043a\u0440\u0438\u043f\u0442 \u0441 \u043f\u0440\u0430\u0432\u0430\u043c\u0438 \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u0430 sudo .\/installation-ubuntu-24.04.sh<\/code><\/pre>\n<div class=\"tm-iframe_temp\" data-src=\"https:\/\/embedd.srv.habr.com\/iframe\/682182578f844fa824a8a309\" data-style=\"\" id=\"682182578f844fa824a8a309\" width=\"\"><\/div>\n<p>\u0427\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442 \u0441\u043a\u0440\u0438\u043f\u0442: <br \/><a href=\"https:\/\/codeberg.org\/bookstack\/devops\/src\/branch\/main\/scripts\/installation-ubuntu-24.04.sh\" rel=\"noopener noreferrer nofollow\">\u0421\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u0441\u043a\u0440\u0438\u043f\u0442<\/a>  <\/p>\n<pre><code class=\"bash\">#!\/bin\/bash  echo \"This script installs a new BookStack instance on a fresh Ubuntu 24.04 server.\" echo \"This script does not ensure system security.\" echo \"\"  # \u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043f\u0443\u0442\u0438 \u0434\u043b\u044f \u0444\u0430\u0439\u043b\u0430 \u043b\u043e\u0433\u0430 \u0434\u043b\u044f \u043e\u0442\u043b\u0430\u0434\u043a\u0438 LOGPATH=$(realpath \"bookstack_install_$(date +%s).log\")  # \u041f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f, \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u044e\u0449\u0435\u0433\u043e \u0441\u043a\u0440\u0438\u043f\u0442 SCRIPT_USER=\"${SUDO_USER:-$USER}\"  # \u041f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 IP-\u0430\u0434\u0440\u0435\u0441\u0430 \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u043c\u0430\u0448\u0438\u043d\u044b CURRENT_IP=$(ip addr | grep 'state UP' -A4 | grep 'inet ' | awk '{print $2}' | cut -f1  -d'\/')  # \u0413\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u043f\u0430\u0440\u043e\u043b\u044f \u0434\u043b\u044f \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445 DB_PASS=\"$(head \/dev\/urandom | tr -dc A-Za-z0-9 | head -c 13)\"  # \u041a\u0430\u0442\u0430\u043b\u043e\u0433 \u0434\u043b\u044f \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 BookStack BOOKSTACK_DIR=\"\/var\/www\/bookstack\"  # \u041f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0434\u043e\u043c\u0435\u043d\u0430 \u0438\u0437 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u0432 (\u0437\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u043e\u0437\u0436\u0435, \u0435\u0441\u043b\u0438 \u043d\u0435 \u0443\u043a\u0430\u0437\u0430\u043d\u043e) DOMAIN=$1  # \u041f\u0440\u0435\u0434\u043e\u0442\u0432\u0440\u0430\u0449\u0435\u043d\u0438\u0435 \u0438\u043d\u0442\u0435\u0440\u0430\u043a\u0442\u0438\u0432\u043d\u044b\u0445 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u0445 export DEBIAN_FRONTEND=noninteractive  # \u0412\u044b\u0432\u043e\u0434 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043e\u0431 \u043e\u0448\u0438\u0431\u043a\u0435 \u0432 \u043a\u043e\u043c\u0430\u043d\u0434\u043d\u0443\u044e \u0441\u0442\u0440\u043e\u043a\u0443 \u0438 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u0435 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b # \u0422\u0430\u043a\u0436\u0435 \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0432 \u0444\u0430\u0439\u043b \u043b\u043e\u0433\u0430 function error_out() {   echo \"ERROR: $1\" | tee -a \"$LOGPATH\" 1&gt;&amp;2   exit 1 }  # \u0412\u044b\u0432\u043e\u0434 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0433\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0432 \u043a\u043e\u043c\u0430\u043d\u0434\u043d\u0443\u044e \u0441\u0442\u0440\u043e\u043a\u0443 \u0438 \u0444\u0430\u0439\u043b \u043b\u043e\u0433\u0430 function info_msg() {   echo \"$1\" | tee -a \"$LOGPATH\" }  # \u0412\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u043e\u043a \u043f\u0435\u0440\u0435\u0434 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u043e\u0439, \u0447\u0442\u043e\u0431\u044b \u0438\u0437\u0431\u0435\u0436\u0430\u0442\u044c \u043d\u0430\u0440\u0443\u0448\u0435\u043d\u0438\u044f \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0439 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0432\u0435\u0431-\u0441\u0435\u0440\u0432\u0435\u0440\u0430 function run_pre_install_checks() {   # \u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430, \u0437\u0430\u043f\u0443\u0449\u0435\u043d \u043b\u0438 \u0441\u043a\u0440\u0438\u043f\u0442 \u043e\u0442 \u0438\u043c\u0435\u043d\u0438 root, \u0438 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u0435, \u0435\u0441\u043b\u0438 \u043d\u0435\u0442   if [[ $EUID -gt 0 ]]   then     error_out \"This script must be ran with root\/sudo privileges\"   fi    # \u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430, \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d \u043b\u0438 Apache, \u0438 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u0435, \u0435\u0441\u043b\u0438 \u043e\u043d \u0443\u0436\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d   if [ -d \"\/etc\/apache2\/sites-enabled\" ]   then     error_out \"This script is intended for a fresh server install, existing apache config found, aborting install\"   fi    # \u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430, \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u0430 \u043b\u0438 MySQL, \u0438 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u0435, \u0435\u0441\u043b\u0438 \u0434\u0430\u043d\u043d\u044b\u0435 MySQL \u0443\u0436\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0442   if [ -d \"\/var\/lib\/mysql\" ]   then     error_out \"This script is intended for a fresh server install, existing MySQL data found, aborting install\"   fi }  # \u041f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0434\u043e\u043c\u0435\u043d\u0430 \u0438\u0437 \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u043d\u043e\u0433\u043e \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430 \u0438\u043b\u0438 \u0437\u0430\u043f\u0440\u043e\u0441 \u0432\u0432\u043e\u0434\u0430 \u0434\u043e\u043c\u0435\u043d\u0430 \u0443 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f function run_prompt_for_domain_if_required() {   if [ -z \"$DOMAIN\" ]   then     info_msg \"\"     info_msg \"Enter the domain (or IP if not using a domain) you want to host BookStack on and press [ENTER].\"     info_msg \"Examples: my-site.com or docs.my-site.com or ${CURRENT_IP}\"     read -r DOMAIN   fi    # \u0417\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u0435 \u0441 \u043e\u0448\u0438\u0431\u043a\u043e\u0439, \u0435\u0441\u043b\u0438 \u0434\u043e\u043c\u0435\u043d \u043d\u0435 \u0443\u043a\u0430\u0437\u0430\u043d   if [ -z \"$DOMAIN\" ]   then     error_out \"A domain must be provided to run this script\"   fi }  # \u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0445 \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u044b\u0445 \u043f\u0430\u043a\u0435\u0442\u043e\u0432 function run_package_installs() {   apt update   apt install -y git unzip apache2 curl mysql-server-8.0 php8.3 \\   php8.3-fpm php8.3-curl php8.3-mbstring php8.3-ldap php8.3-xml php8.3-zip php8.3-gd php8.3-mysql }  # \u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445 function run_database_setup() {   # \u0423\u0431\u0435\u0434\u0438\u0442\u044c\u0441\u044f, \u0447\u0442\u043e \u0441\u043b\u0443\u0436\u0431\u0430 \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445 \u0437\u0430\u043f\u0443\u0449\u0435\u043d\u0430   systemctl start mysql-server.service   sleep 3    # \u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0439 \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445, \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0438 \u043f\u0440\u0430\u0432 \u0434\u043e\u0441\u0442\u0443\u043f\u0430   mysql -u root --execute=\"CREATE DATABASE bookstack;\"   mysql -u root --execute=\"CREATE USER 'bookstack'@'localhost' IDENTIFIED WITH mysql_native_password BY '$DB_PASS';\"   mysql -u root --execute=\"GRANT ALL ON bookstack.* TO 'bookstack'@'localhost';FLUSH PRIVILEGES;\" }  # \u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430 BookStack function run_bookstack_download() {   cd \/var\/www || exit   git clone https:\/\/github.com\/BookStackApp\/BookStack.git --branch release --single-branch bookstack }  # \u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 Composer function run_install_composer() {   EXPECTED_CHECKSUM=\"$(php -r 'copy(\"https:\/\/composer.github.io\/installer.sig\", \"php:\/\/stdout\");')\"   php -r \"copy('https:\/\/getcomposer.org\/installer', 'composer-setup.php');\"   ACTUAL_CHECKSUM=\"$(php -r \"echo hash_file('sha384', 'composer-setup.php');\")\"    if [ \"$EXPECTED_CHECKSUM\" != \"$ACTUAL_CHECKSUM\" ]   then       &gt;&amp;2 echo 'ERROR: Invalid composer installer checksum'       rm composer-setup.php       exit 1   fi    php composer-setup.php --quiet   rm composer-setup.php    # \u041f\u0435\u0440\u0435\u043c\u0435\u0449\u0435\u043d\u0438\u0435 Composer \u0432 \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u0443\u044e \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0443   mv composer.phar \/usr\/local\/bin\/composer }  # \u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439 BookStack \u0447\u0435\u0440\u0435\u0437 Composer function run_install_bookstack_composer_deps() {   cd \"$BOOKSTACK_DIR\" || exit   export COMPOSER_ALLOW_SUPERUSER=1   php \/usr\/local\/bin\/composer install --no-dev --no-plugins }  # \u041a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f BookStack function run_update_bookstack_env() {   cd \"$BOOKSTACK_DIR\" || exit   cp .env.example .env   sed -i.bak \"s@APP_URL=.*\\$@APP_URL=http:\/\/$DOMAIN@\" .env   sed -i.bak 's\/DB_DATABASE=.*$\/DB_DATABASE=bookstack\/' .env   sed -i.bak 's\/DB_USERNAME=.*$\/DB_USERNAME=bookstack\/' .env   sed -i.bak \"s\/DB_PASSWORD=.*\\$\/DB_PASSWORD=$DB_PASS\/\" .env   # \u0413\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u043a\u043b\u044e\u0447\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f   php artisan key:generate --no-interaction --force }  # \u0412\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u043f\u0435\u0440\u0432\u043e\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u044b\u0445 \u043c\u0438\u0433\u0440\u0430\u0446\u0438\u0439 \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445 BookStack function run_bookstack_database_migrations() {   cd \"$BOOKSTACK_DIR\" || exit   php artisan migrate --no-interaction --force }  # \u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u043f\u0440\u0430\u0432 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a \u0444\u0430\u0439\u043b\u0430\u043c \u0438 \u043f\u0430\u043f\u043a\u0430\u043c # \u0423\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442 \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043a\u0430\u043a \u0432\u043b\u0430\u0434\u0435\u043b\u044c\u0446\u0430 \u0438 \u0433\u0440\u0443\u043f\u043f\u0443 www-data \u043a\u0430\u043a \u0432\u043b\u0430\u0434\u0435\u043b\u044c\u0446\u0430 \u0433\u0440\u0443\u043f\u043f\u044b, # \u0437\u0430\u0442\u0435\u043c \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0433\u0440\u0443\u043f\u043f\u0435 \u043f\u0440\u0430\u0432\u0430 \u043d\u0430 \u0437\u0430\u043f\u0438\u0441\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0445 \u043a\u0430\u0442\u0430\u043b\u043e\u0433\u043e\u0432. # \u0421\u043a\u0440\u044b\u0432\u0430\u0435\u0442 \u0444\u0430\u0439\u043b `.env`, \u0447\u0442\u043e\u0431\u044b \u043e\u043d \u043d\u0435 \u0431\u044b\u043b \u0432\u0438\u0434\u0435\u043d \u0434\u0440\u0443\u0433\u0438\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\u043c \u0432 \u0441\u0438\u0441\u0442\u0435\u043c\u0435. function run_set_application_file_permissions() {   cd \"$BOOKSTACK_DIR\" || exit   chown -R \"$SCRIPT_USER\":www-data .\/   chmod -R 755 .\/   chmod -R 775 bootstrap\/cache public\/uploads storage   chmod 740 .env    # \u0423\u043a\u0430\u0437\u0430\u043d\u0438\u0435 git \u0438\u0433\u043d\u043e\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043f\u0440\u0430\u0432 \u0434\u043e\u0441\u0442\u0443\u043f\u0430   git config core.fileMode false }  # \u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 Apache \u0441 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u043c\u0438 \u043c\u043e\u0434\u0443\u043b\u044f\u043c\u0438 \u0438 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0435\u0439 function run_configure_apache() {   # \u0412\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0445 \u043c\u043e\u0434\u0443\u043b\u0435\u0439 \u0438 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 Apache   a2enmod rewrite proxy_fcgi setenvif   a2enconf php8.3-fpm    # \u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0439 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 Apache \u0434\u043b\u044f BookStack   cat &gt;\/etc\/apache2\/sites-available\/bookstack.conf &lt;&lt;EOL &lt;VirtualHost *:80&gt;   ServerName ${DOMAIN}    ServerAdmin webmaster@localhost   DocumentRoot \/var\/www\/bookstack\/public\/    &lt;Directory \/var\/www\/bookstack\/public\/&gt;       Options -Indexes +FollowSymLinks       AllowOverride None       Require all granted       &lt;IfModule mod_rewrite.c&gt;           &lt;IfModule mod_negotiation.c&gt;               Options -MultiViews -Indexes           &lt;\/IfModule&gt;            RewriteEngine On            # Handle Authorization Header           RewriteCond %{HTTP:Authorization} .           RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]            # Redirect Trailing Slashes If Not A Folder...           RewriteCond %{REQUEST_FILENAME} !-d           RewriteCond %{REQUEST_URI} (.+)\/$           RewriteRule ^ %1 [L,R=301]            # Handle Front Controller...           RewriteCond %{REQUEST_FILENAME} !-d           RewriteCond %{REQUEST_FILENAME} !-f           RewriteRule ^ index.php [L]       &lt;\/IfModule&gt;   &lt;\/Directory&gt;    ErrorLog \\${APACHE_LOG_DIR}\/error.log   CustomLog \\${APACHE_LOG_DIR}\/access.log combined  &lt;\/VirtualHost&gt; EOL    # \u041e\u0442\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0441\u0430\u0439\u0442\u0430 Apache \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0438 \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 BookStack   a2dissite 000-default.conf   a2ensite bookstack.conf    # \u041f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a Apache \u0434\u043b\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043d\u043e\u0432\u043e\u0439 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438   systemctl restart apache2   # \u0423\u0431\u0435\u0434\u0438\u0442\u044c\u0441\u044f, \u0447\u0442\u043e \u0441\u043b\u0443\u0436\u0431\u0430 php-fpm \u0437\u0430\u043f\u0443\u0449\u0435\u043d\u0430   systemctl start php8.3-fpm.service }  info_msg \"This script logs full output to $LOGPATH which may help upon issues.\" sleep 1  run_pre_install_checks run_prompt_for_domain_if_required info_msg \"\" info_msg \"Installing using the domain or IP \\\"$DOMAIN\\\"\" info_msg \"\" sleep 1  info_msg \"[1\/9] Installing required system packages... (This may take several minutes)\" run_package_installs &gt;&gt; \"$LOGPATH\" 2&gt;&amp;1  info_msg \"[2\/9] Preparing MySQL database...\" run_database_setup &gt;&gt; \"$LOGPATH\" 2&gt;&amp;1  info_msg \"[3\/9] Downloading BookStack to ${BOOKSTACK_DIR}...\" run_bookstack_download &gt;&gt; \"$LOGPATH\" 2&gt;&amp;1  info_msg \"[4\/9] Installing Composer (PHP dependency manager)...\" run_install_composer &gt;&gt; \"$LOGPATH\" 2&gt;&amp;1  info_msg \"[5\/9] Installing PHP dependencies using composer...\" run_install_bookstack_composer_deps &gt;&gt; \"$LOGPATH\" 2&gt;&amp;1  info_msg \"[6\/9] Creating and populating BookStack .env file...\" run_update_bookstack_env &gt;&gt; \"$LOGPATH\" 2&gt;&amp;1  info_msg \"[7\/9] Running initial BookStack database migrations...\" run_bookstack_database_migrations &gt;&gt; \"$LOGPATH\" 2&gt;&amp;1  info_msg \"[8\/9] Setting BookStack file &amp; folder permissions...\" run_set_application_file_permissions &gt;&gt; \"$LOGPATH\" 2&gt;&amp;1  info_msg \"[9\/9] Configuring apache server...\" run_configure_apache &gt;&gt; \"$LOGPATH\" 2&gt;&amp;1  info_msg \"----------------------------------------------------------------\" info_msg \"Setup finished, your BookStack instance should now be installed!\" info_msg \"- Default login email: admin@admin.com\" info_msg \"- Default login password: password\" info_msg \"- Access URL: http:\/\/$CURRENT_IP\/ or http:\/\/$DOMAIN\/\"<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-459638","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/459638","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=459638"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/459638\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=459638"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=459638"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=459638"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}