Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

getting Che to execute an imported Node.js hello world #3755

Closed
mmalyj opened this issue Jan 16, 2017 · 7 comments
Closed

getting Che to execute an imported Node.js hello world #3755

mmalyj opened this issue Jan 16, 2017 · 7 comments
Labels
kind/question Questions that haven't been identified as being feature requests or bugs.

Comments

@mmalyj
Copy link

mmalyj commented Jan 16, 2017

I am an ops guy, not a developer, trying to demo a DevOps pipeline: Eclipse Che -> committing to Github -> triggering Jenkins to build -> a new container version on Docker hub -> then deploying to Mesos. I have all the last parts working, now I am trying to add Eclipse Che at the front end.

I imported a hello world node.js app into Eclipse Che, but I don’t understand how to execute it to actually say “hello world” inside the Che GUI. Could someone help me?

Background: my node.js app consists of 3 files package.json, app.js, and Dockerfile (contents given below), in a top level subfolder called nodejs_app. I have them in my github repository https://github.com/mmalyj/nodejs_app. I was able use this code to build a container called mmalyj/nodejs_app which I loaded into Docker Hub at https://hub.docker.com/r/mmalyj/nodejs_app/. I successfully tested this nodejs app it from my CentOS 7.2 command prompt with these commands:

$ cd nodejs_app
$ docker run -d --name node_app_test -p 8000:8000 mmalyj/nodejs_app:${version}
$ curl -s GET http://127.0.0.1:8000 | grep Hello

I have shell scripts with these commands working from Jenkins, and am able to successfully deploy the app to Mesos and pull up the resulting “Hello World” from a browser. Finally, I was able to import my github project with my scripts and Node.js files into my Eclipse Che 5.0.1. Here is a screenshot:

nodejs_appimportedinche
But I have no clue how to execute my imported node.js code inside Eclipse Che! Could someone please tell me how to do that? I am expecting to run a CMD command somewhere that will give me a working link to http://127.0.0.1:8000 that will say “Hello World”.

I used “Stack Authoring” when I created my Che workspace, and I specified:

FROM mmalyj/nodejs_app:21
EXPOSE 8000

Here are my three node.js files, taken from Pini Reznik’s sample in the Docker Cookbook http://www.integratedbook.com/docker-cookbook/, section 10.1:

//package.json
{
        "name": "hello-world",
        "description": "hello world",
        "version": "0.0.1",
        "private": true,
        "dependencies": {
                "express": "3.x"
        },
        "scripts": {"start": "node app.js"}
}
//app.js
// Load the http module to create an http server.
var http = require('http');
// Configure our HTTP server to respond with Hello World to all requests.
var server = http.createServer(function (request, response) {
        response.writeHead(200, {"Content-Type": "text/plain"});
        response.end("Hello World 30");
});
// Listen on port 8000, IP defaults to "0.0.0.0"
server.listen(8000);
// Put a friendly message on the terminal
console.log("Server running at http://127.0.0.1:8000/");
//Dockerfile
FROM google/nodejs
WORKDIR /app
ADD package.json /app/
RUN npm install
ADD . /app
EXPOSE 8000
CMD []
ENTRYPOINT ["/nodejs/bin/npm", "start"]

Che version: 5.0.1
OS and version: CentOS 7.2
Docker version: 1.12.6

~ Mark

@TylerJewell TylerJewell added the kind/question Questions that haven't been identified as being feature requests or bugs. label Jan 16, 2017
@TylerJewell
Copy link

Hi @mmalyj - so let me break down your question into two parts. There is the answer that is going to require you to make a couple modifications, but will get you up and running faster. And then there is the much more complicated answer.

After you have your worksapce running and your project source code imported into the workspace, you then interact with the code by using either a terminal or a command. A terminal is what you think it is - command line interface to the terminal. You can then run processes directly on the command line including starting Node as you would normally on any other OS. You could do this with either npm or other node commands.

However, running the server on the terminal will not give you the URL for which you access that server. Thus a "Command". Commands are currently edited in the toolbar. You'll see them in the middle and you can add new commands. Commands are processes that get sent to the workspace to run. It's like what you would do in a terminal, but commands have extra logic in them including macros for automatically determining the URL that you then need to access. So, you want to add a command and then edit it.

Within a Command is a preview URL. Preview URLs can include macros in them. When the user picks a command to run, we execute the macros and then dynamically determine the URL of the server that was started by interpreting the macros within the preview.

This makes sense. Inside of your workspace, you may start a service on port 900. That port is internal to the Docker container powering your workspace. Docker then maps that server on port 900 to a port in the ephemeral range starting at 32768. This ephemeral port changes on your because there could be many containers all running servers on port 900. So, the URL for the end user to get to your Node server is of the format http://<workspace-ip-address>:<ephemeral-port-assigned-by-docker>.

Our Preview URLs will dynamically generate the right IP address and port from the macros.

Commands: https://www.eclipse.org/che/docs/ide/commands/index.html
Previews: https://www.eclipse.org/che/docs/ide/previews/index.html

It's difficult to give you an example, so we would encourage you to just pick our Node stack, create a new workspace, and pick our example Node project app template from within that. In that sample, there are commands that have previews configured with the right macros. If you see how they work, then you can do your own quite easily. It seems hard, but it's quite simple.

BTW, this entire command and preview editing is about to get a major overhaul. You can see a long lived epic we have called "Intelligent Commands". All of these commands are getting their own file editor, so much the way you have text files for code, we have something similar for commands coming, and there is even intellisense for previews and macros in it!

Now, here is the complicated part. You specifically said that you want your end users to do "docker run ... " inside of the workspace. In the example that I gave above, the command would be embedded in the workspace and run Node directly as a process. This is all well in good because we are launching a native Node app inside of a workspace which is a docker container.

