{"id":18390629,"url":"https://github.com/aspnetde/ubuntu-nodejs-mongodb-guide","last_synced_at":"2025-10-09T20:33:54.224Z","repository":{"id":25724318,"uuid":"29161351","full_name":"aspnetde/ubuntu-nodejs-mongodb-guide","owner":"aspnetde","description":"Setting up Ubuntu Server for running a single Website with Node.js and MongoDB","archived":false,"fork":false,"pushed_at":"2015-01-12T22:55:01.000Z","size":124,"stargazers_count":29,"open_issues_count":2,"forks_count":6,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-10-06T01:33:43.351Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/aspnetde.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-01-12T22:54:42.000Z","updated_at":"2021-05-28T17:37:36.000Z","dependencies_parsed_at":"2022-08-24T14:11:24.707Z","dependency_job_id":null,"html_url":"https://github.com/aspnetde/ubuntu-nodejs-mongodb-guide","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/aspnetde/ubuntu-nodejs-mongodb-guide","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aspnetde%2Fubuntu-nodejs-mongodb-guide","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aspnetde%2Fubuntu-nodejs-mongodb-guide/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aspnetde%2Fubuntu-nodejs-mongodb-guide/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aspnetde%2Fubuntu-nodejs-mongodb-guide/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aspnetde","download_url":"https://codeload.github.com/aspnetde/ubuntu-nodejs-mongodb-guide/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aspnetde%2Fubuntu-nodejs-mongodb-guide/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279002000,"owners_count":26083258,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-09T02:00:07.460Z","response_time":59,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-06T01:48:39.472Z","updated_at":"2025-10-09T20:33:54.189Z","avatar_url":"https://github.com/aspnetde.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# Setting up Ubuntu Server for running a single Website with Node.js and MongoDB\n\nThis little guide shows how to set up an Ubuntu Server that is dedicated to run a single website with Node.js and MongoDB. If you are looking for a more generic solution to run multiple websites on a single server, take a look at the [Node.js Web Server Guide](https://github.com/aspnetde/nodejs-webserver-guide). It provides some more details to security aspects which don't matter if there is only one application running.\n\n## Create your Droplet (DigitalOcean only)\n\nI won't tell you how to create a Droplet, because it seems self-explaining to me. If you need any help with this, this little tutorial isn't the thing you should read anyway, at least yet ;-).\n\n## Create a User called www\n\nYou could run all your stuff as root, but I don't think that's a good idea. So connect to your only just created server and log in via root:\n\n\tssh root@{ip-address}\n\t\nNext, create a the www user:\n\n\tadduser www\n\t\nNow provide root privilige, (Other than the root account the www user won't run with these priviliges all the time, but it could when requested, what will be necessary at least during the installation process.)\n\nCall `visudo` and add the following line right below the root's line:\n\t\n\twww ALL=(ALL:ALL) ALL\n\nNow `exit` your ssh connection and re-connect as www.\n\n## Set up SSH Key for www\n\n\tcat ~/.ssh/id_rsa.pub | ssh www@{ip-address} \"mkdir -p ~/.ssh \u0026\u0026 cat \u003e\u003e ~/.ssh/authorized_keys\"\n\n\t\nAt this point you should be requested to provide the password of the www user at login for the last time. `exit` and reconnect – now you should be authenticating via SSH Key.\n\n\tssh www@{ip-address}\n\t\n## Install the required software\n\n### Make Tools\n\nThe make tools are essential to build some npm packages and other stuff. So it’s generally a good idea to install them early.\n\n\tsudo apt-get install gcc make build-essential\n\n(If the installation of build-essential fails, see Misc/Missing packages section).\n\n### nginx\n\n\tsudo apt-get install nginx\n\t\nOnce the setup of nginx is complete, you should be able to call http://{server_ip} and see the default page with the “Welcome to nginx!” headline.\n\nAlso make sure the server starts automatically after booting the system (Should be enabled by default):\n\n\tsudo update-rc.d nginx defaults\n\t\n### Node.js\n\nIf not installed with the initial creation of your droplet (DigitalOcean only; workes just fine!), use this:\n\n\twget -qO- https://raw.githubusercontent.com/creationix/nvm/v0.14.0/install.sh | bash\n\n\t# Refresh Path\n\tsource ~/.profile\n\n\t# Use latest Node.JS version\n\tnvm install v0.11.13\n\t\n\t# Make it default\n\tnvm use default v0.11.13\n\n### Bower\n\n\tsudo npm install bower -g\n\n### PM2\n\nPM2 helps to run the node application by logging errors, restarting after crashing etc.\n\n\tsudo npm install pm2 -g\n\n### Glances\n\nGlances can be used to monitor the overall state of the server.\n\n\tsudo apt-get install python-pip build-essential python-dev\n\tsudo pip install Glances\n\tsudo pip install PySensors\n\n### Git\n\n\tsudo apt-get install git\n\n### Zip\n\n\tsudo apt-get install zip\n\n### MongoDB\n\nFor a detailed explanation see [http://docs.mongodb.org/manual/tutorial/install-mongodb-on-ubuntu/](http://docs.mongodb.org/manual/tutorial/install-mongodb-on-ubuntu/).\n\nInstall the database service:\n\n\tsudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 7F0CEB10\n\techo 'deb http://downloads-distro.mongodb.org/repo/ubuntu-upstart dist 10gen' | sudo tee /etc/apt/sources.list.d/mongodb.list\n\tsudo apt-get update\n\tsudo apt-get install -y mongodb-org\n\nPin the current version:\n\n\techo \"mongodb-org hold\" | sudo dpkg --set-selections\n\techo \"mongodb-org-server hold\" | sudo dpkg --set-selections\n\techo \"mongodb-org-shell hold\" | sudo dpkg --set-selections\n\techo \"mongodb-org-mongos hold\" | sudo dpkg --set-selections\n\techo \"mongodb-org-tools hold\" | sudo dpkg --set-selections\n\n### Add the website’s directories\n\nWebsites are organized as follows:\n\nDirectory | Path\n------------ | -------------\nRoot | /var/www\nGit repository\t | /var/www/repo\nWebsite root | /var/www/www\n\n\tcd /var\n\tsudo mkdir www\n\tsudo chown www www\n\tcd www\n\tmkdir repo \u0026\u0026 mkdir www\n\t\n### Create a Git repository\n\nIn `/var/www/repo` run\n\n\tgit init --bare\n\n### Add the Git deployment hook\n\nThis hook is used to deploy changes made to the master repository. It can be customized for each website depending on the specific needs.\n\nGo to `/var/www/repo/hooks` and create a new file called “post-receive”:\n\n\tvi post-receive\n\t\nAdd the following commands to it:\n\n\t#!/bin/bash\n\n\t# Make this executable: chmod +x post-receive\n\n\tPREPARATION_DIR=\"/var/www/repo/$(uuidgen)\"\n\tWEBSITE_ROOT=\"/var/www/www\"\n\tPM2_APP_NAME=\"website-com\"\n\n\techo \"Deployment started\"\n\n\tread oldrev newrev branch\n\n\tif [[ $branch =~ .*/master$ ]];\n\tthen\n    \techo \"Master received. Deploying to production...\"\n\n    \t# Creates a temporary working directory\n\t    mkdir $PREPARATION_DIR\n\n    \t# Checks out the master from the repository\n\t    GIT_WORK_TREE=\"$PREPARATION_DIR\" git checkout -f\n\n    \t# Installing all npm and bower modules/packages\n\t    cd $PREPARATION_DIR\n\t    npm install\n\t    bower install\n\n\t    # Removes all files in the Website's root\n    \tcd $WEBSITE_ROOT\n\t\trm -rf *\n\n\t\t# Copies all files over\n\t\tcd $PREPARATION_DIR\n\t\tcp -r . $WEBSITE_ROOT\n\n\t\t# Restart the Website via PM2\n\t\tpm2 restart $PM2_APP_NAME\n\n\t\t# Removes the preparation directory\n\t\trm -R $PREPARATION_DIR\n\telse\n    \techo \"$branch successfully received. Nothing to do: only the master branch may be deployed on this server.\"\n\tfi\n\n\techo \"Deployment finished\"\n\nRemember the value of **PM2_APP_NAME** and use it as an identifier for your pm2 application later.\n\nAfter saving, make the script executable:\n\n\tchmod +x post-receive\n\n### Push your application to your repository\n\nBy cloning your deployment repository on your local development machine and pushing the first version to the master branch, you should receive a fresh version at `/var/www/www` (Check with `ls –l`).\n\n\tgit clone ssh://{username}@{ipaddress}/var/www/repo website-com\n\nMake sure the user you’re connecting with has the necessary rights to run the Git repository. It’s recommended to connect with the user you have just created before to run the website, because he/she has the necessary access rights.\n\n### Set up PM2\n\n#### Run the startup script\n\nTo start pm2 with the system:\n\n\tpm2 startup ubuntu\n\t\nPM2 will tell you, you have to run this command as root, and print the full command to execute, for example:\n\n\tsudo env PATH=$PATH:/usr/local/bin pm2 startup ubuntu -u www\n\t\nRun it :-).\n\n#### Start your application \n\n\tcd /var/www/website-com/www/\n\tpm2 start app.js --name \"website-com\"\n\nIf everything works PM2 reponds with `Process {nameofstarting.js}` launched. Wait a few seconds and use\n\n\tpm2 list\n\nfor a fresh status update. For more information see\n\n\tpm2 help\n\n### Configure the website in nginx\n\nWe’re using a single configuration, which can be found at:\n\n\tsudo vi /etc/nginx/sites-available/default\n\nnginx is running as a reverse proxy to handle all the public stuff on port 80 for us. It then passes all the traffic we want to to our node application.\n\n\tserver {\n    \tlisten 80;\n\n\t    server_name your-domain.com;\n\n    \tlocation / {\n        \tproxy_pass http://localhost:{YOUR_PORT};\n\t        proxy_http_version 1.1;\n    \t    proxy_set_header Upgrade $http_upgrade;\n        \tproxy_set_header Connection 'upgrade';\n\t        proxy_set_header Host $host;\n    \t    proxy_cache_bypass $http_upgrade;\n\t    }\n\t}\n\nAfter saving the configuration, use\n\n\tsudo service nginx reload\n\nto tell the server it should use it.\n\n# Backup\n\n## Directory structure\n\nDirectory | Path\n------------ | -------------\nBackup Root | /var/backup\nWebsite Backups | /var/backup/www\nMongoDB Backups | /var/backup/mongo\nnginx Backups | /var/backup/nginx\n\n\tcd /var\n\tsudo mkdir backup\n\tsudo chown www backup\n\tcd backup\n\n## Backup Scripts\n\n### MongoDB\n\nSave the following shell script as `/var/backup/create-backup-for-mongo` and make it executable:\n\n\t#!/bin/bash\n\n\techo \"Mongo Backup started\"\n\n\tBACKUP_TARGET_ROOT=\"/var/backup/mongo\"\n\tCURRENT_BACKUP_TARGET=\"$BACKUP_TARGET_ROOT/$(uuidgen)\"\n\n\t# Remove all but the latest 7 backups\n\tcd $BACKUP_TARGET_ROOT\n\trm -rf `ls -t | tail -n +7`\n\n\t# Back up all the databases to a new directory\n\tmongodump -o $CURRENT_BACKUP_TARGET --authenticationDatabase admin\n\n\tzip -r \"$(uuidgen).zip\" $CURRENT_BACKUP_TARGET\n\trm -rf  $CURRENT_BACKUP_TARGET\n\n\techo \"Mongo Backup finished\"\n\n### Websites\n\nCreate the script `/var/backup/create-backup-for-www` and make it executable:\n\n\t#!/bin/bash\n\n\techo \"WWW Backup started\"\n\n\tBACKUP_SOURCE=\"/var/www\"\n\n\tBACKUP_TARGET_ROOT=\"/var/backup/www\"\n\tCURRENT_BACKUP_TARGET=\"$BACKUP_TARGET_ROOT/$(uuidgen)\"\n\t\n\tcd $BACKUP_TARGET_ROOT\n\trm -rf `ls -t | tail -n +7`\n\n\t# Back up all the websites to a new directory\n\trsync -a -E -c --stats $BACKUP_SOURCE $CURRENT_BACKUP_TARGET\n\n\tzip -r \"$(uuidgen).zip\" $CURRENT_BACKUP_TARGET\n\trm -rf  $CURRENT_BACKUP_TARGET\n\n\techo \"WWW Backup finished\"\n\t\n### nginx\n\nCreate the script `/var/backup/create-backup-for-nginx` and make it executable:\n\n\t#!/bin/bash\n\n\techo \"nginx Backup started\"\n\n\tBACKUP_SOURCE=\"/etc/nginx\"\n\n\tBACKUP_TARGET_ROOT=\"/var/backup/nginx\"\n\tCURRENT_BACKUP_TARGET=\"$BACKUP_TARGET_ROOT/$(uuidgen)\"\n\n\t# Remove all but the latest 7 backups\n\tcd $BACKUP_TARGET_ROOT\n\trm -rf `ls -t | tail -n +7`\n\n\trsync -a -E -c --stats $BACKUP_SOURCE $CURRENT_BACKUP_TARGET\n\n\tzip -r \"$(uuidgen).zip\" $CURRENT_BACKUP_TARGET\n\trm -rf  $CURRENT_BACKUP_TARGET\n\n\techo \"nginx Backup finished\"\n\n## Transfer\n\nThere are many ways to transfer these backup files to another server, I have chosen the way to use rsync over SSH.\n\n### Set up SSH \n\nFirst create a local key without a password:\n\n\tssh-keygen -f ~/.ssh/id_rsa -q -P \"\"\n\nNow get the public key and copy it:\n\n\tvi ~/.ssh/id_rsa.pub\n\t\nOn your backup server add the public SSH key of your web server. If you did not set up SSH before, do it as follows:\n\n\tmkdir ~/.ssh\n\tchmod 0700 ~/.ssh\n\ttouch ~/.ssh/authorized_keys\n\tchmod 0644 ~/.ssh/authorized_keys\n\t\n\t# Paste the public key here:\n\tvi ~/.ssh/authorized_keys\n\n\n### Add the Transfer Script\n\nCreate a script that combines all backup actions and that finally transfers everything from the current backup folder to the backup server. Save that script as `/var/backup/create-and-transfer-backups` and make it executable.\n\n\t#!/bin/bash\n\n\techo \"Global Backup started\"\n\n\t# Important: use absolute paths to be independent of the user context\n\t/var/backup/create-backup-for-mongo\n\t/var/backup/create-backup-for-www\n\t/var/backup/create-backup-for-nginx\n\n\trsync -avz -e \"ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null\" --progress /var/backup www-backup@{ip-of-your-backup-server}:/var/backup\n\n\techo \"Global Backup finished\"\n\n### Schedule backup\n\n\tsudo vi /etc/crontab \n\nSet:\n\n\n\t# m  h  dom mon dow user command\n\t10 14 *   *   *   root bash /var/backup/create-and-transfer-backups\n\n(Runs the backup every day at 2:10 pm.)\n\n#### Troubleshooting\n\nIf it doesn't work, check your timezone. If it is set wrong, you can change it easily (Ubuntu):\n\n\tsudo dpkg-reconfigure tzdata\n\nNow restart cron to apply the new setting:\n\t\n\tsudo service cron restart\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faspnetde%2Fubuntu-nodejs-mongodb-guide","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faspnetde%2Fubuntu-nodejs-mongodb-guide","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faspnetde%2Fubuntu-nodejs-mongodb-guide/lists"}