Односерверное развертывание Nginx/Node/Nuxt/React/NG, рутинная оптимизация и самозапускающиеся скрипты

Node.js Nginx
Односерверное развертывание Nginx/Node/Nuxt/React/NG, рутинная оптимизация и самозапускающиеся скрипты

предисловие

Как небольшая мастерская, интерфейсные и внутренние службы находятся на одном сервере,

С ростом бизнеса внешний интерфейс был окончательно выброшен (независимый), хотя пропускная способность только двухъядерная 2M;

Нужно развернуть так мало, включая тестовую линию и официальную линию (как показано ниже):

официальный сайт ПК (Angular6)/фон администратора (umi+react)/Мобильный обмен(Nuxt)/встроенная страница приложения(Nuxt)

Просто возьмите на заметку, если вам интересно, посмотрите, может быть, это сэкономит вам время.

Что вы можете получить?

Разные очки знаний,linuxнекоторые вещиshell ,chmod,chgrp ,chownИ некоторые знания по основам эксплуатации и обслуживания

nginxНекоторые вещи, более современная конфигурация (не считая следующего IE11);

pm2а такжеnodeнекоторые вещи

основная среда

  • Выбор версии системыCentos 7.4После того, как мА поскользнулся до последней
# 查看版本号
cat /etc/redhat-release
# 更新
yum update 
# 重启
reboot
# 适用于非跨版本大版本的(比如7.x的升级..跨版本的此法子不一定适用)
# 也不建议服务器突然跨大版本升级,新机子就直接上新的,反正全部重新部署的
# 大版本的升级, 注意做好对应的防范措施,避免正式线直接GG,有主从的好一点,可以在从服务器搞了再同步过去
cat /etc/redhat-release  # CentOS Linux release 7.6.1810 (Core)

  • nodeвыбранная версияLTSверсия, ноcurrentВерсия для быстрой итерации (11.x)

официальныйwikiУже предоставлено:GitHub.com/источник узла/…

  • Основа зависимой (gcc,makeполагаться)
yum install gcc-c++ make

В противном случае какая-то зависимая компиляция сообщит об этой ошибке, например, когда я развертываюnuxtстолкнулись, когда

  • yarn, более удобный менеджер пакетов (официальный источник)
# centos
curl --silent --location https://dl.yarnpkg.com/rpm/yarn.repo | sudo tee /etc/yum.repos.d/yarn.repo
sudo yum install yarn
  • nginx, выбратьlts(1.14.2)

Официальный документ nginx дает исходники, можете сделать сами, просто пропишите в vim

Woohoo. Nginx.com/resources/i…

Список изменений для последней LTS:nginx.org/ru/changes-…

  • git, Установка с официального сайта

Исходный пакет:mirrors.edge.kernel.org/general/soft war…

# 2.x.x 是你选择版本(下载那个)
$ tar -zxf git-2.x.x.tar.gz
$ cd git-2.x.x
$ make configure # 编译
$ ./configure --prefix=/usr # 指定安装位置(--prefix)
$ make all doc info
$ sudo make install install-doc install-html install-info
# 走完这一些基本正常安装(无报错的情况,否则缺啥补啥)

Конечно, вы также можете использовать его напрямуюyumУстановить систему вверх по течению складаgit, но версия старше

Есть также сторонние источники, которые также необязательны (угрозы безопасности на ваш страх и риск)

развертывать

После установки nginx по умолчанию обычно используются следующие:

  • html(/usr/share/nginx/html): где хранится веб-страница
  • conf(/etc/nginx/conf.d/): в этом каталогеconfфайл будет добавлен кnginx.confВ частности видnginx.confИспользоватьinclude
  • logs(/var/logs/nginx): nginxМесто хранения журнала по умолчанию

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

я использую последнююlts,Инициализацияnginx.confЭто вообще так, некоторые я добавил от себя

Tencent Cloud имеет соответствующийnginxкитайское руководство

будь осторожен

Пользователь выполнения по умолчанию для последней версии:nginx, некоторые версииwww-data;

Итак, ваша область кода, не помещенная в область по умолчаниюnginxЕсли путь по умолчанию, не забудьте исправить разрешения, не вставляйте егоrootв домашнем каталоге;

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

Более разумный подход состоит в том, чтобы сохранить каталог кода в корневом каталоге и создать новую папку для его хранения;


