Let's assume you’ve already devoured every Docker 101 tutorial for breakfast. You’re now ready to work on your Meteor /Node application and go for an all containerized approach to development and operations.
You're in for a treat. In this blog post, we'll be explaining what a proper Docker workflow looks like, and how to manipulate it to make it your own. We'll guide you through the entire Docker development process, test your Meteor application and run your app in production on the cloud provider of your choice using Cloud 66 and Codeship Pro. To wrap things up, we'll also show you how to scale your Meteor app to greater heights.
If you didn't like reading and just sit back and relax, you can also watch the recorded webinar with did together with Codeship. The webinar will guide your step-by-step and explain all the example code:
<iframe src width height frameborder webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
Let's get started.
We need a plan!
Our plan follows this 5 steps approach:
- Develop your Meteor app on your local dev machine.
- Run your app in a staging environment on any cloud or bring your own server.
- Run your tests using a CI/CD solution provided by Codeship.
- Run your app in a production and scale.
- Start to iterate!
To kickstart the process, we'll need an application to get started. For this example, we are using the official Meteor example app called Todos.
The Meteor Todos app can be found on Github. Please clone it onto your local dev machine, then check out the source and how the project is structured.
Act Local, Think global
Before we get started, make sure you have installed the latest Docker Engine and Docker Compose.
In a containerized world the first thing on your mind is to get the project up and running on your local development box. The preferred way is to create a Dockerfile (Dockerfile.development
» ) which is responsible for all the dependencies (Node.js packages, Meteor runtime and so on) and a Docker Compose (docker-compose.yml
» ) file to make a compositing of your Meteor app and the backend MongoDB.
We need to build all the services we need.
docker-compose build
When this process is done we can run our development environment:
docker-compose run --service-ports meteor
Point your browser to http://localhost:3000
and you can start developing right away.
The app looks like this:
Test first ask questions later
I'm using the BDD way of testing. Every application exposes a contract/software interface, which can be tested from the outside-in.
For the Meteor test, we use the mocha
framework for running tests. For those with a ruby background, mocha
has some similarities with rspec
.
Here's an overview of what a developer workflow will look like using Codeship Pro and Cloud 66.
And this is what's going on under the hood:
- Build the container image for the App
- Run the App and start the dependencies the service relies on. MongoDB in this case.
- Wait for MongoDB to become ready.
- WARNING: You'll never know how long it takes for a service to boot. Make sure to check if a service is running before making calls. You can use a generic wait.sh script (
start_test.sh
» ) - Run the Tests against the App when everything is up and running.
- Notify your Docker stack managed by Cloud 66 using the webhook.
Test time
Build all the services we need.
docker-compose build
Run the test suite
docker-compose run test
Watch the generic wait scrips to check if mongodb is up and start firing off those tests. Expected output:
The works
That's it... you've tested the Todo service. Take a look at our (docker-compose.yml
» )
What you want to remember is, only the meteor service will be deployed to the production stack managed by Cloud 66. The rest of the services are for local development and testing, and will be running on Codeship Pro.
You notice we use an alias for our links. In a real Docker production setup, you need some kind of service discovery. The Cloud 66 platform uses the very stable DNS for service discovery, called ElasticDNS.
After redeploying the service, ElasticDNS automagically updates, providing you with zero-downtime. By linking the containers in our local and test environment this way, we don't need to change the code finding the services.
Use Codeship Pro for running your tests
Nice! Does it run on the new Codeship Pro? Codeship released a CLI tool called Jet to test your service locally, and in the cloud. Follow this instruction and guide to Codeship Docker infrastructure to get Jet installed.
Jet needs a service configuration file called codeship-service.yml
. Looks almost the same as docker-compose.yml
with a couple of exceptions (you can't use ports for example).
Also, we need all the steps of our CI/CD workflow. You can define them in the codeship-steps.yml
. Ours is as simple as a microservice should be.
The codeship-steps.yml
configuration:
You can see two steps. One for the test and the second step it to tell (after the test is green) to redeploy the code in production.
Ready to rock? Run the test suite using the Jet CLI to test if it works with Codeship
jet steps
When the test hits green, we're ready to get the real magic in. Follow the steps for creating a project on the Codeship Docker Infrastructure and automagically, a Github webhook triggers the tests.
If we edit some code. Run the tests:
docker-compose run test
Push the code changes to Git and our test will run on the Codeship Docker Infrastructure. Expected codeship output.
But wait? You bragged about running this thing in production. So let's throw in some more magic. Check the last step called notifier?
Run Meteor in production !
If you're not familiar with Cloud 66; the service simplifies Ops for developers by building, configuring and managing your servers on any cloud. Our Node support provides a complete toolset for rolling out Node application to production on your own infrastructure.
Creating a Meteor cluster
Register with Cloud 66, dial in the credentials of your cloud provider of choice, and begin using the UI to start a Node stack. Pop in the Git repository, analyze it and off you go! Grab a coffee and sit back to get those servers provisioned.
Adding the repo:
Select the cloud deployment:
Once Cloud 66 provisions your server(s) and your Node cluster is up and running, sit back and enjoy the view:
Scale to the moon and back
So you want to scale? Right then. You can scale vertically to add more Node servers to your cluster to scale horizontally and spawn more Meteor instances.
You're working hard on your Meteor app, run the test (green! yeah!), and tell Cloud 66 to redeploy the running services. Let's add a redeploy hook to Codeship and trigger that event at Cloud 66.
Hookup Codeship to Cloud 66
We use the notifier service running during tests on Codeship. The notifier only runs one simple script:
#!/bin/bash
curl -X POST -d "" ${CLOUD_66_REDEPLOY_HOOK}
The script needs an environment variable called CLOUD_66_REDEPLOY_HOOK. How do I get one? Once you’ve deployed your stack with Cloud 66, you’ll see a Redeployment Hook URL on your Stack Information page. To trigger a new deployment via Codeship, simply use the example notifier service (based on the ultra small alpine base image) to last project step.
Recap
With the integration of Codeship Pro and Cloud 66, you get an easy-to-use and fast Node workflow pipeline, and don't have to worry about running Node in production. Let Codeship Pro take care of all the (integration) testing, and don't worry about your infrastructure. Cloud 66 makes Ops simple for Devs.
If you need hand holding. The webinar will guide your step-by-step and explain all the example code:
<iframe src width height frameborder webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>