เป็นไปได้ไหมที่จะใช้ Docker เพื่อแยกเว็บไซต์สำหรับผู้ใช้


12

ฉันจัดการเซิร์ฟเวอร์ที่ผู้ใช้มีเว็บไซต์ของตนเองที่สามารถเข้าถึงได้โดย FTP (เช่น บริษัท โฮสติ้ง) และแทนที่จะทำงานเพื่อแยกกระบวนการสแต็กของ LAMP ฉันคิดว่ามันเป็นไปได้ที่จะใช้งาน Docker และใช้รูปภาพต่อเว็บไซต์

จากสิ่งที่ฉันเข้าใจคุณสามารถเปิดเผยอินสแตนซ์นักเทียบท่าผ่านพอร์ตของพวกเขาดังนั้นหากคุณเรียกใช้อินสแตนซ์นักเทียบท่าสองตัวบนเซิร์ฟเวอร์เดียวกันคุณจะต้องเปิดเผยพอร์ตที่ต่างกันสองพอร์ต

แต่มันเป็นไปได้ที่จะส่งออกไม่ใช่พอร์ต แต่เป็นชื่อเซิร์ฟเวอร์เช่น:

  • www.somewebsite.com: อินสแตนซ์นักเทียบท่า 1
  • www.otherwebsite.com: อินสแตนซ์นักเทียบท่า 2
  • www.etc.com: อินสแตนซ์นักเทียบท่า ...

และในเซิร์ฟเวอร์เดียวกัน

ฉันคิดเกี่ยวกับการติดตั้ง Apache บนเซิร์ฟเวอร์เท่านั้นซึ่งจะเปลี่ยนเส้นทางคำขอไปยังอินสแตนซ์ Docker โดยเฉพาะตามชื่อเซิร์ฟเวอร์ แต่จากนั้นฉันจะต้องติดตั้ง Apache (อีกครั้ง!) และ MySQL ในอินสแตนซ์ Docker ใด ๆ

เป็นไปได้และยิ่งกว่านี้มันน่าสนใจในแง่ของประสิทธิภาพ

ขอขอบคุณสำหรับความช่วยเหลือของคุณ.


1
ตามความเป็นจริงแล้วเป็นไปได้ว่า Apache จะทำ ProxyPass ไปยังพอร์ตที่แต่ละอินสแตนซ์ Docker กำลังรับฟังอยู่
thanasisk

คำตอบ:


12

ใช่มันเป็นไปได้ สิ่งที่คุณต้องทำคือให้ 80 พอร์ตหลายพอร์ต หนึ่งรายการสำหรับแต่ละ URL คุณสามารถทำได้โดยใช้เช่นโฮสต์เสมือนของ Apache ทำงานบนเซิร์ฟเวอร์โฮสต์ Docker

  1. ตั้ง DNS CNAME
  2. รันอินสแตนซ์นักเทียบท่าและแมปพอร์ต 80 เข้ากับพอร์ตพูดว่า 12345 ~ 12347 ของโฮสต์นักเทียบท่า
  3. รันเซิร์ฟเวอร์ Apache บนโฮสต์นักเทียบท่าและตั้งค่าโฮสต์เสมือนสำหรับแต่ละ URL และตั้งค่า ProxyPass และ ProxyPassReverse เป็น localhost: 12345 ซึ่งเป็นหนึ่งในอินสแตนซ์นักเทียบท่าของคุณ

ไฟล์ config ของ Apache จะมีลักษณะดังนี้:

<VirtualHost *:80>
ServerName www.somewebsite.com
  <Proxy *>
    Allow from localhost
  </Proxy>
  ProxyPass        / http://local.hostname.ofDockerHost:12345/
  ProxyPassReverse / http://local.hostname.ofDockerHost:12345/
</VirtualHost>

4
ขอบคุณ! สิ่งนี้ช่วยได้มาก นอกจากนี้ยังมีอีกProxyPreserveHost Onด้วยดังนั้นคุณจึงไม่ต้องลงท้ายด้วยลิงก์จำนวนมากไปยังlocal.hostname.ofDockerHost: 12345 insite เว็บไซต์ของคุณ นี่คือข้อมูลเพิ่มเติมที่เป็นประโยชน์กับฉัน: digitalocean.com/community/tutorials/…
SebastiánRamírez

นักเทียบท่าจะบันทึกการเปลี่ยนแปลงในฐานข้อมูล ฯลฯ หรือไม่
EminezArtus

3

