डॉकटर कंटेनर को स्थानीय / होस्ट पोस्टग्रेज डेटाबेस से कनेक्ट करने की अनुमति दें


143

मैं हाल ही में डॉकर और क्यूजीआईएस के साथ खेल रहा हूं और इस ट्यूटोरियल में निर्देशों का पालन करते हुए एक कंटेनर स्थापित किया है ।

सब कुछ बहुत अच्छा काम करता है, हालांकि मैं एक लोकलहोस्ट पोस्टग्रेज डेटाबेस से कनेक्ट करने में असमर्थ हूं, जिसमें मेरे सभी जीआईएस डेटा शामिल हैं। मुझे लगता है कि यह इसलिए है क्योंकि मेरे पोस्टग्रेज डेटाबेस को दूरस्थ कनेक्शन स्वीकार करने के लिए कॉन्फ़िगर नहीं किया गया है और इस आलेख में दिए गए निर्देशों का उपयोग करके दूरस्थ कनेक्शनों को अनुमति देने के लिए पोस्टग्रैफ्स फाइलों को संपादित कर रहा है ।

जब मैं कोशिश करता हूं और Docker में QGIS चलाने वाले अपने डेटाबेस से कनेक्ट होने पर मुझे अभी भी एक त्रुटि संदेश मिल रहा है: सर्वर से कनेक्ट नहीं हो सका: Connection refused Is the server running on host "localhost" (::1) and accepting TCP/IP connections to port 5433? पोस्टग्रेज सर्वर चल रहा है, और मैंने कई रेंज से कनेक्शन की अनुमति देने के लिए अपनी pg_hba.conf फ़ाइल संपादित की है आईपी ​​पते (172.17.0.0/32)। मैंने पहले docker कंटेनर के IP पते का उपयोग करके जांच की थी docker psऔर यद्यपि IP पता बदलता है, यह अब तक हमेशा 172.17.0.x रेंज में रहा है

किसी भी विचार क्यों मैं इस डेटाबेस से कनेक्ट नहीं कर सकते? शायद कुछ बहुत ही सरल मैं कल्पना करता हूं!

मैं Ubuntu 14.04 चला रहा हूं; 9.3 पोस्ट करता है

जवाबों:


149

टी एल; डॉ

  1. 172.17.0.0/16IP एड्रेस रेंज के रूप में उपयोग करें , नहीं 172.17.0.0/32
  2. localhostअपने होस्ट पर PostgreSQL डेटाबेस से कनेक्ट करने के लिए उपयोग न करें , लेकिन इसके बजाय होस्ट का आईपी। कंटेनर को पोर्टेबल रखने के लिए, --add-host=database:<host-ip>ध्वज के साथ कंटेनर को प्रारंभ करें और databasePostgreSQL से कनेक्ट करने के लिए होस्टनाम के रूप में उपयोग करें ।
  3. सुनिश्चित करें कि PostreSQL सभी आईपी पतों पर कनेक्शन के लिए सुनने के लिए कॉन्फ़िगर किया गया है, न कि केवल पर localhostlisten_addressesआमतौर पर PostgreSQL के कॉन्फ़िगरेशन फ़ाइल में सेटिंग देखें , /etc/postgresql/9.3/main/postgresql.conf(@DazmoNorton को क्रेडिट)।

दीर्घ संस्करण

172.17.0.0/32आईपी ​​पते की एक सीमा नहीं है , लेकिन एक ही पता (नाम 172.17.0.0)। किसी भी डॉकटर कंटेनर को कभी भी वह पता नहीं सौंपा जाएगा, क्योंकि यह डोकर पुल ( docker0) इंटरफेस का नेटवर्क पता है ।

जब डॉकर शुरू होता है, तो यह एक नया ब्रिज नेटवर्क इंटरफेस बनाएगा, जिसे आप कॉल करते समय आसानी से देख सकते हैं ip a:

$ ip a
...
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN 
    link/ether 56:84:7a:fe:97:99 brd ff:ff:ff:ff:ff:ff
    inet 172.17.42.1/16 scope global docker0
       valid_lft forever preferred_lft forever

