I'm pretty new to Docker, so I'm trying to take a node web app that I've written and Docker-ize it. The app is open source, so you can find it and the Dockerfile here: Paw-Wars
So you don't have to click through, the Dockerfile is here:
FROM mhart/alpine-node
WORKDIR /src
ADD . .
RUN npm install
EXPOSE 5050
COPY config.json /src/config.json
CMD npm run docker
So I open up the Docker Quickstart Terminal (I'm on Mac OS X), go to my path, and build it:
docker build -t paw-wars .
After it builds, I run it:
docker run paw-wars
And it spins up just fine and says it's listening on port 5050. I get the ip from docker-machine ip default, and try to connect to it on port 5050, but I get connection refused. Most searches I've done trying to solve this tell me that I need to make sure to use the correct IP, but I'm almost positive I'm doing that. Not really sure what I'm doing wrong. It's not in the repo, but I've also tried binding to 0.0.0.0 in my app (index.js), but that didn't work either.
Thanks!
The issue is that you MUST specify a port in your docker run command. I thought that using EXPOSE in your dockerfile is sufficient, but it's not. That's just to get the port exposed internally.
docker run -p 5050:5050 paw-wars worked great.
Related
I've cloned the following dockerized MEVN app and would like to access it from another PC on the local network.
The box that docker is running on has an ip of 192.168.0.111 but going to http://192.168.0.111:8080/ from another PC just says it can't be reached. I run other services like plex and a minecraft server that can be reached with this ip so I assume it is a docker config issue. I am pretty new to docker.
Here is the Dockerfile for the poral. I made a slight change from the repo adding -p 8080:8080 because I read elsewhere that it would open it up to lan access.
FROM node:16.15.0
RUN mkdir -p /usr/src/www &&
apt-get -y update &&
npm install -g http-server
COPY . /usr/src/vue
WORKDIR /usr/src/vue
RUN npm install
RUN npm run build
RUN cp -r /usr/src/vue/dist/* /usr/src/www
WORKDIR /usr/src/www
EXPOSE 8080
CMD http-server -p 8080:8080 --log-ip
Don't put -p 8080:8080 in the Dockerfile!
You should first build your docker image using docker build command.
docker build -t myapp .
once you've built the image, and confirmed using docker images you can run it using docker run command
docker run -p 8080:8080 myapp
Docker listens 0.0.0.0 IP address and the other machines on the same network can use your ip address to show your website on which port did you use for sharing. For example you use 8080 and actually you listen 0.0.0.0:8080 and the other machines http://192.168.0.111:8080/ can reach that website with your ip address. Without docker you can also listen 0.0.0.0 to share your app on network.
The box that docker is running on
What u mean by saying "BOX"? Is it some kind of virtual box or maybe actual computer with Linux or Windows or maybe MacOS?
Have u checked particular "BOX"'s firewall? (u may need to do "NAT" over firewall to particular in "BOX" running service for incoming requests from outside of "BOX").
I'll be happy to help u our if u'll provide more detailed information about your environment...
I have searched around without much luck, or maybe because I'm too noob, but I this project online on github, https://github.com/bradtraversy/react_express_starter, and I have tried to make it so it can run with docker, but it doesn't seem like it don't want to work, in the docker terminal it says that the server is started and the react app at localhost:3000 but nothing shows up when I paste it into the browser, not even the server and api is accessable, so I figured it has to be something with the docker file.I place the dockerfile in the project folder.
My dockerfile says
FROM node:latest
WORKDIR /app
COPY package.json ./
RUN npm install
CMD npm run client-install
COPY . .
EXPOSE 3000
CMD npm run dev
and I build it by "docker build -t project ." and then run it with "docker run -p 5000:5000 project"
thank you in advance
screenshot of whats happening
EDIT: OK, I have made the server working, it turns out that docker machine has another ip than localhost, so port 5000 work as well as api call, but the react part doesn't show up on port 3000?
It looks like you're mising EXPOSE as apart of your dockerfile. This can be done right before
CMD npm run dev
like so
EXPOSE 3000
The internal port is 3000 - you need to make that available externally (on the host machine). Move EXPOSE 3000 before the CMD, then docker run -p 5000:3000 project should make your docker container available as localhost:5000/.
I have a NodeJS/Vue app that I can run fine until I try to put it in a Docker container. I am using project structure like:
When I do npm run dev I get the output:
listmymeds#1.0.0 dev /Users/.../projects/myproject
webpack-dev-server --inline --progress --config build/webpack.dev.conf.js
and then it builds many modules before giving me the message:
DONE Compiled successfully in 8119ms
I Your application is running here: http://localhost:8080
then I am able to connect via browser at localhost:8080
Here is my Dockerfile:
FROM node:9.11.2-alpine
RUN mkdir -p /app
WORKDIR /app
COPY package.json /app
RUN npm install
COPY . /app
CMD npm run dev
EXPOSE 8080
I then create a docker image with docker build -t myproject . and see the image listed via docker images
I then run docker run -p 8080:8080 myproject and get a message that my application is running here: localhost:8080
However, when I either use a browser or Postman to GET localhost:8080 there is no response.
Also, when I run the container from the command line, it appears to lock up so I have to close the terminal. Not sure if that is related or not though...
UPDATE:
I trying following the Docker logs such as
docker logs --follow
and there is nothing other than the last line that my application is running on localhost:8080
This would seem to indicate that my http requests are never making into my container right?
I also tried the suggestion to
CMD node_modules/.bin/webpack-dev-server --host 0.0.0.0
but that failed to even start.
It occurred to me that perhaps there is a Docker network issue, perhaps resulting in an earlier attempt at kong api learning. So I run docker network ls and see
NETWORK ID NAME DRIVER SCOPE
1f11e97987db bridge bridge local
73e3a7ce36eb host host local
423ab7feaa3c none null local
I have been unable to stop, disconnect or remove any of these networks. I think the 'bridge' might be one Kong created, but it won't let me whack it. There are no other containers running, and I have deleted all images other than the one I am using here.
Answer
It turns out that I had this in my config/index.js:
module.exports = {
dev: {
// Various Dev Server settings
host: 'localhost',
port: 8080,
Per Joachim Schirrmacher excellent help, I changed host from localhost to 0.0.0.0 and that allowed the container to receive the requests from the host.
With a plain vanilla express.js setup this works as expected. So, it must have something to do with your Vue application.
Try the following steps to find the source of the problem:
Check if the container is started or if it exits immediately (docker ps)
If the container runs, check if the port mapping is set up correctly. It needs to be 0.0.0.0:8080->8080/tcp
Check the logs of the container (docker logs <container_name>)
Connect to the container (docker exec -it <container_name> sh) and check if node_modules exists and contains all
EDIT
Seeing your last change of your question, I recommend starting the container with the -dit options: docker run -dit -p 8080:8080 myproject to make it go to the background, so that you don't need to hard-stop it by closing the terminal.
Make sure that only one container of your image runs by inspecting docker ps.
EDIT2
After discussing the problem in chat, we found that in the Vue.js configuration there was a restriction to 'localhost'. After changing it to '0.0.0.0', connections from the container's host system are accepted as well.
With Docker version 18.03 and above it is also possible to set the host to 'host.docker.internal' to prevent connections other than from the host system.
I downloaded the official docker httpd container, but by default it maps my port 32770 to its port 80. i want that whenever i start the container, it listens on my port 80 -> 80.
is there any command line argument at docker startup to give or i can hard-coded this mapping in docker?
I tried to run it with "docker run " command , but every time it starts a new instance of it, and i lose my changes that i made to the docker container i want to use. how can i retain the port mapping changes?
You want to publish the port from the container to the host, as Thilo says the httpd image already exposes port 80 so you can publish it.
This command maps port 80 and runs the web server in the background:
docker run -d -p 80:80 httpd
Now you can browse to http://localhost and see the "It works!" page.
docker run is a shortcut for docker create + docker start, so it always creates a new container from the image. If you want to make changes to a container and preserve them, either use commit or a Dockerfile to create your own image based on httpd - preferably the Dockerfile, because it's easier to manage and automate. Then you'll have a custom website image that will always be the same when you run it.
You should create your own docker image based on the httpd official image. Then expose the port you want to map (EXPOSE 80) https://docs.docker.com/engine/reference/builder/#/expose it should do what you want.
It will give something like :
FROM httpd
EXPOSE 80
build : docker build -t test .
run : docker run test :)
I am completely stuck on the following.
Trying to setup a express app in docker on an Azure VM.
1) VM is all good after using docker-machine create -driver azure ...
2) Build image all good after:
//Dockerfile
FROM iojs:onbuild
ADD package.json package.json
ADD src src
RUN npm install
EXPOSE 8080
CMD ["node", "src/server.js"]
Here's where I'm stuck:
I have tried all of the following plus many more:
• docker run -P (Then adding end points in azure)
• docker run -p 80:8080
• docker run -p 80:2756 (2756, the port created during docker-machine create)
• docker run -p 8080:80
If someone could explain azure's setup with VIP vs internal vs docker expose.
So at the end of all this, every port that I try to hit with Azure's:
AzureVirtualIP:ALL_THE_PORT
I just always get back a ERR_CONNECTION_REFUSED
For sure the express app is running because I get the console log info.
Any ideas?
Thanks
Starting from the outside and working your way in, debugging:
Outside Azure
<start your container on the Azure VM, then>
$ curl $yourhost:80
On the VM
$ docker run -p 80:8080 -d laslo
882a5e774d7004183ab264237aa5e217972ace19ac2d8dd9e9d02a94b221f236
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
64f4d98b9c75 laslo:latest node src/server.js 5 seconds ago up 5 seconds 0.0.0.0:80->8080 something_funny
$ curl localhost:80
That 0.0.0.0:80->8080 shows you that your port forwarding is in effect. If you run other containers, don't have the right privileges or have other networking problems, Docker might give you a container without forwarding the ports.
If this works but the first test didn't, then you didn't open the ports to your VM correctly. It could be that you need to set up the Azure endpoint, or that you've got a firewall running on the VM.
In the container
$ docker run -p 80:8080 --name=test -d laslo
882a5e774d7004183ab264237aa5e217972ace19ac2d8dd9e9d02a94b221f236
$ docker exec it test bash
# curl localhost:8080
In this last one, we get inside the container itself. Curl might not be installed, so maybe you have to apt-get install curl first.
If this doesn't work, then your Express server isn't listening on port 80, and you need to check the setup.