zoukankan      html  css  js  c++  java
  • Nuxt spa deploy

    参考 https://nuxtjs.org/guide/commands/#single-page-application-deployment-spa-

    SSR模式虽然有很好的SEO支持【服务端预渲染】,但是由于我们网站的内容是基于实时API,部分也基于user authentication的,所以采用SPA方式发布。   大部分内容都是固定的,只是数据来源是API获取。采用SSR模式,并且开始https支持。

    参考 https://nuxtjs.org/guide/commands#server-side-rendered-deployment-universal-ssr-

    To deploy, instead of running nuxt, you probably want to build ahead of time. Therefore, building and starting are separate commands:

    nuxt build
    nuxt start

    You can also set server.https in your nuxt.config.js with the same set of options passed to https.createServer, should you choose to serve Nuxt.js in HTTPS mode. Unix sockets are also available if you set the server.socket option in nuxt.config.js (or -n in the CLI). When using Unix sockets, make sure not to set the host and port parameters otherwise the socket parameter is ignored.

    The package.json like follows is recommended:

    {
      "name": "my-app",
       "dependencies": {
        "nuxt": "latest"
       },
       "scripts": {
         "dev": "nuxt",
         "build": "nuxt build",
         "start": "nuxt start"
       }
     }

    开发的时候其实就已经会有上面的配置了:

    批注 2020-07-17 021847
    Note: we recommend putting .nuxt in .npmignore or .gitignore.

    默认 .nuxt文件夹就存在,.gitignore在git 使用之后也是存在的,.npmignore参考官方声明,如果有.gitignore了可以直接在其中添加 ,具体参考 https://docs.npmjs.com/using-npm/developers.html#keeping-files-out-of-your-package 

    摘抄如下:

    Use a .npmignore file to keep stuff out of your package. If there’s no .npmignore file, but there is a .gitignore file, then npm will ignore the stuff matched by the .gitignore file. If you want to include something that is excluded by your .gitignore file, you can create an empty .npmignore file to override it. Like git, npm looks for .npmignore and .gitignore files in all subdirectories of your package, not only the root directory.

    .npmignore files follow the same pattern rules as .gitignore files:

    Blank lines or lines starting with # are ignored.
    Standard glob patterns work.
    You can end patterns with a forward slash / to specify a directory.
    You can negate a pattern by starting it with an exclamation point !.
    By default, the following paths and files are ignored, so there’s no need to add them to .npmignore explicitly:

    .*.swp
    ._*
    .DS_Store
    .git
    .hg
    .npmrc
    .lock-wscript
    .svn
    .wafpickle-*
    config.gypi
    CVS
    npm-debug.log
    Additionally, everything in node_modules is ignored, except for bundled dependencies. npm automatically handles this for you, so don’t bother adding node_modules to .npmignore.

    The following paths and files are never ignored, so adding them to .npmignore is pointless:

    package.json
    README (and its variants)
    CHANGELOG (and its variants)
    LICENSE / LICENCE

    If, given the structure of your project, you find .npmignore to be a maintenance headache, you might instead try populating the files property of package.json, which is an array of file or directory names that should be included in your package. Sometimes a whitelist is easier to manage than a blacklist.

    Testing whether your .npmignore or files config works§
    If you want to double check that your package will include only the files you intend it to when published, you can run the npm pack command locally which will generate a tarball in the working directory, the same way it does for publishing.


    因为要用到server.https 参考: https://nuxtjs.org/api/configuration-server/#example-using-https-configuration

    添加到nuxt.config.js中:

    import path from 'path'
    import fs from 'fs'
    
    export default {
      server: {
        https: {
          key: fs.readFileSync(path.resolve(__dirname, 'server.key')),
          cert: fs.readFileSync(path.resolve(__dirname, 'server.crt'))
        }
      }
    }

    就是读取ssl的两个文件。

    一会Dockerfile 中把数据卷给加载到node.js容器内部,然后读取地址设置为内部地址即可。

    虽然用node.js可以不必用nginx ,不过nginx在静态资源处理等方面依然有巨大优势,所以,要搞一个。


    执行

    docker-compose -f docker-compose.prod.yml build frontapp
    Building frontapp
    Step 1/7 : FROM node:14.5.0-alpine3.11
     ---> 5d97b3d11dc1
    Step 2/7 : RUN mkdir -p /app
     ---> Running in f234d4093ee1
    Removing intermediate container f234d4093ee1
     ---> 7cb78691eb3d
    Step 3/7 : RUN apk update         && apk upgrade         && apk add --no-cache bash         bash-doc         bash-completion         && /bin/bash         && apk add --no-cache busybox         && rm -rf /var/cache/apk/*
     ---> Running in ab1500e3b865
    fetch http://dl-cdn.alpinelinux.org/alpine/v3.11/main/x86_64/APKINDEX.tar.gz
    fetch http://dl-cdn.alpinelinux.org/alpine/v3.11/community/x86_64/APKINDEX.tar.gz
    v3.11.6-93-ga95c3541d2 [http://dl-cdn.alpinelinux.org/alpine/v3.11/main]
    v3.11.6-96-gc0aa9d3d49 [http://dl-cdn.alpinelinux.org/alpine/v3.11/community]
    OK: 11271 distinct packages available
    (1/1) Upgrading ca-certificates-cacert (20191127-r1 -> 20191127-r2)
    OK: 7 MiB in 16 packages
    fetch http://dl-cdn.alpinelinux.org/alpine/v3.11/main/x86_64/APKINDEX.tar.gz
    fetch http://dl-cdn.alpinelinux.org/alpine/v3.11/community/x86_64/APKINDEX.tar.gz
    (1/7) Installing ncurses-terminfo-base (6.1_p20200118-r4)
    (2/7) Installing ncurses-libs (6.1_p20200118-r4)
    (3/7) Installing readline (8.0.1-r0)
    (4/7) Installing bash (5.0.11-r1)
    Executing bash-5.0.11-r1.post-install
    (5/7) Installing pkgconf (1.6.3-r0)
    (6/7) Installing bash-completion (2.9-r0)
    (7/7) Installing bash-doc (5.0.11-r1)
    Executing busybox-1.31.1-r9.trigger
    OK: 14 MiB in 23 packages
    fetch http://dl-cdn.alpinelinux.org/alpine/v3.11/main/x86_64/APKINDEX.tar.gz
    fetch http://dl-cdn.alpinelinux.org/alpine/v3.11/community/x86_64/APKINDEX.tar.gz
    OK: 14 MiB in 23 packages
    Removing intermediate container ab1500e3b865
     ---> 26b6acc1f3a2
    Step 4/7 : WORKDIR /app
     ---> Running in f9621319f198
    Removing intermediate container f9621319f198
     ---> 945127e87a82
    Step 5/7 : ENV NODE_ENV=production
     ---> Running in 08ac3f2d6a51
    Removing intermediate container 08ac3f2d6a51
     ---> d8d659006939
    Step 6/7 : RUN npm install
     ---> Running in 2146a3e2fd52
    npm WARN saveError ENOENT: no such file or directory, open '/app/package.json'
    npm notice created a lockfile as package-lock.json. You should commit this file.
    npm WARN enoent ENOENT: no such file or directory, open '/app/package.json'
    npm WARN app No description
    npm WARN app No repository field.
    npm WARN app No README data
    npm WARN app No license field.
    
    up to date in 0.34s
    found 0 vulnerabilities
    
    Removing intermediate container 2146a3e2fd52
     ---> 5fe1126cc301
    Step 7/7 : ENTRYPOINT [ "npm","start" ]
     ---> Running in 8a6ce295258a
    Removing intermediate container 8a6ce295258a
     ---> 9eebc3bb8cb1


    上面出错是因为 node的Dockerfile在install的时候并未把四大文件【.nuxt, static, package.json, nuxt.config.js】【见文末,是五个文件夹或文件,还有个node_modules】加载到node容器。

    下面就是出错的Dockerfile代码

    #使用node:14.5.0-alpine3.11 作为基础进行构建
    FROM node:14.5.0-alpine3.11
    
    #创建/app 目录作为部署目录,创建容器实例时,挂载此目录
    RUN mkdir -p /app
    
    #安装 bash 和 busybox
    RUN apk update 
            && apk upgrade 
            && apk add --no-cache bash 
            bash-doc 
            bash-completion 
            && /bin/bash 
            && apk add --no-cache busybox 
            && rm -rf /var/cache/apk/*
    #移动工作目录到 /app
    WORKDIR /app
    
    #设置node环境变量为production
    ENV NODE_ENV=production
    
    RUN npm install
    
    #设置容器启动时执行的命令
    ENTRYPOINT [ "npm","start" ]

    添加

    COPY ../../ssr-components/ /app

    因为COPY 后面是外部文件夹,会报异常:

    Service 'frontapp' failed to build: COPY failed: Forbidden path outside the build context: ../../ssr-components/ ()

    原因是因为docker-compose.prod.yml中对frontapp build的context设置了固定

    所以注释掉context  【context不能缺省】,

    那么把ssr-components文件夹迁移到frontapp对应的Dockerfile文件夹下

    然后再切换到存放docker-compose.prod.yml文件夹内执行

    docker-compose -f docker-compose.prod.yml build frontapp

    批注 2020-07-17 234745

    成功build

    但是运行就报错

    批注 2020-07-17 235900

    检查docker-compose配置文件frontapp部分:

    volumes:
          - ~/***client/ssr-components:/app


    volume使用了~路径 所以加载不进去。

    再把刚刚迁移到到frontapp对应的Dockerfile文件夹下的ssr-components文件夹迁移到本docker-composer文件对应文件夹下面的***client文件夹内,再修改volumes:

    最好还是在Dockerfile里直接配置这个VOLUME

    #使用node:14.5.0-alpine3.11 作为基础进行构建
    FROM node:14.5.0-alpine3.11
    
    #创建/app 目录作为部署目录,创建容器实例时,挂载此目录
    RUN mkdir -p /app
    COPY ./ssr-components/ /app
    VOLUME ./ssr-components/ /app
    #安装 bash 和 busybox
    RUN apk update 
            && apk upgrade 
            && apk add --no-cache bash 
            bash-doc 
            bash-completion 
            && /bin/bash 
            && apk add --no-cache busybox 
            && rm -rf /var/cache/apk/*
    #移动工作目录到 /app
    WORKDIR /app
    
    #设置node环境变量为production
    ENV NODE_ENV=production
    
    RUN npm install
    
    #设置容器启动时执行的命令
    ENTRYPOINT [ "npm","start" ]


    至此,错误变成了:

    批注 2020-07-18 003435

    参考 https://stackoverflow.com/questions/50355263/local-package-json-exists-but-node-modules-missing

    https://www.cnblogs.com/cczlovexw/p/12916310.html

    又在Dockerfile中添加了:

    RUN npm run build
    RUN npm cache clean --force

    错误又出:

    批注 2020-07-18 004539

    此时发现了真正的原因,参考 https://hoody.tech/blog/detail/27 两种方法 我其实采用的是第一种,本地build后传文件到服务器。

    发布目录所需文件

    将以下文件拷贝至服务器目录

    /app下的

    .nuxt 编译后生成的目录,开发模式和发布模式通用,注意发布前使用npm run build 防止将dev目录发布

    static  静态资源文件,通过/可直接访问

    package.json npm 包管理配置文件

    nuxt.config.js Nuxt.js 默认的配置涵盖了大部分使用情形,可通过 nuxt.config.js 来覆盖默认的配置。

    node_modules 依赖模块


    没有node_modules

    然后使用rsync传到ssr-components文件夹内

     rsync.exe -e /usr/bin/ssh.exe -avzh "/cygdrive/d/nuxt/***client/node_modules" ****@95.179.242.118:~/***client/dockfiles/node/ssr-components

    注:生成后有一个问题发现,在npm build生成时其实就已经提示过了:

    批注 2020-07-18 125443

    其实就是

    批注 2020-07-18 125840

    target替换成文本链接就不会报错。


    原因是process.env….解析不了。

    参考 https://github.com/nuxt-community/proxy-module/issues/3

    摘:

    process.env reads the environment variables.

    You can use this to add some env variables for your project easily:
    https://www.npmjs.com/package/dotenv

    I believe that adding an file ".env" with your api url and adding
    "require('dotenv').config()" on the top of your nuxt config should do the
    trick

    当然,官方也有说:https://nuxtjs.org/api/configuration-env/


    所以解决办法是:


    执行

    npm install --save-dev @nuxtjs/dotenv

    安装@nuxtjs/dovenv

    在nuxt.config.js顶部:

    require('dotenv').config();

    然后在modules内添加

    问题解决,然后执行npm build生成。


    问题不断,在单独开启一个node docker执行 npm update 及npm install之后,【已经把那五个文件夹及文件给上传了】执行npm start给爷报错:

    批注 2020-07-18 150301

    FATAL  Enable vuex store by creating store/index.js.

    然后搜了搜:

    参考https://segmentfault.com/q/1010000019532412/a-1020000019666338

    将项目文件夹store,在package.json 文件中添加 "scripts"{"prostart": "nuxt start",},发布到服务器,用添加的命令启动

    批注 2020-07-18 150525

    上传package.json文件,

    启动node容器,进入容器内发现:

    *****@laravel-docker-*****:~/***api/****-api$ docker exec -it ****-api_frontapp_run_2bb938841390 sh
    /app # ls
    node_modules    nuxt.config.js  package.json    static
    /app # cd /root
    ~ # ls

    怎么只有四个文件 少了一个.nuxt文件夹

    执行ls -la发现存在的:

    批注 2020-07-18 152531


    docker-compose确实指定了卷。

      frontapp:
        image: node:12-alpine
        container_name: ******frontapp
        restart: unless-stopped
        working_dir: /app
        environment:
         - NODE_ENV=production
        volumes:
         - ./*****/ssr-components:/app
        networks:
          - *****

    执行

    npm run prostart

    错误依然。

    贴上log

    /app # cat /root/.npm/_logs/2020-07-18T07_26_50_279Z-debug.log
    0 info it worked if it ends with ok
    1 verbose cli [ '/usr/local/bin/node', '/usr/local/bin/npm', 'run', 'prostart' ]
    2 info using npm@6.14.5
    3 info using node@v12.18.2
    4 verbose run-script [ 'preprostart', 'prostart', 'postprostart' ]
    5 info lifecycle ***client@1.0.0~preprostart: ***client@1.0.0
    6 info lifecycle ***client@1.0.0~prostart: ***client@1.0.0
    7 verbose lifecycle ***client@1.0.0~prostart: unsafe-perm in lifecycle true
    8 verbose lifecycle ***client@1.0.0~prostart: PATH: /usr/local/lib/node_modules/npm/node_modules/npm-lifecycle/node-gyp-bin:/app/node_modules/.bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
    9 verbose lifecycle ***client@1.0.0~prostart: CWD: /app
    10 silly lifecycle ***client@1.0.0~prostart: Args: [ '-c', 'nuxt start' ]
    11 silly lifecycle ***client@1.0.0~prostart: Returned: code: 1  signal: null
    12 info lifecycle ***client@1.0.0~prostart: Failed to exec prostart script
    13 verbose stack Error: ***client@1.0.0 prostart: `nuxt start`
    13 verbose stack Exit status 1
    13 verbose stack     at EventEmitter.<anonymous> (/usr/local/lib/node_modules/npm/node_modules/npm-lifecycle/index.js:332:16)
    13 verbose stack     at EventEmitter.emit (events.js:315:20)
    13 verbose stack     at ChildProcess.<anonymous> (/usr/local/lib/node_modules/npm/node_modules/npm-lifecycle/lib/spawn.js:55:14)
    13 verbose stack     at ChildProcess.emit (events.js:315:20)
    13 verbose stack     at maybeClose (internal/child_process.js:1021:16)
    13 verbose stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:286:5)
    14 verbose pkgid ***client@1.0.0
    15 verbose cwd /app
    16 verbose Linux 4.15.0-106-generic
    17 verbose argv "/usr/local/bin/node" "/usr/local/bin/npm" "run" "prostart"
    18 verbose node v12.18.2
    19 verbose npm  v6.14.5
    20 error code ELIFECYCLE
    21 error errno 1
    22 error ***client@1.0.0 prostart: `nuxt start`
    22 error Exit status 1
    23 error Failed at the ***client@1.0.0 prostart script.
    23 error This is probably not a problem with npm. There is likely additional logging output above.
    24 verbose exit [ 1, true ]

    接下来直接

    rm –rf node_modules #删除掉【当然就会删除容器挂载卷的宿主机的node_modules文件夹】

    然后 npm install安装再试。

    查看package.json设置 有一个

    "private": true,

    据packageJsonSchema.json 附言:

    "private": {
               "type": "boolean",
               "description": "If set to true, then npm will refuse to publish it."
             },


    如果你在你的package.json中设置了“private”:true,那么npm将拒绝发布它。 这是防止私人存储库意外发布的一种方法。

    如果你希望包装某个包只能被发布到特定的一个registry中(比如,一个内部的registry),则可以使用下面的publishConfig字典来描述以在publish-time重写registry配置参数。

    尝试设置为false,继续:

    依然不行。

    遂改为SPA模式。

  • 相关阅读:
    ionic开发遇到的问题总结
    promise和Rxjs的一点区别
    angular2组件通信
    神奇的函数作用域
    vue模板的几种写法及变化
    在安卓上,微信公众号无法分享到QQ的解决办法之一
    mysql忘记密码
    无法远程连接服务器上的mysql
    gitHub 基础命令
    linux安装Node(Centos)
  • 原文地址:https://www.cnblogs.com/dzkjz/p/13326877.html
Copyright © 2011-2022 走看看