जैसा कि आप देख सकते हैं, मेरे मामले में, docker0इंटरफ़ेस में (या ) के 172.17.42.1नेटमास्क के साथ आईपी ​​पता है । इसका मतलब है कि नेटवर्क एड्रेस है ।/16255.255.0.0172.17.0.0/16

IP पता बेतरतीब ढंग से असाइन किया गया है, लेकिन बिना किसी अतिरिक्त कॉन्फ़िगरेशन के, यह हमेशा 172.17.0.0/16नेटवर्क में रहेगा । प्रत्येक डॉकटर कंटेनर के लिए, उस सीमा से एक यादृच्छिक पता सौंपा जाएगा।

इसका मतलब है, यदि आप अपने डेटाबेस में सभी संभव कंटेनरों से पहुंच प्रदान करना चाहते हैं, तो उपयोग करें 172.17.0.0/16


1
आपकी टिप्पणियों के लिए धन्यवाद। मैंने आपके द्वारा pg_hba.confसुझाए गए पते पर अपना नाम बदल दिया है, लेकिन पोस्टग्रेस सेवा को रोकने और पुनः आरंभ करने के बाद भी उसी कनेक्शन त्रुटि संदेश मिलता है। मैंने अपने आईपीवी 4 कनेक्शन के तहत लाइन जोड़ी है - क्या आपके द्वारा सुझाए गए पते को जोड़ने के लिए कहीं और है? वैकल्पिक रूप से मेरे QGIS ऐप में डॉकर में चल रहा है क्या मुझे पोस्टग्रेज कनेक्शन जानकारी को बदलने की आवश्यकता है? उदाहरण के लिए, अगर मैं एक डॉकटर कंटेनर के भीतर से कनेक्ट कर रहा हूं तो क्या होस्ट अभी भी 'लोकलहोस्ट' है?
marty_c

आह, यह एक महत्वपूर्ण बिंदु है। नहीं, localhostआपके डॉकर कंटेनर के अंदर मेजबान सिस्टम नहीं है। होस्ट सिस्टम के सार्वजनिक आईपी पते से कनेक्ट करने का प्रयास करें। कंटेनर को पोर्टेबल रखने के लिए, आप कंटेनर को भी शुरू कर सकते हैं --add-host=database:<host-ip>और databaseडॉकटर कंटेनर के भीतर से अपने PostgreSQL होस्ट से कनेक्ट करने के लिए होस्टनाम के रूप में उपयोग कर सकते हैं ।
हेल्मट

6
मुझे एक और टुकड़े की जरूरत थी। मुझे /etc/postgresql/9.3/main/postgresql.confअपने सर्वर के eth0आईपी ​​पते को भी संपादित और जोड़ना था listen_addresses। डिफ़ॉल्ट रूप listen_addressesसे पोस्टग्रैड्स बाइंड localhostही है।
डेज़ामो नॉर्टन

@DzamoNorton, संकेत के लिए धन्यवाद! मैंने उसी हिसाब से अपना जवाब अपडेट किया।
helmbert

@helmbert host-ipवर्चुअल मशीन या डॉकटर कंटेनर का आईपी पता है?
मि। जूल

56

मैक समाधान के लिए डॉकर

17.06 के बाद

@Birchlabs की टिप्पणी के लिए धन्यवाद, अब यह विशेष मैक-केवल DNS नाम उपलब्ध के साथ टन आसान है :

docker run -e DB_PORT=5432 -e DB_HOST=docker.for.mac.host.internal

17.12.0-cd-mac46 से, के docker.for.mac.host.internalबजाय का उपयोग किया जाना चाहिए docker.for.mac.localhost। देखें रिहाई टिप्पणी जानकारी के लिए।

पुराना संस्करण

@ हेलम्बर के उत्तर ने इस मुद्दे को अच्छी तरह समझा। लेकिन मैक के लिए डॉकर ब्रिज नेटवर्क को उजागर नहीं करता है , इसलिए मुझे लिमिटेशन को वर्कअराउंड करने के लिए यह ट्रिक करनी थी:

$ sudo ifconfig lo0 alias 10.200.10.1/24

/usr/local/var/postgres/pg_hba.confइस लाइन को खोलें और जोड़ें:

host    all             all             10.200.10.1/24            trust

/usr/local/var/postgres/postgresql.confपरिवर्तन खोलें और संपादित करें listen_addresses:

