Я запускаю приложение Meteor 1.8.1 с Phusion Passenger в nginx в Ubuntu 18.04.
У меня есть скрипт для обновления приложения, который завершается перезапуском приложения следующим образом:
passenger-config restart-app --ignore-app-not-running --ignore-passenger-not-running /var/www/myapp/bundle
Сбой состояния: 500 Internal Server Error. В журнале nginx я вижу это:
[ E 2020-03-13 18:46:49.7679 1615/Tt age/Cor/App/Implementation.cpp:221 ]: Could not spawn process for application /var/www/myapp/bundle/programs: An operating system error occurred while preparing to spawn an application process: Cannot lstat("/var/www/myapp/bundle/programs/main.js"): No such file or directory (errno=2)
И мое приложение теперь не работает.
Если я sh на сервер как пользователь моего приложения (тот же пользователь который запускает удаленный скрипт) и запускает ту же команду restart-app в окне терминала, я получаю ту же ошибку.
Если я затем перезапустить nginx:
sudo service nginx restart
Приложение перезапускается вместе с nginx и запускается, а после этого , если я запускаю restart-app в окне терминала, оно работает:
passenger-config restart-app --ignore-app-not-running --ignore-passenger-not-running /var/www/myapp/bundle
Сценарий запускается как пользователь приложения, и я вошел в систему как пользователь приложения в окне терминала.
Я запустил этот же скрипт на другом сервере, и он работает нормально. Оба сервера имеют одинаковую конфигурацию nginx.
На новом сервере приложение запускается, но перезапускается после сбоя обновления.
Итак, последовательность:
- приложение работает
- запустить сценарий с моего локального компьютера для обновления приложения
- сценарий пытается перезапустить приложение, это происходит с ошибкой, показанной выше
- s sh для сервер как тот же пользователь, попробуйте перезапустить приложение, увидите ту же ошибку
- перезагрузка nginx
- теперь перезапуск приложения в окне терминала работает
Вот мои полные сценарии:
.env (указываете пользователя: сервер)
export SERVER='myappuser@x.x.x.x'
initiate. sh (запускайте это на локальном компьютере)
#!/bin/bash
set -e
# use to reference other scripts in the same directory as this one
my_dir=`dirname $0`
# load environment variables: SERVER
. $my_dir/.env
### Configuration ###
APP_DIR=/var/www/myapp
KEYFILE=
REMOTE_SCRIPT_PATH=/tmp/deploy-myapp.sh
WORK_SCRIPT_PATH=.deploy/myapp/work.sh
### Library ###
function run()
{
echo "Running: $@"
"$@"
}
### Automation steps ###
if [[ "$KEYFILE" != "" ]]; then
KEYARG="-i $KEYFILE"
else
KEYARG=
fi
if [[ `meteor --version` =~ "Meteor 1.4."* ]] || [[ `meteor --version` =~ "Meteor 1.5."* ]] || [[ `meteor --version` =~ "Meteor 1.6."* ]]; then
run meteor build --server-only ../output
mv ../output/*.tar.gz ./package.tar.gz
else
run meteor bundle package.tar.gz
fi
run scp $KEYARG package.tar.gz $SERVER:$APP_DIR/
run scp $KEYARG $WORK_SCRIPT_PATH $SERVER:$REMOTE_SCRIPT_PATH
echo
echo "---- Running deployment script on remote server ----"
run ssh $KEYARG $SERVER bash $REMOTE_SCRIPT_PATH
работа. sh (запускается инициатором на сервере. sh)
#!/bin/bash
set -e
### Configuration ###
APP_DIR=/var/www/myapp
RESTART_ARGS=
# Uncomment and modify the following if you installed Passenger from tarball
#export PATH=/path-to-passenger/bin:$PATH
### Automation steps ###
set -x
# Extract newly uploaded package
mkdir -p $APP_DIR/tmp
cd $APP_DIR/tmp
tar xzf $APP_DIR/package.tar.gz
rm -f $APP_DIR/package.tar.gz
# Install dependencies
cd $APP_DIR/tmp/bundle/programs/server
npm install --production
npm prune --production
# Copy over persistent files
if [[ -e $APP_DIR/bundle/Passengerfile.json ]]; then
cp $APP_DIR/bundle/Passengerfile.json $APP_DIR/tmp/bundle/
fi
# if restart app fails, bundle.old is left behind and causes a new error
rm -rf $APP_DIR/bundle.old
# Switch directories, restart app
mv $APP_DIR/bundle $APP_DIR/bundle.old
mv $APP_DIR/tmp/bundle $APP_DIR/bundle
passenger-config restart-app --ignore-app-not-running --ignore-passenger-not-running $RESTART_ARGS $APP_DIR/bundle
rm -rf $APP_DIR/bundle.old
И когда я подключаюсь к серверу, это выглядит так:
myappuser@x.x.x.x
Edit: я привел в порядок свою конфигурацию nginx, чтобы в / etc / nginx / sites-enabled / default не было ничего нестандартного. Все мои настройки приложения находятся в одном файле и работают правильно.
/ etc / nginx / sites-enabled / myapp.conf
# don't prefix log entries with App PID stdout
passenger_disable_log_prefix on;
# don't show Passenger version
passenger_show_version_in_header off;
server {
listen 80;
server_name myapp.org www.myapp.org;
return 301 https://myapp.org$request_uri;
}
server {
listen 443 ssl http2; #https of www*, 301 to right domain.
server_name www.myapp.org;
ssl_certificate /etc/letsencrypt/live/myapp.org/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/myapp.org/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
return 301 https://myapp.org$request_uri;
}
server {
listen 443 ssl http2;
server_name myapp.org;
# Tell Nginx and Passenger where your app's 'public' directory is
root /var/www/myapp/bundle/public;
# Turn on Passenger
passenger_enabled on;
# Tell Passenger that your app is a Meteor app
passenger_app_type node;
passenger_startup_file main.js;
# number of proxies in front of server
passenger_env_var HTTP_FORWARDED_COUNT 1;
... other app config
# don't show nginx version
server_tokens off;
add_header X-Frame-Options SAMEORIGIN;
# ssl_prefer_server_ciphers and ssl_ciphers are set in /etc/letsencrypt/options-ssl-nginx.conf
ssl_certificate /etc/letsencrypt/live/myapp.org/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/myapp.org/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
# only allow secure ssl
ssl_protocols TLSv1.2;
}
Я тут рву свои волосы! Я не знаю, почему этот скрипт не работает, когда я использовал его на более чем одном сервере раньше. И я не могу понять, почему перезапуск nginx должен привести к тому, что Passenger restart-app заработает ... до следующего обновления ...