Dieses Blog durchsuchen

Sonntag, 4. September 2016

docker: link a node.js container with a mongodb container with legacylinking

To use docker in an enviroment where you have to seperate database from webserver and webserver from contentserver you can use 2 methods in docker.
Today we want to have a  look on Legacy Linking. Like the name describes is this the simplest method to link containers, wich can be marked as deprecated in the future.

This methods simply runs the dependend containers with the --link attribute

 

Prerequisits

We need some things installed on the local machine.

 

Install node.js pet-app

We want to use a little pet app with node.js. It starts an express server and connects to a mongodb server "my-mongodb". The app simply lists some docs pics and some describing texts

Clone the app repository in your projectroot
$ git clone https://github.com/pboethig/dockerlessons.git
$ cd dockerlessons/legacyLinking

 

Inspect the dockerfile

In the projectroot you find a "node.dockerfile" this is the dockerfile for our node webserver with the node.js app in it

This is the content
FROM node:latest

MAINTAINER Peter Böthig

ENV NODE_ENV=production
ENV PORT=3000

COPY . /var/www
WORKDIR /var/www

RUN npm install

EXPOSE $PORT

ENTRYPOINT ["npm", "start"]
To explain that
  • Line 1 load a node baseimage
  • Line 2 define a maintainer (your username in thinat case)
  • Line 3 & 4 define enviromentvariables, to switch from dev to prod
  • Line 5 copy our sourcecode to the container in "var/www"
  • LINE 6 define a workingdirectory
  • Line 7 run npm install
  • Line 8 Expose the default webserverport (prod/live)
  • Line 9 start the express webserver
In the follwing we use <your_docker_username>. Please make sure you have an account

 

Create our image from the Dockerfile

Now, that we have created our Dockerfile we can create our first image from it.

Open a terminal in the folder where your Dockerfile lives
docker build -f node.dockerfile -t <your_docker_username>/node-pet-app .

Don't forget the last point at the end of the line, otherwhis nothing will be found to image. The first load could take some seconds.

You can see you new image with
docker images

Create your mongo-database-container

Our pet app needs a mongodatabase where the pet data live. We simply use an image from the docker hiu

Pull the image and create a named container
docker run -d --name my-mongodb mongo
This will download the mongo-image and create a container "my-mongodb". The name "my-mongodb" is important, because it's  mapped to the configured databasename "mongodb" in our config/config.production.js of our pet app.

 

Create our node-app container and link it to the databasecontainer

Now that we have created our node.js app image and have our database up and running, we want to create our app server and link it to our pet database.

Run and link the containers
docker run -d -p 8080:3000 --link mymongodb:mongodb --name nodeapp <your_docker_username>/node-pet-app


To explain that:
  • -d -> starts container detached, so the console can be used
  • -p 8080:3000 -> maps the hostport 8080 on the containerport 3000
  • --link my-mongodb:mongodb -> creates a link "mongodb" from to the container "my-mongodb". So "mongodb" can be found in the network
  • --name nodeapp <your_docker_username>/node-pet-app -> creates the container "nodeapp" from your app image

Now you can reach your app under http://localhost:8080

This is really great. But you don't see any pets. Thats because you dont have any data in it

Populate database with testdatas
docker exec nodeapp node dbSeeder.js

This will execute "node dbSeeder.js" inside your new container "nodeapp"

That's it. Really awesome stuff. Now your can surf to your new app and see your pets
http://localhost:8080




Samstag, 3. September 2016

docker: create a dockerimage from a dockerfile with a node.js app in it

Let's create a node.js dockerkerimage with a dockerfile and let us start a node.js app on this container

Prerequisits

We need some things installed on the local machine.
  • node.js installed
  • npm installed
  • docker installed

Install node.js sampleapp

If you already have a node.js to pack you can leave this step

We want to use a simple express app with a hello world text, to demonstrate that the webapp is running on our container

Install an express and express-generator
$ npm install -g express express-generator
$ npm install

Create an express project
$ express sampleApp
This will generate our skeleton app in the current folder.

Create our DockerFile

With a DockerFile we are able to describe what we want to install on the container in a easy readable configfile. If you want to see the documentation, what commands the DockerFile can execute, here is the documentation

Now we want to to following things automated by the dockerfile. This can be managed by the following dockerfile

Save following content in a file "Dockerfile" in your project-skeletons root
FROM node:latest

MAINTAINER Peter Böthig

ENV NODE_ENV=production
ENV PORT=3000