listen_addresses = '*'

पुनः लोड सेवा और अपना कंटेनर लॉन्च करें:

$ PGDATA=/usr/local/var/postgres pg_ctl reload
$ docker run -e DB_PORT=5432 -e DB_HOST=10.200.10.1 my_app 

यह वर्कअराउंड मूल रूप से @ helmbert के उत्तर के साथ समान है, लेकिन नेटवर्क इंटरफ़ेस के lo0बजाय IP पते का उपयोग करता docker0है।


3
क्या यह अभी भी 4 अप्रैल 2017 तक चालू है?
पेट्रस थेरॉन

मुझे यह तरीका पसंद है जो डेटाबेस को उजागर नहीं करेगा। BTW, मैं CentOS पर इस का उपयोग कर सकते हैं? मुझे त्रुटि मिली: उपनाम: अज्ञात होस्ट जब मैंने आपके द्वारा दिए गए उपनाम आदेश का उपयोग करने का प्रयास किया।
त्सुंग गोह

6
मैकओएस पर एक बेहतर तरीका है, डॉकर 17.06.0-rc1-ce-mac13 (1 जून 2017) के रूप में। कंटेनर मेजबान को पहचानते हैं docker.for.mac.localhost। यह आपके होस्ट मशीन का IP है। कंटेनर के मेजबानों के डेटाबेस में इसकी प्रविष्टि को इस तरह से docker run alpine /bin/sh -c 'getent hosts docker.for.mac.localhost'
देखना

@Birchlabs यह बहुत बढ़िया है!
qqilihq

5
ऐसा लगता है कि यह host.docker.internal18.03 के बाद से बदल गया , अन्य विकल्प अभी भी उपलब्ध हैं लेकिन पदावनत ( स्रोत )।
gseva

44

मैक के लिए सरल समाधान:

डॉकटर का नवीनतम संस्करण (18.03) एक बिल्ट इन पोर्ट अग्रेषण समाधान प्रदान करता है। आपके डॉकटर कंटेनर के अंदर बस db होस्ट सेट है host.docker.internal। यह उस होस्ट को अग्रेषित किया जाएगा जिस पर डॉक कंटेनर चल रहा है।

इसके लिए प्रलेखन यहाँ है: https://docs.docker.com/docker-for-mac/networking/#i-want-to-connect-from-a-container-to-a-service-on-the-host


3
यह अब तक का सबसे अच्छा जवाब है! रास्ता आसान है और यह कैसा होना चाहिए।
bjm88

2
है host.docker.internalकेवल Macs तक ही सीमित?
ड्रैगस

डॉक्स के अनुसार डॉक्स के अनुसार "यह मैक के बाहर काम नहीं करेगा", लेकिन डॉक्स के लिए डॉक्स के लिए एक ही डीएनएस नाम का उल्लेख किया गया है, इसलिए मुझे लगता है कि यह "डॉकर के लिए सीमित है ..."। किसी भी तरह से यह केवल विकास है: आप इसका उपयोग करने वाले एक डॉक छवि को शिप करने के लिए नहीं हैं।
ररबबार

केवल विंडोज़ और मैक के साथ काम करना। मेरे मामले में
उबंटू

16

सरल उपाय

बस जोड़ते --network=hostहैं docker run। बस इतना ही!

इस तरह से कंटेनर मेजबान के नेटवर्क का उपयोग करेगा, इसलिए localhostऔर 127.0.0.1मेजबान (डिफ़ॉल्ट रूप से वे एक कंटेनर को इंगित) को इंगित करेंगे। उदाहरण:

docker run -d --network=host \
  -e "DB_DBNAME=your_db" \
  -e "DB_PORT=5432" \
  -e "DB_USER=your_db_user" \
  -e "DB_PASS=your_db_password" \
  -e "DB_HOST=127.0.0.1" \
  --name foobar foo/bar

1
सावधान रहे! यह समाधान, मेरी राय में सही है, macOS के लिए काम नहीं करता है। अपना समय बर्बाद न करें यह जानने की कोशिश करें कि यह काम क्यों नहीं कर रहा है। यहाँ देखिए: github.com/docker/for-mac/issues/2716
jfcorugedo

