Skip to content

Commit

Permalink
Merge pull request #200 from withinboredom/master
Browse files Browse the repository at this point in the history
Add docker to yeoman generator
  • Loading branch information
gigabo committed May 25, 2016
2 parents af27983 + b4fa999 commit e5f96fb
Show file tree
Hide file tree
Showing 5 changed files with 115 additions and 7 deletions.
17 changes: 15 additions & 2 deletions packages/generator-react-server/generators/app/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ module.exports = yeoman.Base.extend({
name: 'name',
message: 'What would you like to call your app?',
default: this.appname
}, {
type: 'confirm',
name: 'dockerCfg',
message: 'Do you want to generate a Docker file and Docker Compose file?',
default: false
}];

return this.prompt(prompts).then(function (props) {
Expand All @@ -23,6 +28,7 @@ module.exports = yeoman.Base.extend({

writing: function () {
var _this = this;

[
'_babelrc',
'_gitignore'
Expand All @@ -35,13 +41,20 @@ module.exports = yeoman.Base.extend({
);
});

[
let files = [
'hello-world-page.js',
'hello-world.js',
'package.json',
'README.md',
'routes.js'
].forEach(function (filename) {
];

if (this.props.dockerCfg) {
files.push('Dockerfile');
files.push('docker-compose.yml');
}

files.forEach(function (filename) {
_this.fs.copyTpl(
_this.templatePath(filename),
_this.destinationPath(filename),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
FROM node:slim

EXPOSE 3000
ENV NODE_ENV=docker-dev
VOLUME /www
51 changes: 49 additions & 2 deletions packages/generator-react-server/generators/app/templates/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,62 @@ Very simple example project for `react-server` which only shows server rendering

To start in development mode:

```
```shell
npm start
```

Then go to [localhost:3000](http://localhost:3000/). You will see a simple page that pre-renders and that is interactive on load. It also will include hot reloading of React components in their own file.

If you want to optimize the client code at the expense of startup time, type `NODE_ENV=production npm start`. You can also use any of [the other arguments for react-server-cli](../../react-server-cli#setting-options-manually) after `--`. For example:

```
```shell
# start in dev mode on port 4000
npm start -- --port=4000
```

# Developing using Docker and Docker Compose

These steps assume you are familiar with docker and already have it installed. Some basics:

1. Download [Docker Toolbox](https://www.docker.com/products/docker-toolbox) and install it.
2. Start `docker quick start shell`
3. Navigate to where you generated the project
4. Add a configuration to set the `host` option to the ip given by `docker-machine ip`. An example configuration might be like:
```json
{
"port": "3000",
"env": {
"docker": {
"host": "Your ip from `docker-machine ip` here"
},
"staging": {
"port": "3000"
},
"production": {
"port": "80"
}
}
}
```
5. Now that your system is ready to go, start the containers:
```shell
docker-compose build --pull
docker-compose up
```

The containers will now be running. At any time, press ctrl+c to stop them.

To clean up, run the following commands:

```shell
docker-compose stop
docker-compose rm --all
docker volume ls # and get the name of the volume ending in react_server_node_modules
docker volume rm _react_server_node_modules # this name will be different depending on the name of the project
```

The configuration included stores the node_modules directory in a "named volume". This is a special
persistent data-store that Docker uses to keep around the node_modules directory so that they don't have to
be built on each run of the container. If you need to get into the container in order to investigate what
is in the volume, you can run `docker-compose exec react_server bash` which will open a shell in the
container. Be aware that the exec functionality doesn't exist in Windows (as of this writing).
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
version: '2'
services:
react_server: # The label of the service
build: . # The location of the Dockerfile to build
volumes: # Files to share with the container and the host
- .:/www # Share the project in /www in the container
- react_server_node_modules:/www/node_modules # A special volume so that OS specific node_modules are built correctly
working_dir: /www # The location all commands should run from
environment:
NODE_ENV: 'docker' # Set the NODE_ENV environment variable
command: /bin/bash -c "npm install && npm start" # The command to run in when the container starts
ports: # Ports to expose to your host
- '3000:3000'
- '3001:3001'
# An example database
# my_db:
# image: rethinkdb:latest
# You can reference the db/service by using the dns name `my_db` and docker will do the rest

# Volume to store separate from the container runtime and host
volumes:
react_server_node_modules:
27 changes: 24 additions & 3 deletions packages/generator-react-server/test/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ import path from 'path';
import test from 'ava';
import helpers from 'yeoman-test';

test('generator-react-server:app creates files', async t => {
test('generator-react-server:app creates default files', async t => {
let testDir;
await helpers.run(path.join(__dirname, '../generators/app'))
.inTmpDir(dir => {
testDir = dir;
})
.withPrompts({name: 'foo'})
.withPrompts({name: 'foo', dockerCfg: false})
.toPromise();
t.true(await exists('.babelrc', testDir));
t.true(await exists('.gitignore', testDir));
Expand All @@ -19,6 +19,27 @@ test('generator-react-server:app creates files', async t => {
t.true(await exists('package.json', testDir));
t.true(await exists('README.md', testDir));
t.true(await exists('routes.js', testDir));
t.false(await exists('Dockerfile', testDir));
t.false(await exists('docker-compose.yml', testDir));
});

test('generator-react-server:app creates docker files', async t => {
let testDir;
await helpers.run(path.join(__dirname, '../generators/app'))
.inTmpDir(dir => {
testDir = dir;
})
.withPrompts({name: 'foo', dockerCfg: true})
.toPromise();
t.true(await exists('.babelrc', testDir));
t.true(await exists('.gitignore', testDir));
t.true(await exists('hello-world-page.js', testDir));
t.true(await exists('hello-world.js', testDir));
t.true(await exists('package.json', testDir));
t.true(await exists('README.md', testDir));
t.true(await exists('routes.js', testDir));
t.true(await exists('Dockerfile', testDir));
t.true(await exists('docker-compose.yml', testDir));
});

test('generator-react-server:app passes the test target', async t => {
Expand All @@ -27,7 +48,7 @@ test('generator-react-server:app passes the test target', async t => {
.inTmpDir(dir => {
testDir = dir;
})
.withPrompts({name: 'foo'})
.withPrompts({name: 'foo', dockerCfg: false})
.toPromise();
await installDeps();
t.true(await runsSuccessfully('npm test'));
Expand Down

0 comments on commit e5f96fb

Please sign in to comment.