COPY . /var/www
WORKDIR /var/www

RUN npm install

EXPOSE $PORT

ENTRYPOINT ["npm", "start"]

To explain that
  • Line 1 load a node baseimage
  • Line 2 define a maintainer (your username in thinat case)
  • Line 3 & 4 define enviromentvariables, to switch from dev to prod
  • Line 5 copy our sourcecode to the container in "var/www"
  • LINE 6 define a workingdirectory
  • Line 7 run npm install
  • Line 8 Expose the default webserverport (prod/live)
  • Line 9 start the express webserver

Create our image from the Dockerfile

Now, that we have created our Dockerfile we can create our first image from it.

Open a terminal in the folder where your Dockerfile lives
docker build -f Dockerfile -t <yourdockerhub-username>/node-express
This will create your image

You can see you new image with
docker images


Create a new container from your image

Now, that we have created our image from the dockerfile we can create a new container and run our sample app

Open a terminal in the folder where your Dockerfile lives
docker run -d -p 8081:3000 <yourdockerhub-username>/node-express

Now you can reach your app under http://localhost:8081

docker: dockerize your node.js application and your dev-enviroment and deploy it to the docker cloud

Today we want to setup a simple node.js app with express and expressgenerator and deploy it to a docker container. The goal is:
- to have a linux container with our app up and running.
- The sourcecode lives in mounted volume on the host, so, that we can directly

Prerequisits

At first, you need to have some tools installed locally on yout machine. Here they are.
  • node.js installed
  • npm installed
  • docker installed
On ubuntu you can install it like that
$ apt-get install nodejs
$ apt-get install npm
We only need node and npm installed, to create a boilerplate app. In your daily works you will only checkout your project.

On windows and mac you can do it like that
https://nodejs.org/en/download/

 

Install docker

Windows and Mac, follow the instruction under:
https://www.docker.com/products/docker#/linux

If you are on ubuntu you can install docker like that:
http://magento2-tuts.blogspot.de/2016/08/install-docker-on-ubuntu-1604.html

Install node sample app 

We want to have our node.js sourcecode on the local machine, not in the docker container directly. So we are mounting the workingdirectory into the docker container later

Install an express and express-generator
$ npm install -g express express-generator

Create an express project
$ express sampleApp
$ npm install

This will generate our skeleton app. in the current folder

Download your docker baseimage 

To make things simple, we want to use a predefined "node.js ready" ubuntu image from dockerhub. If you dont know docker hub, take your time to create a an acocunt. you will need it later. https://hub.docker.com/

pull your node container
$ docker pull node 
This will download our working image

 

Create your appcontainer

Now let's create our contrainer in which our node.js express app will live. We want, that we can browse the app on port 8080 and we want our sourcecode is mounted as a volume to the the docker container in dir "/var/www"

This can be done by follwing command
$ docker run -p 8080:3000 -v $(pwd):var/www -w "/var/www" node npm start 
To expain that  
  • -p 8080:3000 -> the host port 8080 will be forwarded to port 3000 on the docker container, so we can reach the container under http://localhost:8080
  • -v -> we want to mount a folder on the host as a volume to the container 
  • $(pwd):var/www -> That means to mount the current dir to "var/www" in the container
  • -w "var/www" -> That means to change to "/var/www" on the container. 
  • npm start -> starts the app in "/var/www"

 

Test your container

Now you can surf "http://localhost:8080" and you should see your express site
WOW. thats awesome.

But wait. We want to test, how easy it is to edit your sourcecode.

Go to your app directory where your code files lives and edit the index.hbm in the views folder.

Type "Hi there" somewhere in the html code.

Reload your browser. 

You will see your changes directly









Sonntag, 28. August 2016

react.js: create a basic table component with bootstrap styles

Today we want to implement a simple task in HTML with css.
A Simple datatable like that:

The tablecomponent has a thead, a tbody and a stripe css set.

In good old html we do that like this:
<table class="table table-striped">
  <thead class="thead-default">
<tr>
    <th>ID</th>
    <th>Name</th>
   </tr>
</thead>
<tbody>
<tr>
  <td>1</td>
  <td>Nikko Laus1</td>
 </tr>
<tr>
  <td>2</td>
  <td>Sam Collins</td>
 </tr>
<tr>
  <td>3</td>
  <td>Carl Smith Wesson</td>
 </tr>
<tr>
  <td>4</td>
  <td>Peter Austin</td>
 </tr>
