Deploying Venom to Docker
Venom is a mnemonic for vue-express-node-mongodb. In a previous post I described how to use mysql in place of mongodb. This post is going to be a short one showing an actual venom with docker deployment. Like the previous post this 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 generation the application code to be hosted : 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 this time choose mongodb as storage choice.
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 start client app by running
cd client npm run serve
which will listen 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 can 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: 'https://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: venom 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 named 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 mongodb database and a mongo-express server for administering our mongodb database.
version: '3.3' services: node: container_name: nodeapp build: context: . dockerfile: node.dockerfile ports: - "3000:3000" networks: - nodeapp-network depends_on: - mongo mongo: image: mongo:4.2.9-bionic container_name: mongo ports: - '27017:27017' networks: - nodeapp-network environment: MONGO_INITDB_ROOT_USERNAME: admin MONGO_INITDB_ROOT_PASSWORD: admin MONGO_INITDB_DATABASE: nodeapp mongo_express: image: mongo-express container_name: mongo_express depends_on: - 'mongo' ports: - '8081:8081' restart: always networks: - nodeapp-network volumes: - ./mongodata:/data/db environment: ME_CONFIG_MONGODB_SERVER: mongo ME_CONFIG_MONGODB_PORT: 27017 ME_CONFIG_MONGODB_ENABLE_ADMIN: "true" ME_CONFIG_MONGODB_ADMINUSERNAME: admin ME_CONFIG_MONGODB_ADMINPASSWORD: admin 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), mongo (our database), mongo-express (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.
mongo service
The mongo service is the database service. It is pulled from the official mongodb image version 4.2.9-bionic on docker hub. MONGO_INITDB_DATABASE: nodeapp # (optional:mongodb databases are created on first insert) Creates an initial db MONGO_INITDB_ROOT_PASSWORD: admin # Creates an admin user when the service starts MONGO_INITDB_ROOT_PASSWORD: admin # Creates a password for the admin user
mongo-express service
Mongo-Express is a web based MongoDB admin interface. This service pulls the official mongo-express image from docker hub. ME_CONFIG_MONGODB_SERVER: mongo # mongodb service host name ME_CONFIG_MONGODB_PORT: 27017 # mongodb listening on default port 2017 (optional value required only if port is not default) ME_CONFIG_MONGODB_ENABLE_ADMIN: "true" # Enable administrator access. ME_CONFIG_MONGODB_ADMINUSERNAME: admin # specify admin username if enable admin is true ME_CONFIG_MONGODB_ADMINPASSWORD: admin # specify admin password if enable admin is true
We are now set to host our service in docker. This tutorial did not focus on installing and setting up docker. You can follow this to install and setup docker.
To lauch our service, on the command line in the venomy directory type :
`docker-compose up`
This will build the service and lauch all containers simultaneosly. The code for this tutorial is hosted on github https://github.com/brudex/venom.
Comments Welcome