Justin Fagnani
Justin Fagnani

Reputation: 11171

How can I run Ghost in Docker with the google/node-runtime image?

I'm very new to Docker, Ghost and node really, so excuse any blatant ignorance here.

I'm trying to set up a Docker image/container for Ghost based on the google/nodejs-runtime image, but can't connect to the server when I run via Docker.

A few details: I'm on OS X, so using I'm boot2docker. I'm running Ghost as a npm module, configured to use port 8080 because that's what google/nodejs-runtime expects. This configuration runs fine outside of Docker when I use npm start. I also tried a simple "Hello, World" Express app on port 8080 which works from within Docker.

My directory structure looks like this:

package.json

{
  "name": "my_app",
  "private": true,
  "dependencies": {
    "ghost": "0.5.2",
    "express": "3.x"
  }
}

Dockerfile

FROM google/nodejs-runtime

ghost_config.js

I changed all occurrences of port 2368 to 8080.

server.js

// This Ghost server works with npm start, but not with Docker
var ghost = require('ghost');
var path = require('path');

ghost({
  config: path.join(__dirname, 'ghost_config.js')
}).then(function (ghostServer) {
  ghostServer.start();
});

// This "Hello World" app works in Docker
// var express = require('express');
// var app = express();

// app.get('/', function(req, res) {
//   res.send('Hello World');
// });

// var server = app.listen(8080, function() {
//   console.log('Listening on port %d', server.address().port);
// });

I build my Docker image with docker build -t my_app ., then run it with docker run -p 8080 my_app, which prints this to the console:

> my_app@ start /app
> node server.js

Migrations: Up to date at version 003
Ghost is running in development... 
Listening on 127.0.0.1:8080 
Url configured as: http://localhost:8080 
Ctrl+C to shut down

docker ps outputs:

CONTAINER ID        IMAGE                  COMMAND                CREATED             STATUS              PORTS                     NAMES
4f4c7027f62f        my_app:latest   "/nodejs/bin/npm sta   23 hours ago        Up About a minute   0.0.0.0:49165->8080/tcp   pensive_lovelace

And boot2docker ip outputs:

The VM's Host only interface IP address is: 192.168.59.103

So I point my browser at: 192.168.59.103:49165 and get nothing, an no output in the Docker logs. Like I said above, running the "Hello World" app in the same server.js works fine.

Everything looks correct to me. The only odd thing that I see is that sqlite3 fails in npm install during docker build:

[sqlite3] Command failed: 
module.js:356
  Module._extensions[extension](this, filename);
                               ^
Error: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.14' not found 

...

node-pre-gyp ERR! Testing pre-built binary failed, attempting to source compile 

but the source compile appears to succeed just fine.

I hope I'm just doing something silly here.

Upvotes: 2

Views: 981

Answers (2)

Daiwei
Daiwei

Reputation: 43566

In your ghost config, change the related server host to 0.0.0.0 instead of 127.0.0.1:

server: {
  host: '0.0.0.0',
  ...
}

PS: for the SQLite error. Try this Dockerfile:

FROM phusion/baseimage:latest

# Set correct environment variables.
ENV HOME /root

# Regenerate SSH host keys. baseimage-docker does not contain any, so you
# have to do that yourself. You may also comment out this instruction; the
# init system will auto-generate one during boot.
RUN /etc/my_init.d/00_regen_ssh_host_keys.sh

# Use baseimage-docker's init system.
CMD ["/sbin/my_init"]

# ...put your own build instructions here...
# Install Node.js and npm
ENV DEBIAN_FRONTEND noninteractive
RUN curl -sL https://deb.nodesource.com/setup | sudo bash -
RUN apt-get install -y nodejs

# Copy Project Files
RUN mkdir /root/webapp
WORKDIR /root/webapp

COPY app /root/webapp/app
COPY package.json /root/webapp/
RUN npm install

# Add runit service for Node.js app
RUN mkdir /etc/service/webapp
ADD deploy/runit/webapp.sh /etc/service/webapp/run
RUN chmod +x /etc/service/webapp/run

# Add syslog-ng Logentries config file
ADD deploy/syslog-ng/logentries.conf /etc/syslog-ng/conf.d/logentries.conf

# Expose Ghost port
EXPOSE 2368

# Clean up APT when done.
RUN apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

Note I used phusion/baseimage instead of google/nodejs-runtime and installed node.js & npm with:

ENV DEBIAN_FRONTEND noninteractive
RUN curl -sL https://deb.nodesource.com/setup | sudo bash -
RUN apt-get install -y nodejs

Upvotes: 3

Thom Parkin
Thom Parkin

Reputation: 346

In your Dockerfile, you need this command EXPOSE 8080. But that only makes that port accessible outside the Docker container. When you run a container from that image you need to 'map' that port. For example:

$ docker run -d -t -p 80:8080 <imagename>

The -p 80:8080 directs port '8080' in the container to port '80' on the outside when it is running.

The syntax always confuses me (I think it is backwards).

Upvotes: 0

Related Questions