I have 3 containers with my bot, server and db. after docker-compose up, server and db are working. telegram bot does get-request and takes this error:
Get "http://localhost:8080/user/": dial tcp 127.0.0.1:8080: connect: connection refused
docker-compose.yml
version: "3"
services:
db:
image: postgres
container_name: todo_postgres
restart: always
ports:
- "5432:5432"
environment:
# TODO: Change it to environment variables
POSTGRES_USER: user
POSTGRES_DB: somedb
POSTGRES_PASSWORD: pass
server:
depends_on:
- db
build: .
restart: always
ports:
- 8080:8080
environment:
DB_NAME: somedb
DB_USERNAME: user
DB_PASSWORD: pass
bot:
depends_on:
- server
build:
./src/telegram_bot
environment:
BOT_TOKEN: TOKEN
restart: always
links:
- server
When using compose, try using the containers hostname.. in the case your bot should try to connect to
server:8080
Compose will handle the name resolution to the IP you need
What you try is to access localhost within your container (service) bot.
Maybe this answer will help you to solve the problem. It sound similar to your problem.
But I want to provide you another solution to your problem:
In case it's not needed to access the containers form outside (from your host), one appraoch would be making use of the expose functionality and a docker network.
See docs.docker.com: network.
The expose functionality allows to access your other containers within your network
See docs.docker.com: expose
Expose ports without publishing them to the host machine - they’ll only be accessible to linked services. Only the internal port can be specified.
Example
What is this example doing?
A couple of steps that are not mandatory
Set a static ip within your docker container
These Steps are not needed and can be omitted. However, I like to do this, since you have now a better control over the network. You can access the containers by their hostname (which is the container name or service name) as well.
The steps that are needed are the following:
This exposes port 8080, but do not publish it.
expose:
- 8080
The network which allows static ip configuration
networks:
vpcbr:
driver: bridge
ipam:
config:
- subnet: 10.5.0.0/16
A complete file could look similar to this:
version: "3.8"
services:
first-service:
image: <your-image>
networks:
vpcbr:
ipv4_address: 10.5.0.2
expose:
- 8080
second-service:
image: <your-image>
networks:
vpcbr:
ipv4_address: 10.5.0.3
depends_on:
- first-service
networks:
vpcbr:
driver: bridge
ipam:
config:
- subnet: 10.5.0.0/16
Your bot container is up before your server & db containers.
When you use depends_on it's not accually waiting them to finish setup themeselves.
You should try some tricky algorithem for waiting the other container finish setup.
I remmember that when I used Nginx proxy I used something called wait-for-it.sh
Related
I have a problem about network in docker. In the docker-compose.yml includes 2 instance below
webserver (frontend + backend)
database
But i tried to bridge network and default but not working at all.The backend cannot connect to database show error "connection refuse". then i tried to docker exec -t .. into webserver and then ping to database it show "timeout".
I cannot connect database with ip address (i got a database ip address from docker exec and then hostname -i) but i connected success using "localhost"
this my docker-compose.yml
version: '3.8'
services:
postgres_server:
container_name: postgres14-4_container
image: postgres:14.4
command: postgres -c 'max_connections=200'
restart: always
environment:
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres
ports:
- '5222:5432'
volumes:
- db:/var/lib/postgresql14/data
networks:
- web_network
webserver:
container_name: frontend_backend_container
image: webserver
ports:
- '9090:80'
- '8081:8081'
env_file:
- backend_env
depends_on:
- postgres_server
restart: always
networks:
- web_network
volumes:
db:
driver: local
networks:
web_network:
driver: bridge
To configure remote connections to postgres, you have to adjust pg_hba.conf. For example add:
# Remote access
host all all 0.0.0.0/0 trust
where is your backend_env file?
I guess you have there the host + port to connect to the db.
You don't need to define anything special (like the bridge).
The webserver container should be able to access the postgres_server via postgres_server:5432 (not localhost and not 5222).
version: "3.5"
services:
database:
container_name: proj-database
env_file: ../orm/.env.${PROJ_ENV}
image: postgres
restart: always
expose:
- 5433
ports:
- 5432:5432
- 5433:5432
networks:
- proj
I can connect from other containers with 5432, but i can't from other containers connect with 5433. Whats the problem?
Connections between containers always use the "normal" port number for the destination service. They don't consider any remappings in ports:; in fact, they don't need ports: at all. ports: are only used for connections from outside Docker into a container. Conversely, since internally each container has its own private IP address, there aren't conflicts even if you are running multiple copies of the same image.
I am trying to access a docker container from another container using localhost address.
The compose file is pretty simple. Both containers ports are exposed.
There are no problems when building.
In my host machine I can successfully execute curl http://localhost:8124/ and get a response.
But inside the django_container when trying the same command I get Connection refused error.
I tried adding them in the same network, still result didn't change.
Well if I try to execute with the internal ip of that container like curl 'http://172.27.0.2:8123/' I get the response.
Is this the default behavior? How can I reach clickhouse_container using localhost?
version: '3'
services:
django:
container_name: django_container
build: ./django
ports:
- "8007:8000"
links:
- clickhouse:clickhouse
volumes:
- ./django:/usr/src/run
command: bash /usr/src/run/run.sh
clickhouse:
container_name: clickhouse_container
build: ./clickhouse
ports:
- "9001:9000"
- "8124:8123"
- "9010:9009"
So with this line here - "8124:8123" you're mapping the port of clickhouse container to localhost 8124. Which allows you to access clickhouse from localhost at port 8124.
If you want to hit clickhouse container from within the dockerhost network you have to use the hostname for the container. This is what I like to do:
version: '3'
services:
django:
hostname: djano
container_name: django
build: ./django
ports:
- "8007:8000"
links:
- clickhouse:clickhouse
volumes:
- ./django:/usr/src/run
command: bash /usr/src/run/run.sh
clickhouse:
hostname: clickhouse
container_name: clickhouse
build: ./clickhouse
ports:
- "9001:9000"
- "8124:8123"
- "9010:9009"
If you make the changes like I have made above you should be able to access clickhouse from within the django container like this curl http://clickhouse:8123.
As in #Billy Ferguson's answer, you can visit using localhost in host machine just because: you define a port mapping to route localhost:8124 to clickhouse:8123.
But when from other container(django), you can't. But if you insist, there is a ugly workaround: share host's network namespace with network_mode, but with this the django container will just share all network of host.
services:
django:
hostname: djano
container_name: django
build: ./django
ports:
- "8007:8000"
links:
- clickhouse:clickhouse
volumes:
- ./django:/usr/src/run
command: bash /usr/src/run/run.sh
network_mode: "host"
It depends of config.xml settings. If in config.xml <listen_host> 0.0.0.0</listen_host> you can use clickhouse-client -h your_ip --port 9001
hey guys I have a docker container A with a domain name attached to it on a host B with a domain name attached to it as well.....how can I access the said container A via A's domain name rather than an B's ip address or domain name from computer C on the host B's local network.
thus C -> A( via wwww.cname.url) rather than C -> B( www.bname.url:port) -> A
E.G.
the following is a docker-compose with services
version: "3.2"
services:
php:
links:
- mysql
image: arm32v6/php:7.1.24-fpm-alpine3.8-lavalite
networks:
- backend
working_dir: /var/www/html
volumes:
- ./website/:/var/www/html/
privileged: true
node:
domainname: docker.local
hostname: node
networks:
frontend:
aliases:
- node.docker.local
links:
- "apache:dev.docker.local"
depends_on:
- apache
image: arm32v7/node:latest
entrypoint: yarn
command: twill-dev
volumes:
- ./website:/usr/src/app
working_dir: /usr/src/app
ports:
- "3000:3000"
- "3001:3001"
apache:
domainname: docker.local
hostname: dev
image: arm32v7/httpd:2.4
depends_on:
- php
- mysql
networks:
frontend:
aliases:
- apache
- dev.docker.local
backend:
aliases:
- apache
privileged: true
ports:
- "8880:80"
working_dir: /var/www/html
volumes:
- ./website/:/var/www/html/
- ./httpd.conf:/usr/local/apache2/conf/httpd.conf
- ./fpm.conf:/usr/local/apache2/conf/extra/httpd-vhosts.conf
mysql:
image: yobasystems/alpine-mariadb:arm32v7
volumes:
- ./datadir:/var/lib/mysql
networks:
- backend
environment:
- MYSQL_VERSION=5.7
- MYSQL_ROOT_PASSWORD=rootpassword
- MYSQL_USER=test
- MYSQL_PASSWORD=testpass
- MYSQL_DATABASE=test_db
networks:
frontend:
external:
name: localnet
backend:
I want to be able to access service apache by its domain name set to dev.docker.local the ip of which is on a network 17.18.0.1/24
The host has an IP which is on a network 192.168.1.0/24 with a domain name dev.server.local
I have a dev pc on the network 192.168.1.0/24 and it can access the service containers via the hosts IP and usually a port exposed for the particular service.
UPDATE
The host can be reached at server.local from outside the network
my network interface has the following entries
dns-search server.local
dns-domain server.local
the docker container has the following
hostname nginx
domainname server.local
do I need to also edit a host file or resolv.conf file?
It seems the host is running avahi service discovery. Would this affect anything?
So can I
set an internal domain set to the host and have docker containers on subdomains? How would outside devices access this via the domain?
attach the docker container to be on the host's network thus having an ip in the 192.168.1.0/24 and being able to be pinged by devices on that network as well. Will the domain resolve to it?
Is there a dynamic DNS software I can use that can hook this up to me so that its not a manual process. Thus it will detect the server and route incoming requests to it via the domain name?
You can do this by configuring an nginx container with the containers bound to the subdomain.
So for example the host is accessible by domain example.com and you want the php container to be accessible on php.example.com you could use a setup like the following:
services:
php:
image: arm32v6/php:7.1.24-fpm-alpine3.8-lavalite
environment:
- VIRTUAL_HOST=php.example.com
nginx-proxy:
image: jwilder/nginx-proxy
depends_on:
- php
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
Any request to the subdomain would first be send to the host, this is bound by nginx, which in turn registers that because the subdomain php is requested it should send the user to that container.
I hope this can help you and if you have any questions please let me know
Seems to be a common question but with different contexts but I'm having a problem connecting to my localhost DB when using Docker.
If I inspect the mysql container using docker inspect and find the IP address and use this as the DB host as part of the CMS, it runs fine... the only issue is the mysql container IP address changes (upon eachdocker-compose up and if I change wifi networks) so ideally I'd like to use 'localhost' or '127.0.0.1' but for some reason this results in a SQLSTATE[HY000] [2002] Connection refused error.
How can I use 'localhost' or '127.0.0.1' as the DB hostname in CMS applications so I don't have to keep changing it as the container IP address changes?
This is my docker-compose.yml file:
version: "3"
services:
webserver:
build:
context: ./bin/webserver
restart: 'always'
ports:
- "80:80"
- "443:443"
links:
- mysql
volumes:
- ${DOCUMENT_ROOT-./www}:/var/www/html
- ${PHP_INI-./config/php/php.ini}:/usr/local/etc/php/php.ini
- ${VHOSTS_DIR-./config/vhosts}:/etc/apache2/sites-enabled
- ${LOG_DIR-./logs/apache2}:/var/log/apache2
networks:
mynet:
aliases:
- john.dev
mysql:
image: 'mysql:5.7'
restart: 'always'
ports:
- "3306:3306"
volumes:
- ${MYSQL_DATA_DIR-./data/mysql}:/var/lib/mysql
- ${MYSQL_LOG_DIR-./logs/mysql}:/var/log/mysql
environment:
MYSQL_ROOT_PASSWORD: example
networks:
- mynet
phpmyadmin:
image: phpmyadmin/phpmyadmin
links:
- mysql
environment:
PMA_HOST: mysql
PMA_PORT: 3306
ports:
- '8080:80'
volumes:
- /sessions
networks:
- mynet
networks:
mynet:
Try using mysql instead of localhost.
You are defining a link between webserver container and mysql container, so webserver container is able to resolve mysql IP.
According to Docker documentation:
Docker Cloud gives your containers two ways find other services:
Using service and container names directly as hostnames
Using service links, which are based on Docker Compose links
Service and Container Hostnames update automatically when a service
scales up or down or redeploys. As a user, you can configure service
names, and Docker Cloud uses these names to find the IP of the
services and containers for you. You can use hostnames in your code to
provide abstraction that allows you to easily swap service containers
or components.
Service links create environment variables which allow containers to
communicate with each other within a stack, or with other services
outside of a stack. You can specify service links explicitly when you
create a new service or edit an existing one, or specify them in the
stackfile for a service stack.
From Docker compose documentation:
Containers for the linked service are reachable at a hostname identical to the alias, or the service name if no alias was specified.