Discourse Bad Gateway после перезагрузки

Мой сервер работает в виртуальной машине, размещённой у одного из крупных облачных провайдеров.
Я успешно установил discourse на него, и он стабильно работал в течение последнего месяца.
Сегодня я решил вернуть спецификации моей ВМ к исходной конфигурации (*) и перезагрузил систему. При запуске, несмотря на то, что всё остальное на сервере работает исправно, при попытке доступа к форуму Discourse я получаю ошибку 502 Bad Gateway. Подумав, что контейнер Docker не запустился автоматически, я подключился к серверу по SSH и выполнил ./launcher start app, но получил сообщение о нехватке места (доступно 5 ГБ). Тогда я запустил df -h, который показал, что на самом деле доступно 14 ГБ. После этого я снова выполнил ./launcher start app, но на этот раз получил предупреждение о том, что Docker будет скачивать файлы и нужно подождать. После некоторых процессов я увидел сообщение Nothing to do, your container has already started!. Однако попытки доступа к форуму по-прежнему возвращали ошибку 502 Bad Gateway.

Обратившись к этому форуму, я решил выполнить ./launcher rebuild app и получил следующие ошибки, связанные с PostgreSQL:

    user@host:[16:48]:/var/discourse# ./launcher rebuild app
    Ensuring launcher is up to date
    Fetching origin
    Launcher is up-to-date
    Stopping old container
    + /usr/bin/docker stop -t 60 app
    app
    cd /pups && git pull && /pups/bin/pups --stdin
    Already up to date.
    I, [2020-07-01T07:19:42.821347 #1]  INFO -- : Loading --stdin
    I, [2020-07-01T07:19:42.831806 #1]  INFO -- : > locale-gen $LANG && update-locale
    I, [2020-07-01T07:19:42.879007 #1]  INFO -- : Generating locales (this might take a while)...
    Generation complete.
    
    I, [2020-07-01T07:19:42.879431 #1]  INFO -- : > mkdir -p /shared/postgres_run
    I, [2020-07-01T07:19:42.885054 #1]  INFO -- :
    I, [2020-07-01T07:19:42.885734 #1]  INFO -- : > chown postgres:postgres /shared/postgres_run
    I, [2020-07-01T07:19:42.891655 #1]  INFO -- :
    I, [2020-07-01T07:19:42.892269 #1]  INFO -- : > chmod 775 /shared/postgres_run
    I, [2020-07-01T07:19:42.898103 #1]  INFO -- :
    I, [2020-07-01T07:19:42.898942 #1]  INFO -- : > rm -fr /var/run/postgresql
    I, [2020-07-01T07:19:42.905607 #1]  INFO -- :
    I, [2020-07-01T07:19:42.906463 #1]  INFO -- : > ln -s /shared/postgres_run /var/run/postgresql
    I, [2020-07-01T07:19:42.912617 #1]  INFO -- :
    I, [2020-07-01T07:19:42.913233 #1]  INFO -- : > socat /dev/null UNIX-CONNECT:/shared/postgres_run/.s.PGSQL.5432 || exit 0 && echo postgres already running stop container ; exit 1
    2020/07/01 07:19:42 socat[26] E connect(6, AF=1 "/shared/postgres_run/.s.PGSQL.5432", 36): No such file or directory
    I, [2020-07-01T07:19:42.925688 #1]  INFO -- :
    I, [2020-07-01T07:19:42.926081 #1]  INFO -- : > rm -fr /shared/postgres_run/.s*
    I, [2020-07-01T07:19:42.931174 #1]  INFO -- :
    I, [2020-07-01T07:19:42.931649 #1]  INFO -- : > rm -fr /shared/postgres_run/*.pid
    I, [2020-07-01T07:19:42.938152 #1]  INFO -- :
    I, [2020-07-01T07:19:42.938850 #1]  INFO -- : > mkdir -p /shared/postgres_run/12-main.pg_stat_tmp
    I, [2020-07-01T07:19:42.943575 #1]  INFO -- :
    I, [2020-07-01T07:19:42.944331 #1]  INFO -- : > chown postgres:postgres /shared/postgres_run/12-main.pg_stat_tmp
    I, [2020-07-01T07:19:42.949159 #1]  INFO -- :
    I, [2020-07-01T07:19:42.961190 #1]  INFO -- : File > /etc/service/postgres/run  chmod: +x  chown:
    I, [2020-07-01T07:19:42.973345 #1]  INFO -- : File > /etc/service/postgres/log/run  chmod: +x  chown:
    I, [2020-07-01T07:19:42.983929 #1]  INFO -- : File > /etc/runit/3.d/99-postgres  chmod: +x  chown:
    I, [2020-07-01T07:19:42.994843 #1]  INFO -- : File > /root/upgrade_postgres  chmod: +x  chown:
    I, [2020-07-01T07:19:42.995487 #1]  INFO -- : > chown -R root /var/lib/postgresql/12/main
    I, [2020-07-01T07:19:44.012812 #1]  INFO -- :
    I, [2020-07-01T07:19:44.013656 #1]  INFO -- : > [ ! -e /shared/postgres_data ] && install -d -m 0755 -o postgres -g postgres /shared/postgres_data && sudo -E -u postgres /usr/lib/postgresql/12/bin/initdb -D /shared/postgres_data || exit 0
    I, [2020-07-01T07:19:44.019545 #1]  INFO -- :
    I, [2020-07-01T07:19:44.019872 #1]  INFO -- : > chown -R postgres:postgres /shared/postgres_data
    I, [2020-07-01T07:19:44.064432 #1]  INFO -- :
    I, [2020-07-01T07:19:44.065186 #1]  INFO -- : > chown -R postgres:postgres /var/run/postgresql
    I, [2020-07-01T07:19:44.071385 #1]  INFO -- :
    I, [2020-07-01T07:19:44.072196 #1]  INFO -- : > /root/upgrade_postgres
    I, [2020-07-01T07:19:44.084004 #1]  INFO -- :
    I, [2020-07-01T07:19:44.084662 #1]  INFO -- : > rm /root/upgrade_postgres
    I, [2020-07-01T07:19:44.090399 #1]  INFO -- :
    I, [2020-07-01T07:19:44.092280 #1]  INFO -- : Replacing data_directory = '/var/lib/postgresql/12/main' with data_directory = '/shared/postgres_data' in /etc/postgresql/12/main/postgresql.conf
    I, [2020-07-01T07:19:44.093969 #1]  INFO -- : Replacing (?-mix:#?listen_addresses *=.*) with listen_addresses = '*' in /etc/postgresql/12/main/postgresql.conf
    I, [2020-07-01T07:19:44.095204 #1]  INFO -- : Replacing (?-mix:#?synchronous_commit *=.*) with synchronous_commit = $db_synchronous_commit in /etc/postgresql/12/main/postgresql.conf
    I, [2020-07-01T07:19:44.095937 #1]  INFO -- : Replacing (?-mix:#?shared_buffers *=.*) with shared_buffers = $db_shared_buffers in /etc/postgresql/12/main/postgresql.conf
    I, [2020-07-01T07:19:44.096695 #1]  INFO -- : Replacing (?-mix:#?work_mem *=.*) with work_mem = $db_work_mem in /etc/postgresql/12/main/postgresql.conf
    I, [2020-07-01T07:19:44.097554 #1]  INFO -- : Replacing (?-mix:#?default_text_search_config *=.*) with default_text_search_config = '$db_default_text_search_config' in /etc/postgresql/12/main/postgresql.conf
    I, [2020-07-01T07:19:44.101971 #1]  INFO -- : > install -d -m 0755 -o postgres -g postgres /shared/postgres_backup
    I, [2020-07-01T07:19:44.112672 #1]  INFO -- :
    I, [2020-07-01T07:19:44.113831 #1]  INFO -- : Replacing (?-mix:#?max_wal_senders *=.*) with max_wal_senders = $db_max_wal_senders in /etc/postgresql/12/main/postgresql.conf
    I, [2020-07-01T07:19:44.114973 #1]  INFO -- : Replacing (?-mix:#?wal_level *=.*) with wal_level = $db_wal_level in /etc/postgresql/12/main/postgresql.conf
    I, [2020-07-01T07:19:44.116047 #1]  INFO -- : Replacing (?-mix:#?checkpoint_segments *=.*) with checkpoint_segments = $db_checkpoint_segments in /etc/postgresql/12/main/postgresql.conf
    I, [2020-07-01T07:19:44.117033 #1]  INFO -- : Replacing (?-mix:#?logging_collector *=.*) with logging_collector = $db_logging_collector in /etc/postgresql/12/main/postgresql.conf
    I, [2020-07-01T07:19:44.118051 #1]  INFO -- : Replacing (?-mix:#?log_min_duration_statement *=.*) with log_min_duration_statement = $db_log_min_duration_statement in /etc/postgresql/12/main/postgresql.conf
    I, [2020-07-01T07:19:44.119352 #1]  INFO -- : Replacing (?-mix:^#local +replication +postgres +peer$) with local replication postgres  peer in /etc/postgresql/12/main/pg_hba.conf
    I, [2020-07-01T07:19:44.120299 #1]  INFO -- : Replacing (?-mix:^host.*all.*all.*127.*$) with host all all 0.0.0.0/0 md5 in /etc/postgresql/12/main/pg_hba.conf
    I, [2020-07-01T07:19:44.121038 #1]  INFO -- : > HOME=/var/lib/postgresql USER=postgres exec chpst -u postgres:postgres:ssl-cert -U postgres:postgres:ssl-cert /usr/lib/postgresql/12/bin/postmaster -D /etc/postgresql/12/main
    I, [2020-07-01T07:19:44.126334 #1]  INFO -- : > sleep 5
    2020-07-01 07:19:44.157 UTC [49] LOG:  starting PostgreSQL 12.2 (Debian 12.2-2.pgdg100+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 8.3.0-6) 8.3.0, 64-bit
    2020-07-01 07:19:44.158 UTC [49] LOG:  listening on IPv4 address "0.0.0.0", port 5432
    2020-07-01 07:19:44.158 UTC [49] LOG:  listening on IPv6 address "::", port 5432
    2020-07-01 07:19:44.161 UTC [49] LOG:  listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
    2020-07-01 07:19:44.162 UTC [49] FATAL:  could not map anonymous shared memory: Cannot allocate memory
    2020-07-01 07:19:44.162 UTC [49] HINT:  This error usually means that PostgreSQL's request for a shared memory segment exceeded available memory, swap space, or huge pages. To reduce the request size (currently 4423172096 bytes), reduce PostgreSQL's shared memory usage, perhaps by reducing shared_buffers or max_connections.
    2020-07-01 07:19:44.162 UTC [49] LOG:  database system is shut down
    I, [2020-07-01T07:19:49.141762 #1]  INFO -- :
    I, [2020-07-01T07:19:49.142221 #1]  INFO -- : > su postgres -c 'createdb discourse' || true
    createdb: error: could not connect to database template1: could not connect to server: No such file or directory
        Is the server running locally and accepting
        connections on Unix domain socket "/var/run/postgresql/.s.PGSQL.5432"?
    I, [2020-07-01T07:19:49.227852 #1]  INFO -- :
    I, [2020-07-01T07:19:49.228226 #1]  INFO -- : > su postgres -c 'psql discourse -c "create user discourse;"' || true
    psql: error: could not connect to server: could not connect to server: No such file or directory
        Is the server running locally and accepting
        connections on Unix domain socket "/var/run/postgresql/.s.PGSQL.5432"?
    I, [2020-07-01T07:19:49.330487 #1]  INFO -- :
    I, [2020-07-01T07:19:49.330822 #1]  INFO -- : > su postgres -c 'psql discourse -c "grant all privileges on database discourse to discourse;"' || true
    psql: error: could not connect to server: could not connect to server: No such file or directory
        Is the server running locally and accepting
        connections on Unix domain socket "/var/run/postgresql/.s.PGSQL.5432"?
    I, [2020-07-01T07:19:49.425970 #1]  INFO -- :
    I, [2020-07-01T07:19:49.426356 #1]  INFO -- : > su postgres -c 'psql discourse -c "alter schema public owner to discourse;"'
    psql: error: could not connect to server: could not connect to server: No such file or directory
        Is the server running locally and accepting
        connections on Unix domain socket "/var/run/postgresql/.s.PGSQL.5432"?
    I, [2020-07-01T07:19:49.506638 #1]  INFO -- :
    I, [2020-07-01T07:19:49.507202 #1]  INFO -- : Terminating async processes
    
    
    FAILED
    --------------------
    Pups::ExecError: su postgres -c 'psql discourse -c "alter schema public owner to discourse;"' failed with return #<Process::Status: pid 75 exit 2>
    Location of failure: /pups/lib/pups/exec_command.rb:112:in `spawn'
    exec failed with the params "su postgres -c 'psql $db_name -c \"alter schema public owner to $db_user;\"'"
    eb41679f76cd749ccd8c84a7543365d093619b80df6fc6750b9349fb63565fa1
    ** FAILED TO BOOTSTRAP ** please scroll up and look for earlier error messages, there may be more than one.
    ./discourse-doctor may help diagnose the problem.
    user@host:[17:19]:/var/discourse#

Странно, но несмотря на вышеуказанные ошибки, выполнение ./launcher start app не вызывает ошибок:

starting up existing container
+ /usr/bin/docker start app
app

С работающим экземпляром я попытался использовать ./launcher enter app, чтобы попасть в контейнер. (По моему скромному мнению, доступные в контейнере инструменты очень ограничены (да, я пользователь nano и люблю иметь различные алиасы, например ll). Я не могу найти физический путь к папкам внутри экземпляра Docker (как я хотел бы, чтобы скачать их через FTP-клиент).

В /var/log/nginx/error.log я вижу следующую запись об ошибке при каждом обновлении страницы в браузере:

2020/07/01 07:44:16 [error] 646#646: *3 connect() failed (111: Connection refused) while connecting to upstream, client: xxx.xx.0.1, server: _, request: "GET / HTTP/1.1", upstream: "http://127.0.0.1:3000/", host: "discourse.myDomain.com"

Что может быть причиной моей проблемы? Почему PostgreSQL внезапно перестал работать?

(*) Через неделю после установки Discourse я обновил сервер, добавив больше процессоров и памяти. Мне это было необходимо для проведения видеоконференции. После завершения конференции я вернулся к своей обычной конфигурации. Обратите внимание, что размер диска я не менял ни на одном из этапов изменения спецификаций.

Это связано с тем, что ваша текущая пересборка контейнера не удалась, и вы запускаете предыдущую версию вашего app. Это нормальное поведение. Когда пересборка не удаётся, исходный контейнер (в общем случае) не удаляется, и исходный образ также остаётся доступным.

Что касается вашей проблемы с PG, вам потребуется предоставить команде более подробную информацию о конфигурации вашего приложения и контейнера, чтобы получить наилучшую поддержку.

@neounix : Спасибо.

Я новичок в хостинге форума Discourse, поэтому не уверен, куда смотреть и на что обращать внимание. У меня установлена практически базовая версия без плагинов и других изменений. В файле app.yml определены некоторые переменные, и я использую свой существующий демон Apache2 в качестве обратного прокси для пересылки трафика Discourse через отдельный виртуальный хост на локальный порт, который я настроил для прослушивания Discourse.

Не могли бы вы подробнее рассказать, какая информация была бы полезной? Есть ли какой-то ресурс, который я мог бы прочитать, чтобы помочь отладить мою ситуацию?

Основная ошибка содержится в приведённом выше файле журнала.

2020-07-01 07:19:44.162 UTC [49] FATAL:  не удалось отобразить анонимную разделяемую память: Невозможно выделить память

2020-07-01 07:19:44.162 UTC [49] HINT:  Эта ошибка обычно означает, что запрос PostgreSQL на сегмент разделяемой памяти превысил доступную память, пространство подкачки или большие страницы. Чтобы уменьшить размер запроса (в настоящее время 4423172096 байт), уменьшите использование разделяемой памяти PostgreSQL, например, снизив параметры shared_buffers или max_connections.

Я видел эту ошибку, но я не вносил никаких изменений в app.yml.
Где можно уменьшить shared_buffers или max_connections, если их нет в app.yml? В app.yml есть только параметр db_shared_buffers, но он установлен в значение по умолчанию “4096MB”, как и всегда было (до и после увеличения памяти сервера).

Возможно, стоит опубликовать статистику, связанную с памятью.

Например, в Linux:

$ free -m
              total        used        free      shared  buff/cache   available
Mem:          64299       12955        9678         361       41664       50265
Swap:          7807          69        7738

А для статистики Docker опубликуйте вывод команды

docker stats

и так далее.

Ошибка связана с нехваткой памяти.

Статистика памяти сервера:

              total        used        free      shared  buff/cache   available
Mem:           3951        2236         414          86        1299        1308
Swap:           511         415          96

Статистика памяти после команды enter app:

              total        used        free      shared  buff/cache   available
Mem:           3951        2363         321          86        1266        1215
Swap:           511         415          96

Выполнение команды docker stats > output.txt дало следующий результат:

        CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT    MEM %               NET I/O             BLOCK I/O           PIDS
       ca4c5f37894c        app                 15.86%              6.48MiB / 3.859GiB   0.16%               20.3kB / 12.6kB     0B / 0B             25
        CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT    MEM %               NET I/O             BLOCK I/O           PIDS
       ca4c5f37894c        app                 15.86%              6.48MiB / 3.859GiB   0.16%               20.3kB / 12.6kB     0B / 0B             25
        CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT     MEM %               NET I/O             BLOCK I/O           PIDS
       ca4c5f37894c        app                 2.83%               6.539MiB / 3.859GiB   0.17%               20.3kB / 12.6kB     0B / 0B             25
        CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT     MEM %               NET I/O             BLOCK I/O           PIDS
       ca4c5f37894c        app                 2.83%               6.539MiB / 3.859GiB   0.17%               20.3kB / 12.6kB     0B / 0B             25
        CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT     MEM %               NET I/O             BLOCK I/O           PIDS
       ca4c5f37894c        app                 3.30%               6.477MiB / 3.859GiB   0.16%               20.3kB / 12.6kB     0B / 0B             25
        CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT     MEM %               NET I/O             BLOCK I/O           PIDS
       ca4c5f37894c        app                 3.30%               6.477MiB / 3.859GiB   0.16%               20.3kB / 12.6kB     0B / 0B             25
        CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT     MEM %               NET I/O             BLOCK I/O           PIDS
       ca4c5f37894c        app                 2.45%               6.535MiB / 3.859GiB   0.17%               20.3kB / 12.6kB     0B / 0B             25
        CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT     MEM %               NET I/O             BLOCK I/O           PIDS
       ca4c5f37894c        app                 2.45%               6.535MiB / 3.859GiB   0.17%               20.3kB / 12.6kB     0B / 0B             25

Привет, @nap

Вы можете освободить много памяти, остановив и затем удалив все старые контейнеры app.

Например:

docker stop <container_id>
docker rm <container_id>

При условии, что они не используются?

Если все они используются, то вам следует рассмотреть возможность увеличения памяти для этого сервера выше 4 ГБ; возможно, стоит перейти на 8 ГБ :slight_smile:

Я остановил приложение командой ./launcher stop app, а затем снова запустил docker stats. Контейнеры не были отображены.
К сожалению, увеличение объема памяти означает дополнительные расходы. Самое раздражающее сейчас то, что месяц назад всё работало с 4 ГБ.

И я даже не могу пересобрать в данный момент, хотя это не должно потреблять так много памяти.

Без запущенного контейнера статистика памяти выглядит так:

              total        used        free      shared  buff/cache   available
Mem:           3951        2207         169          91        1574        1332
Swap:           511         446          65

У меня есть несколько интересных директорий в ./var/lib/docker/overlay2/:

e3e6cdfcc62c2e0b68ec91efxxxxx6c69212c95b5070f7b6b84e97edcb473ea2
64a04d1b97a18f51a5fdc536xxxxxf9473de0c2ccd1a2cc0d62e830164b5f2d8
355303c6af7bebff1163195c5xxxxx8fd1de6333e39adbcb573c7365673b6c85

Могу ли я их удалить?

Верно.

Понял. Я был занят другой задачей и не заметил, что ваш вывод показывал статистику для одного и того же контейнера, а не для нескольких.

Что показывает команда free -m сейчас, когда ваш контейнер не запущен?

Думаю, 4 ГБ оперативной памяти достаточно для одного контейнера, это точно.

Нет.

Не удаляйте эти файлы Docker.

Проблема, судя по сообщению об ошибке, связана с вашей конфигурацией Discourse PG 12. Я не уверен, как это исправить, поскольку, насколько я знаю, изменение файла конфигурации PG 12 для Discourse не поддерживается.

У «топов» с Meta будут лучшие предложения, чем у меня, особенно у команд профессионального хостинга.

Вы имеете в виду, что это касается внутренних файлов конфигурации Docker? И что ручное изменение вызовет проблемы при запуске или обновлении контейнера?

@nap

Если вы выполните поиск в Google по сообщению об ошибке выше (в кавычках), вы найдете несколько тем, напрямую касающихся именно этого сообщения об ошибке PostgreSQL.

Надеюсь, это поможет.

После этого вы перезапустили ./discourse-setup или вручную изменили настройки памяти в файле app.yml? Что означают параметры db_shared_buffers, unicorn_workers и db_work_mem?

За исключением того, что вы работаете за обратным прокси-сервером, что усложняет ситуацию. Неясно, является ли обратный прокси-сервер причиной проблемы, но он действительно усложняет дело.

У вас несколько разделов? Возможно, раздел, где Docker создаёт образы, заполнен?

@pfaffman : Спасибо, что уделили время.

Нет, я лишь добавил ряд определений переменных, касающихся названия сайта и использования тегов.

db_shared_buffers — «4096MB»
unicorn_workers — 8
db_work_mem — закомментирован

У меня есть один основной раздел на 40 ГБ (14 ГБ свободно), 512 МБ своп-памяти и раздел на 8 ГБ для резервных копий (не смонтирован).

Похоже, мне удалось преодолеть проблему. Сначала я попытался уменьшить буферы до 2 ГБ и количество рабочих процессов до 4, но получил ту же ошибку. Затем я уменьшил буферы до 1 ГБ, после чего rebuild завершился успешно, и форум снова заработал.

Спасибо всем!!