# 修正该目录的所属
# 意思就是递归该目录的拥有者为nginx,用户组为nginx, chown(change owner)
chown -R nginx:nginx /code

# 也能用chgrp来修改用户组(change group)

然后给该目下添加对应的文件权限,我们给他755
chmod -R 755 /code


`755 : rwx-rx-rX => u(user)-g(group)-o(other) => r(read[读]:4)-x(excute[执行]:1)-w(write[写]:2)`

# 查询机子的一些信息,比如cpu ,内存这些,可以进到  /proc目录查看
#比如/proc/cpuinfo(cpu信息) ,meminfo(内存信息)等

Наиболее часто используемые команды nginx

  • nginx -t: тестовое заданиеnginxНормальный ли профиль, сразу после перезагрузки службы, если сразу вылетает ошибка и избегайте изменений в файле конфигурации!Проверьте, это единственная правда
  • nginx -s reload: перезагрузить файл конфигурации без перезагрузкиnginxобслуживание, сменаnginxКонфигурацию можно использовать напрямую, чтобы она вступила в силу без простоев.

nginx.conf


# 使用用户
user  nginx;
worker_processes auto; # 进程数,自动就可以
worker_rlimit_nofile 65535; # worker进程的最大打开文件数限制

events { # 处理链接的额外参数,如名事件
    multi_accept on; # 允许尽可能多的连接接入
    use epoll; # 轮询方案
    worker_connections 65535; # 最大的连接数
}

# 错误日志存放
error_log  /var/log/nginx/error.log warn;

# pid(process id), 更多的用于linux操作进程的时候用到,该pid代表nginx实例
pid        /var/run/nginx.pid;




