6

I want to use typescript in my node.js Web Server. However, the Web Sever is in a Docker Container. I use the the Dockerfile like the blow:

FROM node:latest
COPY code/ /usr/local/lib
WORKDIR /usr/local/lib

RUN npm install -g koa@2
RUN npm install -g sequelize
RUN npm install -g mysql
RUN npm install -g typescript

CMD ["sh", "-c", "rm", "webApp.js"]
CMD ["sh", "-c", "tsc", "webApp.ts"]
CMD ["node", "webApp.js"]

After I build my Docker, I find that, no webApp.js is generated after the CMD commands. Why, and How should I solve it? Thanks.

humblebee
  • 1,044
  • 11
  • 25
Andy
  • 161
  • 1
  • 3
  • 9

3 Answers3

2

In the best practice when you create a Dockerfile, you should only user one CMD and one ENTRYPOINT.

In your case, It should be:

COPY code/ /usr/local/lib
WORKDIR /usr/local/lib

RUN npm install -g koa@2
RUN npm install -g sequelize
RUN npm install -g mysql
RUN npm install -g typescript

RUN sh -c rm webApp.js
RUN sh -c tsc webApp.ts
CMD ["node", "webApp.js"]
Nguyen Sy Thanh Son
  • 5,300
  • 1
  • 23
  • 33
  • Thanks, it works for me. Though js file still can not be seen in my folder outside the Dockers, I think the reason is: the cache not flush at the immediate time. – Andy Jul 09 '16 at 15:15
  • The js file is generated in the Container, so it is saved in the new created Container. If you want have it outside you must run the container with a volume. – Julian Jul 09 '16 at 18:59
1

Great start!

You can check out how I accomplish this in my GitHub Docker/NodeJS/Typescript starter project

As another answer noticed, you should only use one CMD command, so instead of using that CMD, you should use RUN sh -c tsc webApp.ts. That will compile your Typescript using the tsc command-line tool that you previously installed on the container using RUN npm install -g typescript.

After doing this and running your Dockerfile, you may expect to see webApp.js in your working folder (the folder that hosts your Dockerfile) now, but you actually won't see it. The container sees it, but you don't. What's going on?

When you run these commands from your Dockerfile, you're actually running them inside the container which lives in a special secluded part of your machine. That secluded part of your machine, and the part of your machine that hosts the Dockerfile, are two completely separate places. Therefore you won't see that generated .js file.

Thankfully, Docker has a way of "mounting" or mirroring files between these two parts of your machine. This is called a "volume".

There's a good StackOverflow answer on volumes. The volume syntax is like this from within your dockerfile: ADD . /path/inside/docker/container. The command is structured like this: ADD {my_filepath} {container_filepath}. It means that whatever is on your machine at {my_filepath} will now be "mounted" or mirrored into the container at the path {container_filepath}.

ADD . . would mount your current working directory to the container's main working directory.

Augie Gardner
  • 2,749
  • 3
  • 25
  • 36
0

I think the problem is the sh -c. When you type in sh -c echo test in your console there will be no output. When you type sh -c "echo test" or only echo test it will work. Thats because only the first argument will be executed (Take a look in man sh).

But besides this it is not necessary. CMD ["rm", "webApp.js"] will do what you want. And if you want it to be executed by bash/sh you can use the string syntax CMD rm webApp.js

Julian
  • 2,724
  • 1
  • 15
  • 21
  • I am sorry for your method didn't work. It is not the Command format's problem, I don't know how, but the another answer works for me. Still thanks for your kindness. – Andy Jul 09 '16 at 15:22
  • Yes, the answer of Nguyen Sy Thanh Son is right. The CMD get overwitten by the other ones – Julian Jul 09 '16 at 19:01