Skip to content

Instantly share code, notes, and snippets.

@MSK998
Last active July 1, 2021 12:30
Show Gist options
  • Save MSK998/cc91c6c150187ae46cb13df8d5a4fb9c to your computer and use it in GitHub Desktop.
Save MSK998/cc91c6c150187ae46cb13df8d5a4fb9c to your computer and use it in GitHub Desktop.

Revisions

  1. MSK998 revised this gist Jul 1, 2021. 1 changed file with 4 additions and 0 deletions.
    4 changes: 4 additions & 0 deletions Basic_PM2_Deployment.md
    Original file line number Diff line number Diff line change
    @@ -77,6 +77,10 @@ esac
    ```
    Doing this will ensure that the PM2 shell can access the NodeJs Binary.

    ### Ecosystem File

    While messing around with PM2 and the deployments settings that can be changed, it is important to include the ecosystem file in the root of the project directory in GitHub. When spinning up instances of your production code, the PM2 instance that is installed on the production server uses the ecosystem file to start, stop and reload apps. If the file isnt present, the deployment will fail. Note that the testing repository has this ecosystem file checked into git.

    # References

    1. https://pm2.keymetrics.io/docs/usage/quick-start/
  2. MSK998 revised this gist Jul 1, 2021. 1 changed file with 7 additions and 2 deletions.
    9 changes: 7 additions & 2 deletions Basic_PM2_Deployment.md
    Original file line number Diff line number Diff line change
    @@ -55,8 +55,13 @@ Once the deploy has been completed if you run `pm2 l` you should be able to see

    ## Notes

    1. One thing that I found out is that pm2 doesn't run an interactive shell when running these scripts. Because of the way the default .bashrc file works, by default it wont load any environment variables. This will break NVM and thus the server will not be able to find the NodeJS binary.
    - Rearrange the .bashrc file to the following, this will allow NVM variables to be set before the check for an interactive terminal is done
    Notes on some unexpected characteristics of PM2

    ### PM2 and Deployment Commands

    One thing that I found out is that pm2 doesn't run an interactive shell when running these scripts. Because of the way the default .bashrc file works, by default it wont load any environment variables. This will break NVM and thus the server will not be able to find the NodeJS binary when deploying.

    To fix this rearrange the .bashrc file to the following, this will allow NVM variables to be set before the check for an interactive terminal is done

    ```
    export NVM_DIR="$HOME/.nvm"
  3. MSK998 revised this gist Jul 1, 2021. 1 changed file with 15 additions and 1 deletion.
    16 changes: 15 additions & 1 deletion Basic_PM2_Deployment.md
    Original file line number Diff line number Diff line change
    @@ -56,7 +56,21 @@ Once the deploy has been completed if you run `pm2 l` you should be able to see
    ## Notes

    1. One thing that I found out is that pm2 doesn't run an interactive shell when running these scripts. Because of the way the default .bashrc file works, by default it wont load any environment variables. This will break NVM and thus the server will not be able to find the NodeJS binary.
    2. To fix this open up your .bashrc file and rearrange NVM so that the variables are set before the interactive shell check is made
    - Rearrange the .bashrc file to the following, this will allow NVM variables to be set before the check for an interactive terminal is done

    ```
    export NVM_DIR="$HOME/.nvm"
    [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
    [ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion
    # If not running interactively, don't do anything
    case $- in
    *i*) ;;
    *) return;;
    esac
    ```
    Doing this will ensure that the PM2 shell can access the NodeJs Binary.

    # References

  4. MSK998 revised this gist Jul 1, 2021. 1 changed file with 5 additions and 0 deletions.
    5 changes: 5 additions & 0 deletions Basic_PM2_Deployment.md
    Original file line number Diff line number Diff line change
    @@ -53,6 +53,11 @@ The deployment type is outlined in your config file, in the example attached you

    Once the deploy has been completed if you run `pm2 l` you should be able to see the newly deployed instance of your appliation.

    ## Notes

    1. One thing that I found out is that pm2 doesn't run an interactive shell when running these scripts. Because of the way the default .bashrc file works, by default it wont load any environment variables. This will break NVM and thus the server will not be able to find the NodeJS binary.
    2. To fix this open up your .bashrc file and rearrange NVM so that the variables are set before the interactive shell check is made

    # References

    1. https://pm2.keymetrics.io/docs/usage/quick-start/
  5. MSK998 revised this gist Jul 1, 2021. 1 changed file with 30 additions and 12 deletions.
    42 changes: 30 additions & 12 deletions ecosystem.config.js
    Original file line number Diff line number Diff line change
    @@ -1,20 +1,38 @@
    module.exports = {
    apps : {
    script: './app.js', // The entrypoint of the Node app
    watch: '.' // This is to allow hot reloading of the application. Optional
    // Entry point of the application
    script: './app.js',
    // A watcher on prod isn't really necessary as
    // the code should only be changed when the deployment
    // is run
    watch: '.'
    },

    deploy : {
    // This is the production configuration, there can be multiple configs: production, dev etc
    production : {
    user : 'admmsk', // The user that should be used to deploy
    host : 'localhost', // The host(s) to deploy to
    ref : 'origin/master', // Branch to deploy
    repo : 'https://github.com/MSK998/pm2test.git', // Repo URL
    path : './prod/', // Location to clone the repo to
    // In order to have PM2 restart the app with the new code pm2 reload <location of config>
    // Can be called
    'post-deploy' : 'npm install && pm2 reload ~/ecosystem.config.js',
    // A password can be used but it is not recommended
    key : '~/.ssh/id_rsa',
    // Username of the account that owns the PM2 instance
    user : 'admmsk',
    // The local virtual machine hosting the application
    // If running 'pm2 deploy production --force' locally,
    // then change this to localhost
    host : 'pm2test',
    // Branch to deploy
    ref : 'origin/master',
    // Repository to deploy
    repo : 'https://github.com/MSK998/pm2test.git',
    // Where the repo files should be stored
    path : './prod/',
    // Commands to be run on the production server
    // during pm2 deploy production setup
    'pre-setup': '',
    // Commands to be run on the machine deploying
    'pre-deploy-local': '',
    // Commands to run on the production server before the repo gets cloned
    'pre-deploy': 'hostname',
    // Commands to run after the new code has been deployed
    'post-deploy' : 'npm install && pm2 reload ecosystem.config.js',
    }
    }
    };
    };
  6. MSK998 revised this gist Jun 28, 2021. 2 changed files with 2 additions and 1 deletion.
    2 changes: 1 addition & 1 deletion Basic_PM2_Deployment.md
    Original file line number Diff line number Diff line change
    @@ -51,7 +51,7 @@ The deployment type is outlined in your config file, in the example attached you

    # Finishing Up

    Once the deploy has been comleted if you run `pm2 l` you should be able to see the newly deployed instance of your appliation.
    Once the deploy has been completed if you run `pm2 l` you should be able to see the newly deployed instance of your appliation.

    # References

    1 change: 1 addition & 0 deletions ecosystem.config.js
    Original file line number Diff line number Diff line change
    @@ -5,6 +5,7 @@ module.exports = {
    },

    deploy : {
    // This is the production configuration, there can be multiple configs: production, dev etc
    production : {
    user : 'admmsk', // The user that should be used to deploy
    host : 'localhost', // The host(s) to deploy to
  7. MSK998 revised this gist Jun 28, 2021. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion Basic_PM2_Deployment.md
    Original file line number Diff line number Diff line change
    @@ -12,7 +12,7 @@ An outline on how to deploy code locally via PM2. Learn how to deploy NodeJs (or
    Assuming that you have created/provisioned a Linux server already:

    1. First install nvm
    *https://github.com/nvm-sh/nvm
    * https://github.com/nvm-sh/nvm
    3. `nvm install --lts`
    4. `npm install -g pm2`

  8. MSK998 revised this gist Jun 28, 2021. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion Basic_PM2_Deployment.md
    Original file line number Diff line number Diff line change
    @@ -12,7 +12,7 @@ An outline on how to deploy code locally via PM2. Learn how to deploy NodeJs (or
    Assuming that you have created/provisioned a Linux server already:

    1. First install nvm
    * https://github.com/nvm-sh/nvm
    *https://github.com/nvm-sh/nvm
    3. `nvm install --lts`
    4. `npm install -g pm2`

  9. MSK998 revised this gist Jun 28, 2021. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions Basic_PM2_Deployment.md
    Original file line number Diff line number Diff line change
    @@ -13,8 +13,8 @@ Assuming that you have created/provisioned a Linux server already:

    1. First install nvm
    * https://github.com/nvm-sh/nvm
    2. `nvm install --lts`
    3. `npm install -g pm2`
    3. `nvm install --lts`
    4. `npm install -g pm2`

    Once all of these commands have been run you should have a working install of PM2 running on your preferred flavour of Linux.

  10. MSK998 created this gist Jun 28, 2021.
    62 changes: 62 additions & 0 deletions Basic_PM2_Deployment.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,62 @@
    # Basic PM2 Deployment

    An outline on how to deploy code locally via PM2. Learn how to deploy NodeJs (or any other codebase) to a server.

    # Requirements

    * A codebase to run on PM2
    * A server to deploy your code to, in this case im just using a VM running Ubuntu:20.04

    # Server Set Up

    Assuming that you have created/provisioned a Linux server already:

    1. First install nvm
    * https://github.com/nvm-sh/nvm
    2. `nvm install --lts`
    3. `npm install -g pm2`

    Once all of these commands have been run you should have a working install of PM2 running on your preferred flavour of Linux.

    # GitHub Repository

    Now that the server is set up make sure the repository that your code is in, has been set up. Once it has been set up take a note of your GitHub clone URL. For this example, we can use: https://github.com/MSK998/pm2test. We will cover the the various ways to clone the code further on in the guide.

    # PM2 Configuration

    In order to deploy using PM2 we need to create a configuration as code (CaC). To generate a sample config, run `pm2 ecosystem`. An `ecosystem.config.js` file will be generated. Because this is a basic deployment, much of what is in this file is a little bit redundant.

    ## Deploying to the Local Machine

    To deploy to the local server(the Ubuntu server we set up) we need to change a few values in the default file. Most importantly, we need to change the host. In a production environment PM2 can be used as a deployment server, i.e. the PM2 server that is managing the deployment doesn't actually deploy the code itself.

    The most important props that need to be changed are the `user` and `host` props. These should be changed to the local user that should be running the deployment, and the `host` should be changed to `localhost`. PM2 will now run deployments on the local machine with this config change.

    Other things of note to change are the `repo` props, this should be changed to the repo address. Both HTTPS and SSH can be used to clone the repository. If using SSH then the server public key should be added to the deploy keys (or using the user SSH keys on the user account).

    Finally, make sure to update the `script` prop to be the entrypoint of the application, so if your Node app starts a server using `server.js` then set `script` to that.

    ## Deploying to a Remote Server

    A great example to take from is the sample config that is generated by PM2. All server IPs that are listed (if there are multiple the IPs can be added to an array [ip 1, ip 2, ip 3])

    # Provisioning the Server(s)

    While in the same directory of the config file. run the following:

    1. `pm2 deploy <deployment type> setup` This will clone and prepare PM2 to deploy using the codebase.
    2. `pm2 deploy <deployment type> --force` This will clone the repository and deploy the latest pulled code. The `--force` allows the user to run the most up-to-date code without any of the git error messages.

    The deployment type is outlined in your config file, in the example attached you would add `production` to the command where `<deployment type>`.

    # Finishing Up

    Once the deploy has been comleted if you run `pm2 l` you should be able to see the newly deployed instance of your appliation.

    # References

    1. https://pm2.keymetrics.io/docs/usage/quick-start/
    2. https://gist.github.com/hoangmirs/b2cb60e0aa60019f0c8b13927ce9d0a2
    3. https://github.com/Unitech/pm2-deploy/pull/70
    4. https://www.programmersought.com/article/85954596204/
    5. https://dev.to/goodidea/setting-up-pm2-ci-deployments-with-github-actions-1494
    19 changes: 19 additions & 0 deletions ecosystem.config.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,19 @@
    module.exports = {
    apps : {
    script: './app.js', // The entrypoint of the Node app
    watch: '.' // This is to allow hot reloading of the application. Optional
    },

    deploy : {
    production : {
    user : 'admmsk', // The user that should be used to deploy
    host : 'localhost', // The host(s) to deploy to
    ref : 'origin/master', // Branch to deploy
    repo : 'https://github.com/MSK998/pm2test.git', // Repo URL
    path : './prod/', // Location to clone the repo to
    // In order to have PM2 restart the app with the new code pm2 reload <location of config>
    // Can be called
    'post-deploy' : 'npm install && pm2 reload ~/ecosystem.config.js',
    }
    }
    };