http {
    charset utf-8; # 默认字符集
    sendfile on; # 提高静态资源的托管效率
    tcp_nopush on; # 只有sendfile 开启的情况下,才会生效,累计包达到一定数量或大小才会发出,降低开销
    tcp_nodelay on; # 尽快发送数据,只会针对处于 keep-alive 状态的 TCP 连接才会启用 tcp_nodelay
    server_tokens off; # 安全隐患规避,隐藏请求头nginx版本
    log_not_found off; # 不存在部分资源的时候记录到日志,比如favico
    types_hash_max_size 2048; # 内存换效率,检索依赖
    client_max_body_size 16M;  # 允许客户端传送body的最大值(看你们上传文件调整)
    include       /etc/nginx/mime.types; # 一个映射表,就是资源的mime表,就是允许的资源类型

    default_type  application/octet-stream; # nginx 默认传送格式

    # 日志格式
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    # 访问日志
    access_log  /var/log/nginx/access.log  main;


    # SSL
    ssl_session_timeout 1d; # 客户端会话中ssl凭证的有效期,自行看着调整
    ssl_session_cache shared:SSL:50m; #ssl/tls会话缓存的类型和大小,官网上说1M可以存放约4000个sessions
    ssl_session_tickets off; # 关闭会话凭证复用

    # 启用TLS1.2及加密方式
    ssl_protocols TLSv1.2;
    ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256;
    ssl_prefer_server_ciphers on; # 优先使用服务端的加密算法而非客户端的

    # 启用证书状态在线校验
    ssl_stapling on; 
    ssl_stapling_verify on;
    # 启动上面的需要有DNS解析服务器,最安全的是自己本地跑一个DNS服务器.否则用第三方的
    resolver 8.8.8.8 8.8.4.4 208.67.222.222 208.67.220.220 valid=60s;
	resolver_timeout 2s;

    # 请求超时时长
    keepalive_timeout  65;

    #默认根配置不做压缩(这里会面向全局)
    # 我们到项目级别做,比如测试线的不需要怎么压缩,正式线压缩到一定程度
    #gzip  on; 
    

    include /etc/nginx/conf.d/*.conf;
}

возьми тот, что у меня есть под рукойnuxtи обычный пакетный проект

  • react or ng6

Обычное развертывание: этот тип развертывания подходит дляbuildИзdistЭтот вид**


server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name proadmin.xxxx.com;
    root /code/react-sx-admin/prod;
    # SSL证书路径
    ssl_certificate /etc/nginx/conf.d/cert/proadmin/proadmin.crt;
    ssl_certificate_key /etc/nginx/conf.d/cert/proadmin/proadmin.key;
    ssl_trusted_certificate /etc/nginx/conf.d/cert/proadmin/proadmin.crt;
    # SPA启用了history模式,必须做一个首页寻址,不然会找不到的
    location / {
        try_files $uri $uri/ /index.html;
    }
    # 拒绝访问
    location ~ /\.(?!well-known) {
        deny all;
    }
    # 缓存以下类型的静态资源
    location ~* \.(?:css(\.map)?|js(\.map)?|jpe?g|png|gif|ico|cur|heic|webp|tiff?|mp3|m4a|aac|ogg|midi?|wav|mp4|mov|webm|mpe?g|avi|ogv|flv|wmv)$ {
        expires 7d;
        access_log off;
    }
    # 允许字符svg这些的访问,且缓存
    location ~* \.(?:svgz?|ttf|ttc|otf|eot|woff2?)$ {
        add_header Access-Control-Allow-Origin "*";
        expires 7d;
        access_log off;
    }
    # gzip 压缩配置
    gzip on;
    gzip_vary on;
    # 无条件启用压缩,支持局部压缩(就是检测部分请求头)
    gzip_proxied any;
    # 压缩等级,吃硬件
    gzip_comp_level 6;
    # 处理的文件类型
    gzip_types text/plain text/css text/xml application/json application/javascript application/xml+rss application/atom+xml image/svg+xml;
}
# http这块我们直接重定向到https
server {
    listen 80;
    listen [::]:80; # 双冒号是全域
    server_name proadmin.xxx.com;
    location / {
        #域名也可以用 $host来替代(内置变量)
        return 301 https://proadmin.xxx.com$request_uri;
    }
}


nuxt

Обратный прокси: это больше применимо к таким сервисам, какnodeВождение и другие услуги, которые могут быть предоставлены


# 这段是nuxt官方文档推荐的写法 ,响应的内容及过期时间
# https://zh.nuxtjs.org/faq/nginx-proxy/
map $sent_http_content_type $expires {
    "text/html" epoch; # epoch是1970开始的时间
    "text/html; charset=utf-8" epoch;
    default off;
}
server {
    listen 80;
    server_name proshare.xxx.com;
# Redirect all HTTP requests to HTTPS with a 301 Moved Permanently response.
    return 301 https://$host$request_uri;
}
server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name proshare.xxx.com;
    gzip on;
    gzip_types text/plain application/xml text/css application/javascript;
    gzip_min_length 1000;
    location / {
        expires $expires;
        proxy_redirect off;
        proxy_set_header Host               $host;
        proxy_set_header X-Real-IP          $remote_addr;
        proxy_set_header X-Forwarded-For    $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto  $scheme;
        proxy_read_timeout 1m;
        proxy_connect_timeout 1m;
        proxy_pass http://127.0.0.1:5555;
    }
    location ~ /\.ht {
        deny all;
    }
    ssl_certificate /etc/nginx/conf.d/cert/proshare/proshare.crt;
    ssl_certificate_key /etc/nginx/conf.d/cert/proshare/proshare.key;
    ssl_session_timeout 1d;
    ssl_session_cache shared:SSL:50m;
    ssl_session_tickets off;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS';
    ssl_prefer_server_ciphers on;
}

обычный скрипт

Сервер не может не падать, в случае простоя и перезапуска необходимо повторное включение необходимых служб.

nginx начинает самозапуск

использоватьsystenctlхорошее обслуживание,systemctl enable nginx;

НетyumУстановил nginx, пользуйся этой поддержкой, напиши самsystemctlнормативные услуги;

потомchmod 754этот скрипт, поставь/usr/lib/systemd/system, готов использоватьsystemctlподдерживать;

754 : rwx-rx-r => u-g-o => r(read[读]:4)-x(excute[执行]:1)-w(write[写]:2)

  • посмотри на официальномnginx serviceнаписание
# /usr/lib/systemd/system/nginx.service
# 除了一些字段有比较多的参数,大体上都可以一目了然
# 服务描述, 文档路径,服务类型,执行路径,重载路径以及进程PID这些

[Unit] 
Description=nginx - high performance web server
Documentation=http://nginx.org/en/docs/
After=network-online.target remote-fs.target nss-lookup.target
Wants=network-online.target

[Service]
Type=forking
PIDFile=/var/run/nginx.pid
ExecStart=/usr/sbin/nginx -c /etc/nginx/nginx.conf
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s TERM $MAINPID

pm2 самозапуск

pm2На данный момент функции последней версии относительно полны, имеется встроенный механизм самозапуска;

узнаетlinuxМеханизм самозапуска, такой как обнаружение того, что мы используемsystemctlсоздастnginx.serviceфайл описания сервиса

  1. pm2 start [services]: начать службу
  2. pm2 list: чтобы убедиться, что служба работает нормально

  1. pm2 save: сохранить текущую задачу

  1. добавить в автозапуск

Что касается выпуска кода

nodeиспользоватьpm2изdeploy(пройти черезsshОпубликовать на удаленке)

Не забудьте настроить пару открытых ключей (для удаленного хранилища).git sshрежим), в противном случае он не может быть инициализирован, напримерCodingиз

Потому что есть тестовые и официальные линейки, поэтому я расписал конфигурацию на две части, а для того, чтобы сократить набор кода, я написал кучуalias

# 这些命令是啥?
# 看pm2文档 : https://pm2.io/doc/en/runtime/guide/easy-deploy-with-ssh/?utm_source=pm2&utm_medium=website&utm_campaign=rebranding

# 函数
# 为什么两个占位符都是$1, 我不想写太多,就部署名字和配置文件一致,只有dev和prod模式
pm2init(){
   pm2 deploy ./ecosystem.$1.config.js $1 setup;
   pm2 deploy ./ecosystem.$1.config.js $1;
}
pm2up(){
  pm2 deploy ./ecosystem.$1.config.js $1 update;
}
pm2rev(){
  pm2 deploy ./ecosystem.$1.config.js $1 revert;
}



#pm2
alias pm2init=pm2init
alias pm2up=pm2up
alias pm2rev=pm2rev

# 用法就是 
# pm2init depoly_name => pm2init dev

  • ecosystem.config.js

module.exports = {
  apps: [
    {
      name: 'stag-sx-share',
      script: 'npm',
      args: 'run start',
      watch: ['.nuxt'], // 监控输出目录
      watch_options: {
        usePolling: true
      },
      env: {
        HOST: '0.0.0.0',
        PORT: 3333,
        NODE_ENV: 'development'
      },
      env_production: {
        NODE_ENV: 'production',
        HOST: '0.0.0.0',
        PORT: 3333
      },
      output: './logs/console.log',
      error: './logs/consoleError.log',
      merge_logs: true,
      log_date_format: 'YYYY-MM-DD HH:mm Z'
    }
  ],
  deploy: {
    dev: {
      // SSH user
      user: 'root',
      // SSH host
      host: ['xxxx'],
      // SSH options with no command-line flag, see 'man ssh'
      // can be either a single string or an array of strings
      ssh_options: 'StrictHostKeyChecking=no',
      // GIT remote/branch
      ref: 'origin/master',
      // GIT remote
      repo: 'git@git.dev.tencent.com:lqh/nuxt-sx-mobile-share.git',
      // path in the server
      path: '/code/stag-nuxt-sx-share',
      // Pre-setup command or path to a script on your local machine
      'pre-setup': 'ls -la',
      'pre-deploy': 'git pull',
      // deploy hook
      'post-deploy':
        'npm install && pm2 reload ./ecosystem.dev.config.js --env production --force'
    }
  }
}


упаковано, готово к использованиюrsyncвыпускать

Возьми тот, который я написалaliasПоясню, это довольно удобно;

# rsync 的几个参数
# -r : 就是recursive,递归,必须的,你打包的文件不可能没有子目录吧!
# -c : 对文件进行校验,必备的,稳一点总好
# -h : --human-readable     输出传送的数值变化比较符合人类阅读的格式
# -v : 就是verbose, 就是进展过程
# --progress : 显示传输文件的过程
# --delete : 从目标目录删除无关文件,就是不匹配的文件会被干掉,多出来的!

alias fdumi="rsync -vrch --progress --delete  /Users/linqunhe/Code/umi_dva_sx_admin/dist/* root@xxx.xxx.xxx:/code/umi-dva-sx-admin/dev"

Суммировать

Если что-то не так, пожалуйста, оставьте сообщение, и оно будет исправлено вовремя Спасибо за чтение