<tr>
  <td>5</td>
  <td>Tini Titus</td>
 </tr>
<tr>
  <td>6</td>
  <td>Sarra Cams</td>
 </tr>
</tbody>
</table>


Now we want to to this the react way.
We want to split the table in 3 components. One "App" component to wrap all other components. One TableRowComponent, which handles each row and a tablehead component to format the tablehead.

We are using Visual Studio code with all available react plugins on ubuntu 16.04

This tutorial is inspired by this great egghead video from Joe Maddalone:
https://egghead.io/lessons/react-dynamically-generated-components 

Prerequisits

At first, you need to have some tools installed. Here they are.
node.js installed
npm installed

babel react
the facebook react library

babel installed
Babel is a javascript compiler, which transforms latest javascriptstandards to native javascript

webpack installed
Webapck is a modulebundler which  creates statis js assets for the browser

Bootstrap installed
Bootstrap is a common css , component framework from twitter


$ apt-get install nodejs
$ apt-get install npm
$ npm install -g --save babel webpack webpack-server-dev
$ npm install --save babel-core babel- loader babel preset-es2015 babel-preset-react
$ npm install css-loader style-loader file-loader url-loader --save-dev
 

Init your node project

To initialise your project simple type:
$ npm init

This will create your package.json

Fill your projectdata 
My package.json looks like that
{
  "name": "react-redux",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "webpack-dev-server"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "babel": "^6.5.2",
    "babel-core": "^6.14.0",
    "babel-loader": "^6.2.5",
    "babel-preset-es2015": "^6.14.0",
    "babel-preset-react": "^6.11.1",
    "bootstrap": "^3.3.7",
    "react": "^15.3.1",
    "react-bootstrap": "^0.30.3",
    "react-dom": "^15.3.1",
    "webpack": "^1.13.2",
    "webpack-dev-server": "^1.15.0"
  },
  "devDependencies": {
    "css-loader": "^0.24.0",
    "file-loader": "^0.9.0",
    "style-loader": "^0.13.1",
    "url-loader": "^0.5.7"
  }
}


Add your component files

Create a index.html 
This will contain your main html page

main.js
this will load your components

webpack.config.js 
this will setup your dependencies and loaders and defines the compilingprocess of es2015 babel to native javascript

App.js
Here you will code your components
touch main.js index.html App.js webpack.config.js 

Configure your webpack.config.js

Open your webpack.config.js and add folling code
module.exports=
{
    entry:'./main.js',
    output:
    {
        path:'./',
        filename: 'index.js'
    },
    devServer:
    {
        inline:true,
        port:3333
    },
    module:
    {
        loaders: [
            {
                test:/\.js$/,
                exclude: /node_modules/,
                loader:'babel-loader',
                query:
                {
                    presets:['es2015','react']
                }
            },
            { 
        test: /\.css$/, 
        loader: "style-loader!css-loader" 
      },
      { 
        test: /\.png$/, 
        loader: "url-loader?limit=100000" 
      },
      { 
        test: /\.jpg$/, 
        loader: "file-loader" 
      },
      {
        test: /\.(woff|woff2)(\?v=\d+\.\d+\.\d+)?$/, 
        loader: 'url?limit=10000&mimetype=application/font-woff'
      },
      {
        test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, 
        loader: 'url?limit=10000&mimetype=application/octet-stream'
      },
      {
        test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, 
        loader: 'file'
      },
      {
        test: /\.svg(\?v=\d+\.\d+\.\d+)?$/, 
        loader: 'url?limit=10000&mimetype=image/svg+xml'
      }
        ]
    }
}
- This will tell webpack to pack a index.js with all javascripts in it
- Start a webserver on port 3333
- test all .js files
- Generate native javascript from babel sources.
- Tell webpack to load boostrap filetypes, mimetypes


Load your javascript on your html page

Open your index.html and add folling snippet
<!DOCTYPE html>
<html>

<head></head>

<body>
    <div id="app"></div>
    <script src="index.js"></script>
</body>

</html>

- This will add a div with id "app" which is the container for our app
- include the webpack generated index.js

Create your bootrap react component

Open your App.js and add folling snippet
import React from 'react';
import ReactDOM from 'react-dom';

class App extends React.Component
{
    constructor() 
    {
        super();
        this.state = {
            data:[
                {id:1, name:"Nikko Laus1"},
                {id:2, name:"Sam Collins"},
                {id:3, name:"Carl Smith Wesson"},
                {id:4, name:"Peter Austin"},
                {id:5, name:"Tini Titus"},
                {id:6, name:"Sarra Cams"}    
            ]
        }
    }
  
