I have a running service within a container on my localhost machine
I Can't establish a connection with it even though I specified the port mapping within my docker-compose.yml here it is
version: '2.1'
services:
users-db:
container_name: users-db
build: ./services/users-service/src/db
ports:
- '27017:27017'
volumes:
- './services/users-service/src/db/:/data/db'
users-service:
container_name: users-service
build: './services/users-service/'
volumes:
- './services/users-service:/usr/src/app'
- './services/users-service/package.json:/usr/src/package.json'
ports:
- '3000:3000'
environment:
- NODE_ENV=test
- JWT_SECRET=fuckOffChinese
depends_on:
users-db:
condition: service_started
presence_db:
image: redis
presense_service:
container_name: presense_service
build: './services/presence-service/'
ports:
- "8081:8081"
environment:
- JWT_SECRET=thirdEyeSecret
- PORT=8081
volumes:
- './services/presence-service:/usr/src/app'
- './services/presence-service/package.json:/usr/src/package.json'
depends_on:
- presence_db
this is the command that I use to run this service
docker-compose run presense_service
and this is what I get every time I try to ping it from the terminal by simply doing an HTTP GET request
http: error: ConnectionError: HTTPConnectionPool(host='localhost', port=8081): Max retries exceeded with url: / (Caused by
NewConnectionError(': Failed to establish a new connection: [Errno
61] Connection refused',)) while doing GET request to URL:
http://localhost:8081/
I'm running macOS 10.13.5 and the server start noramally and here is the logs of it
> users-service#1.0.0 start /usr/src
> gulp --gulpfile app/gulpfile.js
[10:12:46] Working directory changed to /usr/src/app
[10:12:52] Using gulpfile /usr/src/app/gulpfile.js
[10:12:52] Starting 'start'...
[10:12:56] Finished 'start' after 3.99 s
[10:12:56] Starting 'lint'...
[10:12:57] Finished 'lint' after 239 ms
[10:12:57] Starting 'default'...
[10:12:57] Finished 'default' after 131 μs
[10:12:57] [nodemon] 1.18.2
[10:12:57] [nodemon] to restart at any time, enter `rs`
[10:12:57] [nodemon] watching: *.*
[10:12:57] [nodemon] starting `node ./index.js`
Server listening on: http://localhost:8081
Redis client connected
Try docker-compose run presense_service --service-ports, or better, use docker-compose up.
docker-compose run specifically doesn't apply the ports from your Compose file to "prevent port collisions with already-open ports" [1] - so you have to add this option, or specify them manually with the same options you would pass to docker run.
Ideally, use docker-compose up -d and then docker-compose logs -f presense_service to get logs. Shut your application down with docker-compose down.
If you really need to, you can comment services out of your docker-compose.yml file that you don't want started.
If you didn't know, the latest version of the compose format is 3.6 - 2.1 is over two years old (released with Docker v1.12.0 on 201607/28 [2]).
Proving this is easy - since I didn't have your code, I replaced all the image/build lines with image: nginx (and took the host path off any volumes).
Example modified compose file (just for reference):
version: '2.1'
services:
users-db:
container_name: users-db
image: nginx
ports:
- '27017:27017'
volumes:
- './services/users-service/src/db/:/data/db'
users-service:
container_name: users-service
image: nginx
volumes:
- '/usr/src/app'
- '/usr/src/package.json'
ports:
- '3000:3000'
environment:
- NODE_ENV=test
- JWT_SECRET=fuckOffChinese
depends_on:
users-db:
condition: service_started
presence_db:
image: redis
presense_service:
container_name: presense_service
image: nginx
ports:
- "8081:8081"
environment:
- JWT_SECRET=thirdEyeSecret
- PORT=8081
volumes:
- '/usr/src/app'
- '/usr/src/package.json'
depends_on:
- presence_db
Running docker ps after docker-compose up -d gives this (pay attention to the PORTS column):
my-machine$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f1b89cf3d6c2 nginx "nginx -g 'daemon of…" 19 seconds ago Up 14 seconds 80/tcp, 0.0.0.0:3000->3000/tcp users-service
be0e9b2bb005 nginx "nginx -g 'daemon of…" 19 seconds ago Up 13 seconds 80/tcp, 0.0.0.0:8081->8081/tcp presense_service
2efed2546926 nginx "nginx -g 'daemon of…" 20 seconds ago Up 14 seconds 80/tcp, 0.0.0.0:27017->27017/tcp users-db
c7a88a84f422 redis "docker-entrypoint.s…" 20 seconds ago Up 14 seconds 6379/tcp test_presence_db_1
...so there's nothing wrong with your port configuration. docker ps after docker-compose run presense_service, then, shows:
my-machine$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
89e4a4f90a75 nginx "nginx -g 'daemon of…" 28 seconds ago Up 21 seconds 80/tcp test_presense_service_run_1
2c91fcb5091d redis "docker-entrypoint.s…" 29 seconds ago Up 24 seconds 6379/tcp test_presence_db_1
...and therefore it was your command causing the problem. Happy to help as I've learnt something new :)
[1] https://docs.docker.com/compose/reference/run/
[2] https://docs.docker.com/release-notes/docker-engine/#1120-2016-07-28
Try this to find out if port 8081 is open/occupied:
netstat -l | grep 8081
When your server logs say
Server listening on: http://localhost:8081
The server will be inaccessible outside the Docker container. It looks like this is the default behavior of the Express JavaScript Web server, and many other frameworks when run in “developer” mode. You need to set the server to listen on all IP addresses, probably by passing 0.0.0.0 as the “bind” address. (Note that you cannot connect to 0.0.0.0, and saying “listen to 0.0.0.0” means “accept connections from anywhere”.
If your server is in fact based on Express, https://superuser.com/questions/582624/how-to-access-nodejs-server-on-lan might be informative to you.
Related
I'm trying to learn how to understand node containers within a docker-compose environment.
I've built a simple docker container using a nodejs alpine base container. My container has a simple hello world express server. This container has been pushed to the public docker hub repo, zipzit/node-web-app
Container works great from the command line, via docker run -p 49160:8080 -d zipzit/node-web-app
Function verified via browser at http://localhost:49160
After the command line above is run, I can shell into the running container via $ docker exec -it <container_id> sh
I can look at the directories within the running docker container, and see my server.js, package.json files, etc...
From what I can tell, from the command line testing, everything seems to be working just fine.
Not sure why, but this is a total fail when I try to use this in a docker-compose test.
version: "3.8"
services:
nginx-proxy:
# http://blog.florianlopes.io/host-multiple-websites-on-single-host-docker
image: jwilder/nginx-proxy
container_name: nginx-proxy
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
restart: always
mongo_db:
image: mongo
ports:
- "27017:27017"
volumes:
- ./data:/data/db
restart: on-failure:8
environment:
MONGO_INITDB_ROOT_USERNAME: root
MONGO_INITDB_ROOT_PASSWORD: mongo_password
react_frontend:
image: "zipzit/node-web-app"
## working_dir: /usr/src/app ## remarks on / off here testing all the combinations
## environment:
## - NODE_ENV=develop
ports:
- "3000:3000"
volumes:
- ./frontend:/usr/src/app
backend_server:
## image: "node:current-alpine3.10"
image: "zipzit/node-web-app"
user: "node"
working_dir: /usr/src/app
environment:
- NODE_ENV=develop
ports:
- "8080:8080"
volumes:
- ./backend:/usr/src/app
- ./server_error_log:/usr/src/app/error.log
links:
- mongo_db
depends_on:
- mongo_db
volumes:
frontend: {}
backend: {}
data: {}
server_error_log: {}
When I run docker-compose up -d, and then let things settle, the two containers based on zipzit/node-web-app start to run and immediately shut down.
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
92710df9aa89 zipzit/node-web-app "docker-entrypoint.s…" 6 seconds ago Exited (1) 5 seconds ago root_react_frontend_1
48a8abdf02ca zipzit/node-web-app "docker-entrypoint.s…" 8 minutes ago Exited (1) 5 seconds ago root_backend_server_1
27afed70afa0 jwilder/nginx-proxy "/app/docker-entrypo…" 20 minutes ago Up 20 minutes 0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp nginx-proxy
b44344f31e52 mongo "docker-entrypoint.s…" 20 minutes ago Up 20 minutes 0.0.0.0:27017->27017/tcp root_mongo_db_1
When I go to docker logs <container_id> I see:
node:internal/modules/cjs/loader:903
throw err;
^
Error: Cannot find module '/usr/src/app/server.js'
at Function.Module._resolveFilename (node:internal/modules/cjs/loader:900:15)
at Function.Module._load (node:internal/modules/cjs/loader:745:27)
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:72:12)
at node:internal/main/run_main_module:17:47 {
code: 'MODULE_NOT_FOUND',
requireStack: []
}
When I check out the frontend volume, its totally blank. No server.js file, nothing.
Note: I'm running the docker-compose stuff on a Virtual Private Server (VPS) Ubuntu server. I built the container and did my command line testing on a Mac laptop with docker. Edit: I went back and did complete docker-compose up -d testing on the laptop with exactly the same errors as observed in the Virtual Private Server.
I don't understand what's happening here. Why does that container work from the command line but not via docker-compose?
You are binding volumes in ./frontend or ./backend with the same image running the following command:
CMD ["node" "server.js"]
Are you sure this is the right command ? Are you sure there is a server.js in each folder mounted on your host ?
Hope this helps.
Looks like you're trying to mount local paths into your containers, but you're then declaring those paths as volumes in the compose file.
The simple solution is to remove the volumes section of your compose file.
Here's the reference - it's not very clear from the docs but basically when you mount a volume, docker-compose first looks for that volume in the volumes section, and if it is present uses that volume. The name of the volume is not treated as a local path in this scenario, it is an ID of a volume that is then created on the fly (and will be empty). If however the volume is not declared in volumes, then it is treated as a local path and mounted as such.
I trying to implement a dockerized mongo/node based app by this article.
docker-compose.yml
version: '3'
services:
gecar_app:
build:
context: .
dockerfile: Dockerfile.gecars
restart: always
ports:
- 3000:3000
depends_on:
- mongo
command: /usr/app/initAndStartService.sh
mongo:
container_name: mongo
image: mongo
volumes:
- ./data:/data/db
ports:
- "27017:27017"
Dockerfile.gercars
FROM node:latest
RUN mkdir -p /usr/app
WORKDIR /usr/app
COPY src/ /usr/app/src/
COPY package.json /usr/app/package.json
COPY webpack.config.js /usr/app/webpack.config.js
COPY tsconfig.json /usr/app/tsconfig.json
COPY initAndStartService.sh /usr/app/initAndStartService.sh
RUN yarn
RUN yarn build
RUN ["chmod", "+x", "/usr/app/initAndStartService.sh"]
initAndStartService.sh
#!/bin/sh
curl 127.0.0.1:27017
but when run docker-compose up get this:
mongo | 2019-11-19T06:13:21.682+0000 I NETWORK [initandlisten] Listening on 0.0.0.0
mongo | 2019-11-19T06:13:21.683+0000 I NETWORK [initandlisten] waiting for connections on port 27017
...................
gecar_app_1 | Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0curl: (7) Failed to connect to 127.0.0.1 port 27017: Connection refused
If I recognize the situation correctly, gecar_app_1 container cant reachmongo` container.
depends_on
Express dependency between services, Service dependencies cause the
following behaviors:
docker-compose up starts services in dependency order. In the following example, db and redis are started before web.
docker-compose up SERVICE automatically includes SERVICE’s dependencies. In the following example, docker-compose up web also
creates and starts db and redis.
docker-compose stop stops services in dependency order. In the following example, web is stopped before db and redis.
in other words, when you want to communicate with the mongo container, all you have to do is to call it as mongo based on your container service naming.
So curl mongo:27017 from the gecar_app container will do the trick
127.0.0.1 is a loopback address, this mean, when you run curl 127.0.0.1:27017 on gecar_app container, you try to connect to itself, but gecar_app did not have any service running on 27017 port. What you need to connect is mongo service (I think so).
You use depends_on to wait until the mongo service started, then start the gecar_app container (good point), now mongo will be come to a hostname, and gecar_app can connect to mongo via mongo "domain".
But, gecar_app maybe started before mongodb service already, then you have make sure that when mongo service already. You can use healthcheck property to do that.
Finally,
docker-compose.yml
version: '3'
services:
gecar_app:
build:
context: .
dockerfile: Dockerfile.gecars
restart: always
ports:
- 3000:3000
depends_on:
- mongo
command: /usr/app/initAndStartService.sh
mongo:
container_name: mongo
image: mongo
volumes:
- ./data:/data/db
ports:
- "27017:27017"
healthcheck:
test: echo 'db.runCommand("ping").ok' | mongo mongo:27017/test --quiet 1
interval: 3s
timeout: 5s
retries: 5
and, initAndStartService.sh
#!/bin/sh
curl mongo:27017
I am not able to connect to my mongoDB instance through the client such as Robot 3T. It doesn't even give a chance to authenticate.
Here is my docker-compose file:
version: '3'
services:
frontend:
build:
context: panel_front_end/
ports:
- 8080:80
environment:
- NODE_ENV=local
restart: always
networks:
- nginx_network
backend:
build:
context: panel_back_end/
args:
- SSH_PRIVATE_KEY
environment:
- NODE_ENV=local
- HTTPS=true
ports:
- "3000:3000"
- "8443:8443"
volumes:
- ./panel_back_end/ssl:/usr/src/app/ssl
restart: always
networks:
- nginx_network
depends_on:
- mongodb
links:
- mongodb
mongodb:
build:
context: mongo/
ports:
- "27017:27017"
expose:
- 27017
volumes:
- ./data/db:/data/db
- ./backup:/backup
environment:
# provide your credentials here
- MONGODB_ADMIN_USER=${MONGODB_ADMIN_USER}
- MONGODB_ADMIN_PASS=${MONGODB_ADMIN_PASS}
- MONGODB_APPLICATION_DATABASE=${MONGODB_APPLICATION_DATABASE}
- MONGODB_APPLICATION_USER=${MONGODB_APPLICATION_USER}
- MONGODB_APPLICATION_PASS=${MONGODB_APPLICATION_PASS}
networks:
nginx_network:
external: true
I dodocker ps and this is the output:
ef695029ff3f control-panel_backend "/bin/sh -c ./entryp…" 5 minutes ago Restarting (1) 22 seconds ago control-panel_backend_1
d397eac69a70 control-panel_frontend "/bin/sh -c ./entryp…" 5 minutes ago Up 5 minutes 0.0.0.0:8080->80/tcp control-panel_frontend_1
48ee29caee6a control-panel_mongodb "docker-entrypoint.s…" 5 minutes ago Up 5 minutes 0.0.0.0:27017->27017/tcp control-panel_mongodb_1
5514f5e97a65 mysql/mysql-server:5.7 "/entrypoint.sh mysq…" 2 days ago Up 2 days (healthy) 0.0.0.0:3306->3306/tcp, 33060/tcp mysql-migration
The client gives me this:
It doesn't even gives the chance to authenticate the credentials. And i see the port being open locally and in docker container.
I tried:
sudo lsof -i tcp:27017
and it get:
com.docke 31591 jgonz 23u IPv4 0xaa557204f5a42733 0t0 TCP *:27017 (LISTEN)
com.docke 31591 jgonz 26u IPv6 0xaa557204e73407f3 0t0 TCP localhost:27017 (LISTEN)
I not exactly sure what i am missing in my configuration. Also, at the folder level of the docker-compose I have a .env file with all the environment variables. My mongodb Dockerfile run two scripts, by following this article:
http://blog.bejanalex.com/2017/03/running-mongodb-in-a-docker-container-with-authentication/
So I'm writing a node application, and my docker-compose.yml looks like:
version: '2'
services:
redis:
image: "redis:latest"
web:
build: .
ports:
- "3000:3000"
volumes:
- .:/app
links:
- redis
emailworker:
build: .
env_file:
- ./.env
command: node ./lib/workers/email.js
volumes:
- .:/app
links:
- redis
smsworker:
build: .
env_file:
- ./.env
command: node ./lib/workers/sms.js
volumes:
- .:/app
links:
- redis
Pretty straight forward, a webserver, and two workers to process email and sms jobs. All has been great, until this afternoon, where nothing seemed to change, but I can not longer connect to the redis container when my app boots up. I run docker-compose up and I get the following error when trying to connect to redis using the kue node module:
Error: Redis connection to 127.0.0.1:6379 failed - connect ECONNREFUSED 127.0.0.1:6379
at Object.exports._errnoException (util.js:1022:11)
at exports._exceptionWithHostPort (util.js:1045:20)
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1087:14)
My kue connection to redis looks like:
const kue = require('kue'),
queue = kue.createQueue({
root: __dirname,
redis: {
host: 'redis',
port: 6379
}
});
queue.on('error', err => {
console.log('QUEUE ERROR: ', err);
});
Any ideas where I'm going wrong here? I just set this up last night and emails were happily being sent, and like I mentioned, the only thing that would have changed is app code in the web service. I'm developing on a Mac if that makes a difference and have the latest version of docker and docker-compose. A docker ps after doing a docker-compose up shows:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3af92333ad53 expapi_web "yarn docker" About a minute ago Up About a minute 0.0.0.0:3000->3000/tcp expapi_web_1
d26f1d81ad22 expapi_emailworker "node ./lib/workers/e" About a minute ago Up About a minute 3000/tcp expapi_emailworker_1
1695ec819777 expapi_smsworker "node ./lib/workers/s" About a minute ago Up About a minute 3000/tcp expapi_smsworker_1
5cb6701f3586 redis:latest "docker-entrypoint.sh" About a minute ago Up About a minute 6379/tcp expapi_redis_1
I'm experimenting with docker and reflected a very slow connection from the nodejs (4.2.3) container to mongodb (3.2) container.
My setup, very basic, is this (docker-compose):
version: '2'
services:
web:
build: ./app
volumes:
- "./app:/src/app"
ports:
- "80:3000"
links:
- "db_cache:redis"
- "db:mongodb"
command: nodemon -L app/bin/www
db_cache:
image: redis
db:
image: mongo
My s.o. is OSX 10.10 and the docker version is 1.10.2.
The strange thing is that the connection time to the db is always 30 seconds.
Is there any automatic delay?
EDIT:
if I set ip address of mongodb container intead a "dns" (mongodb), the delay disappears!
Any ideas?
This does not completely solve the problem, but it allows you to restore the normal behavior.
The cause of this seems to be the version 2 of the docker-compose.yml.
If I remove the version 2 is completely eliminated the 30-second delay when connecting to mongodb:
web:
build: ./app
volumes:
- "./app:/src/app"
ports:
- "80:3000"
links:
- "db_cache:redis"
- "db:mongodb"
command: nodemon -L app/bin/www
db_cache:
image: redis
db:
image: mongo
I opened an issue here.