Migrate to jekyll for static gen
This commit is contained in:
parent
8280d4fcab
commit
0cc7d7fe42
27 changed files with 1424 additions and 100 deletions
143
_posts/2015-11-21-dockerizing-lubot.md
Normal file
143
_posts/2015-11-21-dockerizing-lubot.md
Normal file
|
@ -0,0 +1,143 @@
|
|||
---
|
||||
layout: post
|
||||
title: Dockerizing Lubot
|
||||
tag:
|
||||
- docker
|
||||
- technical
|
||||
---
|
||||
|
||||
Lubot is the [Lansing Codes](http://lansing.codes/) chat bot responsible for
|
||||
bringing updates about all local events to chatters everywhere…or just in
|
||||
Lansing. Previously, it resided on a Heroku Free instance and was required to
|
||||
sleep for six hours out of every twenty-four hours. After some issues with him
|
||||
waking up, we began looking for alternatives. Since I already had a server
|
||||
hosting several Docker containers, it seemed like the best choice.
|
||||
|
||||
Docker is basically a way to create a container that can be easily distributed
|
||||
across many operating systems. Using it, we can take the code, runtime, and
|
||||
libraries that Lubot requires and put them in a package. You can read more about
|
||||
it in the
|
||||
[Official “What is Docker” article](https://www.docker.com/what-docker).
|
||||
|
||||
To begin, we need to determine the necessary dependencies for our application.
|
||||
Lubot is built using NodeJS and uses npm to manage dependencies. Specifically,
|
||||
we are using Node v5.0.0 and npm v3.3.9. There’s an official Node Dockerfile to
|
||||
use to begin with so it is pretty easy to start.
|
||||
|
||||
```
|
||||
FROM node
|
||||
|
||||
ENV NODE_VERSION 5.0.0
|
||||
ENV NPM_VERSION 3.3.9
|
||||
```
|
||||
|
||||
After that, we want to take care of the dependencies for our application.
|
||||
Because of the way Docker works, we want to cache this step so when our
|
||||
packages.json file does not change, we do not have to rebuild our dependencies.
|
||||
|
||||
```
|
||||
ADD package.json /tmp/
|
||||
RUN cd /tmp && npm install
|
||||
RUN mkdir -p /opt/hubot && cp -a /tmp/node_modules /opt/hubot
|
||||
```
|
||||
|
||||
Then, we need to add the application code to the container.
|
||||
|
||||
```
|
||||
ADD . /opt/hubot
|
||||
WORKDIR /opt/hubot
|
||||
```
|
||||
|
||||
Finally, we can start the service.
|
||||
|
||||
```
|
||||
CMD ["/opt/hubot/bin/hubot", "--adapter", "slack"]
|
||||
```
|
||||
|
||||
Combine these steps and we end up with a
|
||||
[Dockerfile](https://github.com/lansingcodes/lubot/blob/master/Dockerfile). This
|
||||
gets added to the repisitory so that we can build the application. Building an
|
||||
image is easy.
|
||||
|
||||
```
|
||||
docker build -t lansingcodes/lubot .
|
||||
```
|
||||
|
||||
This will download and build the necessary filesystems, caching where necessary
|
||||
and giving us a runable container image. Starting the container is also simple.
|
||||
|
||||
```
|
||||
docker run lansingcodes/lubot
|
||||
```
|
||||
|
||||
Lubot expects some environment variables to be there. But since we are in a
|
||||
container, no environment variables exist on the system and we need to pass them
|
||||
in. Our new run command accounts for this.
|
||||
|
||||
```
|
||||
docker run -d --restart=always --name lubot \
|
||||
-e HUBOT_SLACK_TOKEN=$HUBOT_SLACK_TOKEN \
|
||||
-e TWITTER_LANSINGCODES_CONSUMER_KEY=$TWITTER_LANSINGCODES_CONSUMER_KEY \
|
||||
-e TWITTER_LANSINGCODES_CONSUMER_SECRET=$TWITTER_LANSINGCODES_CONSUMER_SECRET \
|
||||
-e TWITTER_LANSINGCODES_ACCESS_TOKEN=$TWITTER_LANSINGCODES_ACCESS_TOKEN \
|
||||
-e TWITTER_LANSINGCODES_ACCESS_TOKEN_SECRET=$TWITTER_LANSINGCODES_ACCESS_TOKEN_SECRET \
|
||||
-e GOOGLE_API_KEY=$GOOGLE_API_KEY \
|
||||
-e LUBOT_MEETUP_API_KEY=$LUBOT_MEETUP_API_KEY \
|
||||
-e TZ=$TZ \
|
||||
-e REDIS_URL=$REDIS_URL \
|
||||
lansingcodes/lubot
|
||||
```
|
||||
|
||||
Lubot is now running in a container. However, Heroku also provided easy
|
||||
continuous deployment when combined with [Circle CI](https://circleci.com/).
|
||||
Being able to have changes deployed when the master branch changes is handy.
|
||||
Circle CI allows us to specify post-build commands to run. Typically, we’d want
|
||||
to build the container on our CI server and then push to a Docker registry, butI
|
||||
didn’t have one of those available. We can still use Circle CI to execute
|
||||
commands on a remote server with SSH. This makes our deploy process simple.
|
||||
|
||||
- clone the repository on our remote server
|
||||
- build the docker image from that repositry
|
||||
- run the docker image that was build
|
||||
|
||||
Our CI build file will trigger these actions via a script.
|
||||
|
||||
```
|
||||
scp deploy/deploy.sh lubot@app.atomaka.com:/home/lubot
|
||||
ssh lubot@app.atomaka.com "bash /home/lubot/deploy.sh"
|
||||
```
|
||||
|
||||
And then, deploy.sh will take care of the parts we already discussed.
|
||||
|
||||
```
|
||||
#!/bin/bash
|
||||
|
||||
cd $HOME
|
||||
source lubotrc
|
||||
|
||||
git clone https://github.com/lansingcodes/lubot.git
|
||||
|
||||
cd $HOME/lubot
|
||||
sudo docker build -t lansingcodes/lubot .
|
||||
cd $HOME
|
||||
rm -rf $HOME/lubot
|
||||
|
||||
sudo docker rm -f lubot
|
||||
sudo docker run -d --restart=always --name lubot \
|
||||
-e HUBOT_SLACK_TOKEN=$HUBOT_SLACK_TOKEN \
|
||||
-e TWITTER_LANSINGCODES_CONSUMER_KEY=$TWITTER_LANSINGCODES_CONSUMER_KEY \
|
||||
-e TWITTER_LANSINGCODES_CONSUMER_SECRET=$TWITTER_LANSINGCODES_CONSUMER_SECRET \
|
||||
-e TWITTER_LANSINGCODES_ACCESS_TOKEN=$TWITTER_LANSINGCODES_ACCESS_TOKEN \
|
||||
-e TWITTER_LANSINGCODES_ACCESS_TOKEN_SECRET=$TWITTER_LANSINGCODES_ACCESS_TOKEN_SECRET \
|
||||
-e GOOGLE_API_KEY=$GOOGLE_API_KEY \
|
||||
-e LUBOT_MEETUP_API_KEY=$LUBOT_MEETUP_API_KEY \
|
||||
-e TZ=$TZ \
|
||||
-e REDIS_URL=$REDIS_URL \
|
||||
lansingcodes/lubot
|
||||
```
|
||||
|
||||
Deploying Lubot is now just as easy as it was with Heroku and he never has to
|
||||
sleep again.
|
||||
|
||||
- [Other details surrounding the deployment](https://github.com/lansingcodes/lubot/tree/master/deploy)
|
||||
- [Lubot repository](https://github.com/lansingcodes/slackbot)
|
Loading…
Add table
Add a link
Reference in a new issue