    render() {
        
        let rows = this.state.data.map(person =>
        {
            return <TableRow key={person.id} data={person}/>
        });

        return (<table className="table table-striped">
            <TableHead/>
                <tbody>{rows}</tbody>
            </table>
            );
    }
}

class TableHead extends React.Component
{
    constructor()
    {
        super();
    }

    render()
    {
         return (<thead className="thead-default">
        <tr>
            <th>ID</th>
            <th>Name</th>
        </tr>
        </thead>
        );
    }
}

class TableRow extends React.Component
{
    constructor()
    {
        super();
    }

    render()
    {
        return (<tr>
                    <td>{this.props.data.id}</td>
                    <td>{this.props.data.name}</td>
                </tr>
            );
    }
}

export default App

- This adds a the base App Component with a dataset constructed as a state property in the constructor.
- This will add your App Component. This component renders an HTML-table with a seperate <TableRow> and a separate <TableHead> component in boostrap style.
- It also adds a <TableRow> component, which handles the row pattern
- At the end it adds a <TableHead> component, which builds the header of the tablecomponent 

Load your component in main.js

Open your main.js and add folling snippet
import App from './App';
import Bootstrap from 'bootstrap/dist/css/bootstrap.css';
import React from 'react';

import ReactDOM from 'react-dom';

ReactDOM.render( 
    < App / > 
    , document.getElementById('app')
    );

- Import your App component, which you have prevoiusly created and render it to a div with the id 'app'

Start your server and test your app

Open a terminal and type:
npm start 

This will start your webserver on port 3333

Surf to localhost:3333

Thats it, you have created your first bootstrap table component with bootstrap

Nice isn't it?

Samstag, 27. August 2016

react.js: create your first react app with webpack and babel on es2015

Today we want to write our first react Hello world app. Before we can start, we have to setup out dev-enviroment.

We are using Visual Studio code with all available react plugins on ubuntu 16.04

This tutorial is inspired by this great egghead video:

Prerequisits

At first, you need to have some tools installed. Here they are.
node.js installed
npm installed

babel react
the facebook react library

babel installed
Babel is a javascript compiler, which transforms latest javascriptstandards to native javascript

webpack installed
Webapck is a modulebundler which  creates statis js assets for the browser

$ apt-get install nodejs
$ apt-get install npm
$ npm install -g --save babel webpack webpack-server-dev
$ npm install --save babel-core babel- loader babel preset-es2015 babel-preset-react

Init your node project

To initialise your project simple type:
$ npm init

This will create your package.json

Fill your projectdata 
My package.json looks like that
{
  "name": "simplecommand",
  "version": "1.0.0",
  "description": "a simple console command",
  "main": "createUser.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/pboethig/nodejs-lessons.git"
  },
  "keywords": [
    "nodejs",
    "command"
  ],
  "author": "pboethig",
  "license": "MIT",
  "bugs": {
    "url": "https://github.com/pboethig/nodejs-lessons/issues"
  },
  "homepage": "https://github.com/pboethig/nodejs-lessons#readme"
}

Add your component files

Create a index.html 
This will contain your main html page

main.js
this will load your components

webpack.config.js 
this will setup your dependencies and loaders and defines the compilingprocess of es2015 babel to native javascript

App.js
Here you will code your components
touch main.js index.html App.js webpack.config.js 

Configure your webpack.config.js

Open your webpack.config.js and add folling code
module.exports=
{
    entry:'./main.js',
    output:
    {
        path:'./',
        filename: 'index.js'
    },
    devServer:
    {
        inline:true,
        port:3333
    },
    module:
    {
        loaders: [
            {
                test:/\.js$/,
                exclude: /node_modules/,
                loader:'babel',
                query:
                {
                    presets:['es2015','react']
                }
            }
        ]
    }
}
- This will tell webpack to pack a index.js with all javascripts in it
- Start a webserver on port 3333
- test all .js files
- Generate native javascript from babel sources.


Load your javascript on your html page

Open your index.html and add folling snippet
<!DOCTYPE html>
<html>

<head></head>

<body>
    <div id="app"></div>
    <script src="index.js"></script>
</body>

</html>

- This will add a div with id "app" which is the container for our app
- include the webpack generated index.js

Create your first component

