A tiny webserver + shopping cart for developers looking to setup simple shop pages quickly on virtual private servers without any SAAS fees or bloated CMS.
Webserver = Node + Express
Database = NeDB
Front end = Vue + Vue-Router + Vuex + Vuetify
Build = webpack
email = nodemailer
payments = braintree
# build with webpack
npm run build
# run the server
pm2 start server.js
Realtime video of install - https://youtu.be/JONrKYcsnEw
Dependencies
- external mail account list
- Braintree account
- Paypal account
create VPS
- ubuntu (tested on 14 and 16)
- cheapest is fine (1gb ram)
login via putty / ssh
- should get an email with ip and root password
- login as root
update
apt-get update
apt-get upgrade
install nodejs
- https://nodejs.org/en/download/package-manager/#debian-and-ubuntu-based-linux-distributions
- tested with 8.x and 9.x
install build tools
apt-get install -y build-essential libjpeg-dev
get okcart code
git clone https://github.com/1010101110/okcart.git
cd okcart
install okcart dependencies
npm install
install server runner/watcher
npm install -g pm2
- Login to your braintree account
- Account > Merchange Account Info - get Merchant ID
- Settings > API Keys - get public, private, and tokenization key
- if using gmail you will need to enable access for lesssecureapps
- note you might get critical security error email, you will have to approve the new server IP on first use
this is your secret server only config file. put secure info here.
- braintree merchant details
- Email details see nodemailer documentation
- admin password - change this to something else!! - use: https://www.browserling.com/tools/bcrypt
this is your public config file.
- store name
- store url - this helps our requests find the server whether on client or server.
- braintree token
- locale
- currency
- order shipping base charge - if you want every order to have a shipping charge no matter items set this to x amount, otherwise 0
- order shipping free limit - if you want orders to ship free after x amount use this, otherwise 0
- icons
Add HTML to your about page. You can use Vuetify to make it pretty.
Webpack will build our application. This combines all our source files into minified / optimized files in the dist directory.
npm run build
After you rebuild the application you should restart the server
pm2 restart server
you must have a domain name pointing to the server's ip for this to work. (set the server ip address up with your domain host) (this can take a few hours for the domain to point to your droplet)
certbot + letsencrypt free ssl certificate
wget https://dl.eff.org/certbot-auto
chmod a+x certbot-auto
./certbot-auto certonly --standalone -d yourdomainname.com
now you need to tell your server where the certs are (example paths)
//server.js
var privateKey = fs.readFileSync('/etc/letsencrypt/live/mystore.com/privkey.pem', 'utf8');
var certificate = fs.readFileSync('/etc/letsencrypt/live/mystore.com/fullchain.pem', 'utf8');
run the server once, useful for debugging errors / watching activity.
npm start
if everything is good lets go ahead and configure the server to run forever.
pm2 start server.js
pm2 startup
pm2 save
test it will work by rebooting
shtudown -r now
- login to the backend and get your products setup
- https://yourdomain.com/admin
All the pages are in the src/components folder. Feel free to change the style of pages to your liking. Most html code is done with Vuetify so check out their docs. Anytime you make changes you need to rebuild and restart the server.
You can edit theme colors via vuetify.
color codes see https://material.io/guidelines/style/color.html
We mainly only use the primary color as the page is so simple, you can go through and edit each component to use other colors if you want.
// src/app.js
Vue.use(Vuetify,{
theme:{
primary: '#616161',
accent: '#E53935',
secondary: '#9E9E9E',
error: '#F44336'
}
})
You can also change the browser theme (changes mobile browser color)
<!-- index.html -->
<meta name="theme-color" content="#616161">
If you need more pages it is pretty simple to add. Here we will create an example News page.
- create file.vue in src/components. can edit hellow world to any HTML or see vuetify docs for pretty components.
<!-- src/components/News.Vue -->
<template>
<div :key="news_view">
<h1>hello world</h1>
</div>
</template>
<script>
import store from './../store.js'
export default {
name: 'News'
}
</script>
<style scoped>
</style>
-
change key and name in above to something unique. like News for a news page. It needs to be unique.
-
in router.js import the file and add the page to routes
// src/router.js
// add route to array
routes: [
{ path: '/news', component: () => import('./components/News.vue') },
]
- optional add to menu
// src/App.vue
//find menuitems array, add news entry
//can add an icon from material icons https://material.io/icons/
{icon:"storage",text:"News",href:"/news"},
- rebuild the app
npm run build
follow the create new page guide above
in router.js routes, change the product list view to a different path
add your splash page to as the / path
//src/router.js
//updated routes
routes: [
{ path: '/', component: () => import('./components/Splash.vue') },
{ path: '/store', component: () => import('./components/ProductList.vue') },
also you will need up update your menus with the correct path in App.vue
//src/App.vue
menuitems:[
{icon:"home",text:"Home",href:"/"},
{icon:"store",text:"Store",href:"/store"},
{icon:"people",text:"About",href:"/about"},
{icon:"contact_mail",text:"Contact",href:"/contact"},
],