มันเป็นไปได้. คุณอาจใช้ apache (หรือดีกว่า, haproxy, nginx หรือ varnish ซึ่งอาจมีประสิทธิภาพมากกว่า apache สำหรับงานการเปลี่ยนเส้นทางนั้น) ในเซิร์ฟเวอร์หลักเพื่อเปลี่ยนเส้นทางไปยังพอร์ต apache ของแต่ละคอนเทนเนอร์

แต่ขึ้นอยู่กับเว็บไซต์ที่คุณใช้งาน (และการกำหนดค่า apache) อาจต้องใช้หน่วยความจำมากกว่าการใช้ apache ส่วนกลางเพียงเครื่องเดียวกับ virtualhosts เป็นพิเศษหากคุณมีโมดูล (เช่น php) ที่ต้องการ RAM จำนวนมาก


ขอบคุณสำหรับคำตอบ. แน่นอนว่าบริการ "โฮสติ้ง" ที่ฉันจะให้นั้นมีหลายอย่างเช่น Prestashop, Wordpress และอื่น ๆ ดังนั้นขึ้นอยู่กับ PHP และเครื่องมือหนัก ๆ
Cyril N.

1
ระบบโฮสติ้งเสมือนจริงของ Dockerized จะถูกทำให้เป็นโมดูลได้ดีขึ้นโดยการแยก PHP ออกเป็นคอนเทนเนอร์ Docker ของตัวเองและทำให้คอนเทนเนอร์ Apache ใช้คอนเทนเนอร์นั้นสำหรับการประมวลผล PHP หรือไม่ ฐานข้อมูลเดียวกันจะนำไปใช้หรือไม่ เช่นมีปริมาณพร็อกซีโฮสต์ไปยังคอนเทนเนอร์ Apache (ซึ่งมีเว็บไซต์ผู้ใช้) ซึ่งส่งการประมวลผล PHP ทั้งหมดไปยังคอนเทนเนอร์ PHP และฐานข้อมูลอ่าน / เขียนไปยังคอนเทนเนอร์ MySQL หรือไม่ หรือ PHP จะมีทรัพยากรน้อยลงด้วยวิธีนี้? PHP-FPM, SuPHP หรือคล้ายกันจะให้การตั้งค่าแบบเดียวกันในสภาพแวดล้อมที่ไม่ใช่นักเทียบท่าหรือไม่?
ojrask

PHP-FPM ในคอนเทนเนอร์อย่างน้อยจะเป็นไฟล์ที่ซ้ำซ้อนเล็กน้อย: code.google.com/p/sna/wiki/NginxWithPHPFPMการติดตั้ง Apache / Nginx ต้องคัดลอกไฟล์ PHP ไปยังคอนเทนเนอร์ PHP-FPM ตามลำดับ เพื่อให้ระบบนี้ใช้งานได้ คอนเทนเนอร์ข้อมูลที่ใช้ร่วมกันที่เมาท์จะแก้ไขปัญหานี้ได้หรือไม่
ojrask

หากคุณต้องการแบ่งปันข้อมูล (เช่นไฟล์ php) ระหว่างคอนเทนเนอร์ปริมาณเป็นวิธีที่จะไปคุณสามารถติดพวกเขาจากภาชนะอื่น ๆ (แม้จะมีคนทุ่มเทข้อมูล) หรือระบบไฟล์จริง apache module เคยเป็นวิธีที่เร็วที่สุดในการรัน php code โดยมีเพียงหนึ่งสำหรับ php ไม่ใช่ไฟล์สแตติกและมีเลเยอร์ด้านบนเพื่อส่งเนื้อหาแบบสแตติก / แคชได้ (Ie varnish) อาจเป็นคำสั่งผสมที่ดี
gmuslera

3

ฉันรู้ว่าคำตอบนี้ได้รับการตอบแล้ว แต่ฉันต้องการที่จะก้าวไปอีกขั้นหนึ่งและแสดงให้คุณเห็นตัวอย่างของวิธีการนี้สามารถทำได้เพื่อให้คำตอบที่สมบูรณ์ยิ่งขึ้น

โปรดดูภาพนักเทียบท่าของฉันที่นี่พร้อมคำแนะนำเกี่ยวกับวิธีใช้งานซึ่งจะแสดงวิธีกำหนดค่าสองไซต์https://hub.docker.com/r/vect0r/httpd-proxy/

