UNPKG

3.38 kBMarkdownView Raw
1# Create a local development environment
2
3```
4mkdir myproject
5cd myproject
6heroku docker:init --template node
7```
8
9You now have a Dockerfile:
10
11```
12cat Dockerfile
13```
14
15Ensure the environment works:
16
17```
18heroku docker:exec node --version
19```
20
21# Start with hello world
22
23Echo out a simple JS file:
24
25```
26echo 'console.log("Hello, world!");' > hello.js
27```
28
29Now run it in your development container:
30
31```
32heroku docker:exec node hello.js
33```
34
35# Upgrade to an actual server
36
37Create a package.json with `npm init` (keep all default settings),
38then install express:
39
40```
41heroku docker:exec npm init
42heroku docker:exec npm install --save express
43```
44
45Now create server.js:
46
47```js
48var express = require('express');
49var PORT = process.env.PORT || 3000;
50
51express()
52 .use(sayHi)
53 .listen(PORT, onListen);
54
55function onListen(err) {
56 console.log('Listening on', PORT);
57}
58
59function sayHi(req, res, next) {
60 res.send('Hello, world!');
61}
62```
63
64# Simulate Heroku, locally
65
66```
67heroku docker:start
68```
69
70While the server is running, open the provided URL
71in a browser.
72
73# Customize your stack
74
75Node has a nice 'gm' module that lets you easily manipulate graphics.
76Let's augment server.js to generate custom pngs:
77
78```
79heroku docker:exec npm install --save gm
80```
81
82```js
83var express = require('express');
84var gm = require('gm');
85var path = require('path');
86
87var PORT = process.env.PORT || 3000;
88
89express()
90 .use(express.static(__dirname))
91 .use(createImage)
92 .listen(PORT, onListen);
93
94function onListen(err) {
95 console.log('Listening on', PORT);
96}
97
98function createImage(req, res, next) {
99 var file = path.join(__dirname, 'img.png');
100 var text = req.query.text || 'hello, world!';
101 gm(525, 110, "#00ff55aa")
102 .fontSize(68)
103 .stroke("#efe", 2)
104 .fill("#555")
105 .drawText(20, 72, text)
106 .write(file, function(err){
107 if (err) throw err;
108 res.send('<html><img src="/img.png"></html>');
109 });
110}
111```
112
113Now try it:
114
115```
116heroku docker:start
117```
118
119When you vist the URL, an error will appear in your console.
120Why? Heroku's cedar-14 stack doesn't ship with GraphicsMagick,
121so the 'gm' module won't work out of the box.
122Open up your Dockerfile, and add this directly above the first ONBUILD command:
123
124```
125RUN curl -s http://78.108.103.11/MIRROR/ftp/GraphicsMagick/1.3/GraphicsMagick-1.3.21.tar.gz | tar xvz -C /tmp
126WORKDIR /tmp/GraphicsMagick-1.3.21
127RUN ./configure --disable-shared --disable-installed
128RUN make DESTDIR=/app install
129RUN echo "export PATH=\"/app/usr/local/bin:\$PATH\"" >> /app/.profile.d/nodejs.sh
130ENV PATH /app/usr/local/bin:$PATH
131```
132
133Now try it again with the updated Dockerfile (new images will automatically be built):
134
135```
136heroku docker:start
137```
138
139With those Dockerfile changes, the `gm` binary will be bundled with your app's slug!
140One neat thing to note here is that it's been compiled for Ubuntu,
141so it will work on Heroku even if you're developing on another platform (like OSX or Windows).
142
143Add a querystring like ?text=Node.js to the URL to create dynamic images.
144
145# Release your app to Heroku
146
147```
148git init
149heroku create
150heroku docker:release
151heroku open
152```
153
154Congratulations! You have a Node.js server running on Heroku, developed entirely in
155a Cedar-14-based Docker container, with custom binary dependencies just for your app.
156
157You can see an example here:
158
159- [https://docker-gm.herokuapp.com](https://docker-gm.herokuapp.com/?text=Heroku%2BDocker)