Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot Compile the typescript in Docker

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.

like image 672
Andy Avatar asked Jul 09 '16 09:07

Andy


2 Answers

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"]
like image 74
Nguyen Sy Thanh Son Avatar answered Nov 19 '22 18:11

Nguyen Sy Thanh Son


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.

like image 2
Augie Gardner Avatar answered Nov 19 '22 18:11

Augie Gardner