डेबियन पर काम करता है। बदलते हुए पोस्टग्रैक्स्ल.कॉन्फ़ और pg_hba.conf की कोशिश की जा रही है लेकिन यह सरल और तेज़ है।
फ्रैम्बेलज

2

उबंटू में:

सबसे पहले आपको यह जांचना होगा कि आपके सिस्टम में Docker डेटाबेस पोर्ट उपलब्ध है या नहीं -

sudo iptables -L -n

नमूना बाहर:

Chain DOCKER (1 references)
target     prot opt source               destination         
ACCEPT     tcp  --  0.0.0.0/0            172.17.0.2           tcp dpt:3306
ACCEPT     tcp  --  0.0.0.0/0            172.17.0.3           tcp dpt:80
ACCEPT     tcp  --  0.0.0.0/0            172.17.0.3           tcp dpt:22

यहाँ 3306172.17.0.2 IP पर डॉकर डेटाबेस पोर्ट के रूप में उपयोग किया जाता है, यदि यह पोर्ट उपलब्ध नहीं है, तो निम्न कमांड चलाएँ -

sudo iptables -A INPUT -p tcp --dport 3306 -j ACCEPT

अब, आप विन्यास के बाद आसानी से अपने स्थानीय सिस्टम से डॉकर डेटाबेस तक पहुँच सकते हैं

  host: 172.17.0.2 
  adapter: mysql
  database: DATABASE_NAME
  port: 3307
  username: DATABASE_USER
  password: DATABASE_PASSWORD
  encoding: utf8

CentOS में:

सबसे पहले आपको यह जांचना होगा कि आपके आदेश के बाद Docker Database पोर्ट आपके फ़ायरवॉल में उपलब्ध है -

sudo firewall-cmd --list-all

नमूना बाहर:

  target: default
  icmp-block-inversion: no
  interfaces: eno79841677
  sources: 
  services: dhcpv6-client ssh
  **ports: 3307/tcp**
  protocols: 
  masquerade: no
  forward-ports: 
  sourceports: 
  icmp-blocks: 
  rich rules:

यहाँ 3307172.17.0.2 IP पर डॉकर डेटाबेस पोर्ट के रूप में उपयोग किया जाता है, यदि यह पोर्ट उपलब्ध नहीं है, तो निम्न कमांड चलाएँ -

sudo firewall-cmd --zone=public --add-port=3307/tcp

सर्वर में, आप पोर्ट को स्थायी रूप से जोड़ सकते हैं

sudo firewall-cmd --permanent --add-port=3307/tcp
sudo firewall-cmd --reload

अब, आप उपरोक्त विन्यास द्वारा आसानी से अपने स्थानीय सिस्टम से डॉकर डेटाबेस तक पहुँच सकते हैं।


मुझे पता है कि यह पुराना है, लेकिन अब, आप कॉन्फ़िगरेशन का पालन करके आसानी से अपने स्थानीय सिस्टम से डॉकर डेटाबेस तक पहुंच सकते हैं - आपके पास यह गलत तरीका है। उसके पास एक स्थानीय डेटाबेस है, और एक docker ऐप उस स्थानीय db से जुड़ने की कोशिश नहीं कर रहा है, जो चारों ओर से नहीं है
Craicerjack

2

यहाँ पोस्ट किया गया समाधान मेरे लिए काम नहीं करता है। इसलिए, मैं इस उत्तर को किसी ऐसे ही मुद्दे का सामना करने में मदद करने के लिए पोस्ट कर रहा हूं।

OS: Ubuntu 18
PostgreSQL: 9.5 (Ubuntu पर होस्ट किया गया)
Docker: सर्वर अनुप्रयोग (जो PostgreSQL से जुड़ता है)

मैं एप्लिकेशन बनाने के लिए docker-compose.yml का उपयोग कर रहा हूं।

चरण 1: कृपया जोड़ेंhost.docker.internal:<docker0 IP>

version: '3'
services:
  bank-server:
    ...
    depends_on:
      ....
    restart: on-failure
    ports:
      - 9090:9090
    extra_hosts:
      - "host.docker.internal:172.17.0.1"

Docker का IP खोजने के लिए i.e. 172.17.0.1 (in my case)आप इसका उपयोग कर सकते हैं

