<?xml version="1.0" encoding="utf-8" ?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:tt="http://teletype.in/" xmlns:opensearch="http://a9.com/-/spec/opensearch/1.1/"><title>IceSlam</title><subtitle>Официальный блог веб-разработчика
VueJS/NuxtJS, WordPress, MODX Revo, PHP, сервера</subtitle><author><name>IceSlam</name></author><id>https://teletype.in/atom/iceslam</id><link rel="self" type="application/atom+xml" href="https://teletype.in/atom/iceslam?offset=0"></link><link rel="alternate" type="text/html" href="https://teletype.in/@iceslam?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=iceslam"></link><link rel="next" type="application/rss+xml" href="https://teletype.in/atom/iceslam?offset=10"></link><link rel="search" type="application/opensearchdescription+xml" title="Teletype" href="https://teletype.in/opensearch.xml"></link><updated>2026-05-25T16:53:33.990Z</updated><entry><id>iceslam:launch-nodejs-with-pm2-and-proxying-it-by-apache2</id><link rel="alternate" type="text/html" href="https://teletype.in/@iceslam/launch-nodejs-with-pm2-and-proxying-it-by-apache2?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=iceslam"></link><title>Разворачиваем NodeJS-проект (NuxtJS) на базе VDS с ОС Ubuntu Server</title><published>2021-02-27T14:27:02.154Z</published><updated>2021-02-28T17:19:40.011Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://teletype.in/files/51/85/51857e45-70bb-4435-b94c-703acc61ca6f.png"></media:thumbnail><category term="servers" label="Servers"></category><summary type="html">&lt;img src=&quot;https://teletype.in/files/ee/42/ee4235aa-7166-4eb8-9032-371524c9d116.png&quot;&gt;Доброго времени суток, уважаемые читатели!</summary><content type="html">
  &lt;p&gt;Доброго времени суток, уважаемые читатели!&lt;/p&gt;
  &lt;p&gt;В данной статье мы рассмотрим вопрос развертывания с нуля NuxtJS-проекта (либо любого другого проекта на NodeJS) на VDS-сервере с использованием веб-сервера Apahce2, NodeJS, менеджера процессов pm2 с полным циклом установки всех компонентов. &lt;/p&gt;
  &lt;p&gt;Установка будет производится на чистом VDS-сервере, не имеющем каких-либо настроек&lt;/p&gt;
  &lt;h2&gt;Шаг 1. Подключаемся по SSH к VDS&lt;/h2&gt;
  &lt;p&gt;Для подключения к VDS-серверу по SSH более не требуется скачивать и устанавливать какие-либо дополнительные программы, так как в &lt;strong&gt;Windows PowerShell&lt;/strong&gt; на ОС Windows 10 последних версий уже встроен клиент OpenSSH.&lt;/p&gt;
  &lt;p&gt;Я же буду использовать приложение Windows Terminal, скачать которое можно в Microsoft Store (разработчик &lt;strong&gt;Windows Terminal &lt;/strong&gt;- сами Microsoft).&lt;/p&gt;
  &lt;p&gt;В данной инструкции в качестве операционной системы на сервере мы будем использовать &lt;strong&gt;Ubuntu Server 20.04&lt;/strong&gt;&lt;/p&gt;
  &lt;p&gt;Итак, подключаемся к серверу при помощи следующей команды&lt;/p&gt;
  &lt;pre&gt;ssh root@Ваш_IP_сервера&lt;/pre&gt;
  &lt;p&gt;Вместо &lt;strong&gt;root &lt;/strong&gt;вы должны указать своего пользователя, который у Вас был выдан при создании сервера.&lt;/p&gt;
  &lt;p&gt;Вместо IP-адреса также можно использовать и FQDN-адрес сервера, если вы уже прописали DNS A-запись на Вашем домене со значением Вашего IP-адреса сервера.&lt;/p&gt;
  &lt;figure class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/ee/42/ee4235aa-7166-4eb8-9032-371524c9d116.png&quot; width=&quot;786&quot; /&gt;
    &lt;figcaption&gt;Команда подключения к серверу по SSH&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p&gt;При успешном логине Вы увидите уже терминал (консоль) сервера&lt;/p&gt;
  &lt;figure class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/84/4f/844fab14-992d-462e-b1f2-d566ff6b72cb.png&quot; width=&quot;680&quot; /&gt;
    &lt;figcaption&gt;Терминал Ubuntu Server&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p&gt;Как видим, мы подключены к удаленному серверу.&lt;/p&gt;
  &lt;h2&gt;Шаг 2. Добавление репозитория Apache2 на сервер и установка веб-сервера&lt;/h2&gt;
  &lt;p&gt;В данной инструкции мы будем устанавливать веб-сервер Apache2 из официального репозитория, так как в репозитории Ubuntu не всегда последняя версия веб-сервера Apache2.&lt;/p&gt;
  &lt;p&gt;Для начала установим необходимые пакеты командой:&lt;/p&gt;
  &lt;pre&gt;apt install software-properties-common&lt;/pre&gt;
  &lt;figure class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/7a/e9/7ae9f217-dbc5-459a-bc76-9a0d7f1487f8.png&quot; width=&quot;578&quot; /&gt;
    &lt;figcaption&gt;Команда установки необходимого пакета&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p&gt;Если данный пакет уже установлен, то вы увидите следующее:&lt;/p&gt;
  &lt;figure class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/d0/3e/d03ec480-d5c7-4fc0-ba06-0d61c3efdd0a.png&quot; width=&quot;988&quot; /&gt;
    &lt;figcaption&gt;Необходимый пакет уже установлен&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p&gt;После установки необходимых пакетов добавляем официальный репозиторий Apache2 следующей командой:&lt;/p&gt;
  &lt;pre&gt;apt-add-repository ppa:ondrej/apache2&lt;/pre&gt;
  &lt;p&gt;При добавлении репозитория, в терминале появится вопрос, на который необходимо нажать клавишу &lt;em&gt;Enter&lt;/em&gt;&lt;/p&gt;
  &lt;figure class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/91/1e/911efdf3-617d-4605-8103-a5de51a9f4d3.png&quot; width=&quot;1109&quot; /&gt;
    &lt;figcaption&gt;Подтверждение добавления репозитория&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p&gt;После добавления репозитория производим установку самого веб-сервера Apache2:&lt;/p&gt;
  &lt;pre&gt;apt install apache2&lt;/pre&gt;
  &lt;p&gt;В терминале появится вопрос о подтверждении установки веб-сервера Apache2. Если согласны с установкой - смело нажимайте клавишу &lt;em&gt;Enter.&lt;/em&gt;&lt;/p&gt;
  &lt;figure class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/ce/ed/ceedac6d-bfc3-41e4-bd0b-ad6c0559b0f4.png&quot; width=&quot;1095&quot; /&gt;
    &lt;figcaption&gt;Подтверждение установки пакета Apache2&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p&gt;Готово!&lt;/p&gt;
  &lt;p&gt;Теперь можно перейти по IP-адресу, либо по FQDN-адресу вашего сервера и убедиться, что веб-сервер Apache2 успешно установлен.&lt;/p&gt;
  &lt;figure class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/42/8a/428a6981-a9d8-43f2-ac99-48b79b673cb6.png&quot; width=&quot;1368&quot; /&gt;
    &lt;figcaption&gt;Успешная установка Apache2&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;h2&gt;Шаг 3. Установка менеджера версий NodeJS (nvm) и самого NodeJS.&lt;/h2&gt;
  &lt;p&gt;Для установки и более удобного дальнейшего контроля версий NodeJS мы установки менеджер версии NodeJS. Пакет называется nvm.&lt;/p&gt;
  &lt;p&gt;Для этого перейдем в официальный репозиторий на GitHub:&lt;/p&gt;
  &lt;p&gt;&lt;a href=&quot;https://github.com/nvm-sh/nvm&quot; target=&quot;_blank&quot;&gt;https://github.com/nvm-sh/nvm&lt;/a&gt;&lt;/p&gt;
  &lt;p&gt;И перейдем в раздел Installing and Updating и выберем один их способов установки скрипта. Я выберу второй через утилиту wget:&lt;/p&gt;
  &lt;figure class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/1b/8c/1b8c8b44-0a1d-4f47-908d-6493570e8bed.png&quot; width=&quot;896&quot; /&gt;
    &lt;figcaption&gt;Раздел установки и обновления скрипта NVM в официальном репозитории на GitHub&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p&gt;&lt;/p&gt;
  &lt;p&gt;Копируем команду и вставляем ее в терминал сервера:&lt;/p&gt;
  &lt;pre&gt;wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.37.2/install.sh | bash&lt;/pre&gt;
  &lt;figure class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/37/5d/375d787a-492d-4782-9732-9f56a9dfe07d.png&quot; width=&quot;1028&quot; /&gt;
    &lt;figcaption&gt;Команда установки NVM в терминале&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p&gt;И жмем клавишу &lt;em&gt;Enter&lt;/em&gt;&lt;/p&gt;
  &lt;p&gt;После установки перезагружаем сервер при помощи кнопки перезагрузки в панели управления сервером, либо через команду в терминале&lt;code&gt; init 6 &lt;/code&gt;&lt;/p&gt;
  &lt;figure class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/1a/e6/1ae6e669-ca1c-43b1-8298-ae2bb7f1b0b6.png&quot; width=&quot;762&quot; /&gt;
    &lt;figcaption&gt;Автоматическое отключение от сервера после применения команды перезагрузки&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p&gt;После перезагрузки снова подключаемся к серверу согласно шагу 1.&lt;/p&gt;
  &lt;p&gt;Запускаем команду nvm для того, чтобы посмотреть и ознакомится со списком команд скрипта. Находим команду установки NodeJS в версии LTS:&lt;/p&gt;
  &lt;figure class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/92/e7/92e70f2f-2414-4b71-ad16-589737a3ebfc.png&quot; width=&quot;951&quot; /&gt;
    &lt;figcaption&gt;Команда установки NodeJS LTS-версии&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p&gt;Вводим эту команду в терминал и жмем клавишу &lt;em&gt;Enter&lt;/em&gt;:&lt;/p&gt;
  &lt;pre&gt;nvm install --lts&lt;/pre&gt;
  &lt;figure class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/32/01/32017733-1526-4b58-8ebe-bba7bb1e225b.png&quot; width=&quot;1104&quot; /&gt;
    &lt;figcaption&gt;Успешная установка NodeJS через менеджер NVM&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p&gt;Проверяем установленную версию NodeJS слудующей командой:&lt;/p&gt;
  &lt;pre&gt;node -v&lt;/pre&gt;
  &lt;p&gt;И получаем сообщение об установленной версии NodeJS&lt;/p&gt;
  &lt;figure class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/31/6e/316efed1-a1e0-432e-89d3-b234144b8240.png&quot; width=&quot;1104&quot; /&gt;
    &lt;figcaption&gt;Установленная версия NodeJS&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;h2&gt;Шаг 4. Установка менеджера процессов pm2&lt;/h2&gt;
  &lt;p&gt;Для того, чтобы управлять процессами и приложениями, запущенными в среде NodeJS, а также автоматического их запуска после перезагрузки сервера, нам понадобится менеджер процессов NodeJS, который мы установим глобально в систему через пакетный менеджер npm - pm2:&lt;/p&gt;
  &lt;pre&gt;npm install -g pm2&lt;/pre&gt;
  &lt;p&gt;При успешной установке мы увидим следующее:&lt;/p&gt;
  &lt;figure class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/69/6e/696eae0a-9438-4dfa-8168-6ab2fb59abc4.png&quot; width=&quot;1100&quot; /&gt;
    &lt;figcaption&gt;Пакет pm2 успешно установлен&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p&gt;При помощи команды&lt;code&gt; pm2 -h &lt;/code&gt;можно посмотреть список доступных команд&lt;/p&gt;
  &lt;h2&gt;Шаг 5. Запуск NodeJS-приложения (в нашем случае - NuxtJS-приложения)&lt;/h2&gt;
  &lt;p&gt;Я создам новое приложение на NuxtJS для демонстрации работы. Вы же можете запустить таким же образом любое NodeJS-приложение, как новое, только что созданное, так и уже готовое приложение.&lt;/p&gt;
  &lt;p&gt;NuxtJS проект по-умолчанию запускается в двух режимах:&lt;/p&gt;
  &lt;ul&gt;
    &lt;li&gt;Dev: &lt;code&gt;npm run dev&lt;/code&gt;&lt;/li&gt;
    &lt;li&gt;Prod: &lt;code&gt;npm run build&lt;/code&gt; и &lt;code&gt;npm run start&lt;/code&gt;&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p&gt;Мы же не будем запускать это приложение этими командами, а сразу воспользуемся менеджером &lt;strong&gt;pm2&lt;/strong&gt;&lt;/p&gt;
  &lt;p&gt;Для этого перейдем в папку с проектом и запустим команду инициализации менеджера &lt;strong&gt;pm2:&lt;/strong&gt;&lt;/p&gt;
  &lt;pre&gt;pm2 init&lt;/pre&gt;
  &lt;figure class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/5f/e9/5fe9a3b2-77c0-45b6-b3d5-3569b6f4d9d5.png&quot; width=&quot;1108&quot; /&gt;
    &lt;figcaption&gt;pm2 сообщает об успешной генерации файла экосистемы&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p&gt;Открываем файл &lt;code&gt;ecosystem.config.js&lt;/code&gt; прямо в терминале через редактор &lt;strong&gt;nano&lt;/strong&gt; командой и удаляем все содержимое:&lt;/p&gt;
  &lt;pre&gt;nano ecosystem.config.js&lt;/pre&gt;
  &lt;figure class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/5f/79/5f79d0c0-3e44-4cf3-9707-27d63f18b416.png&quot; width=&quot;1103&quot; /&gt;
    &lt;figcaption&gt;Пустой файл ecosystem.config.js с удаленными стандартными значениями&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p&gt;Вставляем туда следующее содержимое и сохраняем комбинацией клавиш &lt;em&gt;Ctrl+O&lt;/em&gt;, затем жмем &lt;em&gt;Enter&lt;/em&gt;:&lt;/p&gt;
  &lt;pre&gt;module.exports = {
  apps : [
    {
      name: &amp;quot;nuxt-dev&amp;quot;,
      script: &amp;quot;npm&amp;quot;,
      args: &amp;quot;run dev&amp;quot;
    },
    {
      name: &amp;quot;nuxt-prod&amp;quot;,
      script: &amp;quot;npm&amp;quot;,
      args: &amp;quot;run start&amp;quot;
    }
  ]
}&lt;/pre&gt;
  &lt;p&gt;Для запуска dev-версии используем команду следующую команду:&lt;/p&gt;
  &lt;pre&gt;pm2 start ecosystem.config.js --only nuxt-dev&lt;/pre&gt;
  &lt;p&gt;Для запуска prod-версии:&lt;/p&gt;
  &lt;pre&gt;npm run build &amp;amp;&amp;amp; pm2 start ecosystem.config.js --only nuxt-prod&lt;/pre&gt;
  &lt;p&gt;Я, для примера, запущу Dev-версию&lt;/p&gt;
  &lt;figure class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/8c/36/8c36191c-6214-485b-884a-040135f00fd9.png&quot; width=&quot;1271&quot; /&gt;
    &lt;figcaption&gt;Запущена dev-версия NuxtJS-приложения через pm2&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p&gt;Для последующей остановки/запуска приложения не нужно будет заходить в папку с проектом и запускать командой выше. Достаточно будет ввести название приложения из монитора &lt;strong&gt;pm2&lt;/strong&gt;:&lt;/p&gt;
  &lt;pre&gt;pm2 start nuxt-dev&lt;/pre&gt;
  &lt;p&gt;для запуска, либо&lt;/p&gt;
  &lt;pre&gt;pm2 stop nuxt-dev &lt;/pre&gt;
  &lt;p&gt;для остановки приложения.&lt;/p&gt;
  &lt;p&gt;Для просмотра всех запущенных NodeJS-приложений посредством pm2 небходимо ввести в терминал следующую команду:&lt;/p&gt;
  &lt;pre&gt;pm2 status&lt;/pre&gt;
  &lt;figure class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/05/50/0550c972-8277-4a83-af12-87dac270a51a.png&quot; width=&quot;1269&quot; /&gt;
    &lt;figcaption&gt;Статус-панель pm2&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p&gt;Для просмотра монитора процессов:&lt;/p&gt;
  &lt;pre&gt;pm2 monit&lt;/pre&gt;
  &lt;figure class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/db/75/db7545ef-9981-4932-b0d5-bdad17071415.png&quot; width=&quot;1255&quot; /&gt;
    &lt;figcaption&gt;Моинтор pm2&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p&gt;Подключаем автоматический запуск приложений через pm2 после перезагрузки сервера:&lt;/p&gt;
  &lt;pre&gt;pm2 startup&lt;/pre&gt;
  &lt;p&gt;и сохраняем изменения:&lt;/p&gt;
  &lt;pre&gt;pm2 save&lt;/pre&gt;
  &lt;figure class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/c7/62/c762a6e1-fe6a-49c7-9015-d1b95c583121.png&quot; width=&quot;1278&quot; /&gt;
    &lt;figcaption&gt;Запуск автозагрузки и сохранение параметров&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;h3&gt;[Дополнительно] Графический интерфейс pm2 вне терминала&lt;/h3&gt;
  &lt;p&gt;Для запуска веб-интерфейса управления процессами pm2 необходимо зарегистрироваться на сайте pm2.io и создать Bucket&lt;/p&gt;
  &lt;p&gt;Будем считать, что есть существующий аккаунт и Bucket (инструкцию можно почитать на оф. сайте pm2)&lt;/p&gt;
  &lt;p&gt;Вводим команду для подключения к веб-интерфейсу:&lt;/p&gt;
  &lt;pre&gt;pm2 plus&lt;/pre&gt;
  &lt;p&gt;На первом этапе pm2 спросит, есть ли у Вас аккаунт pm2.io (в нашем случае есть и мы вводим букву &lt;strong&gt;&lt;code&gt;y&lt;/code&gt;&lt;/strong&gt; и жмем клавишу &lt;em&gt;Enter&lt;/em&gt;&lt;/p&gt;
  &lt;figure class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/80/38/8038c4e2-a8cc-47df-8433-66e54c8ec1d9.png&quot; width=&quot;999&quot; /&gt;
    &lt;figcaption&gt;Есть ли аккаунт pm2.io?&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p&gt;Вводим ваш email и пароль от аккаунта.&lt;/p&gt;
  &lt;p&gt;Если все введено верно, то &lt;strong&gt;pm2&lt;/strong&gt; попросит Вас выбрать, к какому Bucket подключиться - выбирайте ранее созданный. У меня это &lt;em&gt;TestBucket&lt;/em&gt;&lt;/p&gt;
  &lt;figure class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/ff/0f/ff0f1fd0-eaf4-4375-b265-14e4564f8178.png&quot; width=&quot;978&quot; /&gt;
    &lt;figcaption&gt;Выбор Bucket для подключения приложения к веб-интерфейсу pm2&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p&gt;При успешном подключении к Bucket в веб-интерфейсе &lt;strong&gt;pm2&lt;/strong&gt; появится Ваше приложение(процесс). Там вы сможете посмотреть статистику, сбросить монитор и перезагрузить приложение&lt;/p&gt;
  &lt;figure class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/dd/99/dd99ba8c-170d-4951-b4cc-0cfee334723f.png&quot; width=&quot;1920&quot; /&gt;
    &lt;figcaption&gt;Веб-интерфейс pm2&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p&gt;Далее нам необходимо повторно добавить в автозагрузку pm2 и сохранить изменения:&lt;/p&gt;
  &lt;pre&gt;pm2 unstartup
pm2 startup
pm2 save&lt;/pre&gt;
  &lt;figure class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/ba/f6/baf6cd3d-816f-42b2-92ab-50c0d4f3d663.png&quot; width=&quot;983&quot; /&gt;
    &lt;figcaption&gt;Перезапуск автозагрузки pm2 и сохранение параметров&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;h2&gt;Шаг 6. Проксирование NodeJS-приложения через Apache2 Proxy&lt;/h2&gt;
  &lt;p&gt;У нас уже запущено приложение на NuxtJS на порту 3000 (по-умолчанию)&lt;/p&gt;
  &lt;p&gt;Теперь нам необходимо проксировать его на определенный адрес и стандартный порт 80 (для HTTP).&lt;/p&gt;
  &lt;p&gt;Для этого установим и включим модуль Apache2 Proxy:&lt;/p&gt;
  &lt;pre&gt;a2enmod proxy_http&lt;/pre&gt;
  &lt;p&gt;И перезагрузим веб-сервер командой:&lt;/p&gt;
  &lt;pre&gt;systemctl restart apache2&lt;/pre&gt;
  &lt;figure class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/ce/fc/cefc356f-285a-4b3c-ad05-21c6954a823b.png&quot; width=&quot;986&quot; /&gt;
    &lt;figcaption&gt;Включение модуля Apache2 Proxy HTTP&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p&gt;Переходим в папку с виртуальными хостами Apache2 командой:&lt;/p&gt;
  &lt;pre&gt;cd /etc/apache2/sites-available&lt;/pre&gt;
  &lt;p&gt;и дублируем дефолтный файл конфигурации виртуального хоста Apache2:&lt;/p&gt;
  &lt;pre&gt;cp 000-default.conf ваш_домен.conf&lt;/pre&gt;
  &lt;p&gt;Открываем файл ваш_домен.conf с помощью редактора nano. Изменяем на Ваши следующие значения:&lt;/p&gt;
  &lt;ul&gt;
    &lt;li&gt;&lt;strong&gt;ServerName&lt;/strong&gt;: необходимо раскомментировать и значение example.com поменять на ваше доменное имя&lt;/li&gt;
    &lt;li&gt;&lt;strong&gt;ServerAdmin&lt;/strong&gt;: &lt;em&gt;webmaster@localhost&lt;/em&gt; меняем на Ваш email&lt;/li&gt;
    &lt;li&gt;&lt;strong&gt;DocumentRoot&lt;/strong&gt;: можно закомментировать значком &lt;strong&gt;#&lt;/strong&gt;&lt;/li&gt;
  &lt;/ul&gt;
  &lt;figure class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/2b/97/2b974a04-2895-413e-be3c-235efb479c29.png&quot; width=&quot;973&quot; /&gt;
    &lt;figcaption&gt;Пример оформления файла конфигурации виртуального хоста&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p&gt;Затем, чтобы проксировать наше приложение на этот адрес, нам необходимо добавить следующие строки&lt;/p&gt;
  &lt;pre&gt;ProxyPreserveHost On

ProxyPass / http://127.0.0.1:3000/
ProxyPassReverse / http://127.0.0.1:3000/&lt;/pre&gt;
  &lt;p&gt;Где &lt;strong&gt;:3000&lt;/strong&gt; - Ваш порт приложения&lt;/p&gt;
  &lt;p&gt;Сохраняем изменения комбинацией клавиш &lt;em&gt;Ctrl+O&lt;/em&gt; и жмем &lt;em&gt;Enter.&lt;/em&gt; Выходим из редактора комбинацией &lt;em&gt;Ctrl+Z&lt;/em&gt;&lt;/p&gt;
  &lt;figure class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/19/ee/19eed5d6-54d2-4be3-a35c-91971580a107.png&quot; width=&quot;983&quot; /&gt;
    &lt;figcaption&gt;Проксирование 3000 порта&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p&gt;Теперь можно включить виртуальный хост и перезагрузить веб-сервер*:&lt;/p&gt;
  &lt;pre&gt;a2ensite ваш_домен
systemctl reload apache2&lt;/pre&gt;
  &lt;blockquote&gt;* В команде a2ensite ваш_домен не обязательно указывать расширение конфигурационного файла&lt;/blockquote&gt;
  &lt;p&gt;Смотрим результат&lt;/p&gt;
  &lt;figure class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/93/3c/933c0566-a652-4dc0-a36a-eaac6a16c4f5.png&quot; width=&quot;1919&quot; /&gt;
    &lt;figcaption&gt;NuxtJS-приложение успешно проксировано&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p&gt;Как видим - приложение успешно открывается на необходимом нам адресе и стандартном порту веб-сервера Apache2&lt;/p&gt;
  &lt;h2&gt;&lt;strong&gt;Шаг 7. Тестирование работы pm2&lt;/strong&gt;&lt;/h2&gt;
  &lt;p&gt;Теперь необходимо проверить, срабатывает ли автоматический запуск приложений менеджером pm2 после перезагрузки сервера.&lt;/p&gt;
  &lt;p&gt;Для этого в терминале пропишем команду &lt;code&gt;init 6&lt;/code&gt;, либо перезагрузим сервер в панели управления хостингом.&lt;/p&gt;
  &lt;p&gt;Если Вы все сделали правильно и согласно инструкции - приложение на NodeJS автоматически запустится на вашем адресе в течение минуты после запуска VDS-сервера.&lt;/p&gt;
  &lt;h2&gt;Заключение&lt;/h2&gt;
  &lt;p&gt;В данном материале мы рассмотрели подробно установку веб-сервера Apache2, установку менеджера версий NodeJS - NVM и установку самого NodeJS через этот менеджер, запуск NodeJS-приложения на примере приложения на VueJS-фреймворке NuxtJS, автоматический запуск этого приложения после перезагрузки сервера с помощью менеджера процессов pm2 и проксирование приложения на определенный адрес.&lt;/p&gt;
  &lt;hr /&gt;
  &lt;p&gt;Другие статьи по теме NodeJS приложений, веб-разработки, администрирования серверов Вы можете найти у меня в блоге&lt;/p&gt;

</content></entry><entry><id>iceslam:0WAAVVt1w</id><link rel="alternate" type="text/html" href="https://teletype.in/@iceslam/0WAAVVt1w?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=iceslam"></link><title>Скрипт динамической обложки: инструкция</title><published>2020-10-03T08:32:42.542Z</published><updated>2020-10-03T08:32:42.542Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://homework-cool.ru/wp-content/uploads/2017/05/pic-02-PSD-shablon.png"></media:thumbnail><category term="php" label="PHP"></category><summary type="html">&lt;img src=&quot;https://homework-cool.ru/wp-content/uploads/2017/05/pic-01-nastrojki-OpenServer-pod-skript-dinamicheskoj-oblozhki.png&quot;&gt;Данная инструкция поможет понять, как настроить наш скрипт динамической обложки Вконтакте. Так же вы научитесь настраивать автозапуск скрипта на локальном и удаленном сервере.</summary><content type="html">
  &lt;p&gt;Данная инструкция поможет понять, как настроить наш скрипт динамической обложки Вконтакте. Так же вы научитесь настраивать автозапуск скрипта на локальном и удаленном сервере.&lt;/p&gt;
  &lt;p&gt;Что такое &lt;a href=&quot;https://homework-cool.ru/zarabotok-v-soc-setjah/dinamicheskaya-oblozhka-vkontakte.html&quot; target=&quot;_blank&quot;&gt;динамическая обложка для группы Вконтакте&lt;/a&gt; можно прочитать по ссылке. Там же находится ссылка на скачивание рассматриваемого в статье скрипта.&lt;/p&gt;
  &lt;p&gt;После скачивания файлов вы получите &lt;em&gt;скрипт динамической обложки и PSD шаблон&lt;/em&gt;, чтобы его редактировать и создать уникальное &lt;a href=&quot;https://homework-cool.ru/oformlenie-gruppy-vkontakte&quot; target=&quot;_blank&quot;&gt;оформление группы Вконтакте&lt;/a&gt;.&lt;/p&gt;
  &lt;p&gt;Чтобы иметь возможность настраивать скрипт, вам понадобится установить локальный сервер на свой компьютер. Я использую &lt;a href=&quot;https://ospanel.io/&quot; target=&quot;_blank&quot;&gt;OpenServer&lt;/a&gt;.&lt;/p&gt;
  &lt;p&gt;Перейдите по ссылке и начните скачивать &lt;strong&gt;Premium&lt;/strong&gt; или &lt;strong&gt;Ultimate&lt;/strong&gt; версию. Бесплатный метод скачивания ограничен в максимальной скорости, так что это может занять какое-то время. А пока вы читаете данную статью, сервер уже наполовину скачается.&lt;/p&gt;
  &lt;p&gt;Вы можете использовать любой другой сервер. Это не имеет большого значения. Главное, чтобы в нем был планировщик заданий (cron) и версия PHP не ниже 5.5.&lt;/p&gt;
  &lt;blockquote&gt;В некоторых случаях возможны проблемы с запуском OpenServer – его любит блокировать брадмауэр. Если такое происходит, то добавьте программу в исключения и запускайте от имени администратора.&lt;/blockquote&gt;
  &lt;p&gt;После успешного запуска сервера (в трее будет гореть зеленый флажок) откройте настройки и в закладке Модули выберите Apache-2.4 и PHP-5.5, как показано на скриншоте.&lt;/p&gt;
  &lt;figure class=&quot;m_custom&quot;&gt;
    &lt;img src=&quot;https://homework-cool.ru/wp-content/uploads/2017/05/pic-01-nastrojki-OpenServer-pod-skript-dinamicheskoj-oblozhki.png&quot; width=&quot;582&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;После сохранения настроек и перезапуска локальный сервер будет полностью готов к работе.&lt;/p&gt;
  &lt;h2&gt;Знакомство с PSD шаблоном&lt;/h2&gt;
  &lt;p&gt;Откроем и ознакомимся сначала с PSD шаблоном.&lt;/p&gt;
  &lt;figure class=&quot;m_custom&quot;&gt;
    &lt;img src=&quot;https://homework-cool.ru/wp-content/uploads/2017/05/pic-02-PSD-shablon.png&quot; width=&quot;1525&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;Внутри файла все разложено по слоям, любой элемент можно редактировать: менять цвет, размер, форму. Используемый в проекте шрифт есть в папке font со скриптом.&lt;/p&gt;
  &lt;p&gt;В общем, изменяйте дизайн по своему усмотрению. Только учтите, что скачанный вами скрипт позволяет отображать следующие элементы:&lt;/p&gt;
  &lt;ul&gt;
    &lt;li&gt;Последних подписчиков: от одного до трех;&lt;/li&gt;
    &lt;li&gt;Время: в формате 14:59;&lt;/li&gt;
    &lt;li&gt;Текущую дату: 21 мая 2017;&lt;/li&gt;
    &lt;li&gt;День недели: воскресенье&lt;/li&gt;
  &lt;/ul&gt;
  &lt;h2&gt;Знакомство с файлами скрипта&lt;/h2&gt;
  &lt;p&gt;Переходим в папку со скриптом динамической обложки.&lt;/p&gt;
  &lt;figure class=&quot;m_custom&quot;&gt;
    &lt;img src=&quot;https://homework-cool.ru/wp-content/uploads/2017/05/pic-03-fajly-skripta-dinamicheskoj-oblozhki.png&quot; width=&quot;650&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;В папке cover находится изначальный файл обложки. Он обязательно должен иметь имя cover_bg.jpg. Иначе скрипт не будет работать. Размер файла 1590×400 пикселей.&lt;/p&gt;
  &lt;p&gt;В папку font нужно закинуть шрифты, которые вы использовали при разработке дизайна. Настройки шрифта задаются в файле setup.php. Обратите внимание, что названия шрифтов не должны иметь пробелов.&lt;/p&gt;
  &lt;p&gt;Файлы function.php, grous_getMembers.php и style.css изменять не рекомендуется. Вы можете их посмотреть, но менять в них ничего не стоит.&lt;/p&gt;
  &lt;p&gt;Нужно настраивать только файлы setup.php и при необходимости index.php.&lt;/p&gt;
  &lt;h3&gt;Настройка файла setup.php&lt;/h3&gt;
  &lt;p&gt;Это основной файл настройки. Открывайте его с помощью текстового редактора. Я рекомендую Notepad++. И в разделе «Типографика» настраиваете используемые шрифты, размер и цвет.&lt;/p&gt;
  &lt;figure class=&quot;m_custom&quot;&gt;
    &lt;img src=&quot;https://homework-cool.ru/wp-content/uploads/2017/05/pic-04-nastrojka-skripta-dinamicheskoj-oblozhki.png&quot; width=&quot;690&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;$font — шрифт отображения имени и фамилии новых подписчиков   $font_clock — шрифт отображения часов   $font_date — шрифт отображения текущей даты и дня недели   $last_subscriber_font_size — размер шрифта имени и фамилии подписчиков   $last_subscriber_font_color — цвет шрифта имени и фамилии подписчиков   $today_font_size — размер шрифта дня недели   $today_font_color — цвет шрифта дня недели   $date_font_size — размер шрифта текущего числа   $date_font_color — цвет шрифта числа   $clock_font_size — размер шрифта часов   $clock_font_color — цвет шрифта часов&lt;/p&gt;
  &lt;p&gt;Теперь поднимемся в начало файла. Пора заполнить самую важную часть настройки скрипта.&lt;/p&gt;
  &lt;figure class=&quot;m_custom&quot;&gt;
    &lt;img src=&quot;https://homework-cool.ru/wp-content/uploads/2017/05/pic-05-glavnye-nastrojki.png&quot; width=&quot;670&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;Нам нужно получить токен доступа. Для этого есть отдельный файл token.php. Открываем его:&lt;/p&gt;
  &lt;figure class=&quot;m_custom&quot;&gt;
    &lt;img src=&quot;https://homework-cool.ru/wp-content/uploads/2017/05/pic-06-poluchenie-tokena.png&quot; width=&quot;1220&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;И видим одну незаполненную ячейку в массиве $params, а именно client_id.&lt;/p&gt;
  &lt;p&gt;Чтобы его получить, вам нужно создать свое приложение Вконтакте. Для этого переходим по ссылке: &lt;a href=&quot;https://vk.com/apps?act=manage&quot; target=&quot;_blank&quot;&gt;https://vk.com/apps?act=manage&lt;/a&gt;&lt;/p&gt;
  &lt;ol&gt;
    &lt;li&gt;Жмем в правом верхнем углу кнопку «Создать приложение».&lt;/li&gt;
    &lt;li&gt;Придумываем ему название.&lt;/li&gt;
    &lt;li&gt;Оставляем платформу Standalone-приложение&lt;/li&gt;
    &lt;li&gt;Жмем «Подключить приложение»&lt;/li&gt;
    &lt;li&gt;Подтверждаем свои действия с помощью SMS (это бесплатно)&lt;/li&gt;
  &lt;/ol&gt;
  &lt;p&gt;Все, приложение создано. Просто, правда?&lt;/p&gt;
  &lt;p&gt;Переключаем вкладку Настройки и копируем оттуда ID приложения:&lt;/p&gt;
  &lt;figure class=&quot;m_custom&quot;&gt;
    &lt;img src=&quot;https://homework-cool.ru/wp-content/uploads/2017/05/pic-07-poluchenie-ID-prilozhenija-Vkontakte.png&quot; width=&quot;993&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;После чего вставляем его в файл token.php&lt;/p&gt;
  &lt;figure class=&quot;m_custom&quot;&gt;
    &lt;img src=&quot;https://homework-cool.ru/wp-content/uploads/2017/05/pic-08-vstavka-ID-v-skript-dinamicheskoj-oblozhki.png&quot; width=&quot;530&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;Жмем сохранить и открываем файл в браузере локального сервера по адресу:&lt;/p&gt;
  &lt;p&gt;http://covers-script/token.php&lt;/p&gt;
  &lt;blockquote&gt;Этот путь будет верен, если вы не изменяли название папки со скриптом динамической обложки при копировании в проекты OpenServer.&lt;/blockquote&gt;
  &lt;p&gt;В браузере сгенерируется ссылка на получение токена. Переходите по ней (откроется в новом окне). Вконтакте попросит разрешить доступ созданному вами приложению к вашему аккаунту. Разрешаете и попадаете на страницу со сгенерированным токеном в адресной строке. Копируете его и вставляете между одинарными кавычками в файле setup.php&lt;/p&gt;
  &lt;figure class=&quot;m_custom&quot;&gt;
    &lt;img src=&quot;https://homework-cool.ru/wp-content/uploads/2017/05/pic-09-vstavka-tokena-v-skript-dinamicheskoj-oblozhki.png&quot; width=&quot;890&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;$group_id вставляете ID группы, в которую собираетесь устанавливать динамическую обложку.&lt;/p&gt;
  &lt;p&gt;Обратите внимание, что получать токен необходимо с аккаунта, которые имеет как минимум права редактора или администратора в сообществе, для которого настраивается динамическая обложка.&lt;/p&gt;
  &lt;blockquote&gt;Для настройки обложки можно &lt;a href=&quot;https://homework-cool.ru/zarabotok-v-soc-setjah/sozdanie-gruppy-vkontakte.html&quot; target=&quot;_blank&quot;&gt;создать группу Вконтакте&lt;/a&gt; в качестве тестовой и попросить вступить туда 3-5 человек, чтобы скрипту было кого показывать. После завершения всех манипуляций достаточно будет только сменить ID группы и все.&lt;/blockquote&gt;
  &lt;p&gt;После того, как эти данные заполнены, можно приступать к следующим настройкам.&lt;/p&gt;
  &lt;h4&gt;Настройка отображения новых подписчиков&lt;/h4&gt;
  &lt;p&gt;Пролистываем файл setup.php до блока «Последний подписавшийся». В нем можно настроить количество отображаемых подписчиков, размер и форму аватарок: круглые или квадратные. Далее настраивается положение аватарки, имени и фамилии по каждому подписчику.&lt;/p&gt;
  &lt;figure class=&quot;m_custom&quot;&gt;
    &lt;img src=&quot;https://homework-cool.ru/wp-content/uploads/2017/05/pic-10-nastrojka-otobrazhenija-novyh-podpischikov.png&quot; width=&quot;670&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;Координаты расположения аватарки рассчитываются до верхнего левого края. Вычислить их можно с помощью PSD файла. Переключаетесь на нужный слой и тянете направляющую (включаются с помощью Ctrl + R) пока её не примагнитит к краю. Это и будет нужное значение. По оси X значение получилось 816 пикселей. По оси Y высчитывается аналогично.&lt;/p&gt;
  &lt;figure class=&quot;m_custom&quot;&gt;
    &lt;img src=&quot;https://homework-cool.ru/wp-content/uploads/2017/05/pic-11-opredelenie-koordinat-v-PSD-shablone.png&quot; width=&quot;900&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;Координаты расположения текста под аватарками рассчитываются по оси X до центра аватарки, по оси Y до низа текста.&lt;/p&gt;
  &lt;p&gt;После того, как пропишите все координаты в соответствии с вашим оформлением &lt;a href=&quot;https://homework-cool.ru/zarabotok-v-soc-setjah/oblozhka-dlya-gruppy-vkontakte.html&quot; target=&quot;_blank&quot;&gt;обложки для группы Вконтакте&lt;/a&gt;, можно переходить к завершающим настройкам.&lt;/p&gt;
  &lt;figure class=&quot;m_custom&quot;&gt;
    &lt;img src=&quot;https://homework-cool.ru/wp-content/uploads/2017/05/pic-12-nastrojki-setup.php_.png&quot; width=&quot;660&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;Координаты расположения дня недели (TODAY), даты и часов рассчитываются до левого нижнего угла.&lt;/p&gt;
  &lt;p&gt;В блоке «Константа» можно поменять часовой пояс, если он у вас отличается от установленного. Остальное трогать не рекомендуется.&lt;/p&gt;
  &lt;h3&gt;Настройка файла index.php&lt;/h3&gt;
  &lt;p&gt;На самом деле изменять что-то в этом файле без знаний PHP не следует. Единственное исключение: если нужно изменить выключку текста.&lt;/p&gt;
  &lt;figure class=&quot;m_custom&quot;&gt;
    &lt;img src=&quot;https://homework-cool.ru/wp-content/uploads/2017/05/pic-13-nastrojki-skripta-indeh.php-dinamicheskoj-oblozhki.png&quot; width=&quot;610&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;Во всех трех случаях выравнивание стоит по левому краю. Если того требует дизайн-макет, вы можете поставить выравнивание по центру или по правому краю. Для этого замените &lt;strong&gt;ALIGN_LEFT&lt;/strong&gt; на &lt;strong&gt;ALIGN_CENTER&lt;/strong&gt; или &lt;strong&gt;ALIGN_RIGHT&lt;/strong&gt; соответственно. Осторожно! Не удалите случайно двоеточие или скобки!&lt;/p&gt;
  &lt;blockquote&gt;При изменении выключки имейте ввиду, что тогда для текста координаты по оси X будут рассчитываться до центра объекта или до его правого края.&lt;/blockquote&gt;
  &lt;p&gt;На этом настройку можно считать законченной и произвести тестовый запуск скрипта, открыв в браузере ссылку:&lt;/p&gt;
  &lt;p&gt;http://covers-script/index.php&lt;/p&gt;
  &lt;p&gt;Если все настроено верно, то вы увидите сообщение, что динамическая обложка успешно загружена в группу. А ниже выведется получившееся изображение.&lt;/p&gt;
  &lt;h2&gt;Настройка автоматического выполнения скрипта&lt;/h2&gt;
  &lt;p&gt;Весь замысел динамической обложки состоит в том, что она обновляется постоянно и без нашего участия. Поэтому нужно научиться работать с планировщиком заданий.&lt;/p&gt;
  &lt;h3&gt;Настройка на локальном сервере&lt;/h3&gt;
  &lt;p&gt;Первым делом рассмотрим работу с планировщиком OpenServer. Открываем настройки и переключаемся на закладку «Планировщик заданий». В строке «Выполнить» прописываем код:&lt;/p&gt;
  &lt;p&gt;%progdir%\modules\wget\bin\wget.exe -q —no-cache http://covers-script/index.php&lt;/p&gt;
  &lt;p&gt;Допустим, мы хотим, чтобы скрипт динамической обложки запускался каждые 5 минут. Тогда в верхних ячейках прописываем следующие параметры:&lt;/p&gt;
  &lt;figure class=&quot;m_custom&quot;&gt;
    &lt;img src=&quot;https://homework-cool.ru/wp-content/uploads/2017/05/pic-14-planirovshhik-zadanij-OpenServer.png&quot; width=&quot;650&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;В первой ячейке */5 расшифровывается как «каждые 5 минут». Если написать */15, то скрипт будет запускаться каждые 15 минут. Если написать просто *, то каждую минуту.&lt;/p&gt;
  &lt;p&gt;Нажимаем кнопку сохранить. Сервер перезапустится и cron начнет работать.&lt;/p&gt;
  &lt;p&gt;Таким образом можно настроить работу скрипта на компьютере. Но этот вариант не идеален, потому что скрипт будет работать лишь пока компьютер включен.&lt;/p&gt;
  &lt;h3&gt;Настройка на хостинге REG.RU&lt;/h3&gt;
  &lt;p&gt;Рассмотрим настройку автоматического запуска скрипта динамической обложки на примере &lt;a href=&quot;https://homework-cool.ru/kakoj-hosting-vybrat-dlja-sajta&quot; target=&quot;_blank&quot;&gt;хостинга REG.RU&lt;/a&gt;. Алгоритм работы с другими удаленными серверами будет аналогичен. Единственный момент: на разных серверах может отличаться путь до php-интерпретатора. Узнать его можно у службы поддержки или в разделе «Справка», или с помощью команды which php.&lt;/p&gt;
  &lt;p&gt;После того, как хостинг будет оплачен и к нему припаркован домен, можно размещать файлы скрипта на удаленном сервере. Для файла index.php обязательно должны быть выставлены права на исполнение: 744 или 755.&lt;/p&gt;
  &lt;p&gt;Далее стоит проверить включенную версию PHP. Для этого в ISPmanager находим пункт меню Версия PHP в разделе Инструменты. При необходимости включаем версию 5.5&lt;/p&gt;
  &lt;figure class=&quot;m_custom&quot;&gt;
    &lt;img src=&quot;https://homework-cool.ru/wp-content/uploads/2017/05/pic-15-versija-PHP-v-ISPmanager.png&quot; width=&quot;660&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;После этого переходим в Планировщик (cron), который находится в том же разделе, и создаем новое задание. В строку «Команда» вводим следующее задание:&lt;/p&gt;
  &lt;p&gt;/usr/bin/wget -O /dev/null http://LINK/index.php&lt;/p&gt;
  &lt;p&gt;Где &lt;strong&gt;LINK&lt;/strong&gt; – это пусть до исполнительного файла скрипта динамической обложки Вконтакте.&lt;/p&gt;
  &lt;p&gt;Настраиваете частоту обновлений, выставив нужные значения, и жмете ОК&lt;/p&gt;
  &lt;figure class=&quot;m_custom&quot;&gt;
    &lt;img src=&quot;https://homework-cool.ru/wp-content/uploads/2017/05/pic-16-planirovshhik-zadanij-reg.ru_.png&quot; width=&quot;530&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;Задание создано. Подождите некоторое время и убедитесь, что cron работает и обложка обновляется.&lt;/p&gt;
  &lt;p&gt;Вот мы и научились запускать скрипт динамической обложки на удаленном сервере. Если у вас что-то не будет получаться, пишите на &lt;a href=&quot;mailto:support@homework-cool.ru?subject=Вопрос%20по%20настройке%20скрипта%20динамической%20обложки&quot; target=&quot;_blank&quot;&gt;нашу почту&lt;/a&gt; или в комментариях под статьей.&lt;/p&gt;
  &lt;p&gt;Если вам нужен скрипт с дополнительными функциями, также пишите на почту. Мы подберем и реализуем идеальное решение именно для вас.&lt;/p&gt;

</content></entry><entry><id>iceslam:l5f1WQHDx</id><link rel="alternate" type="text/html" href="https://teletype.in/@iceslam/l5f1WQHDx?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=iceslam"></link><title>Динамическая обложка для группы ВК, последний подписчик, топ комментатор и прочее</title><published>2020-10-03T08:31:02.351Z</published><updated>2020-10-03T08:33:20.994Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://kotoff.net/uploads/posts/2019-03/1553019380_375194-1.jpg"></media:thumbnail><category term="php" label="PHP"></category><summary type="html">&lt;img src=&quot;https://kotoff.net/uploads/posts/2019-03/1553019380_375194-1.jpg&quot;&gt;Для установки динамической шапки требуется совсем немного, мы будем использовать компьютер как сервер, в дальнейшем сам скрипт можете установить на купленный сервер или обратиться в нашу группу для установки вашей шапки на ваше сообщество -&gt; В личные сообщения сообщества KotOFF</summary><content type="html">
  &lt;figure class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://kotoff.net/uploads/posts/2019-03/1553019380_375194-1.jpg&quot; width=&quot;645&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;Для установки динамической шапки требуется совсем немного, мы будем использовать компьютер как сервер, в дальнейшем сам скрипт можете установить на купленный сервер или обратиться в нашу группу для установки вашей шапки на ваше сообщество -&amp;gt; &lt;a href=&quot;https://vk.me/kotoffs&quot; target=&quot;_blank&quot;&gt;В личные сообщения сообщества KotOFF&lt;/a&gt;&lt;/p&gt;
  &lt;p&gt;Создание шапки происходит в 4 этапа, о них по порядку &lt;/p&gt;
  &lt;p&gt;1. Создание самой шапки.&lt;br /&gt;2. Создание скрипта.&lt;br /&gt;3. Установка OpenServer.&lt;br /&gt;4. Настройка сервера и шапки.&lt;/p&gt;
  &lt;h1&gt;1. Создание самой шапки.&lt;/h1&gt;
  &lt;p&gt;Шапка должна иметь вот такой вид примерно:&lt;/p&gt;
  &lt;figure class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://kotoff.net/uploads/posts/2019-03/1552998896_1552998867148.png&quot; width=&quot;969&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;На шапке заранее размещаете будущие отделы для аватарок и имен тех пользователей, который мы будем определять с помощью скрипта &lt;/p&gt;
  &lt;p&gt;Для создания такой шапки можно обратиться в группу, которая делает очень дешево такие шапки и оформления для сообществ — &amp;gt; &lt;a href=&quot;https://vk.me/totsamyulev&quot; target=&quot;_blank&quot;&gt;В личные сообщения сообщества Тот самый Лев&lt;/a&gt;&lt;/p&gt;
  &lt;p&gt;На этом с 1 пунктом закончим, переходим к созданию скрипта&lt;/p&gt;
  &lt;h1&gt;2. Создание скрипта.&lt;/h1&gt;
  &lt;p&gt;Этот процесс самый трудоемкий, поэтому если Вы не хотите вдаваться в подробности, то можете сразу скачать архив и перейти к 3 и 4 пункту настройки.&lt;/p&gt;
  &lt;p&gt;Создаем файл с расширением api.php (Скрипт работает на версии php +5.6) и переходим в редактор Sublime Text или любой другой и вставляем туда этот код:&lt;/p&gt;
  &lt;pre&gt;&amp;lt;?php

require_once(&amp;#x27;config.php&amp;#x27;);

function DownloadImages($url, $filename){
    $ch = curl_init($url);
    $fp = fopen($filename, &amp;#x27;wb&amp;#x27;);
    curl_setopt($ch, CURLOPT_FILE, $fp);
    curl_setopt($ch, CURLOPT_HEADER, 0);
    curl_exec($ch);
    curl_close($ch);
    fclose($fp);
}  

function getPOST($url, $post) {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url); //урл сайта к которому обращаемся 
    curl_setopt($ch, CURLOPT_HEADER, false); //выводим заголовки
    curl_setopt($ch, CURLOPT_RETURNTRANSFER,true); //теперь curl вернет нам ответ, а не выведет
    curl_setopt($ch, CURLOPT_POST, true); //передача данных методом POST
    curl_setopt($ch, CURLOPT_USERAGENT,&amp;#x27;Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.106 Safari/537.36&amp;#x27;);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $post); //тут переменные которые будут переданы методом POST
    $result = curl_exec($ch);
    curl_close($ch);
    
    return $result;
}
    
function getApiMethod($method_name, $params) {
    global $access_token;
    global $api_version;

    // Сделаем проверки на токен и версию апи, если их не указали, добавим.
    if (!array_key_exists(&amp;#x27;access_token&amp;#x27;, $params) &amp;amp;&amp;amp; !is_null($access_token)) {
        $params[&amp;#x27;access_token&amp;#x27;] = $access_token;
    }

    if (!array_key_exists(&amp;#x27;v&amp;#x27;, $params) &amp;amp;&amp;amp; !is_null($api_version)) {
        $params[&amp;#x27;v&amp;#x27;] = $api_version;
    }
    
    // Сортируем массив по ключам
    ksort($params);
    
    // Отправим запрос
    return(getPOST(&amp;#x27;https://api.vk.com/method/&amp;#x27;.$method_name, $params));
}

?&amp;gt;&lt;/pre&gt;
  &lt;p&gt;сохраняем и создаем еще 1 файл с названием config.php и вставляем в него следующий код:&lt;/p&gt;
  &lt;pre&gt;&amp;lt;?php

// KOTOFF.NET 
// Здесь вводим токен своего ПРОФИЛЯ а не сообщества. Получить можно здесь https://vkhost.github.io/
$access_token = &amp;#x27;ТОКЕН&amp;#x27;;
// ID группы
$group_id = &amp;#x27;ИД ГРУППЫ&amp;#x27;;
// Круглые аватарки [true - круглые false - квадратные]
$roundingOff = true;
// Шрифт текста (положить свой в папку font)
$font = &amp;quot;UniNeue-HeavyItalic.otf&amp;quot;; 

/* ----------------------- ПОСЛЕДНИЙ ПОДПИСАВШИЙСЯ ----------------------- */

// Показывать последнего подписчика [true - показывать false - нет]
$show_last_subscribe = true; 
// Размер шрифта
$last_subscribe_font_size = 20;
// Цвет текста
$last_subscribe_font_color = &amp;#x27;255,255,255&amp;#x27;;
// Ширина аватарки
$last_subscribe_width = 137;
// Высота аватарки
$last_subscribe_height = 137;
// Координаты аватарки по оси Х
$last_subscribe_photo_pixel_x = 44;
// Координаты аватарки по оси Y
$last_subscribe_photo_pixel_y = 66;
// Координаты имени и фамилии по оси Х
$last_subscribe_text_pixel_x = 108;
// Координаты имени и фамилии по оси Y
$last_subscribe_text_pixel_y = 235;


/* ------------------------ ТОП ПО КОЛ-ВУ ЛАЙКОВ ------------------------ */

// Показывать пользователя который за сегодня набрал большее кол-во лайков к комментариям [true - показывать false - нет]
$show_top_like = true; 
// Размер шрифта
$top_like_font_size = 20;
// Цвет текста
$top_like_font_color = &amp;#x27;255,255,255&amp;#x27;;
// Ширина аватарки
$top_like_width = 137;
// Высота аватарки
$top_like_height = 137;
// Координаты аватарки по оси Х
$top_like_photo_pixel_x = 229;
// Координаты аватарки по оси Y
$top_like_photo_pixel_y = 66;
// Координаты имени и фамилии по оси Х
$top_like_text_pixel_x = 295;
// Координаты имени и фамилии по оси Y
$top_like_text_pixel_y = 235;


/* ----------------------- ТОП ПО КОЛ-ВУ КОММЕНТОВ ----------------------- */

// Показывать пользователя который за сегодня оставил большее кол-во комментариев [true - показывать false - нет]
$show_top_comments = true;
// Размер шрифта
$top_comments_font_size = 20;
// Цвет текста
$top_comments_font_color = &amp;#x27;255,255,255&amp;#x27;;
// Ширина аватарки
$top_comments_width = 137;
// Высота аватарки
$top_comments_height = 137;
// Координаты аватарки по оси Х
$top_comments_photo_pixel_x = 416;
// Координаты аватарки по оси Y
$top_comments_photo_pixel_y = 66;
// Координаты имени и фамилии по оси Х
$top_comments_text_pixel_x = 485;
// Координаты имени и фамилии по оси Y
$top_comments_text_pixel_y = 235;

// Домашняя директория скрипта
define(&amp;#x27;BASEPATH&amp;#x27;, str_replace(&amp;#x27;\\&amp;#x27;, &amp;#x27;/&amp;#x27;, dirname(__FILE__)) . &amp;#x27;/&amp;#x27;);
// Временная зона
date_default_timezone_set(&amp;#x27;Europe/Moscow&amp;#x27;);
// Путь к финальному изображению. 
// Минимальный размер обложки 795 x 200
$output_header = BASEPATH.&amp;#x27;header/output.png&amp;#x27;;
// Путь к изображению которое будет браться за основу. 
// Минимальный размер обложки 795 x 200
$image_bg = BASEPATH.&amp;#x27;header/bg.jpg&amp;#x27;;
// Версия API
$api_version = &amp;quot;5.63&amp;quot;;

?&amp;gt;&lt;/pre&gt;
  &lt;p&gt;В данном коде нужно указать токен и ID самой группы. Токен должен быть пользовательский&lt;br /&gt;Пример:&lt;/p&gt;
  &lt;p&gt;$access_token = &amp;#x27;d398d012e185e01edf145450b7899d90b49a6dfee30af063a788deb6a33219249db3463664cd4a0354a57&amp;#x27;;&lt;br /&gt;$group_id = &amp;#x27;176771278&amp;#x27;;&lt;/p&gt;
  &lt;p&gt;Теперь создаем директорию (папку) с названием header и туда загружаем нашу шапку с таким навзанием — bg.jpg&lt;/p&gt;
  &lt;figure class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://kotoff.net/uploads/posts/2019-03/1552999851_1552999769510.png&quot; width=&quot;490&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;После этого нужно создать еще 1 папку, где будут хранится наши шрифты для имен пользователей, назовем ее font и загружаем туда наши шрифты, скачать можно ниже&lt;/p&gt;
  &lt;figure class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://kotoff.net/uploads/posts/2019-03/1553001750_1553001682538.png&quot; width=&quot;631&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;Возвращаемся туда, где создавали наши файлы и создаем финальный файл под названием index.php и давайте более детальнее разберем этот код&lt;/p&gt;
  &lt;pre&gt;&amp;lt;?php

require_once(&amp;#x27;config.php&amp;#x27;);
require_once(&amp;#x27;api.php&amp;#x27;);

header(&amp;#x27;Content-type: text/html; charset=utf-8&amp;#x27;);

// Получим текущую дату
$date_today = date(&amp;#x27;Ymd&amp;#x27;);

if($show_top_like or $show_top_comments) {
    setLog(&amp;#x27;Получаю посты группы&amp;#x27;);
    // Получим посты со стены
    // больше 100 постов получать нет смысла, так как в вк ограничение
    // разрешено постить не больше 50 постов в сутки.
    $wall_get = getApiMethod(&amp;#x27;wall.get&amp;#x27;, array(
        &amp;#x27;owner_id&amp;#x27; =&amp;gt; &amp;#x27;-&amp;#x27;.$group_id,
        &amp;#x27;count&amp;#x27; =&amp;gt; &amp;#x27;50&amp;#x27;
    ));

    if($wall_get) {
        $wall_get = json_decode($wall_get, true);

        $countlike = array();
        $countcomments = array();
        
        foreach($wall_get[&amp;#x27;response&amp;#x27;][&amp;#x27;items&amp;#x27;] as $wall) {
            
            // Получим кол-во комментариев к посту
            $count = $wall[&amp;#x27;comments&amp;#x27;][&amp;#x27;count&amp;#x27;];
            $offset = 0;

            if($count &amp;gt; 0) { 
                // Получим все комментарии, так как их может быть больше 100.
                while($offset &amp;lt; $count){
                    setLog(&amp;#x27;Получаю кол-во комментариев к посту &amp;#x27;.$wall[&amp;#x27;id&amp;#x27;]);
                    // Отправим запрос на получение комментариев
                    $comments_get = getApiMethod(&amp;#x27;wall.getComments&amp;#x27;, array(
                        &amp;#x27;owner_id&amp;#x27; =&amp;gt; &amp;#x27;-&amp;#x27;.$group_id,
                        &amp;#x27;post_id&amp;#x27; =&amp;gt; $wall[&amp;#x27;id&amp;#x27;],
                        &amp;#x27;need_likes&amp;#x27; =&amp;gt; &amp;#x27;1&amp;#x27;,
                        &amp;#x27;count&amp;#x27; =&amp;gt; &amp;#x27;100&amp;#x27;,
                        &amp;#x27;offset&amp;#x27; =&amp;gt; $offset
                    ));
                    
                    if($comments_get) {
                        $comments_get = json_decode($comments_get, true);

                        foreach($comments_get[&amp;#x27;response&amp;#x27;][&amp;#x27;items&amp;#x27;] as $comments) {
                            
                            if($date_today == date(&amp;#x27;Ymd&amp;#x27;, $comments[&amp;#x27;date&amp;#x27;])) {
                                // В двух словах мы заносим данные в массив, суммируя их
                                if(!isset($countcomments[$comments[&amp;#x27;from_id&amp;#x27;]]) and !isset($countlike[$comments[&amp;#x27;from_id&amp;#x27;]])) {
                                    $countcomments[$comments[&amp;#x27;from_id&amp;#x27;]] = 1;
                                    $countlike[$comments[&amp;#x27;from_id&amp;#x27;]] = $comments[&amp;#x27;likes&amp;#x27;][&amp;#x27;count&amp;#x27;];   
                                } else {
                                    $countcomments[$comments[&amp;#x27;from_id&amp;#x27;]]++;
                                    $countlike[$comments[&amp;#x27;from_id&amp;#x27;]] += $comments[&amp;#x27;likes&amp;#x27;][&amp;#x27;count&amp;#x27;];
                                } 
                                var_dump($comments);
                            }
                            
                        }  
                    }

                    if($offset&amp;lt;$count) 
                        $offset = $offset + 100;
                }
            }

        }
    }
}



if($show_top_like) {
$day_like_top = 0;


if(count($countlike) &amp;gt; 0) {
    // Теперь найдем кто суммарно получил большее кол-во лайков к комментариям
    $value = max($countlike); 
    $day_like_top = array_search($value, $countlike);
    setLog(&amp;#x27;Получаю ID кто сумарно набрал большее кол-во лайков к комментариям &amp;#x27;.$day_like_top);

    if($day_like_top &amp;gt; 0) {
        $user_top_like = getApiMethod(&amp;#x27;users.get&amp;#x27;, array(
            &amp;#x27;user_ids&amp;#x27; =&amp;gt; $day_like_top,
            &amp;#x27;fields&amp;#x27; =&amp;gt; &amp;#x27;photo_200&amp;#x27;
        ));

        if($user_top_like) {
            $user_top_like = json_decode($user_top_like, true);

            $top_like_name = $user_top_like[&amp;#x27;response&amp;#x27;][0][&amp;#x27;first_name&amp;#x27;];
            $top_like_lastname = $user_top_like[&amp;#x27;response&amp;#x27;][0][&amp;#x27;last_name&amp;#x27;];
            $top_like_photo = $user_top_like[&amp;#x27;response&amp;#x27;][0][&amp;#x27;photo_200&amp;#x27;];
            
            // Скачиваем фото
            if(!empty($top_like_name) &amp;amp;&amp;amp; !empty($top_like_lastname) &amp;amp;&amp;amp; !empty($top_like_photo)){
                DownloadImages($top_like_photo, &amp;#x27;header/top_likes.jpg&amp;#x27;);
            }
        }
    }
}

}


if($show_top_comments) {
    $day_comment_top = 0;




if(count($countcomments) &amp;gt; 0) {
        // Теперь найдем кто суммарно написал больше всех комментариев
        $value = max($countcomments); 
        $day_comment_top = array_search($value, $countcomments);
        setLog(&amp;#x27;Получаю ID кто суммарно написал больше всех комментариев &amp;#x27;.$day_comment_top);

        if($day_comment_top &amp;gt; 0) {
            $user_top_comment = getApiMethod(&amp;#x27;users.get&amp;#x27;, array(
                &amp;#x27;user_ids&amp;#x27; =&amp;gt; $day_comment_top,
                &amp;#x27;fields&amp;#x27; =&amp;gt; &amp;#x27;photo_200&amp;#x27;
            ));

            if($user_top_comment) {
                $user_top_comment = json_decode($user_top_comment, true);

                $top_comment_name = $user_top_comment[&amp;#x27;response&amp;#x27;][0][&amp;#x27;first_name&amp;#x27;];
                $top_comment_lastname = $user_top_comment[&amp;#x27;response&amp;#x27;][0][&amp;#x27;last_name&amp;#x27;];
                $top_comment_photo = $user_top_comment[&amp;#x27;response&amp;#x27;][0][&amp;#x27;photo_200&amp;#x27;];
                
                // Скачиваем фото
                if(!empty($top_comment_name) &amp;amp;&amp;amp; !empty($top_comment_lastname) &amp;amp;&amp;amp; !empty($top_comment_photo)){
                    DownloadImages($top_comment_photo, &amp;#x27;header/top_comments.jpg&amp;#x27;);
                }
            }
        }
    }
}


if($show_last_subscribe) {
    // Теперь найдем последнего подписчика
    $last_subscribe = getApiMethod(&amp;#x27;groups.getMembers&amp;#x27;, array(
                &amp;#x27;group_id&amp;#x27; =&amp;gt; $group_id,
                &amp;#x27;sort&amp;#x27; =&amp;gt; &amp;#x27;time_desc&amp;#x27;,
                &amp;#x27;count&amp;#x27; =&amp;gt; &amp;#x27;1&amp;#x27;,
                &amp;#x27;fields&amp;#x27; =&amp;gt; &amp;#x27;photo_200&amp;#x27;,
                &amp;#x27;access_token&amp;#x27; =&amp;gt; $access_token
            ));

    if($last_subscribe) {
        $last_subscribe = json_decode($last_subscribe, true);

        $members_count = $last_subscribe[&amp;#x27;response&amp;#x27;][&amp;#x27;count&amp;#x27;];
        $last_subscribe_firstname = $last_subscribe[&amp;#x27;response&amp;#x27;][&amp;#x27;items&amp;#x27;][0][&amp;#x27;first_name&amp;#x27;];
        $last_subscribe_lastname = $last_subscribe[&amp;#x27;response&amp;#x27;][&amp;#x27;items&amp;#x27;][0][&amp;#x27;last_name&amp;#x27;];
        $last_subscribe_photo = $last_subscribe[&amp;#x27;response&amp;#x27;][&amp;#x27;items&amp;#x27;][0][&amp;#x27;photo_200&amp;#x27;];

        setLog(&amp;#x27;Получаю последнего вступившего в группу &amp;#x27;.$last_subscribe_firstname.&amp;#x27; &amp;#x27;.$last_subscribe_lastname);
        
        // Скачиваем фото
        if(!empty($last_subscribe_firstname) &amp;amp;&amp;amp; !empty($last_subscribe_lastname) &amp;amp;&amp;amp; !empty($last_subscribe_photo)){
            DownloadImages($last_subscribe_photo, &amp;#x27;header/last_subscribe.jpg&amp;#x27;);
        }

    }
}
sleep(3);
if($show_weather){
    $ResultWeatherApi = getPOST(&amp;#x27;http://api.openweathermap.org/data/2.5/weather&amp;#x27;, array(
        &amp;#x27;id&amp;#x27; =&amp;gt; $weather_city_id,
        &amp;#x27;units&amp;#x27; =&amp;gt; &amp;#x27;metric&amp;#x27;,
        &amp;#x27;CNT&amp;#x27; =&amp;gt; &amp;#x27;1&amp;#x27;,
        &amp;#x27;lang&amp;#x27; =&amp;gt; &amp;#x27;ru&amp;#x27;,
        &amp;#x27;appid&amp;#x27; =&amp;gt; $weather_api_id
    ));

    $s = array(
        &amp;#x27;id&amp;#x27; =&amp;gt; $weather_city_id,
        &amp;#x27;units&amp;#x27; =&amp;gt; &amp;#x27;metric&amp;#x27;,
        &amp;#x27;CNT&amp;#x27; =&amp;gt; &amp;#x27;1&amp;#x27;,
        &amp;#x27;lang&amp;#x27; =&amp;gt; &amp;#x27;ru&amp;#x27;,
        &amp;#x27;appid&amp;#x27; =&amp;gt; $weather_api_id
    );
}

// -----------------------------------------------------------------------------
// --------------------------------- РИСОВАНИЕ ---------------------------------
// -----------------------------------------------------------------------------
setLog(&amp;#x27;Создание обложки&amp;#x27;);

$draw = new ImagickDraw(); 
$bg = new Imagick($image_bg);
$draw-&amp;gt;setFont(BASEPATH.&amp;quot;/font/&amp;quot;.$font);
$draw-&amp;gt;setTextAlignment(Imagick::ALIGN_CENTER);

// Последний подписчик
if($show_last_subscribe) {
    $file_name = BASEPATH.&amp;#x27;header/last_subscribe.jpg&amp;#x27;;

    if(file_exists($file_name) &amp;amp;&amp;amp; $show_last_subscribe) {
        $last_subscribe_photo = new Imagick($file_name);
        if($roundingOff==true) {
            RoundingOff($last_subscribe_photo, $last_subscribe_width,$last_subscribe_height);
        }

        $draw-&amp;gt;setFontSize($last_subscribe_font_size);
        $draw-&amp;gt;setFillColor(&amp;quot;rgb(&amp;quot;.$last_subscribe_font_color.&amp;quot;)&amp;quot;);

        $bg-&amp;gt;compositeImage($last_subscribe_photo, Imagick::COMPOSITE_DEFAULT, $last_subscribe_photo_pixel_x, $last_subscribe_photo_pixel_y);
        $bg-&amp;gt;annotateImage($draw, $last_subscribe_text_pixel_x, $last_subscribe_text_pixel_y, 0, mb_strtoupper($last_subscribe_firstname.&amp;quot;\n&amp;quot;.$last_subscribe_lastname, &amp;#x27;UTF-8&amp;#x27;));
    }
}

// Топ по комментам
$file_name = BASEPATH.&amp;#x27;header/top_comments.jpg&amp;#x27;;

if(file_exists($file_name) &amp;amp;&amp;amp; $show_top_comments) {
    $top_comments_photo = new Imagick($file_name);
    if($roundingOff==true) {
        RoundingOff($top_comments_photo, $top_comments_width,$top_comments_height);
    }

    $draw-&amp;gt;setFontSize($top_comments_font_size);
    $draw-&amp;gt;setFillColor(&amp;quot;rgb(&amp;quot;.$top_comments_font_color.&amp;quot;)&amp;quot;);

    $bg-&amp;gt;compositeImage($top_comments_photo, Imagick::COMPOSITE_DEFAULT, $top_comments_photo_pixel_x, $top_comments_photo_pixel_y);
    $bg-&amp;gt;annotateImage($draw, $top_comments_text_pixel_x, $top_comments_text_pixel_y, 0, mb_strtoupper($top_comment_name.&amp;quot;\n&amp;quot;.$top_comment_lastname, &amp;#x27;UTF-8&amp;#x27;));
}

// Топ по лайкам
$file_name = BASEPATH.&amp;#x27;header/top_likes.jpg&amp;#x27;;

if(file_exists($file_name) &amp;amp;&amp;amp; $show_top_like) {
    $top_like_photo = new Imagick($file_name);
    if($roundingOff==true) {
        RoundingOff($top_like_photo, $top_like_width,$top_like_height);
    }

    $draw-&amp;gt;setFontSize($top_like_font_size);
    $draw-&amp;gt;setFillColor(&amp;quot;rgb(&amp;quot;.$top_like_font_color.&amp;quot;)&amp;quot;);

    $bg-&amp;gt;compositeImage($top_like_photo, Imagick::COMPOSITE_DEFAULT, $top_like_photo_pixel_x, $top_like_photo_pixel_y);
    $bg-&amp;gt;annotateImage($draw, $top_like_text_pixel_x, $top_like_text_pixel_y, 0, mb_strtoupper($top_like_name.&amp;quot;\n&amp;quot;.$top_like_lastname, &amp;#x27;UTF-8&amp;#x27;));
}

$bg-&amp;gt;setImageFormat(&amp;quot;png&amp;quot;);
$bg-&amp;gt;writeImage($output_header);

//echo &amp;#x27;&amp;lt;img src=&amp;quot;&amp;#x27;.&amp;#x27;header/output.png&amp;#x27;.&amp;#x27;&amp;quot;&amp;gt;&amp;#x27;;

// -----------------------------------------------------------------------------
// --------------------------- ЗАГРУЗКА НА СЕРВЕР ------------------------------
// -----------------------------------------------------------------------------

// Получим адресс сервера
$getUrl = getApiMethod(&amp;#x27;photos.getOwnerCoverPhotoUploadServer&amp;#x27;, array(
    &amp;#x27;group_id&amp;#x27; =&amp;gt; $group_id,
    &amp;#x27;crop_x2&amp;#x27; =&amp;gt; &amp;#x27;1590&amp;#x27;
));
setLog(&amp;#x27;Получаю адресс сервера &amp;#x27;.$getUrl);


if($getUrl) {
    $getUrl = json_decode($getUrl, true);

    $url = $getUrl[&amp;#x27;response&amp;#x27;][&amp;#x27;upload_url&amp;#x27;];

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); 
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
    curl_setopt($ch, CURLOPT_POSTFIELDS, array(&amp;#x27;photo&amp;#x27; =&amp;gt; new CURLFile($output_header, &amp;#x27;image/jpeg&amp;#x27;, &amp;#x27;image0&amp;#x27;)));
    $upload = curl_exec( $ch );
    curl_close( $ch );

    if($upload) {
        $upload = json_decode($upload, true);

        $getUrl = getApiMethod(&amp;#x27;photos.saveOwnerCoverPhoto&amp;#x27;, array(
            &amp;#x27;hash&amp;#x27; =&amp;gt; $upload[&amp;#x27;hash&amp;#x27;],
            &amp;#x27;photo&amp;#x27; =&amp;gt; $upload[&amp;#x27;photo&amp;#x27;],
        ));
        
        setLog(&amp;#x27;Загружаю обложку &amp;#x27;.$getUrl);

        if(stripos($getUrl, &amp;#x27;response&amp;quot;:{&amp;quot;images&amp;quot;:[{&amp;#x27;)) {
            print_r(&amp;#x27;Успешно загрузили обложку &amp;lt;a href =&amp;quot;https://kotoff.net/ target=&amp;quot;_blank&amp;quot; &amp;gt;kotoff.net&amp;lt;/a&amp;gt;&amp;lt;/br&amp;gt;&amp;#x27;);
             echo &amp;#x27;&amp;lt;p&amp;gt;*** Больше всех сегодня лайков набрал: &amp;lt;a href =&amp;quot;https://vk.com/id&amp;#x27;.$day_like_top.&amp;#x27;&amp;quot; target=&amp;quot;_blank&amp;quot; &amp;gt;&amp;#x27;.$top_like_name.&amp;#x27; &amp;#x27;.$top_like_lastname.&amp;#x27; - &amp;#x27;.$countlike[$day_like_top].&amp;#x27;&amp;lt;/a&amp;gt; шт.&amp;lt;/p&amp;gt;&amp;lt;/br&amp;gt;&amp;#x27;;
            echo &amp;#x27;&amp;lt;p&amp;gt;*** Больше всех сегодня комментариев написал: &amp;lt;a href =&amp;quot;https://vk.com/id&amp;#x27;.$day_comment_top.&amp;#x27;&amp;quot; target=&amp;quot;_blank&amp;quot; &amp;gt;&amp;#x27;.$top_comment_name.&amp;#x27; &amp;#x27;.$top_comment_lastname.&amp;#x27; - &amp;#x27;.$countcomments[$day_comment_top].&amp;#x27;&amp;lt;/a&amp;gt; шт.&amp;lt;/p&amp;gt;&amp;lt;/br&amp;gt;&amp;#x27;;
              echo &amp;#x27;&amp;lt;p&amp;gt;*** Последний подписчик &amp;lt;a href =&amp;quot;https://vk.com/id&amp;#x27;.$day_like_top.&amp;#x27;&amp;quot; target=&amp;quot;_blank&amp;quot; &amp;gt;&amp;#x27;.$last_subscribe_firstname.&amp;#x27; &amp;#x27;.$last_subscribe_lastname.&amp;#x27;&amp;lt;/a&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;/br&amp;gt;&amp;#x27;;
             echo &amp;#x27;&amp;lt;br&amp;gt;&amp;lt;img src=&amp;quot;&amp;#x27;.&amp;#x27;header/output.png&amp;#x27;.&amp;#x27;&amp;quot;&amp;gt;&amp;#x27;;
            setLog(&amp;#x27;Загружаю обложку в &amp;#x27;.$group_id);
        } else {
            print_r(&amp;#x27;Ошибка при загрузке обложки &amp;#x27;.$getUrl);
            setLog(&amp;#x27;Ошибка при загрузке обложки &amp;#x27;.$getUrl);
        }
        
    }
   
}



function RoundingOff($_imagick, $width, $height) {
    $_imagick-&amp;gt;adaptiveResizeImage($width, $height, 100);
    $_imagick-&amp;gt;setImageFormat(&amp;#x27;png&amp;#x27;);
        
    $_imagick-&amp;gt;roundCornersImage(
        90, 90, 0, 0, 0
    );
}

function setLog($message) {
    $log_file_name = &amp;#x27;logs.txt&amp;#x27;;

    if(file_exists($log_file_name)) {
        $log = array_diff(explode(&amp;quot;\r\n&amp;quot;, file_get_contents($log_file_name)), array(&amp;#x27;&amp;#x27;));
    }

    $log[] = date(&amp;quot;m.d.Y-H:i:s&amp;quot;).&amp;#x27; | &amp;#x27;.$message;

    if(file_put_contents($log_file_name, implode(&amp;quot;\r\n&amp;quot;, $log))) {
        return true;
    } else {
        return false;
    }
}


?&amp;gt;&lt;/pre&gt;
  &lt;p&gt;Данный код собирает посты и с помощью циклов считает лайки, комментарии и определяет последнего вступившего. Код полностью рабочий, более детальную настройку рассмотрим в 4 пункте данной статьи. У данного скрипта есть несколько недоработок, часть из них была уже исправлена, для платных групп мы используем собственную версию скрипта. Сохраняем все файлы и переходим к 3 пункту настроек.&lt;/p&gt;
  &lt;h1&gt;3. Установка OpenServer.&lt;/h1&gt;
  &lt;p&gt;Для работы шапки нам потребуется сервер, а что бы не покупать и не платить деньги, мы будем использовать &lt;strong&gt;Open Server Panel&lt;/strong&gt; — это портативная серверная платформа и программная среда для разработки&lt;/p&gt;
  &lt;figure class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://kotoff.net/uploads/posts/2019-03/1553002409_logo.gif&quot; width=&quot;360&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;Переходим на официальный сайт и скачиваем дистрибутив-&amp;gt; &lt;a href=&quot;https://kotoff.net/index.php?do=go&amp;url=aHR0cHM6Ly9vc3BhbmVsLmlvL2Rvd25sb2FkLw%3D%3D&quot; target=&quot;_blank&quot;&gt;Скачать Open Server&lt;/a&gt;&lt;/p&gt;
  &lt;p&gt;Нам предлагают на выбор 3 версии дистрибутива (ULTIMATE PREMIUM BASIC) с различным включенным функционалом, нам подойдет самый простой — BASIC, но если есть возможность, советую скачивать ULTIMATE версию!&lt;/p&gt;
  &lt;figure class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://kotoff.net/uploads/posts/2019-03/1553002703_1553002655563.png&quot; width=&quot;853&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;После скачивания, распаковываем архив в удобное для Вас место, у Вас появится папка OSPanel&lt;/p&gt;
  &lt;figure class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://kotoff.net/uploads/posts/2019-03/1553002919_1553002859322.png&quot; width=&quot;1145&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;Заходим в нее и запускаем наш сервер&lt;/p&gt;
  &lt;figure class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://kotoff.net/uploads/posts/2019-03/1553003002_1553002931484.png&quot; width=&quot;648&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;В трее, у Вас появится красный флажок, сервер нужно запустить выбрав зеленый&lt;/p&gt;
  &lt;figure class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://kotoff.net/uploads/posts/2019-03/1553003172_1553003081501.png&quot; width=&quot;718&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;После запуска, там же выбираем &lt;u&gt;Папка с сайтами&lt;/u&gt; и открываем уже созданный каталог с сайтом localhost, удаляем все что там есть и загружаем наши созданные файлы&lt;/p&gt;
  &lt;figure class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://kotoff.net/uploads/posts/2019-03/1553003279_1553003236276.png&quot; width=&quot;984&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;Все готово, переходим к настройке и запуску.&lt;/p&gt;
  &lt;h1&gt;4. Настройка сервера и шапки.&lt;/h1&gt;
  &lt;p&gt;После успешной настройки, переходим к настройке, перейдя в браузере по адресу — &lt;a href=&quot;http://localhost/index.php&quot; target=&quot;_blank&quot;&gt;http://localhost/index.php&lt;/a&gt;:&lt;/p&gt;
  &lt;p&gt;Если получили Warning похожий на этот:&lt;/p&gt;
  &lt;figure class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://kotoff.net/uploads/posts/2019-03/1553003500_1553003408224.png&quot; width=&quot;1036&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;То Вам нужно проверить правильно ли Вы указали токен профиля или ID группы, получить ID группы можно перейдя настройки сообщества&lt;/p&gt;
  &lt;figure class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://kotoff.net/uploads/posts/2019-03/1553003691_1553003667224.png&quot; width=&quot;894&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;Если у Вас стоит короткое название, то просто откройте любую фотографию в группе и скопируйте ID с браузерной строки, все что после photo-ID_ЦИФРЫ (без минуса):&lt;/p&gt;
  &lt;figure class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://kotoff.net/uploads/posts/2019-03/1553003847_1553003749425.png&quot; width=&quot;613&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;Если же Вы получили шапку:&lt;/p&gt;
  &lt;figure class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://kotoff.net/uploads/posts/2019-03/1553003559_1553003499512.png&quot; width=&quot;1594&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;Это значит что Вы сделали все правильно, давайте перейдем в группу, напишем пост, комментарий и поставим лайк:&lt;/p&gt;
  &lt;figure class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://kotoff.net/uploads/posts/2019-03/1553004161_1553004073253.png&quot; width=&quot;902&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;Снова переходим на — &lt;a href=&quot;http://localhost/index.php&quot; target=&quot;_blank&quot;&gt;http://localhost/index.php&lt;/a&gt; и смотрим что у нас получилось:&lt;/p&gt;
  &lt;figure class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://kotoff.net/uploads/posts/2019-03/1553004202_1553004195353.png&quot; width=&quot;753&quot; /&gt;
  &lt;/figure&gt;
  &lt;figure class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://kotoff.net/uploads/posts/2019-03/1553004236_1553004219307.png&quot; width=&quot;884&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;Как видим все работает, аватарки и текст можно перемещать, так как в Вашей шапке расположение может быть другое как тут например&lt;/p&gt;
  &lt;figure class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://kotoff.net/uploads/posts/2019-03/1553004367_1553004345525.png&quot; width=&quot;834&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;Для этого открываем файл config.php&lt;/p&gt;
  &lt;figure class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://kotoff.net/uploads/posts/2019-03/1553004464_1553004433607.png&quot; width=&quot;1772&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;И меняем координаты, это один из трудоемких процессов, так как здесь нужно будет поиграться с положением и найти те самые координаты, примерное расположение можно узнавать используя Paint, наводим курсор в верхнюю правую точку устанавливаемого аватара и ниже получаем координаты:&lt;/p&gt;
  &lt;figure class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://kotoff.net/uploads/posts/2019-03/1553004700_1553004608911.png&quot; width=&quot;518&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;Это условные координаты по оси Х и Y, далее просто смещаете по несколько пикселей в одну из сторон и находите оптимальную точку.&lt;/p&gt;
  &lt;p&gt;Настройка на этом практически завершена. Осталось сделать так, что бы скрипт сам обновлял ее, допустим каждые 5 минут, заходим в настройки OpenServer из трея и выбираем вкладку планировщик задач, прописываем команду:&lt;/p&gt;
  &lt;p&gt;%progdir%\modules\wget\bin\wget.exe -q —no-cache http://localhost/index.php&lt;/p&gt;
  &lt;p&gt;И указываем тайминги, в какое время нужно запускать скрипт, мы выставили что бы скрипт запускался каждые 5 минут в любой час, день, неделю и месяц, нажимаем добавить и сохраняем, сервер сам перезагрузится и планировщик задач начнет выполнять команду в указанные временные интервалы&lt;/p&gt;
  &lt;figure class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://kotoff.net/uploads/posts/2019-03/1553004946_1553004849271.png&quot; width=&quot;878&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;При желании, можете загрузить скрипт на хостинг, и использовать CRON для запуска этого скрипта в нужное время.&lt;/p&gt;
  &lt;p&gt;На этом у меня все, пишите свои комментарии, задавайте вопросы, мы постараемся ответить на них, всем динамичных шапок&lt;/p&gt;

</content></entry><entry><id>iceslam:easy-generating-ssl-lets-encrypt-on-vps</id><link rel="alternate" type="text/html" href="https://teletype.in/@iceslam/easy-generating-ssl-lets-encrypt-on-vps?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=iceslam"></link><title>Как повысить безопасность Apache с помощью Let's Encrypt в Ubuntu 18.04</title><published>2020-07-29T22:28:51.274Z</published><updated>2020-07-29T22:32:50.287Z</updated><category term="ubuntu" label="Ubuntu"></category><summary type="html">Let’s Encrypt представляет собой центр сертификации (Certificate Authority, CA), позволяющий получать и устанавливать бесплатные сертификаты TLS/SSL, тем самым позволяя использовать шифрованный HTTPS на веб-серверах. Процесс получения сертификатов упрощается за счёт наличия клиента Certbot, который пытается автоматизировать большую часть (если не все) необходимых операций. В настоящее время весь процесс получения и установки сертификатов полностью автоматизирован и для Apache и для Nginx.</summary><content type="html">
  &lt;h3&gt;Введение&lt;/h3&gt;
  &lt;p&gt;Let’s Encrypt представляет собой центр сертификации (Certificate Authority, CA), позволяющий получать и устанавливать бесплатные &lt;a href=&quot;https://www.digitalocean.com/community/tutorials/openssl-essentials-working-with-ssl-certificates-private-keys-and-csrs&quot; target=&quot;_blank&quot;&gt;сертификаты TLS/SSL&lt;/a&gt;, тем самым позволяя использовать шифрованный HTTPS на веб-серверах. Процесс получения сертификатов упрощается за счёт наличия клиента Certbot, который пытается автоматизировать большую часть (если не все) необходимых операций. В настоящее время весь процесс получения и установки сертификатов полностью автоматизирован и для Apache и для Nginx.&lt;/p&gt;
  &lt;p&gt;В этом руководстве мы используем Certbot для получения бесплатного SSL сертификата для Apache на Ubuntu 18.04, а также настроим автоматическое продление этого сертификата.&lt;/p&gt;
  &lt;p&gt;В этом руководстве мы будем использовать файл отдельного виртуального хоста Apache вместо дефолтного файла конфигурации. &lt;a href=&quot;https://www.digitalocean.com/community/tutorials/how-to-install-the-apache-web-server-on-ubuntu-18-04#step-5-%E2%80%94-setting-up-virtual-hosts-recommended&quot; target=&quot;_blank&quot;&gt;Мы рекомендуем&lt;/a&gt; создавать новый файлы виртуальных хостов Apache для каждого доменного имени, потому что это помогает избегать распространённых ошибок и использовать дефолтные файлы в качестве примера корректной конфигурации, когда что-нибудь пойдёт не так.&lt;/p&gt;
  &lt;h2&gt;Шаг 1 - Установка Certbot&lt;/h2&gt;
  &lt;p&gt;Перед началом использования Let’s Encrypt для получения SSL сертификаты установим Certbot на ваш сервер.&lt;/p&gt;
  &lt;p&gt;Certbot находится в активной разработке, поэтому пакеты Certbot, предоставляемые Ubuntu, обычно являются устаревшими. Тем не менее, разработчики Certbot поддерживают свой репозиторий пакетов для Ubuntu с актуальными версиями, поэтому мы будем использовать именно этот репозиторий.&lt;/p&gt;
  &lt;p&gt;Сначала добавим репозиторий:&lt;/p&gt;
  &lt;pre&gt;sudo add-apt-repository ppa:certbot/certbot
&lt;/pre&gt;
  &lt;p&gt;Далее нажмите &lt;code&gt;ENTER&lt;/code&gt;.&lt;/p&gt;
  &lt;p&gt;Установим пакет Certbot для Apache с помощью &lt;code&gt;apt&lt;/code&gt;:&lt;/p&gt;
  &lt;pre&gt;sudo apt install python-certbot-apache
&lt;/pre&gt;
  &lt;p&gt;Теперь Certbot готов к использованию, но для того, чтобы он мог настроить SSL для Apache, нам сперва необходимо проверить кое-какие настройки Apache.&lt;/p&gt;
  &lt;h2&gt;Шаг 2 - Настройка SSL сертификата&lt;/h2&gt;
  &lt;p&gt;Certbot должен иметь возможность найти корректный виртуальный хост в вашей конфигурации Apache для того, чтобы автоматически конфигурировать SSL. Для этого он будет искать директиву &lt;code&gt;ServerName&lt;/code&gt;, которая совпадает с доменным именем, для которого вы запросите сертификат.&lt;/p&gt;
  &lt;p&gt;Если вы следовали инструкциям по &lt;a href=&quot;https://www.digitalocean.com/community/tutorials/how-to-install-the-apache-web-server-on-ubuntu-18-04#step-5-%E2%80%94-setting-up-virtual-hosts-recommended&quot; target=&quot;_blank&quot;&gt;настройке виртуального хоста в руководстве по установке Apache&lt;/a&gt;, у вас должен быть виртуальный хост для вашего домена по адресу &lt;code&gt;/etc/apache2/sites-available/example.com.conf&lt;/code&gt; с уже правильно настроенной директивой &lt;code&gt;ServerName&lt;/code&gt;.&lt;/p&gt;
  &lt;p&gt;Для проверки откройте файл серверного блока в &lt;code&gt;nano&lt;/code&gt; или любом другом текстовом редакторе:&lt;/p&gt;
  &lt;pre&gt;sudo nano /etc/apache2/sites-available/example.com.conf
&lt;/pre&gt;
  &lt;p&gt;Найдите строку с &lt;code&gt;ServerName&lt;/code&gt;. Она должна выглядеть примерно так:&lt;/p&gt;
  &lt;pre&gt;...
ServerName example.com;
...&lt;/pre&gt;
  &lt;p&gt;Если она выглядит таким образом, закройте файл и переходите к следующему шагу.&lt;/p&gt;
  &lt;p&gt;Если она не выглядит так, как описано выше, обновите директиву &lt;code&gt;ServerName&lt;/code&gt;. Затем сохраните и закройте файл, после чего проверьте корректность синтаксиса вашего конфигурационного файла командой:&lt;/p&gt;
  &lt;pre&gt;sudo apache2ctl configtest
&lt;/pre&gt;
  &lt;p&gt;Если вы получили ошибку, откройте файл серверного блока и проверьте его на наличие опечаток или пропущенных символов. После того, как ваш конфигурационный файл будет проходить проверку на корректность, перезагрузите Apache для применения новой конфигурации:&lt;/p&gt;
  &lt;pre&gt;sudo systemctl reload apache2
&lt;/pre&gt;
  &lt;p&gt;Теперь Certbot может находить и обновлять корректный виртуальный хост.&lt;/p&gt;
  &lt;p&gt;Далее обновим настройки файрвола для пропуска HTTPS трафика.&lt;/p&gt;
  &lt;h2&gt;Шаг 3 - Разрешение HTTPS в файрволе&lt;/h2&gt;
  &lt;p&gt;Если у вас включен файрвол &lt;code&gt;ufw&lt;/code&gt;, как рекомендуется в руководстве по первичной настройке сервера, вам необходимо внести некоторые изменения в его настройки для разрешения трафика HTTPS. К счастью, Apache регистрирует необходимые профили в &lt;code&gt;ufw&lt;/code&gt; в момент установки.&lt;/p&gt;
  &lt;p&gt;Вы можете ознакомиться с текущими настройками командой:&lt;/p&gt;
  &lt;pre&gt;sudo ufw status
&lt;/pre&gt;
  &lt;p&gt;Скорее всего вывод будет выглядеть следующим образом:&lt;/p&gt;
  &lt;pre&gt;ВыводStatus: active

To                         Action      From
--                         ------      ----
OpenSSH                    ALLOW       Anywhere                  
Apache                     ALLOW       Anywhere                  
OpenSSH (v6)               ALLOW       Anywhere (v6)             
Apache (v6)                ALLOW       Anywhere (v6)
&lt;/pre&gt;
  &lt;p&gt;Как видно из вывода, разрешён только трафик HTTP.&lt;/p&gt;
  &lt;p&gt;Для того, чтобы разрешить трафик HTTPS, разрешим профиль &lt;code&gt;Apache Full&lt;/code&gt; и удалим избыточный профиль &lt;code&gt;Apache&lt;/code&gt;:&lt;/p&gt;
  &lt;pre&gt;sudo ufw allow &amp;#x27;Apache Full&amp;#x27;
sudo ufw delete allow &amp;#x27;Apache&amp;#x27;
&lt;/pre&gt;
  &lt;p&gt;Проверим внесённые изменения:&lt;/p&gt;
  &lt;pre&gt;sudo ufw status
&lt;/pre&gt;
  &lt;p&gt;Теперь настройки &lt;code&gt;ufw&lt;/code&gt; должны выглядеть следующим образом:&lt;/p&gt;
  &lt;pre&gt;ВыводStatus: active

To                         Action      From
--                         ------      ----
OpenSSH                    ALLOW       Anywhere                  
Apache Full                ALLOW       Anywhere                  
OpenSSH (v6)               ALLOW       Anywhere (v6)             
Apache Full (v6)           ALLOW       Anywhere (v6)  
&lt;/pre&gt;
  &lt;p&gt;Теперь мы можем запустить Certbot и получить наши сертификаты.&lt;/p&gt;
  &lt;h2&gt;Шаг 4 - Получение SSL сертификата&lt;/h2&gt;
  &lt;p&gt;Certbot предоставляет несколько способов получения сертификатов SSL с использованием плагинов. Плагин для Apache берёт на себя настройку Apache и перезагрузку конфигурации, когда это необходимо. Для использования плагина выполним команду:&lt;/p&gt;
  &lt;pre&gt;sudo certbot --apache -d example.com -d www.example.com
&lt;/pre&gt;
  &lt;p&gt;Эта команда запускает &lt;code&gt;certbot&lt;/code&gt; с плагином &lt;code&gt;--apache&lt;/code&gt;, ключи &lt;code&gt;-d&lt;/code&gt; определяют имена доменов, для которых должен быть выпущен сертификат.&lt;/p&gt;
  &lt;p&gt;Если это первый раз, когда вы запускаете &lt;code&gt;certbot&lt;/code&gt;, вам будет предложено ввести адрес электронной почты и согласиться с условиями использования сервиса. После этого &lt;code&gt;certbot&lt;/code&gt; свяжется с сервером Let’s Encrypt, а затем проверит, что вы действительно контролируете домен, для которого вы запросили сертификат.&lt;/p&gt;
  &lt;p&gt;Если всё прошло успешно, &lt;code&gt;certbot&lt;/code&gt; спросит, как вы хотите настроить конфигурацию HTTPS.&lt;/p&gt;
  &lt;pre&gt;ВыводPlease choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access.
-------------------------------------------------------------------------------
1: No redirect - Make no further changes to the webserver configuration.
2: Redirect - Make all requests redirect to secure HTTPS access. Choose this for
new sites, or if you&amp;#x27;re confident your site works on HTTPS. You can undo this
change by editing your web server&amp;#x27;s configuration.
-------------------------------------------------------------------------------
Select the appropriate number [1-2] then [enter] (press &amp;#x27;c&amp;#x27; to cancel):
&lt;/pre&gt;
  &lt;p&gt;Выберите подходящий вариант и нажмите &lt;code&gt;ENTER&lt;/code&gt;. Конфигурация будет обновлена, а Apache перезапущен для применения изменений. &lt;code&gt;certbot&lt;/code&gt; выдаст сообщение о том, что процесс прошёл успешно, и где хранятся ваши сертификаты:&lt;/p&gt;
  &lt;pre&gt;ВыводIMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/example.com/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/example.com/privkey.pem
   Your cert will expire on 2018-07-23. To obtain a new or tweaked
   version of this certificate in the future, simply run certbot again
   with the &amp;quot;certonly&amp;quot; option. To non-interactively renew *all* of
   your certificates, run &amp;quot;certbot renew&amp;quot;
 - Your account credentials have been saved in your Certbot
   configuration directory at /etc/letsencrypt. You should make a
   secure backup of this folder now. This configuration directory will
   also contain certificates and private keys obtained by Certbot so
   making regular backups of this folder is ideal.
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let&amp;#x27;s Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le
&lt;/pre&gt;
  &lt;p&gt;Ваши сертификаты загружены, установлены и работают. Попробуйте перезагрузить ваш сайт с использованием &lt;code&gt;https://&lt;/code&gt; и вы увидите значок безопасности в браузере. Он означает, что соединение с сайтом зашифровано, обычно он выглядит, как зелёная иконка замка. Если вы проверите ваш сервер тестом &lt;a href=&quot;https://www.ssllabs.com/ssltest/&quot; target=&quot;_blank&quot;&gt;SSL Labs Server Test&lt;/a&gt;, он получит оценку &lt;strong&gt;A&lt;/strong&gt;.&lt;/p&gt;
  &lt;p&gt;Закончим тестированием процесса обновления сертификата.&lt;/p&gt;
  &lt;h2&gt;Шаг 5 - Проверка автоматического обновления сертификата&lt;/h2&gt;
  &lt;p&gt;Сертификаты Let’s Encrypt действительны только 90 дней. Это сделано для того, чтобы пользователи автоматизировали процесс обновления сертификатов. Пакет &lt;code&gt;certbot&lt;/code&gt;, который мы установили, делает это путём добавления скрипта обновления в &lt;code&gt;/etc/cron.d&lt;/code&gt;. Этот скрипт запускается раз в день и автоматически обновляет любые сертификаты, которые закончатся в течение ближайших 30 дней.&lt;/p&gt;
  &lt;p&gt;Для тестирования процесса обновления мы можем сделать “сухой” запуск (dry run) &lt;code&gt;certbot&lt;/code&gt;:&lt;/p&gt;
  &lt;pre&gt;sudo certbot renew --dry-run
&lt;/pre&gt;
  &lt;p&gt;Если вы не видите каких-либо ошибок в результате выполнения этой команды, то всё в полном порядке. При необходимости Certbot будет обновлять ваши сертификаты и перезагружать Apache для применения изменений. Если автоматическое обновление по какой-либо причине закончится ошибкой, Let’s Encrypt отправит электронное письмо на указанный вами адрес электронной почты с информацией о сертификате, который скоро закончится.&lt;/p&gt;
  &lt;h2&gt;Заключение&lt;/h2&gt;
  &lt;p&gt;В этом руководстве мы рассмотрели процесс установки клиента Let’s Encrypt &lt;code&gt;certbot&lt;/code&gt;, загрузили SSL сертификаты для вашего домена, настроили Apache для использования этих сертификатов и настроили процесс автоматического обновления сертификатов. Если у вас есть вопросы по работе с Certbot, рекомендуем ознакомиться с &lt;a href=&quot;https://certbot.eff.org/docs/&quot; target=&quot;_blank&quot;&gt;документацией Certbot&lt;/a&gt;.&lt;/p&gt;
  &lt;hr /&gt;
  &lt;p&gt;Переведено: &lt;a href=&quot;https://iceslam.ru&quot; target=&quot;_blank&quot;&gt;IceSlam&lt;/a&gt;&lt;/p&gt;
  &lt;p&gt;Оригинал: &lt;a href=&quot;https://www.digitalocean.com/community/tutorials/apache-let-s-encrypt-ubuntu-18-04-ru&quot; target=&quot;_blank&quot;&gt;DigitalOcean&lt;/a&gt;&lt;/p&gt;

</content></entry><entry><id>iceslam:easy-openvpn-server-installation</id><link rel="alternate" type="text/html" href="https://teletype.in/@iceslam/easy-openvpn-server-installation?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=iceslam"></link><title>Настраиваем OpenVPN-сервер самостоятельно и без лишних хлопот на Ubuntu</title><published>2020-07-29T21:57:15.083Z</published><updated>2020-07-29T22:29:30.170Z</updated><category term="servers" label="Servers"></category><summary type="html">OpenVPN пошаговый автоустановщик для Ubuntu, Debian, CentOS и Fedora.</summary><content type="html">
  &lt;p&gt;OpenVPN пошаговый автоустановщик для Ubuntu, Debian, CentOS и Fedora.&lt;/p&gt;
  &lt;p&gt;Этот скрипт позволит вам настроить свой собственный VPN-сервер не более чем за минуту, даже если вы раньше не использовали OpenVPN. Он был разработан, чтобы быть как можно более ненавязчивым и универсальным.&lt;/p&gt;
  &lt;h3&gt;Установка&lt;/h3&gt;
  &lt;p&gt;Запустите скрипт и следуйте за помощником:&lt;/p&gt;
  &lt;p&gt;&lt;code&gt;wget https://git.io/vpn -O openvpn-install.sh &amp;amp;&amp;amp; bash openvpn-install.sh&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;Как только он закончится, вы можете запустить его снова, чтобы добавить больше пользователей, удалить некоторых из них или даже полностью удалить OpenVPN.&lt;/p&gt;
  &lt;p&gt;Я хочу запустить свой собственный VPN, но у меня нет сервера для этого:&lt;/p&gt;
  &lt;p&gt;Недорогие VPS-серверы можно приобрести у компании FirstByte (не реклама), серверы от 55 рублей в месяц&lt;/p&gt;
  &lt;hr /&gt;
  &lt;p&gt;Переведено: &lt;a href=&quot;https://iceslam.ru&quot; target=&quot;_blank&quot;&gt;IceSlam&lt;/a&gt;&lt;/p&gt;
  &lt;p&gt;Оригинал: &lt;a href=&quot;https://github.com/Nyr/openvpn-install&quot; target=&quot;_blank&quot;&gt;Nyr&lt;/a&gt;&lt;/p&gt;

</content></entry><entry><id>iceslam:seo-for-vue-nuxt-project-via-wp-rest-api</id><link rel="alternate" type="text/html" href="https://teletype.in/@iceslam/seo-for-vue-nuxt-project-via-wp-rest-api?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=iceslam"></link><title>SEO-оптимизация проекта на Vue/Nuxt с использованием WordPress REST API</title><published>2020-07-29T21:45:11.072Z</published><updated>2020-07-29T21:51:06.357Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://teletype.in/files/7b/b1/7bb1b800-7ad5-4b48-b4bd-81bad8f81e9d.png"></media:thumbnail><category term="vuejs" label="VueJS"></category><summary type="html">&lt;img src=&quot;https://teletype.in/files/b4/e5/b4e5928b-7653-4126-af39-ebb9c0b45d9f.png&quot;&gt;Этот туториал очень просто демонстрирует, как можно было бы использовать Yoast Seo Plugin для WordPress, чтобы получить SEO-заголовок и Meta-данные во фронтенд VueJS/NuxtJS через WordPress REST API.</summary><content type="html">
  &lt;h3&gt;WordPress и VueJS/NuxtJS - инструкция по SEO&lt;/h3&gt;
  &lt;p&gt;Этот туториал очень просто демонстрирует, как можно было бы использовать Yoast Seo Plugin для WordPress, чтобы получить SEO-заголовок и Meta-данные во фронтенд VueJS/NuxtJS через WordPress REST API.&lt;/p&gt;
  &lt;p&gt;В этом пазле несколько кусочков и я постараюсь как можно понятнее, не занимая много времени, объяснить каждый кусочек, в достаточных, не очень трудоемких деталях.&lt;/p&gt;
  &lt;p&gt;Я создал простейший пример, чтобы продемонстрировать, как это работает, но вам понадобится гораздо больше, чтобы все это работало гладко в production-версии вашего проекта, про это я кратко коснусь в конце.&lt;/p&gt;
  &lt;h2&gt;Мы пройдем через следующие шаги:&lt;/h2&gt;
  &lt;ul&gt;
    &lt;li&gt;Установим VueJS (NuxtJS) фронтенда для отображения отдельных постов&lt;/li&gt;
    &lt;li&gt;Настроим WordPress API, чтобы получать данные поста через эндпоинт RESTful API&lt;/li&gt;
    &lt;li&gt;Добавим Yoast SEO плагин в этот эндпоинт&lt;/li&gt;
    &lt;li&gt;Подключим фронтенд VueJS к API чтобы получить данные поста и SEO мета-дату&lt;/li&gt;
  &lt;/ul&gt;
  &lt;h3&gt;В этом туториале предполагается следующее:&lt;/h3&gt;
  &lt;ul&gt;
    &lt;li&gt;Промежуточное знание разработки WordPress (PHP)&lt;/li&gt;
    &lt;li&gt;Понимание разработки Javascript и некоторые моменты из того, что с этим связано: NPM и т. д&lt;/li&gt;
    &lt;li&gt;Небольшое знакомство с SEO-плагином Yoast для WordPress&lt;/li&gt;
    &lt;li&gt;Интерес к использованию VueJS&lt;/li&gt;
  &lt;/ul&gt;
  &lt;h2&gt;Установим VueJS (NuxtJS) фронтенда для отображения отдельных постов&lt;/h2&gt;
  &lt;p&gt;Выберите каталог на вашем компьютере и создайте новый nuxt проект вот так:&lt;/p&gt;
  &lt;pre&gt;npx create-nuxt-app &amp;lt;project-name&amp;gt;&lt;/pre&gt;
  &lt;p&gt;Следуйте инструкциям и настройте его, как вы хотите — я пошел с NPM без Yarn, без проверки на ошибки, без тестов.&lt;/p&gt;
  &lt;p&gt;Выполните следующие действия, чтобы увидеть свой сайт на: &lt;a href=&quot;http://localhost:3000&quot; target=&quot;_blank&quot;&gt;http://localhost:3000&lt;/a&gt;&lt;/p&gt;
  &lt;pre&gt;npm run dev&lt;/pre&gt;
  &lt;p&gt;И вуаля - вы увидите, как работает ваш замечательный новый проект!&lt;/p&gt;
  &lt;figure class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/b4/e5/b4e5928b-7653-4126-af39-ebb9c0b45d9f.png&quot; width=&quot;700&quot; /&gt;
    &lt;figcaption&gt;Страница по умолчанию после установки и запуска проекта на NuxJS&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p&gt;После этого вам нужно будет перейти в каталог “pages” и создать новую папку под названием “post”. Внутри этой папки создайте два файла: index.vue и _id.vue.&lt;/p&gt;
  &lt;p&gt;Индексный файл будет использоваться для отображения страницы списка постов, которые мы не будем рассматривать в этом учебнике, и _id.vue будет использоваться для отображения отдельных постов.&lt;/p&gt;
  &lt;p&gt;В &amp;#x27; _id.vue &amp;#x27; теперь добавьте следующий код:&lt;/p&gt;
  &lt;pre&gt;&amp;lt;template&amp;gt;
  &amp;lt;section class=&amp;quot;container&amp;quot;&amp;gt;
    &amp;lt;div&amp;gt;
      &amp;lt;logo/&amp;gt;
      &amp;lt;h1 class=&amp;quot;title&amp;quot;&amp;gt;
        Static Post Title
      &amp;lt;/h1&amp;gt;
      &amp;lt;span class=&amp;quot;content&amp;quot;&amp;gt;
        Static Post Content
      &amp;lt;/span&amp;gt;
    &amp;lt;/div&amp;gt;
  &amp;lt;/section&amp;gt;
&amp;lt;/template&amp;gt;
&amp;lt;script&amp;gt;
  export default {}
&amp;lt;/script&amp;gt;
&amp;lt;style&amp;gt;
.container {
  min-height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
  text-align: center;
}
.title {
  font-family: &amp;#x27;Quicksand&amp;#x27;, &amp;#x27;Source Sans Pro&amp;#x27;, -apple-system, BlinkMacSystemFont,
    &amp;#x27;Segoe UI&amp;#x27;, Roboto, &amp;#x27;Helvetica Neue&amp;#x27;, Arial, sans-serif;
  display: block;
  font-weight: 300;
  font-size: 100px;
  color: #35495e;
  letter-spacing: 1px;
}
&amp;lt;/style&amp;gt;&lt;/pre&gt;
  &lt;p&gt;Затем посетите эту страницу: &lt;a href=&quot;http://localhost:3000/post/1&quot; target=&quot;_blank&quot;&gt;http://localhost:3000/post/1&lt;/a&gt;&lt;/p&gt;
  &lt;p&gt;И мы получаем прекрасный маленький шаблон поста, показывающий одни и те же статические данные снова и снова, независимо от того, какой идентификатор вводится в URL-адрес.&lt;/p&gt;
  &lt;figure class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/8d/cd/8dcde90c-8314-4217-83c6-59977f683564.png&quot; width=&quot;700&quot; /&gt;
    &lt;figcaption&gt;Наша статичная страница поста&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;h2&gt;Далее мы настроим WordPress API, который подгружает данные поста&lt;/h2&gt;
  &lt;p&gt;Я устанавливаю WP локально через Docker, но это полностью ваш выбор, как вы хотите выполнить установку. После того, как вы настроили сайт, мы работаем с WordPress Rest API для обслуживания данных поста — с некоторыми дополнительными метаданными SEO с помощью SEO-плагина Yoast.&lt;/p&gt;
  &lt;p&gt;WordPress по умолчанию предоставляет конечную точку API для постов.&lt;/p&gt;
  &lt;p&gt;Вы можете посетить адрес: &lt;a href=&quot;http://localhost/wp-json/wp/v2/posts/POST_ID&quot; target=&quot;_blank&quot;&gt;http://localhost/wp-json/wp/v2/posts/POST_ID&lt;/a&gt;&lt;/p&gt;
  &lt;p&gt;Мой адрес выглядит так: &lt;a href=&quot;http://devapi.seotest.com:20080/wp-json/wp/v2/posts/1&quot; target=&quot;_blank&quot;&gt;http://devapi.seotest.com:20080/wp-json/wp/v2/posts/1&lt;/a&gt;&lt;/p&gt;
  &lt;p&gt;Это приведет к ответу, который выглядит примерно следующим образом:&lt;/p&gt;
  &lt;pre&gt;{  
   &amp;quot;id&amp;quot;:1,
   &amp;quot;date&amp;quot;:&amp;quot;2019-01-03T09:54:21&amp;quot;,
   &amp;quot;date_gmt&amp;quot;:&amp;quot;2019-01-03T09:54:21&amp;quot;,
   &amp;quot;guid&amp;quot;:{  
      &amp;quot;rendered&amp;quot;:&amp;quot;http://devapi.seotest.com:20080/?p=1&amp;quot;
   },
   &amp;quot;modified&amp;quot;:&amp;quot;2019-01-03T09:54:21&amp;quot;,
   &amp;quot;modified_gmt&amp;quot;:&amp;quot;2019-01-03T09:54:21&amp;quot;,
   &amp;quot;slug&amp;quot;:&amp;quot;test-post-seo&amp;quot;,
   &amp;quot;status&amp;quot;:&amp;quot;publish&amp;quot;,
   &amp;quot;type&amp;quot;:&amp;quot;post&amp;quot;,
   &amp;quot;link&amp;quot;:&amp;quot;http://devapi.seotest.com:20080/test-post-seo/&amp;quot;,
   &amp;quot;title&amp;quot;:{  
      &amp;quot;rendered&amp;quot;:&amp;quot;My test Post for SEO&amp;quot;
   },
   &amp;quot;content&amp;quot;:{  
      &amp;quot;rendered&amp;quot;:&amp;quot;&amp;lt;p&amp;gt;My test post main body content &amp;amp;#8211; ain&amp;amp;#8217;t that nice!&amp;lt;/p&amp;gt;\n&amp;quot;,
      &amp;quot;protected&amp;quot;:false
   }........&lt;/pre&gt;
  &lt;p&gt;Вот так! У вас есть настройка конечной точки API, которая возвращает данные поста, и вам даже не нужно было писать какой-либо код!&lt;/p&gt;
  &lt;h2&gt;Добавим SEO-данные для этих постов&lt;/h2&gt;
  &lt;p&gt;Следующая часть также довольно прямолинейна. Нужно добавить seo-метаданные Yoast к этому ответу.&lt;/p&gt;
  &lt;p&gt;Перво - наперво - посетите страницу плагинов и установите &lt;a href=&quot;https://yoast.com/wordpress/plugins/seo/&quot; target=&quot;_blank&quot;&gt;плагин Yoast SEO&lt;/a&gt;&lt;/p&gt;
  &lt;p&gt;Я собираюсь сосредоточиться только на названии и мета-описании, чтобы этот пост не стал слишком длинным, но остальные поля следуют очень похожей схеме.&lt;/p&gt;
  &lt;p&gt;&lt;strong&gt;Добавьте следующий код в свои functions.php:&lt;/strong&gt;&lt;/p&gt;
  &lt;pre&gt;add_action( &amp;#x27;rest_api_init&amp;#x27;, &amp;#x27;slug_register_yoast_seo_meta&amp;#x27; );

function slug_register_yoast_seo_meta() {
    register_rest_field( &amp;#x27;post&amp;#x27;,
        &amp;#x27;_yoast_wpseo_title&amp;#x27;,
        array(
            &amp;#x27;get_callback&amp;#x27;    =&amp;gt; &amp;#x27;get_seo_meta_field&amp;#x27;,
            &amp;#x27;update_callback&amp;#x27; =&amp;gt; null,
            &amp;#x27;schema&amp;#x27;          =&amp;gt; null,
        )
    );
    register_rest_field( &amp;#x27;post&amp;#x27;,
        &amp;#x27;_yoast_wpseo_metadesc&amp;#x27;,
        array(
            &amp;#x27;get_callback&amp;#x27;    =&amp;gt; &amp;#x27;get_seo_meta_field&amp;#x27;,
            &amp;#x27;update_callback&amp;#x27; =&amp;gt; null,
            &amp;#x27;schema&amp;#x27;          =&amp;gt; null,
        )
    );
}

function get_seo_meta_field( $object, $field_name, $request ) {
    return get_post_meta( $object[ &amp;#x27;id&amp;#x27; ], $field_name, true );
}&lt;/pre&gt;
  &lt;p&gt;&lt;strong&gt;Это приводит к следующему:&lt;/strong&gt; &lt;/p&gt;
  &lt;p&gt;Хуки в функции &amp;#x27;rest_api_init&amp;#x27; регистрируют два пользовательских поля. Используем &amp;#x27;rest_api_init&amp;#x27; вместо &amp;#x27; init’, чтобы этот код выполнялся только на запросах API, а не на обычных постах...&lt;/p&gt;
  &lt;p&gt;Указываем функцию обратного вызова для извлечения двух полей как &amp;#x27; get_seo_meta_field’, которая просто принимает идентификатор объекта (в данном случае post) и имя поля (либо ‘_yoast_wpseo_title’, либо ‘_yoast_wpseo_metadesc’) и возвращает значение этого мета-поля поста.&lt;/p&gt;
  &lt;p&gt;Замечательно! Теперь у нас есть конечная точка API для постов, которая возвращает метаданные Yoast SEO!&lt;/p&gt;
  &lt;p&gt;Полное описание того, как добавить дополнительные мета-поля в конечные точки, вы можете найти здесь: &lt;a href=&quot;https://v2.wp-api.org/extending/modifying&quot; target=&quot;_blank&quot;&gt;https://v2.wp-api.org/extending/modifying&lt;/a&gt;&lt;/p&gt;
  &lt;h2&gt;Подключите приложение VueJS для извлечения данных поста&lt;/h2&gt;
  &lt;p&gt;Это последний шаг — нам нужно сказать фронтенду Vue, чтобы он извлекал данные поста для каждого поста из API WordPress. Мы делаем это следующим образом:&lt;/p&gt;
  &lt;p&gt;Мы собираемся использовать Axios для этого, поэтому в вашем _id.vue добавьте следующее в теги &amp;lt;script&amp;gt;.&lt;/p&gt;
  &lt;pre&gt;&amp;lt;script&amp;gt;
import axios from &amp;#x27;axios&amp;#x27;export default {
  
  asyncData ({ params }) {
    return axios.get(&amp;#x60;http://devapi.seotest.com:20080/test-post-seo/wp-json/wp/v2/posts/${params.id}&amp;#x60;)
      .then(response =&amp;gt; {
        return { post: response.data }
      })
      .catch((error) =&amp;gt; {
        return { error: error }
      })
  },
  data () {
    return {
      post: {},
      error: []
    }
  }
}
&amp;lt;/script&amp;gt;&lt;/pre&gt;
  &lt;p&gt;&lt;strong&gt;Что здесь будет происходить?&lt;/strong&gt;&lt;/p&gt;
  &lt;ul&gt;
    &lt;li&gt;Мы импортируем Axios в файл&lt;/li&gt;
    &lt;li&gt;Мы используем метод Nuxt ‘asyncData &amp;#x27; для выполнения нашего запроса Axios&lt;/li&gt;
    &lt;li&gt;Мы используем параметр динамического идентификатора, чтобы получать разные сообщения, посещая разные URL-адреса&lt;/li&gt;
    &lt;li&gt;Мы добавляем возвращаемые POST-данные в объект ‘пост’, что мы создали&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p&gt;&lt;strong&gt;Теперь мы можем отображать динамический заголовок и динамическое содержимое для нашего поста примерно так:&lt;/strong&gt;&lt;/p&gt;
  &lt;pre&gt;&amp;lt;template&amp;gt;
  &amp;lt;section class=&amp;quot;container&amp;quot;&amp;gt;
    &amp;lt;div&amp;gt;
      &amp;lt;h1 class=&amp;quot;title&amp;quot;&amp;gt;
        {{post.title.rendered}}
      &amp;lt;/h1&amp;gt;
      &amp;lt;span v-html=&amp;quot;post.content.rendered&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;
    &amp;lt;/div&amp;gt;
  &amp;lt;/section&amp;gt;
&amp;lt;/template&amp;gt;&lt;/pre&gt;
  &lt;p&gt;&lt;strong&gt;Пожалуйста, обратите внимание на:&lt;/strong&gt;&lt;/p&gt;
  &lt;pre&gt;v-html=”post.content.rendered”&lt;/pre&gt;
  &lt;p&gt;Это форматирует HTML разметку возвращенную красиво и мы должны увидеть что-то вроде следующего:&lt;/p&gt;
  &lt;figure class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/50/f6/50f620b7-839a-441f-8dc5-d87b1eb55c40.png&quot; width=&quot;700&quot; /&gt;
    &lt;figcaption&gt;Ура! Мы получили заголовок!&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p&gt;Конечно, сам контент будет зависеть от того, что вы помещаете в посте, созданное на стороне WordPress, а идентификатор в строке URL будет зависеть от идентификатора этого поста.&lt;/p&gt;
  &lt;p&gt;&lt;strong&gt;Далее мы хотим включить SEO данные следующим образом:&lt;/strong&gt;&lt;/p&gt;
  &lt;pre&gt;&amp;lt;script&amp;gt;
import axios from &amp;#x27;axios&amp;#x27;export default {
  head () {
    return {
      title: this.post._yoast_wpseo_title,
      meta: [
        { hid: &amp;#x27;description&amp;#x27;, id: &amp;#x27;description&amp;#x27;, name: &amp;#x27;description&amp;#x27;, content: this.post._yoast_wpseo_metadesc }
      ]
    }
  },
  asyncData ({ params }) {&lt;/pre&gt;
  &lt;p&gt;&lt;strong&gt;Полный код для файла ниже:&lt;/strong&gt;&lt;/p&gt;
  &lt;pre&gt;&amp;lt;template&amp;gt;
  &amp;lt;section class=&amp;quot;container&amp;quot;&amp;gt;
    &amp;lt;div&amp;gt;
      &amp;lt;h1 class=&amp;quot;title&amp;quot;&amp;gt;
        {{post.title.rendered}}
      &amp;lt;/h1&amp;gt;
      &amp;lt;span v-html=&amp;quot;post.content.rendered&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;
    &amp;lt;/div&amp;gt;
  &amp;lt;/section&amp;gt;
&amp;lt;/template&amp;gt;
&amp;lt;script&amp;gt;
import axios from &amp;#x27;axios&amp;#x27;export default {
  head () {
    return {
      title: this.post._yoast_wpseo_title,
      meta: [
        { hid: &amp;#x27;description&amp;#x27;, id: &amp;#x27;description&amp;#x27;, name: &amp;#x27;description&amp;#x27;, content: this.post._yoast_wpseo_metadesc }
      ]
    }
  },
  asyncData ({ params }) {
    return axios.get(&amp;#x60;http://devapi.go2africa.com:20080/wp-json/wp/v2/posts/${params.id}&amp;#x60;)
      .then(response =&amp;gt; {
        return { post: response.data }
      })
      .catch((error) =&amp;gt; {
        return { error: error }
      })
  },
  data () {
    return {
      post: {},
      error: []
    }
  }
}
&amp;lt;/script&amp;gt;
&amp;lt;style&amp;gt;
.container {
  min-height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
  text-align: center;
}
.title {
  font-family: &amp;#x27;Quicksand&amp;#x27;, &amp;#x27;Source Sans Pro&amp;#x27;, -apple-system, BlinkMacSystemFont,
    &amp;#x27;Segoe UI&amp;#x27;, Roboto, &amp;#x27;Helvetica Neue&amp;#x27;, Arial, sans-serif;
  display: block;
  font-weight: 300;
  font-size: 100px;
  color: #35495e;
  letter-spacing: 1px;
}
.subtitle {
  font-weight: 300;
  font-size: 42px;
  color: #526488;
  word-spacing: 5px;
  padding-bottom: 15px;
}
.links {
  padding-top: 15px;
}
&amp;lt;/style&amp;gt;&lt;/pre&gt;
  &lt;p&gt;Это было сделано самым простым из возможных способов - просто чтобы проиллюстрировать, как связать все это вместе. Я упоминаю ниже, как мы на самом деле сделали совсем немного больше, чтобы заставить это работать в production.&lt;/p&gt;
  &lt;h2&gt;Заключение&lt;/h2&gt;
  &lt;p&gt;Ну вот, теперь у тебя есть Vue.JS фронтенд с SEO, предоставляемым SEO-плагином Yoast из бэкенда WordPress!&lt;/p&gt;
  &lt;p&gt;&lt;strong&gt;Вот скриншот нашего примера:&lt;/strong&gt;&lt;/p&gt;
  &lt;figure class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/67/ae/67aeb64e-112d-49a8-ab8b-a993a2c053f6.png&quot; width=&quot;700&quot; /&gt;
    &lt;figcaption&gt;Вы можете увидеть SEO-заголовок и мета-описание, проходящие через вкладку и консоль!&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;hr /&gt;
  &lt;p&gt;Переведено: &lt;a href=&quot;https://iceslam.ru&quot; target=&quot;_blank&quot;&gt;IceSlam&lt;/a&gt;&lt;/p&gt;
  &lt;p&gt;Оригинал: &lt;a href=&quot;https://medium.com/nona-web/wordpress-vue-and-nuxt-an-seo-love-story-7593d0827730&quot; target=&quot;_blank&quot;&gt;NONA-WEB&lt;/a&gt;&lt;/p&gt;

</content></entry><entry><id>iceslam:creating-pptp-vpn-server-on-ubuntu-server</id><link rel="alternate" type="text/html" href="https://teletype.in/@iceslam/creating-pptp-vpn-server-on-ubuntu-server?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=iceslam"></link><title>PPTP-сервер своими руками на Ubuntu 18.04</title><published>2020-07-29T15:15:14.178Z</published><updated>2020-07-29T15:15:14.178Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://teletype.in/files/c3/99/c399f47f-f3b5-44db-83b9-4afa6468efd2.png"></media:thumbnail><category term="servers" label="Servers"></category><summary type="html">&lt;img src=&quot;https://profitserver.ru/files/images/faq/vpn-setup/1-ip-forward.jpg?d05f771e2e&quot;&gt;Независимо от того, какой из вариантов VPN сервера вы предпочтете, доступ клиентов в Интернет будет реализован штатными средствами операционной системы. Для того, чтобы из внутренней сети открыть доступ в Интернет через внешний интерфейс сервера необходимо разрешить пересылку пакетов между интерфейсами (форвардинг пакетов), и настроить трансляцию адресов.</summary><content type="html">
  &lt;h3&gt;Подготовительные операции&lt;/h3&gt;
  &lt;p&gt;Независимо от того, какой из вариантов VPN сервера вы предпочтете, доступ клиентов в Интернет будет реализован штатными средствами операционной системы. Для того, чтобы из внутренней сети открыть доступ в Интернет через внешний интерфейс сервера необходимо разрешить пересылку пакетов между интерфейсами (форвардинг пакетов), и настроить трансляцию адресов.&lt;/p&gt;
  &lt;p&gt;Для включения форвардинга пакетов откроем файл “/etc/sysctl.conf” и изменим значение параметра “net.ipv4.ip_forward” на 1.&lt;/p&gt;
  &lt;figure class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://profitserver.ru/files/images/faq/vpn-setup/1-ip-forward.jpg?d05f771e2e&quot; width=&quot;773&quot; /&gt;
    &lt;figcaption&gt;включение форвардинга пакетов для настройки VPN сервера&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p&gt;Чтобы изменения применились без перезагрузки сервера, выполним команду&lt;/p&gt;
  &lt;p&gt;sudo sysctl -p /etc/sysctl.conf&lt;/p&gt;
  &lt;p&gt;Трансляция адресов настраивается средствами iptables. Предварительно уточним имя внешнего сетевого интерфейса, выполнив команду “ip link show”, оно понадобится на следующем шаге. В нашем случае имя интерфейса “ens3”.&lt;/p&gt;
  &lt;figure class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://profitserver.ru/files/images/faq/vpn-setup/2_ip_link_show.jpg?4a489de69c&quot; width=&quot;800&quot; /&gt;
    &lt;figcaption&gt;ip link show&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p&gt;Включаем трансляцию адресов на внешнем интерфейсе для всех узлов локальной сети.&lt;/p&gt;
  &lt;p&gt;sudo iptables -t nat -A POSTROUTING -o ens3 -j MASQUERADE&lt;/p&gt;
  &lt;p&gt;Обратите внимание, что в команде необходимо указать реальное имя сетевого интерфейса. На вашем сервере оно может отличаться.&lt;/p&gt;
  &lt;p&gt;По умолчанию все созданные правила iptables сбрасываются после перезагрузки сервера, для того, чтобы этого избежать, воспользуемся утилитой “iptables-persistent” Устанавливаем пакет.&lt;/p&gt;
  &lt;p&gt;sudo apt install iptables-persistent&lt;/p&gt;
  &lt;p&gt;В процессе установки откроется окно конфигурации, в котором система предложит сохранить текущие правила iptables. Так как правила уже настроены, соглашаемся и дважды нажимаем “Yes”. Теперь, после перезагрузки сервера правила будут восстанавливаться автоматически.&lt;/p&gt;
  &lt;figure class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://profitserver.ru/files/images/faq/vpn-setup/3_ip_tables_persistent.jpg?9bd8025161&quot; width=&quot;800&quot; /&gt;
    &lt;figcaption&gt;Включаем трансляцию адресов на внешнем интерфейсе для всех узлов локальной сети&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;h3&gt;1. PPTP сервер&lt;/h3&gt;
  &lt;h3&gt;Настройка сервера&lt;/h3&gt;
  &lt;p&gt;Устанавливаем пакет&lt;/p&gt;
  &lt;p&gt;sudo apt install pptpd&lt;/p&gt;
  &lt;p&gt;После завершения установки открываем в любом текстовом редакторе файл “/etc/pptpd.conf” и приводим его к следующему виду.&lt;/p&gt;
  &lt;p&gt;&lt;code&gt;option /etc/ppp/pptpd-options #путь к файлу с настройками&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;&lt;code&gt; logwtmp #механизм логирования клиентских подключений&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;&lt;code&gt; connections 100 #количество одновременных подключений&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;&lt;code&gt; localip 172.16.0.1 #адрес, который будет шлюзом для клиентов&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;remoteip 172.16.0.2-200 #диапазон адресов для клиентов&lt;/p&gt;
  &lt;p&gt;Далее редактируем файл “/etc/ppp/pptpd-options”, большинство параметров уже установлены по умолчанию.&lt;/p&gt;
  &lt;p&gt;&lt;code&gt;#имя сервиса, потребуется при создании учетных записей для клиентов&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;name pptpd&lt;/p&gt;
  &lt;p&gt;&lt;code&gt;#запрещаем устаревшие методы аутентификации&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;&lt;code&gt; refuse-pap&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;&lt;code&gt; refuse-chap&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;refuse-mschap&lt;/p&gt;
  &lt;p&gt;&lt;code&gt;#разрешаем более надежный метод аутентификации&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;require-mschap-v2&lt;/p&gt;
  &lt;p&gt;&lt;code&gt;#включаем шифрование&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;require-mppe-128&lt;/p&gt;
  &lt;p&gt;&lt;code&gt;#указываем dns сервера для клиентов, можно указать любые доступные&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;&lt;code&gt; ms-dns 8.8.8.8&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;ms-dns 8.8.4.4&lt;/p&gt;
  &lt;p&gt;&lt;code&gt;proxyarp&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;&lt;code&gt; nodefaultroute&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;&lt;code&gt; lock&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;&lt;code&gt; nobsdcomp&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;&lt;code&gt; novj&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;&lt;code&gt; novjccomp&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;nologfd&lt;/p&gt;
  &lt;p&gt;На следующем этапе необходимо создать учетную запись для подключения клиентов. Предположим, мы хотим добавить пользователя “vpnuser”, с паролем “1” и разрешить для него динамическую адресацию. Открываем файл “/etc/ppp/chap-secrets” и добавляем в конец строку с параметрами пользователя.&lt;/p&gt;
  &lt;p&gt;vpnuser pptpd 1 *&lt;/p&gt;
  &lt;p&gt;Значение “pptpd” это имя сервиса, которое мы указали в файле “pptpd-options”. Вместо символа “*” для каждого клиента можно указать фиксированный ip-адрес. В результате содержимое файла “chap-secrets” будет таким.&lt;/p&gt;
  &lt;figure class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://profitserver.ru/files/images/faq/vpn-setup/4_chap_secreets.jpg?3e479666af&quot; width=&quot;701&quot; /&gt;
    &lt;figcaption&gt;Настройка VPN сервера - создание учетной записи для подключения клиентов&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p&gt;Для применения настроек перезагружаем службу pptpd и добавляем её в автозагрузку.&lt;/p&gt;
  &lt;p&gt;&lt;code&gt;sudo systemctl restart pptpd&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;sudo systemctl enable pptpd&lt;/p&gt;
  &lt;p&gt;Настройка сервера завершена.&lt;/p&gt;
  &lt;h3&gt;Настройка клиента&lt;/h3&gt;
  &lt;p&gt;Открываем “Пуск” - “Параметры” - “Сеть и интернет” - “VPN” и нажимаем “Добавить VPN-подключение”&lt;/p&gt;
  &lt;figure class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://profitserver.ru/files/images/faq/vpn-setup/5_VPN_add.jpg?3429c064d4&quot; width=&quot;497&quot; /&gt;
    &lt;figcaption&gt;Настройка клиента для VPN подключения&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p&gt;В открывшемся окне вводим параметры подключения и нажимаем “Сохранить”&lt;/p&gt;
  &lt;ul&gt;
    &lt;li&gt;Поставщик услуг VPN: “Windows (встроенные)”&lt;/li&gt;
    &lt;li&gt;Имя подключения: “vpn_connect” (можно ввести любое)&lt;/li&gt;
    &lt;li&gt;Имя или адрес сервера: (указываем внешний ip адрес сервера)&lt;/li&gt;
    &lt;li&gt;Тип VPN: “Автоматически”&lt;/li&gt;
    &lt;li&gt;Тип данных для входа: “Имя пользователя и пароль”&lt;/li&gt;
    &lt;li&gt;Имя пользователя: vpnuser (имя, которое указано в файле “chap-secrets” на сервере)&lt;/li&gt;
    &lt;li&gt;Пароль: 1 (так же из файла “chap-secrets”)&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p&gt;После сохранения параметров, в окне VPN появится новое подключение. Щелкаем по нему левой кнопкой мыши и нажимаем “Подключиться”. При успешном соединении с сервером, на значке подключения появится надпись “Подключено”.&lt;/p&gt;
  &lt;figure class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://profitserver.ru/files/images/faq/vpn-setup/6_vpn_connect.jpg?1d6d856507&quot; width=&quot;556&quot; /&gt;
    &lt;figcaption&gt;Добавляем VPN подключение&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p&gt;В свойствах подключения отображаются внутренние адреса клиента и сервера. В поле “Адрес назначения” указан внешний адрес сервера.&lt;/p&gt;
  &lt;figure class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://profitserver.ru/files/images/faq/vpn-setup/7_vpn_connect_prop.jpg?5e54a17075&quot; width=&quot;612&quot; /&gt;
    &lt;figcaption&gt;В свойствах подключения отображаются внутренние адреса клиента и сервера. В поле “Адрес назначения” указан внешний адрес сервера.&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p&gt;При установленном соединении внутренний ip-адрес сервера, в нашем случае 172.16.0.1, становится шлюзом по умолчанию для всех исходящих пакетов.&lt;/p&gt;
  &lt;figure class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://profitserver.ru/files/images/faq/vpn-setup/8_test_connect.jpg?daaea6d349&quot; width=&quot;635&quot; /&gt;
    &lt;figcaption&gt;Проверка внешнего адреса компьютера при настройке VPN-соединения&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;h4&gt;Воспользовавшись любым онлайн-сервисом вы можете убедиться, что внешний IP адрес компьютера теперь совпадает с IP адресом вашего VPN сервера.&lt;/h4&gt;
  &lt;hr /&gt;
  &lt;p&gt;Материал с сайта &lt;a href=&quot;https://profitserver.ru/knowledge-base/vpn-setup-linux&quot; target=&quot;_blank&quot;&gt;profitserver.ru&lt;/a&gt;&lt;/p&gt;

</content></entry><entry><id>iceslam:how-to-install-lamp-on-ubuntu-server</id><link rel="alternate" type="text/html" href="https://teletype.in/@iceslam/how-to-install-lamp-on-ubuntu-server?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=iceslam"></link><title>Настройка веб-сервера (Apache-PHP-MySQL/MariaDB) на Linux Ubuntu</title><published>2020-07-29T15:13:52.483Z</published><updated>2020-07-29T15:13:52.483Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://teletype.in/files/84/f9/84f9b3a2-750a-4771-912c-d44fb0045e28.png"></media:thumbnail><category term="servers" label="Servers"></category><summary type="html">&lt;img src=&quot;https://profitserver.ru/files/images/faq/vps-web-server/1-apache-default-page.jpg?491d621b81&quot;&gt;В данной статье будет дана пошаговая инструкция, как настроить веб-окружение на сервере под управлением Linux. Для начала, необходимо понимать, что типовой веб сервер состоит из взаимодействующих между собой компонентов, а именно:</summary><content type="html">
  &lt;p&gt;В данной статье будет дана пошаговая инструкция, как настроить веб-окружение на сервере под управлением Linux. Для начала, необходимо понимать, что типовой веб сервер состоит из взаимодействующих между собой компонентов, а именно:&lt;/p&gt;
  &lt;ul&gt;
    &lt;li&gt;HTTP сервер&lt;/li&gt;
    &lt;li&gt;интерпретатор языка программирования&lt;/li&gt;
    &lt;li&gt;система управления базами данных (СУБД)&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p&gt;Также для работы с сайтом необходима система управления контентом (CMS), веб интерфейс для управления базами данных и возможность доступа по FTP.&lt;/p&gt;
  &lt;p&gt;Рассмотрим процесс установки и настройки распространенной связки Apache-PHP-MySQL(MariaDB) в операционной системе Linux. Дополнительно будут установлены ftp-сервер vsftpd, веб-интерфейс для управления базой данных phpMyAdmin и система управления контентом Wordpress.&lt;/p&gt;
  &lt;p&gt;Для начала работы, следует &lt;a href=&quot;https://profitserver.ru/vps/&quot; target=&quot;_blank&quot;&gt;заказать VPS&lt;/a&gt; или &lt;a href=&quot;https://profitserver.ru/dedicated/&quot; target=&quot;_blank&quot;&gt;выделенный сервер&lt;/a&gt;. В данной статье примеры выполнены на виртуальном сервере со статическим публичным IP-адресом под управлением Ubuntu Server 18.04. Команды выполняются от имени суперпользователя.&lt;/p&gt;
  &lt;h3&gt;Настройка HTTP-сервера Apache&lt;/h3&gt;
  &lt;h3&gt;1. Установка&lt;/h3&gt;
  &lt;p&gt;&lt;code&gt;apt install apache2&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;После завершения установки откроем браузер на любом устройстве с доступом в Интернет и перейдем по ссылке &lt;strong&gt;“http://[ip_адрес_сервера]”&lt;/strong&gt;&lt;/p&gt;
  &lt;figure class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://profitserver.ru/files/images/faq/vps-web-server/1-apache-default-page.jpg?491d621b81&quot; width=&quot;800&quot; /&gt;
    &lt;figcaption&gt;Установка и настрйока HTTP-сервера&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p&gt;Если вы увидите страницу приветствия как на скриншоте, значит HTTP сервер работает.&lt;/p&gt;
  &lt;h3&gt;2. Создание тестовой страницы&lt;/h3&gt;
  &lt;p&gt;По умолчанию корневым каталогом для размещения сайта является директория &lt;strong&gt;“/var/www/html”&lt;/strong&gt;, именно там находится страница приветствия. Создадим отдельную директорию &lt;strong&gt;“/var/www/sites”&lt;/strong&gt; для размещения виртуальных хостов и вложенную папку &lt;strong&gt;“/var/www/sites/site1”&lt;/strong&gt; с индексной страницей тестового сайта.&lt;/p&gt;
  &lt;p&gt;&lt;code&gt;cd /var/www/&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;&lt;code&gt;mkdir -p sites/site1&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;&lt;code&gt;echo &amp;quot;&amp;lt;H1&amp;gt;Welcome&amp;lt;/H1&amp;gt;&amp;quot; &amp;gt; sites/site1/index.html&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;В результате файл &lt;strong&gt;“/var/www/sites/site1/index.html”&lt;/strong&gt; будет содержать одну html-строку:&lt;/p&gt;
  &lt;p&gt;&lt;code&gt;&amp;lt;H1&amp;gt;Welcome&amp;lt;/H1&amp;gt;&lt;/code&gt;&lt;/p&gt;
  &lt;h3&gt;3. Конфигурация Apache-сервера&lt;/h3&gt;
  &lt;p&gt;Конфигурационные файлы сайтов находятся в каталоге &lt;strong&gt;“/etc/apache2/sites-available/”&lt;/strong&gt;. Создадим конфигурационный файл для нового виртуального хоста взяв за основу конфигурацию по умолчанию из файла &lt;strong&gt;“000-default.conf”&lt;/strong&gt;&lt;/p&gt;
  &lt;p&gt;&lt;code&gt;cd /etc/apache2/sites-available/&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;&lt;code&gt;cp 000-default.conf site1.conf&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;Откроем файл &lt;strong&gt;“site1.conf”&lt;/strong&gt; и изменим параметр &lt;strong&gt;“DocumentRoot”&lt;/strong&gt;. В качестве значения нужно указать путь к новому сайту, в нашем случае это &lt;strong&gt;“/var/www/sites/site1”&lt;/strong&gt;&lt;/p&gt;
  &lt;figure class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://profitserver.ru/files/images/faq/vps-web-server/2-new-conf.jpg&quot; width=&quot;800&quot; /&gt;
    &lt;figcaption&gt;Настрйока и конфигурация Apache-сервера&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p&gt;На данном этапе нам не требуется настройка одновременной работы нескольких сайтов, поэтому отключим сайт по умолчанию и включим новый сайт. Для применения изменений перезагружаем конфигурацию сервера.&lt;/p&gt;
  &lt;p&gt;&lt;code&gt;a2dissite 000-default&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;&lt;code&gt;a2ensite site1&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;&lt;code&gt;systemctl reload apache2&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;Снова переходим по ссылке &lt;strong&gt;“http://[ip_адрес_сервера]”&lt;/strong&gt; и убеждаемся, что вместо стандартной страницы приветствия отображается наша новая страница.&lt;/p&gt;
  &lt;figure class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://profitserver.ru/files/images/faq/vps-web-server/3-new-site.jpg&quot; width=&quot;663&quot; /&gt;
    &lt;figcaption&gt;Настройка HTTP-сервера&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p&gt;Настройка HTTP-сервера завершена, переходим к следующему этапу.&lt;/p&gt;
  &lt;h3&gt;Настройка FTP-сервера&lt;/h3&gt;
  &lt;h3&gt;1. Установка&lt;/h3&gt;
  &lt;p&gt;Устанавливаем ftp-сервер и дополнительный пакет &lt;strong&gt;“db-util”&lt;/strong&gt;, который потребуется для настройки виртуальных пользователей.&lt;/p&gt;
  &lt;p&gt;&lt;code&gt;apt install vsftpd db-util&lt;/code&gt;&lt;/p&gt;
  &lt;h3&gt;2. Создание локальной учетной записи&lt;/h3&gt;
  &lt;p&gt;Сервер &lt;strong&gt;vsftpd&lt;/strong&gt; позволяет очень гибко настраивать права доступа. Для решения наших задач ftp-пользователям необходимо обеспечить следующие возможности:&lt;/p&gt;
  &lt;ul&gt;
    &lt;li&gt;полный доступ к содержимому директории &lt;strong&gt;“/var/www/sites/”&lt;/strong&gt;;&lt;/li&gt;
    &lt;li&gt;невозможность выхода за пределы директории &lt;strong&gt;“/var/www/”&lt;/strong&gt;;&lt;/li&gt;
    &lt;li&gt;подключение с использованием виртуальной учетной записи;&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p&gt;Создадим локальную учетную запись &lt;strong&gt;“virtual”&lt;/strong&gt; без возможности входа в систему, с домашней директорией &lt;strong&gt;“/var/www/”&lt;/strong&gt;. Эта учетная запись будет использоваться для подключения виртуальных ftp-пользователей.&lt;/p&gt;
  &lt;p&gt;&lt;code&gt;useradd -d /var/www virtual&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;По умолчанию, владельцем директории &lt;strong&gt;“/var/www”&lt;/strong&gt; является &lt;strong&gt;“root”&lt;/strong&gt;. Для того, того, чтобы ftp-пользователи могли изменять содержимое сайтов, изменим владельца каталога &lt;strong&gt;“/var/www/sites/”&lt;/strong&gt;, включая вложенные папки на &lt;strong&gt;“virtual”&lt;/strong&gt;.&lt;/p&gt;
  &lt;p&gt;&lt;code&gt;chown -R virtual:root /var/www/sites&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;В результате изменения прав, пользователь &lt;strong&gt;“virtual”&lt;/strong&gt; сможет просматривать содержимое каталога &lt;strong&gt;“/var/www/”&lt;/strong&gt; и записывать во вложенный каталог &lt;strong&gt;“/var/www/sites/”&lt;/strong&gt;&lt;/p&gt;
  &lt;h3&gt;3. Конфигурация&lt;/h3&gt;
  &lt;p&gt;Основная конфигурация хранится в файле &lt;strong&gt;“/etc/vsftpd.conf”&lt;/strong&gt;, приводим его к следующему виду:&lt;/p&gt;
  &lt;p&gt;&lt;code&gt;#Включаем виртуальных пользователей&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;&lt;code&gt;anonymous_enable=NO&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;&lt;code&gt;local_enable=YES&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;&lt;code&gt;guest_enable=YES&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;&lt;code&gt;guest_username=virtual&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;&lt;code&gt;#Настраиваем права&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;&lt;code&gt;write_enable=YES&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;&lt;code&gt;anon_upload_enable=YES&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;&lt;code&gt;anon_mkdir_write_enable=YES&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;&lt;code&gt;anon_other_write_enable=YES&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;&lt;code&gt;anon_world_readable_only=NO&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;&lt;code&gt;anon_umask=0022&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;&lt;code&gt;chroot_local_user=YES&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;&lt;code&gt;#задаем параметры запуска&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;&lt;code&gt;listen=YES&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;&lt;code&gt;pasv_min_port=30000&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;&lt;code&gt;pasv_max_port=30999&lt;/code&gt;&lt;/p&gt;
  &lt;h3&gt;4. Создание базы данных&lt;/h3&gt;
  &lt;p&gt;База данных необходима для хранения виртуальных учетных записей.&lt;/p&gt;
  &lt;p&gt;Предварительно создадим в домашнем каталоге простой текстовый файл &lt;strong&gt;“users.txt”&lt;/strong&gt; и запишем логины и пароли виртуальных пользователей в чередующиеся строки. Например нам нужен виртуальный пользователь с логином &lt;strong&gt;“ftp”&lt;/strong&gt; и паролем &lt;strong&gt;“Qwe123”&lt;/strong&gt;, тогда содержимое файла будет таким:&lt;/p&gt;
  &lt;p&gt;&lt;code&gt;ftp&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;&lt;code&gt;Qwe123&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;Создаем базу данных&lt;/p&gt;
  &lt;p&gt;&lt;code&gt;db_load -T -t hash -f ~/users.txt /etc/vsftpd_login.db&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;Меняем стандартное содержимое PAM файла &lt;strong&gt;“/etc/pam.d/vsftpd”&lt;/strong&gt; на следующие строки.&lt;/p&gt;
  &lt;p&gt;&lt;code&gt;auth required /lib/x86_64-linux-gnu/security/pam_userdb.so db=/etc/vsftpd_login&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;&lt;code&gt;account required /lib/x86_64-linux-gnu/security/pam_userdb.so db=/etc/vsftpd_login&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;Обратите внимание, что в различных дистрибутивах расположение библиотеки &lt;strong&gt;“pam_userdb.so”&lt;/strong&gt; может отличаться, при необходимости путь к файлу нужно скорректировать.&lt;/p&gt;
  &lt;p&gt;Для применения изменений перезагружаем &lt;strong&gt;vsftpd&lt;/strong&gt; сервер.&lt;/p&gt;
  &lt;p&gt;&lt;code&gt;systemctl restart vsftpd&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;Настройка FTP-сервера завершена.&lt;/p&gt;
  &lt;p&gt;Данные для подключения:&lt;/p&gt;
  &lt;ul&gt;
    &lt;li&gt;ftp://[ip_адрес_сервера]&lt;/li&gt;
    &lt;li&gt;Логин: ftp&lt;/li&gt;
    &lt;li&gt;Пароль: Qwe123&lt;/li&gt;
  &lt;/ul&gt;
  &lt;h3&gt;Настройка PHP-сервера&lt;/h3&gt;
  &lt;h3&gt;1. Установка&lt;/h3&gt;
  &lt;p&gt;На текущий момент последней стабильной версией PHP является &lt;strong&gt;php 7.4.5&lt;/strong&gt;, которая отсутствует в официальных репозиториях Ubuntu. Подключим сторонний репозиторий и установим последнюю версию PHP.&lt;/p&gt;
  &lt;p&gt;&lt;code&gt;apt update&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;&lt;code&gt;apt install software-properties-common&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;&lt;code&gt;add-apt-repository ppa:ondrej/php&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;&lt;code&gt;apt update&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;&lt;code&gt;apt install php7.4&lt;/code&gt;&lt;/p&gt;
  &lt;h3&gt;2. Проверка&lt;/h3&gt;
  &lt;p&gt;Для того, чтобы PHP код мог быть исполнен, файл веб страницы должен иметь расширение &lt;strong&gt;“.php”&lt;/strong&gt;. Переименовываем тестовою страницу&lt;/p&gt;
  &lt;p&gt;&lt;code&gt;cd /var/www/sites/site1/&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;&lt;code&gt;mv index.html index.php&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;Добавляем в файл &lt;strong&gt;“/var/www/sites/site1/index.php”&lt;/strong&gt; строку php-кода. В результате содержимое файла будет таким:&lt;/p&gt;
  &lt;p&gt;&lt;code&gt;&amp;lt;H1&amp;gt;Welcome&amp;lt;/H1&amp;gt;&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;&lt;code&gt; &amp;lt;?php&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;&lt;code&gt; phpinfo();&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;&lt;code&gt; ?&amp;gt;&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;Сохраняем изменения и проверяем результат в браузере.&lt;/p&gt;
  &lt;figure class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://profitserver.ru/files/images/faq/vps-web-server/4-test-php.jpg&quot; width=&quot;800&quot; /&gt;
    &lt;figcaption&gt;Настройка PHP-сервера&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p&gt;Если вы видите результат работы функции &lt;strong&gt;“phpinfo()”&lt;/strong&gt;, значит интерпретатор PHP работает корректно. Приступаем к следующему этапу.&lt;/p&gt;
  &lt;h3&gt;Настройка MySQL (MariaDB)&lt;/h3&gt;
  &lt;h3&gt;1. Установка&lt;/h3&gt;
  &lt;p&gt;Устанавливаем MariaDB и PHP-модуль для работы с MySQL, после завершения установки перезагружаем Apache&lt;/p&gt;
  &lt;p&gt;&lt;code&gt;apt install mariadb-server php-mysql&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;&lt;code&gt;systemctl restart apache2&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;Для проверки обновим тестовую страницу и в таблице с конфигурацией PHP и перейдем к разделу &lt;strong&gt;PDO&lt;/strong&gt;. Наличие секции &lt;strong&gt;“PDO_mysql”&lt;/strong&gt; говорит о корректной установке драйвера для работой с базой данных Mysql.&lt;/p&gt;
  &lt;figure class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://profitserver.ru/files/images/faq/vps-web-server/5-pdo-mysql.jpg&quot; width=&quot;800&quot; /&gt;
    &lt;figcaption&gt;Настройка и установка MySQL на сервер&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p&gt;Для дальнейшей работы необходимо выполнить первоначальную настройку безопасности MariaDB, во время которой для пользователя&lt;strong&gt; “root”&lt;/strong&gt; устанавливается пароль, запрещается удаленный вход и удаляются гостевые учетные записи.&lt;/p&gt;
  &lt;p&gt;&lt;code&gt;mysql_secure_installation&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;На первом шаге необходимо ввести пароль пользователя&lt;strong&gt; &amp;quot;root&amp;quot;&lt;/strong&gt; для входа в СУБД или нажать Enter, если пароль не задан. Так как после установки учетная запись &lt;strong&gt;&amp;quot;root&amp;quot;&lt;/strong&gt; не имеет пароля, нажимаем&lt;strong&gt; “Enter”&lt;/strong&gt;.&lt;/p&gt;
  &lt;p&gt;Обратите внимание, что в MariaDB существуют собственные учетные записи, которые не имеют отношения к учетным записям операционной системы. Речь идет о пользователе &lt;strong&gt;&amp;quot;root&amp;quot;&lt;/strong&gt; в MariaDB.&lt;/p&gt;
  &lt;figure class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://profitserver.ru/files/images/faq/vps-web-server/6-mysql-secure-inst.jpg&quot; width=&quot;800&quot; /&gt;
    &lt;figcaption&gt;MySQL: Создание пользователя и установка пароля&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p&gt;Далее конфигуратор предложит задать пароль для пользователя &lt;strong&gt;root&lt;/strong&gt;, нажимаем&lt;strong&gt; “y”&lt;/strong&gt; для подтверждения и вводим новый пароль, в нашем случае &lt;strong&gt;“Qwe123”&lt;/strong&gt;&lt;/p&gt;
  &lt;figure class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://profitserver.ru/files/images/faq/vps-web-server/7-mysql-secure-pass.jpg&quot; width=&quot;800&quot; /&gt;
    &lt;figcaption&gt;MySQL: установка пароля и доступа пользователей&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p&gt;На все последующие запросы просто нажимаем &lt;strong&gt;“y”&lt;/strong&gt; до окончания настройки.&lt;/p&gt;
  &lt;p&gt;Настройка завершена.&lt;/p&gt;
  &lt;p&gt;&lt;strong&gt;Данные для входа в MariaDB:&lt;/strong&gt;&lt;/p&gt;
  &lt;ul&gt;
    &lt;li&gt;Логин: root&lt;/li&gt;
    &lt;li&gt;Пароль: Qwe123&lt;/li&gt;
  &lt;/ul&gt;
  &lt;h3&gt;Настройка phpMyAdmin&lt;/h3&gt;
  &lt;h3&gt;1. Установка&lt;/h3&gt;
  &lt;p&gt;Устанавливаем обязательное PHP-расширение &lt;strong&gt;mbstring&lt;/strong&gt;.&lt;/p&gt;
  &lt;p&gt;&lt;code&gt;apt install php-mbstring&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;В официальном репозитории размещена устаревшая версия phpMyAdmin, поэтому выполним установку в ручном режиме.&lt;/p&gt;
  &lt;p&gt;Заходим на официальный сайт проекта “&lt;a href=&quot;https://www.phpmyadmin.net/&quot; target=&quot;_blank&quot;&gt;https://www.phpmyadmin.net/&lt;/a&gt;” и скачиваем архив актуальной версии.&lt;/p&gt;
  &lt;figure class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://profitserver.ru/files/images/faq/vps-web-server/8-pma-download.jpg&quot; width=&quot;800&quot; /&gt;
    &lt;figcaption&gt;Установка phpMyAdmin на сервер под управлением Linux&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p&gt;Копируем архив на сервер в каталог &lt;strong&gt;“/var/www/sites/”&lt;/strong&gt; используя любой ftp-клиент.&lt;/p&gt;
  &lt;p&gt;Распаковываем архив, и для удобства, переименовываем извлеченную папку в &lt;strong&gt;“phpMyAdmin”&lt;/strong&gt;. Для распаковки zip-архива предварительно установим утилиту &lt;strong&gt;“unzip”&lt;/strong&gt;. После распаковки архив можно удалить.&lt;/p&gt;
  &lt;p&gt;&lt;code&gt;apt install unzip&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;&lt;code&gt;cd /var/www/sites/&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;&lt;code&gt;unzip phpMyAdmin-5.0.2-all-languages.zip&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;&lt;code&gt;mv phpMyAdmin-5.0.2-all-languages phpMyAdmin&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;&lt;code&gt;rm phpMyAdmin-5.0.2-all-languages.zip&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;Создаем папку &lt;strong&gt;“/var/www/sites/phpMyAdmin/tmp”&lt;/strong&gt; для хранения временных файлов с полными доступом для всех. Если этого не сделать phpMyAdmin сообщит об отсутствии доступа в временной папке.&lt;/p&gt;
  &lt;p&gt;&lt;code&gt;cd /var/www/sites/phpMyAdmin/&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;&lt;code&gt;mkdir tmp&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;&lt;code&gt;chmod 777 tmp&lt;/code&gt;&lt;/p&gt;
  &lt;h3&gt;2. Создание псевдонима&lt;/h3&gt;
  &lt;p&gt;Так как phpMyAdmin не является отдельным виртуальным хостом и находится за пределами корневой директории сайта, настроим псевдоним для возможности доступа.&lt;/p&gt;
  &lt;p&gt;Открываем файл &lt;strong&gt;“/etc/apache2/mods-available/alias.conf”&lt;/strong&gt; и вставляем строку&lt;/p&gt;
  &lt;p&gt;&lt;code&gt;Alias /pma “/var/www/sites/phpMyAdmin&amp;quot;&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;внутри секции&lt;/p&gt;
  &lt;p&gt;&lt;code&gt;&amp;lt;IfModule alias_module&amp;gt;&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;&lt;code&gt; &amp;lt;/IfModule&amp;gt;&lt;/code&gt;&lt;/p&gt;
  &lt;figure class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://profitserver.ru/files/images/faq/vps-web-server/9-pma-alias.jpg&quot; width=&quot;797&quot; /&gt;
    &lt;figcaption&gt;Создание псевдонима в phpMyAdmin&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p&gt;Перезагружаем конфигурацию Apache для применения изменений.&lt;/p&gt;
  &lt;p&gt;&lt;code&gt;systemctl reload apache2&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;Псевдоним настроен. Сейчас мы можем входить в phpMyAdmin по ссылке &lt;strong&gt;“http://[ip_адрес_сервера]/pma”&lt;/strong&gt;&lt;/p&gt;
  &lt;h3&gt;3. Подготовка базы данных&lt;/h3&gt;
  &lt;p&gt;Так как при первоначальной настройке MariaDB мы запретили использование учетной записи &lt;strong&gt;root&lt;/strong&gt; для удаленного подключения, необходимо создать новую учетную запись с полными правами, которая будет использоваться для входа в phpMyAdmin.&lt;/p&gt;
  &lt;p&gt;Кроме того, для работы дополнительных функций phpMyAdmin необходима служебная база данных и учетная запись для доступа к ней.&lt;/p&gt;
  &lt;p&gt;Создадим учетные записи&lt;/p&gt;
  &lt;p&gt;&lt;code&gt;mariadb -u root -p&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;&lt;code&gt;GRANT ALL PRIVILEGES ON *.* TO &amp;#x27;pma&amp;#x27;@&amp;#x27;localhost&amp;#x27; IDENTIFIED BY &amp;#x27;Qwe123&amp;#x27; WITH GRANT OPTION;&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;&lt;code&gt;GRANT SELECT, INSERT, UPDATE, DELETE ON &amp;#x60;phpmyadmin&amp;#x60;.* TO &amp;#x27;pmaservice&amp;#x27;@&amp;#x27;localhost&amp;#x27; IDENTIFIED BY &amp;#x27;Qwe123&amp;#x27; WITH grant option;&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;&lt;code&gt;quit&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;&lt;u&gt;Обратите внимание, что имя базы данных во втором запросе заключено в обратные апострофы: “… ON &lt;strong&gt;&amp;#x60;phpmyadmin&amp;#x60;&lt;/strong&gt;.* TO &amp;#x27;pma&amp;#x27;@&amp;#x27;localhost&amp;#x27; IDENTIFIED BY …”,&lt;/u&gt;&lt;/p&gt;
  &lt;p&gt;В результате в MariaDB будет создано две учетные записи:&lt;/p&gt;
  &lt;ol&gt;
    &lt;li&gt;Логин: pma, пароль: Qwe123&lt;/li&gt;
    &lt;li&gt;Учетная запись имеет полные права и будет использоваться для входа в phpMyAdmin&lt;/li&gt;
    &lt;li&gt;Логин: pmaservice, пароль:Qwe123&lt;/li&gt;
    &lt;li&gt;Служебная учетная запись необходимая для работы дополнительных функций.&lt;/li&gt;
  &lt;/ol&gt;
  &lt;p&gt;&lt;u&gt;На следующем шаге эти учетные данные должны быть указаны в конфигурационном файле &lt;strong&gt;“config.inc.php”&lt;/strong&gt;&lt;/u&gt;&lt;/p&gt;
  &lt;p&gt;Далее необходимо импортировать базу данных из файла &lt;strong&gt;“phpMyAdmin/sql/create_tables.sql”&lt;/strong&gt;. Выполним импорт средствами phpMyAdmin.&lt;/p&gt;
  &lt;p&gt;Открываем браузер и переходим по ссылке &lt;strong&gt;“http://[ip_адрес _сервера]/pma”&lt;/strong&gt;&lt;/p&gt;
  &lt;p&gt;Вводим логин &lt;strong&gt;“pma”&lt;/strong&gt;, пароль &lt;strong&gt;“Qwe123”&lt;/strong&gt;&lt;/p&gt;
  &lt;p&gt;Переходим на вкладку &lt;strong&gt;“Импорт”&lt;/strong&gt;, нажимаем кнопку &lt;strong&gt;“Выберите файл”&lt;/strong&gt; и выбираем файл &lt;strong&gt;”sql/create_tables.sql”&lt;/strong&gt; в корневой директории phpMyAdmin. Предполагается что на локальном компьютере существует папка с файлами &lt;strong&gt;“phpMyAdmin”&lt;/strong&gt;, если необходимо, распакуйте архив.&lt;/p&gt;
  &lt;figure class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://profitserver.ru/files/images/faq/vps-web-server/10-pma-import-sql.jpg&quot; width=&quot;800&quot; /&gt;
    &lt;figcaption&gt;Настройка phpmyadmin&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p&gt;Для завершения импорта нажимаем кнопку &lt;strong&gt;“Вперед”&lt;/strong&gt;.&lt;/p&gt;
  &lt;h3&gt;4. Конфигурация&lt;/h3&gt;
  &lt;p&gt;Копируем файл конфигурации из шаблона&lt;/p&gt;
  &lt;p&gt;&lt;code&gt;cd /var/www/sites/phpMyAdmin/&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;&lt;code&gt;cp config.sample.inc.php config.inc.php&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;Открываем конфигурационный файл &lt;strong&gt;“/var/www/sites/phpMyAdmin/config.inc.php”&lt;/strong&gt; и вносим следующие изменения:&lt;/p&gt;
  &lt;ol&gt;
    &lt;li&gt;Задаем произвольное значение длиной 32 символа для параметра &lt;strong&gt;“$cfg[&amp;#x27;blowfish_secret&amp;#x27;]”&lt;/strong&gt;. Можно воспользоваться любым генератором паролей.&lt;/li&gt;
  &lt;/ol&gt;
  &lt;figure class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://profitserver.ru/files/images/faq/vps-web-server/11-pma-conf-blowfish.jpg&quot; width=&quot;800&quot; /&gt;
    &lt;figcaption&gt;Конфигурация phpmyadmin&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;ol&gt;
    &lt;li&gt;Снимаем комментарии со всех строк раздела &lt;strong&gt;“phpMyAdmin configuration storage settings”&lt;/strong&gt; и указываем для параметров &lt;strong&gt;“controluser”&lt;/strong&gt; и &lt;strong&gt;“controlpass”&lt;/strong&gt; логин и пароль служебной учетной записи MariaDB, созданной на предыдущем шаге. В нашем случае логин - &lt;strong&gt;pmaservice&lt;/strong&gt;, пароль - &lt;strong&gt;Qwe123&lt;/strong&gt;&lt;/li&gt;
  &lt;/ol&gt;
  &lt;figure class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://profitserver.ru/files/images/faq/vps-web-server/12-pma-config-storage.jpg&quot; width=&quot;800&quot; /&gt;
    &lt;figcaption&gt;Конфигурация phpmyadmin&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p&gt;Сохраняем изменения. Настройка завершена.&lt;/p&gt;
  &lt;p&gt;&lt;strong&gt;Данные для входа в phpMyadmin:&lt;/strong&gt;&lt;/p&gt;
  &lt;ul&gt;
    &lt;li&gt;http://[ip_адрес_сервера]/pma/&lt;/li&gt;
    &lt;li&gt;Логин: pma&lt;/li&gt;
    &lt;li&gt;Пароль: Qwe123&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p&gt;Материал взят с сайта &lt;a href=&quot;https://profitserver.ru/knowledge-base/web-server-setup-linux&quot; target=&quot;_blank&quot;&gt;profitserver.ru&lt;/a&gt;&lt;/p&gt;

</content></entry><entry><id>iceslam:easy-vue-js-slider-component</id><link rel="alternate" type="text/html" href="https://teletype.in/@iceslam/easy-vue-js-slider-component?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=iceslam"></link><title>Простой слайдер-компонент на VueJS</title><published>2020-07-29T15:09:23.546Z</published><updated>2020-07-29T15:17:34.091Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://teletype.in/files/78/b6/78b603f4-cce6-4bca-b7da-0e3a7a734496.png"></media:thumbnail><category term="vuejs" label="VueJS"></category><summary type="html">&lt;img src=&quot;https://telegra.ph/file/cee16d553dbde5f3e20a4.png&quot;&gt;Сделай слайдер простым...</summary><content type="html">
  &lt;p&gt;Сделай слайдер простым...&lt;/p&gt;
  &lt;p&gt;&lt;strong&gt;Демо&lt;/strong&gt;: &lt;a href=&quot;https://codesandbox.io/embed/vnynj6o500&quot; target=&quot;_blank&quot;&gt;CodeSandbox&lt;/a&gt;&lt;/p&gt;
  &lt;h4&gt;Установка&lt;/h4&gt;
  &lt;pre&gt;npm i -S vue-easy-slider
&lt;/pre&gt;
  &lt;h4&gt;Использование&lt;/h4&gt;
  &lt;p&gt;Установка плагина&lt;/p&gt;
  &lt;pre&gt;import Vue from &amp;#x27;vue&amp;#x27;
import EasySlider from &amp;#x27;vue-easy-slider&amp;#x27;

Vue.use(EasySlider)
&lt;/pre&gt;
  &lt;p&gt;или использование в инстансе Vue&lt;/p&gt;
  &lt;pre&gt;&amp;lt;slider animation=&amp;quot;fade&amp;quot;&amp;gt;
  &amp;lt;slider-item
    v-for=&amp;quot;(i, index) in list&amp;quot;
    :key=&amp;quot;index&amp;quot;
    :style=&amp;quot;i&amp;quot;
    @click=&amp;quot;hello&amp;quot;
  &amp;gt;
    &amp;lt;p style=&amp;quot;line-height: 280px; font-size: 5rem; text-align: center;&amp;quot;&amp;gt;Страница{{ index + 1 }}&amp;lt;/p&amp;gt;
  &amp;lt;/slider-item&amp;gt;
&amp;lt;/slider&amp;gt;
&lt;/pre&gt;
  &lt;pre&gt;import { Slider, SliderItem } from &amp;#x27;vue-easy-slider&amp;#x27;

new Vue({
  el: &amp;#x27;body&amp;#x27;,
  components: {
    Slider,
    SliderItem,
  },
  data() {
    return {
      list: [
        { backgroundColor: &amp;#x27;#3f51b5&amp;#x27;, width: &amp;#x27;100%&amp;#x27;, height: &amp;#x27;100%&amp;#x27; },
        { backgroundColor: &amp;#x27;#eee&amp;#x27;, width: &amp;#x27;100%&amp;#x27;, height: &amp;#x27;100%&amp;#x27; },
        { backgroundColor: &amp;#x27;#f44336&amp;#x27;, width: &amp;#x27;100%&amp;#x27;, height: &amp;#x27;100%&amp;#x27; },
      ],
    }
  },
  methods: {
    hello($event) {
      console.log(&amp;#x60;hello index: ${$event}&amp;#x60;)
    },
  },
})
&lt;/pre&gt;
  &lt;p&gt;Управление слайдером через v-model&lt;/p&gt;
  &lt;pre&gt;&amp;lt;slider animation=&amp;quot;fade&amp;quot; v-model=&amp;quot;sliderIndex&amp;quot;&amp;gt;
  ...
&amp;lt;/slider&amp;gt;
&amp;lt;button @click=&amp;quot;moveToIndex(2)&amp;quot;&amp;gt;пролистать на страницу 3&amp;lt;/button&amp;gt;
&lt;/pre&gt;
  &lt;pre&gt;...
  data() {
    return {
      // initial index
      sliderIndex: 1,
      list: [
        { backgroundColor: &amp;#x27;#3f51b5&amp;#x27;, width: &amp;#x27;100%&amp;#x27;, height: &amp;#x27;100%&amp;#x27; },
        { backgroundColor: &amp;#x27;#eee&amp;#x27;, width: &amp;#x27;100%&amp;#x27;, height: &amp;#x27;100%&amp;#x27; },
        { backgroundColor: &amp;#x27;#f44336&amp;#x27;, width: &amp;#x27;100%&amp;#x27;, height: &amp;#x27;100%&amp;#x27; },
      ],
    }
  },
  methods: {
    moveToIndex(index) {
      this.sliderIndex = index
    },
  },
...
&lt;/pre&gt;
  &lt;h4&gt;Пропсы&lt;/h4&gt;
  &lt;p&gt;Слайдер&lt;/p&gt;
  &lt;figure class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://telegra.ph/file/cee16d553dbde5f3e20a4.png&quot; width=&quot;848&quot; /&gt;
  &lt;/figure&gt;
  &lt;h4&gt;События&lt;/h4&gt;
  &lt;p&gt;Слайдер&lt;/p&gt;
  &lt;figure class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://telegra.ph/file/a2908c4ac76221ba251b7.png&quot; width=&quot;805&quot; /&gt;
  &lt;/figure&gt;
  &lt;h4&gt;Слоты&lt;/h4&gt;
  &lt;p&gt;Элемент слайда&lt;/p&gt;
  &lt;figure class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://telegra.ph/file/30bd10b5371458075b3d3.png&quot; width=&quot;285&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;Использование&lt;/p&gt;
  &lt;pre&gt;&amp;lt;slider&amp;gt;
  &amp;lt;slider-item&amp;gt;
    &amp;lt;img src=&amp;quot;&amp;quot;&amp;gt;
    &amp;lt;p&amp;gt;&amp;lt;/p&amp;gt;
    &amp;lt;button&amp;gt;&amp;lt;/button&amp;gt;
  &amp;lt;/slider-item&amp;gt;
  &amp;lt;div slot=&amp;quot;loading&amp;quot;&amp;gt;custom loading ...&amp;lt;/div&amp;gt;
&amp;lt;/slider&amp;gt;
&lt;/pre&gt;
  &lt;p&gt;_____________________________________&lt;/p&gt;
  &lt;p&gt;Оригинал на &lt;a href=&quot;https://github.com/shhdgit/vue-easy-slider&quot; target=&quot;_blank&quot;&gt;GitHub &lt;/a&gt;(автор компонента - &lt;a href=&quot;https://github.com/shhdgit&quot; target=&quot;_blank&quot;&gt;shhdgit&lt;/a&gt;)&lt;/p&gt;

</content></entry><entry><id>iceslam:vue-2-breadcrumbs-how-to-translated</id><link rel="alternate" type="text/html" href="https://teletype.in/@iceslam/vue-2-breadcrumbs-how-to-translated?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=iceslam"></link><title>&quot;Хлебные крошки&quot; на VueJS (vue-2-breadcrumbs)</title><published>2020-07-29T14:59:51.677Z</published><updated>2020-07-29T15:16:32.343Z</updated><summary type="html">Vue-2-breadcrumbs построены на базе официального плагина vue-router для создания простых &quot;хлебных крошек&quot;</summary><content type="html">
  &lt;blockquote&gt;Vue-2-breadcrumbs построены на базе официального плагина vue-router для создания простых &amp;quot;хлебных крошек&amp;quot;&lt;/blockquote&gt;
  &lt;p&gt;Демо: &lt;a href=&quot;https://scrum.github.io/vue-2-breadcrumbs/&quot; target=&quot;_blank&quot;&gt;GitHub&lt;/a&gt;&lt;/p&gt;
  &lt;h4&gt;Поддержка&lt;/h4&gt;
  &lt;ul&gt;
    &lt;li&gt;Поддержка SSR&lt;/li&gt;
    &lt;li&gt;Установка родительского маршрута без необходимости фактически вложить его в дочерний массив&lt;/li&gt;
    &lt;li&gt;Кастомизированный шаблон&lt;/li&gt;
    &lt;li&gt;Динамические &amp;quot;хлебные крошки&amp;quot;&lt;/li&gt;
    &lt;li&gt;Динамический родитель&lt;/li&gt;
    &lt;li&gt;Динамический заголовок&lt;/li&gt;
    &lt;li&gt;Сокращенный заголовок (&lt;code&gt;breadcrumb: &amp;#x27;Заголовок страницы&amp;#x27;&lt;/code&gt;)&lt;/li&gt;
    &lt;li&gt;Суб-роутинг&lt;/li&gt;
  &lt;/ul&gt;
  &lt;h4&gt;Установка&lt;/h4&gt;
  &lt;pre&gt;npm install vue-2-breadcrumbs
&lt;/pre&gt;
  &lt;blockquote&gt;&lt;strong&gt;Примечание:&lt;/strong&gt; Этот компонент совестим с NodeJS v10+&lt;/blockquote&gt;
  &lt;h4&gt;Использование&lt;/h4&gt;
  &lt;pre&gt;import Vue from &amp;#x27;vue&amp;#x27;;
import VueBreadcrumbs from &amp;#x27;vue-2-breadcrumbs&amp;#x27;;
import App from &amp;#x27;./App.vue&amp;#x27;;

Vue.use(VueBreadcrumbs);
&lt;/pre&gt;
  &lt;blockquote&gt;&lt;strong&gt;Примечание&lt;/strong&gt;: После этого компонент &lt;code&gt;&amp;lt;Breadcrumbs/&amp;gt;&lt;/code&gt; будет в вашем распоряжении&lt;/blockquote&gt;
  &lt;p&gt;Мета во Vue Router&lt;/p&gt;
  &lt;pre&gt;import Vue from &amp;#x27;vue&amp;#x27;;
import VueRouter from &amp;#x27;vue-router&amp;#x27;;

Vue.use(VueRouter);

const router = new VueRouter({
  routes: [
    {
      path: &amp;#x27;/&amp;#x27;,
      name: &amp;#x27;Главная&amp;#x27;,
      component: { template: &amp;#x27;&amp;lt;h2&amp;gt;Главная&amp;lt;/h2&amp;gt;&amp;#x27; },
      meta: {
        breadcrumb: &amp;#x27;Главная&amp;#x27;
      }
    },
    {
      path: &amp;#x27;/params&amp;#x27;,
      name: &amp;#x27;Параметры&amp;#x27;,
      component: { template: &amp;#x27;&amp;lt;h2&amp;gt;Параметры&amp;lt;/h2&amp;gt;&amp;#x27; },
      meta: {
        breadcrumb: routeParams =&amp;gt; &amp;#x60;route params id: ${routeParams.id}&amp;#x60;
      }
    },
    {
      path: &amp;#x27;/context&amp;#x27;,
      name: &amp;#x27;Контекст&amp;#x27;,
      component: { template: &amp;#x27;&amp;lt;h2&amp;gt;Контекст&amp;lt;/h2&amp;gt;&amp;#x27; },
      meta: {
        breadcrumb() {
            const { name } = this.$route;
            return &amp;#x60;Имя &amp;quot;${name}&amp;quot; рута контекста&amp;#x60;;
        }
      }
    },
    {
      path: &amp;#x27;/parent&amp;#x27;,
      component: { template: &amp;#x27;&amp;lt;router-view/&amp;gt;&amp;#x27; },
      meta: {
        breadcrumb: {
          label: &amp;#x27;Родитель для параметров&amp;#x27;,
          parent: &amp;#x27;Параметры&amp;#x27;
        }
      },
      {
        name: &amp;#x27;dynamic-parent&amp;#x27;,
        path: &amp;#x27;/dynamic-parent&amp;#x27;,
        component: { template: &amp;#x27;&amp;lt;h2&amp;gt;Динамический родитель&amp;lt;/h2&amp;gt;&amp;#x27; },
        meta: {
          breadcrumb() {
            const { name } = this.$route;

            return {
              label: name,
              parent: &amp;#x27;settings&amp;#x27;
            };
          }
        }
    }
  ]
});
&lt;/pre&gt;
  &lt;h4&gt;Опции&lt;/h4&gt;
  &lt;p&gt;Объект options также может быть передан в плагин для указания вашего собственного шаблона и методов рендеринга при желании. Например:&lt;/p&gt;
  &lt;pre&gt;import Vue from &amp;#x27;vue&amp;#x27;;
import VueBreadcrumbs from &amp;#x27;vue-2-breadcrumbs&amp;#x27;;

Vue.use(VueBreadcrumbs, {
  template:
    &amp;#x27;        &amp;lt;nav v-if=&amp;quot;$breadcrumbs.length&amp;quot; aria-label=&amp;quot;breadcrumb&amp;quot;&amp;gt;\n&amp;#x27; +
    &amp;#x27;            &amp;lt;ol class=&amp;quot;breadcrumb&amp;quot;&amp;gt;\n&amp;#x27; +
    &amp;#x27;                &amp;lt;li v-for=&amp;quot;(crumb, key) in $breadcrumbs&amp;quot; v-if=&amp;quot;crumb.meta.breadcrumb&amp;quot; :key=&amp;quot;key&amp;quot; class=&amp;quot;breadcrumb-item active&amp;quot; aria-current=&amp;quot;page&amp;quot;&amp;gt;\n&amp;#x27; +
    &amp;#x27;                    &amp;lt;router-link :to=&amp;quot;{ path: getPath(crumb) }&amp;quot;&amp;gt;{{ getBreadcrumb(crumb.meta.breadcrumb) }}&amp;lt;/router-link&amp;gt;&amp;#x27; +
    &amp;#x27;                &amp;lt;/li&amp;gt;\n&amp;#x27; +
    &amp;#x27;            &amp;lt;/ol&amp;gt;\n&amp;#x27; +
    &amp;#x27;        &amp;lt;/nav&amp;gt;&amp;#x27;
});
&lt;/pre&gt;
  &lt;p&gt;_________________________&lt;/p&gt;
  &lt;p&gt;Оригинал на &lt;a href=&quot;https://github.com/Scrum/vue-2-breadcrumbs&quot; target=&quot;_blank&quot;&gt;Github &lt;/a&gt;(автор компонента - &lt;a href=&quot;https://github.com/Scrum&quot; target=&quot;_blank&quot;&gt;Scrum(Иван Демидов)&lt;/a&gt;)&lt;/p&gt;

</content></entry></feed>