Open your App.js and add folling snippet
import React from 'react';
class App extends React.Component {
    render() {
        return <div> Hello World</div>
    }
}

export default App
- This will import the react library and add a class App which only renders a div with the text "Hello world"

Load your component in main.js

Open your main.js and add folling snippet
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

ReactDOM.render( < App / > , document.getElementById('app'));

- main.js is the startup file, you have configured in webpack.config.js
- This will import the react library
- Import your App component, which you have prevoiusly created
- Adds your App component to the "app" div in your html


Start your server and test your app

Open a terminal and type:
npm start 

This will start your webserver on port 3333

Surf to localhost:3333

Thats it, you have created your first simple react app.+

That's awesome !

Mittwoch, 24. August 2016

node.js: create a console command without shell scriptig on ubuntu

Shellscripting for some simple commands are the 90ies. Today we want to setup a console command without any shell scripting. Only with javascript

Prerequisits

At first, you need to have some tools installed. Here they are.
node.js installed
npm installed
$ apt-get install nodejs
$ apt-get install npm

Init your node project

To initialise your project simple type:
$ npm init

This will create your package.json

Fill your projectdata 
My package.json looks like that
{
  "name": "simplecommand",
  "version": "1.0.0",
  "description": "a simple console command",
  "main": "createUser.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/pboethig/nodejs-lessons.git"
  },
  "keywords": [
    "nodejs",
    "command"
  ],
  "author": "pboethig",
  "license": "MIT",
  "bugs": {
    "url": "https://github.com/pboethig/nodejs-lessons/issues"
  },
  "homepage": "https://github.com/pboethig/nodejs-lessons#readme"
}

Add you command script

Get you node.js path
which node
This could output:
/usr/bin/node

Create a file "createUser.js" and add the shebang to it
!#/usr/bin/env node 
This will tell the system to use node.js to execute your script

Make your script executable
chmod a+x createUser.js


Tell npm to install your command
Edit your package.json and add the bin object
{
  "name": "simplecommand",
  "version": "1.0.0",
  "description": "a simple console command",
  "main": "createUser.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/pboethig/nodejs-lessons.git"
  },
  "keywords": [
    "nodejs",
    "command"
  ],
  "author": "pboethig",
  "license": "MIT",
  "bugs": {
    "url": "https://github.com/pboethig/nodejs-lessons/issues"
  },

 "bin": {
      "createUser": "createUser.js"
    },
"homepage": "https://github.com/pboethig/nodejs-lessons#readme"


Everytime you modifiý your command, you have to run the global installer
npm install -g

Install commander

To get your command running, we need the commander library, wich does the whole parsing thing for us,
npm install --save commander

Add you command code to the scriptfile

Open your createUser.js and add a simple command
#!/usr/bin/env node

var program = require('commander');

program
    .version('0.0.1')
    .usage('<username>')
    .parse(process.argv);

if(!program.args.length) {
    program.help();
} else {
    console.log('Username: ' + program.args);   
}

As you can see, we are requiring  the commander lib, add an option "username" and parse the input on the terminal.

If no argument was set, we display the helpfile.

If the username was given, we are outputting the username. And we succeed

Instead of that simple sample, you can implement your complex logic here.

That's it. Now you can run your command after you have installed your final scriptversion
 
$ npm install -g createUser.js 
$ createUser


This will output the helpfile of your new command. Nice !


Dienstag, 23. August 2016

Symfony3: create a console command and test it

Sometimes you need an easy way to create a console command to add some automation and some admintools to your application. With Symfony3 it is rediculous simple

Install symfony3

Open a console and execute:
$ composer require symfony/symfony

Create a project

Create a project "consoletest" by executing following command on the terminal
$ symfony new consoletest.

Now you have a new project created.

Add your command

Create a file "CreateUserCommand.php" on folder "src/AppBundle/Command" and add following Code
As you can see, this simple command extends from Class Command and implements only 2 methods.
The configure command sets up the command, setup name, description and , prints out helptexts if you want

The execute method does the final work and runs your commandcode. You can manipulate databases, filesystems, get a servicereponse or configure your application with it.

Run your command

At next you can test your command by typing :
$ bin/console app:create-user

You should see your helptext,



Awsome. Isn´t it?

Create a unittest for your command

With symfony it´s very easy to test your new command. Here is a simple test for it:
- Create a folder and a file "test/Appbundle/CreateUserCommandTest.php" with following content in it

And now you can run
$ phpunit symfony