/venomy

Vuejs Express Node Mysql BoilerPlate

Primary LanguageJavaScript

Deploying Venomy to Docker

Venomy my mnemonic for vue-express-node-mysql. After building several vuejs projects, I wanted a way to scaffold SPAs faster. I built this boilerplate for deployment of my apps to docker fast. This post will focus more on the deployment of the stack than on the actual application code. At the end of this post I will provide links to the github repository.

Generating the node app

Lets do quick run of how the application code was generated : The application code is made up of the server app (nodeapp) which will be hosted on production and the client vuejs app. The server app was generated with yoeman express generator. The commands to get yoeman and generate the app as follows

`npm install -g yo`
`npm install -g generator-express`
`yo nodeapp`

The client app was generated with using vue-cli. Commands to get vue-cli and generate the app :

 `npm install -g @vue/cli`
 `vue create client`

The client vue app will be making api calls to the nodeapp(server) over cors. You can client app by running

 `cd client`
 `npm run serve`

which will lister on port 8080. With hot reloading any changes made to the client app reflects immediately. To run the server app :

  `cd nodeapp`
  `npm start` listening on port 3000.

So we have an expressjs backend and a vuejs frontend working together. Cool!! but we can't host the 2 apps separately so we have to merge them for production.

Merging the apps for production

To prepare the app for production we are going to merge the client app into the server backend. By default when you run npm run build in the client directory it publishes into a dist folder. We are going to configure the client to publish into the public directory of our server app. In vuejs you can create a vue.config.js file to handle this kind of configurations, you learn more about this here https://cli.vuejs.org/config/#vue-config-js. Create a vue.config.js file and paste the following code :

`
const path = require('path');
module.exports = {
    outputDir: path.resolve(__dirname,'../nodeapp/public'),
    devServer:{
        proxy:{
            '/api':{
                target: 'http://localhost:3000'
            }
        }
    }
}
`

The path configuration allows the client to call the server backend on a seprate port only on development machine.

Deploying the app with docker.

Now to the meat of matter. How do we dploy to a docker container. Lets create a docker file in the root of our application. Structure of project as follows: venomy directory -nodeapp -app -config -public -app.js -package.json -client -public -src -package.json -node.dockerfile -docker-compose.yml

By default docker files should be name Dockerfile to be automatically loaded by docker compose but we are ninjas we can choose any name and specify that in the compose file so lets call the compose file node.dockerfile. Our docker file will contain definitions for building the node app into a container. Lets go over our node.dockerfile explaining each line in a comment. Comments in docker file begin with #

FROM node:12.18.3-alpine3.10   #using node version 12 from alpine image. Tip:alpine images and smaller in size recommended
LABEL author="brudex:Penrose"  #Specifying the author. Yours truly
ENV NODE_ENV=production        #Setting or node environment to production. To be read in the nodeapp
ENV PORT=3000                  #Set the port environment variable to 3000. To be read in the nodeapp
COPY      nodeapp /var/www     #Copying the contents of nodeapp our application to /var/www in the container
WORKDIR   /var/www/            #Set our workding directory to /var/www, Context to run subsequent commands
RUN       npm install          #Install npm modules
EXPOSE $PORT                   #Expose port 3000 defined above
ENTRYPOINT ["npm", "start"]    # Run the app

`

Next up we create our docker-compose file. Our docker compose file will contain definitions for building our node service, adding a mysql database and a phpmyadmin server for administering our mysql database. I know phpmyadmin is old school but it works with mysql better than any web database administrator.

version: '3.3'
services:
node:
    container_name: nodeapp
    build:
        context: .
        dockerfile: node.dockerfile
    ports:
      - "3000:3000"
    networks:
      - nodeapp-network
    depends_on:
      - mysql
mysql:
    image: mysql/mysql-server:5.7
    container_name: mysql
    networks:
      - nodeapp-network
    environment:
        MYSQL_DATABASE: nodeapp
        MYSQL_USER: admin
        MYSQL_PASSWORD: pass
        MYSQL_ROOT_PASSWORD: my@secret-root
phpmyadmin:
    image: phpmyadmin/phpmyadmin
    container_name: pma
    links:
      - mysql
    external_links:
      - db_server:mysql
    ports:
      - "8183:80"
    networks:
      - nodeapp-network
    environment:
        PMA_HOST: mysql
        PMA_HOSTS: mysql
        PMA_PORT: 3306
        PMA_ARBITRARY: 1
networks:
  nodeapp-network:
    driver: bridge

We are using version 3.3 of docker compose, every compose file must choose from a range of versions 1.0 to 3.8 more about that here. There are 3 services defined in our docker compose file : node (our node app), mysql (our database), phpmyadmin (web db admin).

node service

The node service is built from the `node.dockerfile`. The container is given a name `nodeapp`. Port 3000 is exposed to be accessible from outside the container. All 3 services is joined to nodeapp-network using a bridge driver.

mysql service

The mysql servic is the database service. It is pulled from the official mysql service version 5.7 on docker hub.
  MYSQL_DATABASE: nodeapp # Creates and initial database when the container starts
  MYSQL_USER: admin       # Creates an initial user when the database starts
  MYSQL_PASSWORD: pass    # Creates a password for the admin user
  MYSQL_ROOT_PASSWORD: my@secret-root # Create a password for the root user

`

phpmyadmin service

Phpmyadmin is used as the web admin service, built from the official phpmyadmin service on docker hub. It opens a login  page on launch. You can enter the followign values to login base on our mysql service configuration.
  `Server : mysql
  `Username : admin
  `Password : pass

We are now set to host our service in docker. This tutorial did not focus on installing and setting up docker but there many resources on the web that teach that. To lauch our service, on the command line in the venomy directory type :

`docker-compose up`

The will build the service and lauch all containers simultaneosly. If you have issues with your node app conncecting to the mysql service. Stop the service with control + c and rerun docker-compose up again. This is an issue with docker starting all services at once so mysql does not finish initializing before the node app tries to connect. You can do a setTimeout to launch the node server after 30 seconds to subvert this.