After I carry out docker-compose up, it starts the containers.
when I do docker ps I get the below, which tells me that the containers are running. However when I do docker network inspect bridge the result shows me that there are no containers part of the docker0 bridge.
When I then carry out docker run meanchat_myserver it actually does show up on docker0 and I am also getting the data that the server is running on port 3000.
Which I don't get by using docker-compose.
What am I doing wrong here?
I am reading that when I use docker0 I can only refer to IP's to connect to other containers and not the name. Can I assume the ip's don't change on the containers and that this works without issue on deploying the app in production?
02cf08b1c3da d57f06ba9c68 "npm start" 33 minutes ago Up 33 minutes 4200/tcp meanchat_client_1
e257063c9e21 meanchat_myserver "npm start" 33 minutes ago Up 33 minutes 3000/tcp meanchat_myserver_1
02441c2e43f5 e114a298eabd "npm start" About an ago Up 33 minutes 0.0.0.0:80->80/tcp meanchat_nginx_1
88d9841d2553 mongo "docker-entrypoint..." 3 hours ago Up 3 hours 27017/tcp meanchat_mongo_1
compose
version: '3'
services:
# Build the container using the client Dockerfile
client:
build: ./
# This line maps the contents of the client folder into the container.
volumes:
- ./:/usr/src/app
myserver:
build: ./express-server
volumes:
- ./:/usr/src/app
depends_on:
- mongo
nginx:
build: ./nginx
# Map Nginx port 80 to the local machine's port 80
ports:
- "80:80"
# Link the client container so that Nginx will have access to it
mongo:
environment:
- AUTH=yes
- MONGO_INITDB_ROOT_USERNAME=superAdmin
- MONGO_INITDB_ROOT_PASSWORD=admin123
- MONGO_INITDB_DATABASE=d0c4ae452a5c
image: mongo
volumes:
- /var/mongodata/data:/data/db
By default Compose sets up a single network for your app.
For more detail, refer this link.
This means containers with compose won't be located in default bridge network by default.
You can check which network the containers with compose are using with the command.
docker inspect $container_name -f "{{.NetworkSettings.Networks}}"
However, If you want containers to be in default bridge network, you can use network_mode.
services:
service_name:
# other options....
network_mode: bridge
Related
I'm in the process of creating a docker-compose config which maintains:
a node.js server, and
a separate postgres server.
Tutorials emphasise that postgres port 5432 must be exposed or forwarded so that the node container can access it: facilitated in the below docker-compose.yml.
version: "3.7"
services:
db:
container_name: db
image: postgres:alpine
ports:
- "5010:5432"
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: verysecretpass
POSTGRES_DB: pg-dev
server:
container_name: dashboard-api
build: .
volumes:
- .:/server
ports:
- "5000:5000"
This produces the below docker ps output:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0d790cd4929e server_server "docker-entrypoint.s…" 4 minutes ago Up 4 minutes 0.0.0.0:5000->5000/tcp dashboard-api
818296c1fc02 postgres:alpine "docker-entrypoint.s…" 7 minutes ago Up 4 minutes 0.0.0.0:5010->5432/tcp pg
In the above state, node gets ECONN REFUSED when attempting to connect with this url: postgres://postgres:verysecretpass#db:5010/pg-dev
Yet, the same connection string can connect when using 5432 instead of 5010.
In fact, using 5432, connection succeeds even when pg container has no port configuration whatsoever. The below docker ps output reflects no-port-config state in which node container can happily connect:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
76da96c15c05 server_server "docker-entrypoint.s…" 7 seconds ago Up 7 seconds 0.0.0.0:5000->5000/tcp dashboard-api
51c221ac2c54 postgres:alpine "docker-entrypoint.s…" 8 seconds ago Up 7 seconds 5432/tcp db
Why does this work? What am I missing here?
Using:
Docker version 20.10.0, build 7287ab3
docker-compose version 1.27.4, build 40524192
Unless otherwise configured, the services in a docker-compose document are automatically added to a network. There's no need to expose ports in this network.
If you want to expose ports on a container to the outside world, you will need to explicitly map these as you did. This however does not change anything for communication between services in the same network. If you have no reason to access the database from outside the network (e.g. inspect data using a DB tool on your own machine), you don't have to map / expose any ports of the db container.
I'm using docker-compose to run MariaDB and it is working fine. I am fetching jasper server and maria DB docker images and running them. When I telnet the jasper server image, it responds correctly, but when I telnet to MariaDB, it says:
telnet localhost 3306
Trying ::1...
Trying 127.0.0.1...
telnet: Unable to connect to remote host: Connection refused
What I might be doing wrong?
Here is the output of sudo docker ps -a:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9e759f106006 bitnami/jasperreports:7 "/app-entrypoint.sh …" 21 minutes ago Up 21 minutes 0.0.0.0:9093->8080/tcp, 0.0.0.0:443->8443/tcp ceyedev_jasperreports_1
9242e52f6af8 bitnami/mariadb:10.3 "/opt/bitnami/script…" 21 minutes ago Up 21 minutes 3306/tcp ceyedev_mariadb_1
Here is my docker compose file:
version: '2'
services:
mariadb:
image: 'bitnami/mariadb:10.3'
environment:
- MARIADB_USER=bn_jasperreports
- MARIADB_DATABASE=bitnami_jasperreports
- ALLOW_EMPTY_PASSWORD=yes
volumes:
- 'mariadb_data:/bitnami'
jasperreports:
image: 'bitnami/jasperreports:7'
environment:
- MARIADB_HOST=mariadb
- MARIADB_PORT_NUMBER=3306
- JASPERREPORTS_DATABASE_USER=bn_jasperreports
- JASPERREPORTS_DATABASE_NAME=bitnami_jasperreports
- ALLOW_EMPTY_PASSWORD=yes
ports:
- '9093:8080'
- '443:8443'
volumes:
- 'jasperreports_data:/bitnami'
depends_on:
- mariadb
volumes:
mariadb_data:
driver: local
jasperreports_data:
driver: local
You have to open the ports in your Docker compose file (that thing you posted is called a Docker Compose file, not Dockerfile which is the one containing the commands to build a Docker image).
In the mariadb section make it like this:
services:
mariadb:
image: 'bitnami/mariadb:10.3'
environment:
- MARIADB_USER=bn_jasperreports
- MARIADB_DATABASE=bitnami_jasperreports
- ALLOW_EMPTY_PASSWORD=yes
volumes:
- 'mariadb_data:/bitnami'
ports:
- 3306
This way, the 3306 port of MariaDB will be exposed to your local computer. This means:
that you may access MariaDB through the 3306 port
that ANYONE with direct network access to your computer (i.e. local IP address) will be able to access MariaDB through port 3306.
Bear in mind those two things regarding your system security.
Note: am new to docker/swarm.
I've created a WordPress/mysql containers in a docker swarm mode running on Azure as per https://docs.docker.com/compose/wordpress/.
The cluster was created as per https://docs.docker.com/docker-for-azure/
here is my dockerfile:
======================
version: '3.3'
services:
db:
image: mysql:5.7
volumes:
- db_data:/var/lib/mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: somewordpress
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress
wordpress:
depends_on:
- db
image: wordpress:latest
ports:
- "8000:80"
restart: always
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress
WORDPRESS_DB_NAME: wordpress
volumes:
db_data: {}
=======================
as per official documentation, I can publish ports using --published flag, however, I need to know how to include that in Dockerfile.
Running apps
You can now start creating containers and services.
$ docker run hello-world
You can run websites too. Ports exposed with --publish are automatically exposed through the platform load balancer:
$ docker service create --name nginx --publish published=80,target=80 nginx
Once up, find the DefaultDNSTarget output in either the AWS or Azure portals to access the site.
Using docker ps, I can see that it is listening on 0.0.0.0:8000->80, however, without a service, it will not automatically create an azure load balance rule to the container.
swarm-manager000000:~/compose$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8c94587acd97 wordpress:latest "docker-entrypoint.s…" 10 minutes ago Up 10 minutes 0.0.0.0:8000->80/tcp compose_wordpress_1
aff61e0022a8 mysql:5.7 "docker-entrypoint.s…" 10 minutes ago Up 10 minutes 3306/tcp, 33060/tcp compose_db_1
5d2fdb3d75c4 docker4x/l4controller-azure:18.09.2-ce-azure1 "loadbalancer run --…" 2 hours ago Up 2 hours editions_controller
d5f0a8a91f66 docker4x/meta-azure:18.09.2-ce-azure1 "metaserver -iaas_pr…" 2 hours ago Up 2 hours 10.0.0.4:9024->8080/tcp meta-azure
93c6571b6ee6 docker4x/guide-azure:18.09.2-ce-azure1 "/entry.sh" 2 hours ago Up 2 hours editions_guide
b6cad5676b10 docker4x/logger-azure:18.09.2-ce-azure1 "python /server.py" 2 hours ago Up 2 hours 0.0.0.0:514->514/udp editions_logger
d2a74fe21751 docker4x/agent-azure:18.09.2-ce-azure1 "supervisord --confi…" 2 hours ago Up 2 hours agent
swarm-manager000000:~/compose$
If, for example, I tried to create a service that is mapped to a new image i.e: nginx. this will immediately create an inbound rule in the Azure load balancer.
$ docker service create --name nginx --publish published=80,target=80 nginx
Please advise of how to map the service to the existing WordPress container, or how to update the Dockerfile to create the service and use --published.
Thanks
I have no experience that maps the docker service to an existing container. As I know, it just does the same in the swarm as docker run command. You can take a look at the description of them.
If you really like to map the service to a container, I suggest the AKS than Docker Swarm in Azure, it's more manageable to you for the service and container. It can map the service to the container no matter it's existing one or creates a new one.
For the issue to publish the port. You can achieve it by using the parameter --publish in the docker run command like this:
docker run -d -p 80:80 my_image
Or you can do it in the compose file like this:
ports:
- "8000:80"
But you cannot publish the port in the Dockerfile, you just can tell the container which port the application listen to by using EXPOSE. Take a look at Expose vs publish: Docker port commands explained simply, then you will know it.
/usr/local/bin/docker-compose up
I am using this command on Amazon Linux. It does not bind the ports, so I could not connect to the services running inside the container. The same configuration is working on a local development server. Not sure what I am missing.
[root#ip-10-0-1-42 ec2-user]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ec6320747ef3 d8bd4345ca7f "/bin/sh -c 'gulp bu…" 30 seconds ago Up 30 seconds vigilant_jackson
Here is the docker-compose.yml:
version: '2'
services:
web:
build: .
command: gulp serve
env_file:
- .env
volumes:
- .:/app/code
ports:
- "8050:8000"
- "8005:8005"
- "8888:8888"
npm -v 5.6.0
docker -v Docker version 18.06.1-ce, build e68fc7a215d7133c34aa18e3b72b4a21fd0c6136
Are you sure the ports are not published?
Use docker inspect, I would guess that they are published. If this is the case, then my guess is that as you are on AWS, you are not ssh-ing to the opened port (8050, 8005, 8888 are ports of the AWS linux instance, if I got your question correctly).
docker-ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
83b1503d2e7c app_nginx "nginx -g 'daemon ..." 2 hours ago Up 2 hours 0.0.0.0:80->80/tcp app_nginx_1
c9dd2231e554 app_web "/home/start.sh" 2 hours ago Up 2 hours 8000/tcp app_web_1
baad0fb1fabf app_gremlin "/start.sh" 2 hours ago Up 2 hours 8182/tcp app_gremlin_1
b663a5f026bc postgres:9.5.1 "docker-entrypoint..." 25 hours ago Up 2 hours 5432/tcp app_db_1
They all work fine:
app_nginx connects well with app_web
app_web connects well with postgres
No working file:
app_web is not able to connect with app_gremlin
docker-compose.yaml
version: '3'
services:
db:
image: postgres:9.5.12
web:
build: .
expose:
- "8000"
depends_on:
- gremlin
command: /home/start.sh
nginx:
build: ./nginx
links:
- web
ports:
- "80:80"
command: nginx -g 'daemon off;'
gremlin:
build: ./gremlin
expose:
- "8182"
command: /start.sh
Errors:
Basically I am not able to connect to gremlin container from my app_web container.
All below have been executed inside web_app container
curl:
root#49a8f08a7b82:/# curl 0.0.0.0:8182
curl: (7) Failed to connect to 0.0.0.0 port 8182: Connection refused
netstat
root#49a8f08a7b82:/# netstat -l
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 127.0.0.11:42681 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:8000 0.0.0.0:* LISTEN
udp 0 0 127.0.0.11:54232 0.0.0.0:*
Active UNIX domain sockets (only servers)
Proto RefCnt Flags Type State I-Node Path
nmap
root#49a8f08a7b82:/# nmap -p 8182 0.0.0.0
Starting Nmap 7.60 ( https://nmap.org ) at 2018-06-22 09:28 UTC
Nmap scan report for 0.0.0.0
Host is up.
PORT STATE SERVICE
8182/tcp filtered vmware-fdm
Nmap done: 1 IP address (1 host up) scanned in 2.19 seconds
nslookup
root#88626de0c056:/# nslookup app_gremlin_1
Server: 127.0.0.11
Address: 127.0.0.11#53
Non-authoritative answer:
Name: app_gremlin_1
Address: 172.19.0.3
Experimenting:
For Gremlin container I did,
ports:
- "8182:8182"
Then from Host I can connect to gremlin container BUT still no connection between web and gremlin container
I am working on creating a re-creating sample Docker file (minimal stuff to recreate the issue) meanwhile anyone has any idea what the issue might be?
curl 0.0.0.0:8182
The 0.0.0.0 address is a wild card that tells an app to listen on all network interfaces, you do not connect to this interface as a client. For container to container communication, you need:
containers on the same user generated network (compose does this for you by default)
connect to the name of the service (or container name)
connect to the port inside the other container, not the published port.
In your case, the command should be:
curl http://gremlin:8182
Networking is namespaced in apps running inside containers, so each container gets it's open loopback interface and ip address on a bridge network. So moving an app into containers means you need to listen on 0.0.0.0 and connect to the bridge ip using DNS.
You should also remove links and depends_on from your Dockerfile, they don't apply in version 3. Links have long since been deprecated in favor of shared networks. And depends_on doesn't work in swarm mode along with probably not doing what you wanted since it never checked for the target app to be running, only the start of that container to have been kicked off.
One last note, expose doesn't affect the ability to communicate between containers on common networks or publish ports on the host. Expose simply sets meta data on the image that is documentation between the person creating the image and the person running the image. Applications are not required to use that value, but it's a good habit to make your app default to that value for the benefit of downstream users. Because of its role, unless you have another app checking for the exposed port list, like a self updating reverse proxy, there's no need to expose the port in the compose file unless you're giving the compose file to another person and they need the documentation.
There is no link configured in the docker-compose.yaml between web and gremlin. Try to use the following:
version: '3'
services:
db:
image: postgres:9.5.12
web:
links:
- gremlin
build: .
expose:
- "8000"
depends_on:
- gremlin
command: /home/start.sh
nginx:
build: ./nginx
links:
- web
ports:
- "80:80"
command: nginx -g 'daemon off;'
gremlin:
build: ./gremlin
expose:
- "8182"
command: /start.sh