ดังที่จีฮุนกล่าวว่าคุณจะต้องแน่ใจว่าคุณมีชุดการกำหนดค่า vhost ตัวอย่างของฉันใช้พอร์ต 80 เพื่อแสดงเว็บไซต์ทดสอบ example.com และ 81 เพื่อแสดงเว็บไซต์ทดสอบ example2.com สิ่งสำคัญที่ควรทราบคือคุณจะต้องระบุเนื้อหาของคุณและแสดงพอร์ตที่จำเป็นใน Dockerfile ของคุณเช่นนั้น

FROM centos:latest
Maintainer vect0r
LABEL Vendor="CentOS"

RUN yum -y update && yum clean all
RUN yum -y install httpd && yum clean all

EXPOSE 80 81

#Simple startup script to aviod some issues observed with container restart
ADD run-httpd.sh /run-httpd.sh
RUN chmod -v +x /run-httpd.sh

#Copy config file across
COPY ./httpd.conf /etc/httpd/conf/httpd.conf
COPY ./example.com /var/www/example.com
COPY ./example2.com /var/www/example2.com
COPY ./sites-available /etc/httpd/sites-available
COPY ./sites-enabled /etc/httpd/sites-enabled

CMD ["/run-httpd.sh"]

หวังว่านี่จะช่วยอธิบายกระบวนการให้ดีขึ้นอีกนิด โปรดอย่าลังเลที่จะถามคำถามเพิ่มเติมใด ๆ เกี่ยวกับเรื่องนี้ยินดีที่จะช่วยเหลือ

ความนับถือ,

V


ฉันได้อัปโหลดไฟล์ที่ใช้สร้างภาพนี้บน github ด้วย; github.com/V3ckt0r/docker-httpd-proxy
Vect0r

1

ในกรณีของฉันฉันต้องเพิ่มSSLProxyEngine On , ProxyPreserveHost Onและ RequestHeader ตั้ง Front-End-Https "On"ในไฟล์ apache 2.4 vhost ของฉันเพราะฉันต้องการเปิดใช้งาน SSL บนคอนเทนเนอร์ docker เกี่ยวกับlocal.hostname.ofDockerHostในกรณีของฉันชื่อของเซิร์ฟเวอร์โฮสต์ที่ใช้งานนักเทียบท่าคอนเทนเนอร์คือลูคัสและพอร์ตที่แมปไปยังพอร์ต 443 ของคอนเทนเนอร์นักเทียบท่าคือ1443 (เพราะพอร์ต 443 มีการใช้งานโดย apache ในโฮสต์แล้ว เซิร์ฟเวอร์) ดังนั้นบรรทัดนั้นจึงลงเอยด้วยวิธีนี้https: // lucas: 1443 /

นี่เป็นการตั้งค่าสุดท้ายและมันใช้ได้ดี!

<VirtualHost *:443> # Change to *:80 if no https required
    ServerName www.somewebsite.com
    <Proxy *>
        Allow from localhost
    </Proxy>
    SSLProxyEngine On # Comment this out if no https required
    RequestHeader set Front-End-Https "On" # Comment this out if no https required
    ProxyPreserveHost    On
    ProxyPass        / http://local.hostname.ofDockerHost:12345/
    ProxyPassReverse / http://local.hostname.ofDockerHost:12345/
</VirtualHost>

ในที่สุดใน container docker ผมต้องทำการติดตั้ง SSL header header ในกรณีของฉันคอนเทนเนอร์กำลังเรียกใช้ nginx และสิ่งที่เรียกว่าomnibusสำหรับการตั้งค่าแอพ ruby ฉันคิดว่านี่สามารถติดตั้งในไฟล์กำหนดค่า nginx ได้เช่นกัน จะเขียนลงตามที่เป็นอยู่ในกรณีที่มีคนพบว่ามีประโยชน์

nginx['redirect_http_to_https'] = true
nginx['proxy_set_headers'] = {
    "Host" => "$http_host",
    "X-Real-IP" => "$remote_addr",
    "X-Forwarded-For" => "$proxy_add_x_forwarded_for",
    "X-Forwarded-Proto" => "https",
    "X-Forwarded-Ssl" => "on"
}
nginx['real_ip_trusted_addresses'] = ['10.0.0.77'] # IP for lucas host
nginx['real_ip_header'] = 'X-Real-IP'
nginx['real_ip_recursive'] = 'on'

คู่มือฉบับสมบูรณ์สำหรับ apache, ISP Config, เซิร์ฟเวอร์ Ubuntu 16.04 ที่นี่https://www.howtoforge.com/community/threads/subdomain-or-subfolder-route-requests-to-running-docker-image.73845/#post-347744

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.