$> ifconfig docker0
docker0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 172.17.0.1  netmask 255.255.0.0  broadcast 172.17.255.255

या

$> ip a
1: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever

चरण 2: postgresql.conf में, change_addresses को बदल देंlisten_addresses = '*'

चरण 3: pg_hba.conf में, इस पंक्ति को जोड़ें

host    all             all             0.0.0.0/0               md5

चरण 4: अब postgresql सेवा का उपयोग करके पुनः आरंभ करें,sudo service postgresql restart

चरण 5:host.docker.internal सर्वर अनुप्रयोग से डेटाबेस को जोड़ने के लिए कृपया hostname का उपयोग करें ।
उदाहरण के लिए:jdbc:postgresql://host.docker.internal:5432/bankDB

का आनंद लें!!


1

डॉकटर-कंपोज के लिए आप सिर्फ जोड़ने की कोशिश कर सकते हैं

network_mode: "host"

उदाहरण :

version: '2'
services:
  feedx:
    build: web
    ports:
    - "127.0.0.1:8000:8000"
    network_mode: "host"

https://docs.docker.com/compose/compose-file/#network_mode


4
मेजबानी के लिए networkd_mode जोड़ने एक और कंटेनर के बीच संबंध को तोड़ने
Bawantha

1

कुछ सरल है कि एक Postgresql कनेक्शन की अनुमति देता है सेट करने के लिए से डोकर कंटेनर मेरी स्थानीय होस्ट करने के लिए मैं postgresql.conf में यह प्रयोग किया है:

listen_addresses = '*'

और इस pg_hba.conf को जोड़ा:

host    all             all             172.17.0.0/16           password

फिर एक पुनरारंभ करें। Docker कंटेनर से मेरा क्लाइंट (जो 172.17.0.2 पर था) तब होस्ट, पासवर्ड, डेटाबेस, उपयोगकर्ता नाम और पासवर्ड का उपयोग करके मेरे लोकलहोस्ट पर चलने वाले Postgresql से जुड़ सकता था।


0

मेरे सेटअप के लिए एक और चीज़ जोडनी थी

172.17.0.1  localhost

सेवा /etc/hosts

ताकि डॉकर 172.17.0.1डीबी होस्टनाम के रूप में इंगित हो , और डीबी खोजने के लिए एक बदलते बाहरी आईपी पर भरोसा न करें। आशा है कि यह इस मुद्दे के साथ किसी और की मदद करता है!


14
यह एक बुरा उपाय है। लोकलहोस्ट को आमतौर पर 127.0.0.1 की ओर इशारा करना चाहिए। इसे बदलने से अवांछित परिणाम हो सकते हैं, भले ही इस विशेष मामले में यह काम करता हो।
एलेक्स

2
एक बेहतर तरीका कंटेनर को चलाते समय एक databaseमेजबान स्थापित करना है --add-host=database:172.17.0.1। फिर अपने ऐप को उस होस्ट पर इंगित करें। यह एक कंटेनर के अंदर एक आईपी पते के हार्ड-कोडिंग से बचा जाता है।
jaredsk 16

1
--add-host=database:172.17.0.1बेहतर है
लुइस मार्टिंस

-3

एक अन्य समाधान सेवा की मात्रा है, आप एक सेवा की मात्रा को परिभाषित कर सकते हैं और उस मात्रा में होस्ट के पोस्टग्रेक्यूएल डेटा निर्देशिका को माउंट कर सकते हैं। विवरण के लिए दिए गए कम्पोज़ फ़ाइल को देखें।

version: '2'
services:
  db:   
    image: postgres:9.6.1
    volumes:
      - "/var/lib/postgresql/data:/var/lib/postgresql/data" 
    ports:
      - "5432:5432"

ऐसा करने से, एक अन्य PostgreSQL सेवा कंटेनर के नीचे चलेगी, लेकिन उसी डेटा निर्देशिका का उपयोग करती है जिसे HostgreSQL सेवा होस्ट कर रही है।


1
यह संभवतः एक रनिंग होस्ट PostgreSQL सेवा के साथ संघर्ष का कारण बनेगा
पेट्रस थेरॉन

मुझे लगता है कि मेजबान सेवा को रोकने से उस मामले में समस्या हल हो जाएगी।
Hrishi
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.