But if you want your end users to use "docker run ... " syntax as a command, then we are in a situation where you have a Docker-powered workspace with a command that launches another Docker container inside of it. So it's either Docker-in-Docker ... OR ... setting up Che's workspaces so that they have direct access to the Docker Daemon AND making sure your workspaces have a Docker client in their recipe. These are both possible, and we have documentaiton on how to set this up. But it's not straight forward right now. The setup for doing this is the same setup that we do for how we develop Che in Che because in that situation we get into Docker inside of Docker inside of Docker (you get the idea).

My recommendation would be to get the system working first without the Docker in Docker. and then if you want to advance to a more sophisticated deployment, then set up these extra parameters.

https://www.eclipse.org/che/docs/tutorials/che-in-che/index.html

@mmalyj
Copy link
Author

mmalyj commented Jan 17, 2017

Tyler, thanks for the detailed reply. I was hoping for something easier, since I don’t know node.js or that much about Eclipse Che.

It may take a while to get back to this, then I’ll try reverse engineering what you have inside one of your sample Node projects, like you suggest.

(FYI, sorry for the confusion, but I don’t need “end users to do docker run ... inside of the workspace”. Instead, my “docker run” command, and also a “docker build” that I forgot to mention, occur within the scripts that Jenkins runs to build a new version of the production container and inject the latest Node code into it, then another script that does a simple level container test.)

My goal here is to show my developers how to create a workspace from dev versions of existing production containers, then import existing code into the workspace, and finally get the code to execute within Eclipse Che, so that they can use it for development going forward. This could be useful to other companies who are transitioning to Eclipse Che and Codenvy.

~ Mark

@TylerJewell
Copy link

I would expect this shouldn't take you more than 15 minutes or so. It sounds rather complicated if you have to explain it all on GitHub. If you launch one of the sample workspaces that are provided within Che and then open up their built-in commands, the syntax around commands and previews becomes really easy. Almost a head slap.

Now, this does assume that you have the right syntax for how to start Node as your developers normally do within the container. So there is usually some sort of 'node ' that you would need anyways, as that is what we are running inside of the workspace container.

@ghost
Copy link

ghost commented Jan 17, 2017

@mmalyj it should be as easy as creating the following command:

image

Just change the port:

image

@mmalyj
Copy link
Author

mmalyj commented Jan 17, 2017

@eivantsov I went your way and created a CMD called nodejs_app:run with
Command line = cd ${current.project.path}/nodejs_app && node app.js
Preview URL = http://${server.port.8000}

But when I click right arrow to run it, I get this error in the output window:

command: cd /projects/myproject/nodejs_app && node app.js
preview: http://172.17.0.1:32778
Server running at http://127.0.0.1:8000/
events.js:141
throw er; // Unhandled 'error' event
^
.
Error: listen EADDRINUSE :::8000
at Object.exports._errnoException (util.js:874:11)
at exports._exceptionWithHostPort (util.js:897:20)
at Server._listen2 (net.js:1234:14)
at listen (net.js:1270:10)
at Server.listen (net.js:1366:5)
at Object. (/projects/myproject/nodejs_app/app.js:9:8)
at Module._compile (module.js:435:26)
at Object.Module._extensions..js (module.js:442:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:311:12)

Then when I click on the preview link http://172.17.0.1:32778, I am expecting “Hello World 30” from my app.js, but instead it pulls up a web page that says “Hello World 21”. The 21 is coming from my Stack Authoring definition for my workspace, which is currently (in the Workspace Config "content" tag):

FROM mmalyj/nodejs_app:21
EXPOSE 8000
USER root
CMD tail -f /dev/null

with mmalyj/nodejs_app:21 being a Docker hub container with an embedded app.js that is coded to say "Hello World 21”.

Why is it telling me EADDRINUSE :::8000 ? Am I messing up with my Workspace Config "content tag" ?

FYI, @bmicklea told me to use a dev image for the workspace that is inherited from the prod image. I didn't think I needed any extra node.js tools for the dev image to do this simple demo, so I'm using an older prod image (21) to be my dev image. I built the mmalyj/nodejs_app:21 container with the following docker build command which refers to the package.json, and app.js (with Hello 21 in it) given above, and the following Dockerfile:

cd ~/dockerwork/nodejshello/nodejs_app 
$docker build -t mmalyj/nodejs_app:21 .
//Dockerfile
FROM google/nodejs
WORKDIR /app
ADD package.json /app/
RUN npm install
ADD . /app
EXPOSE 8000
CMD []
ENTRYPOINT ["/nodejs/bin/npm", "start"]

@mmalyj
Copy link
Author

mmalyj commented Jan 18, 2017

I figured out that creating my workspace FROM mmalyj/nodejs_app:21 was resulting in port 8000 being already bound from the v21 version of the app that was installed into that container.

I fixed my problem by stopping my workspace, then I changed the Workspace Config "content" to instead use the container that underlies mmalyj/node_app:21

FROM google/nodejs
WORKDIR /app
EXPOSE 8000
USER root
CMD tail -f /dev/null

When I started the workspace again, I found the "Use latest snapshot" box and unchecked it. I ran the CMD that @eivantsov recommended, and no errors! The preview link then opened up a browser window with "Hello World 30" as I have in my app.js code.

Thank you @TylerJewell @eivantsov @bmicklea !!

@mmalyj mmalyj closed this as completed Jan 18, 2017
@TylerJewell
Copy link

Nice work, @mmalyj - you are now definitely getting some advanced experience in the world of Docker now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/question Questions that haven't been identified as being feature requests or bugs.
Projects
None yet
Development

No branches or pull requests

2 participants