Docker - 在不同网站的主机和容器上运行Apache

时间:2022-05-08 20:45:29

I want to use Docker in order to be able to run an old application that requires PHP 5.3, while still having my other websites on my host server, running on the host Apache.

我想使用Docker,以便能够运行需要PHP 5.3的旧应用程序,同时仍然在我的主机服务器上运行其他网站,在主机Apache上运行。

So I have siteA.com, siteB.com, siteC.com running on the host, using the host Apache / PHP / MySQL server, and I have siteZ.com that is installed in a Docker container, which should be using the container's Apache / PHP but the host MySQL server.

所以我在主机上运行了siteA.com,siteB.com,siteC.com,使用主机Apache / PHP / MySQL服务器,我有一个安装在Docker容器中的siteZ.com,它应该使用容器的Apache / PHP但主机MySQL服务器。

Here's a representation of the architecture I'd like to obtain :

这是我想要获得的架构的表示:

Docker  - 在不同网站的主机和容器上运行Apache

My issue is that it seems like I can't run Apache in the container, since the port 80 is already in use on the host.

我的问题是,似乎我无法在容器中运行Apache,因为端口80已经在主机上使用。

My goal would be that the people could access siteA.com, siteB.com, siteC.com and siteZ.com, without having to specify a different port for any of those websites.

我的目标是人们可以访问siteA.com,siteB.com,siteC.com和siteZ.com,而无需为任何这些网站指定不同的端口。

I managed to get siteZ.com running by using port 8080, but it's obviously not an option.

我设法使用端口8080运行siteZ.com,但显然不是一个选项。

Thanks

谢谢

PS : Please note that I'm completly new to Docker.

PS:请注意我对Docker完全不熟悉。

Edit : You can find my working solution here. Thanks to VonC for showing me the way to go :)

编辑:您可以在这里找到我的工作解决方案。感谢VonC向我展示了要走的路:)

3 个解决方案

#1


9  

I can't run Apache in the container, since the port 80 is already in use on the host.

我无法在容器中运行Apache,因为端口80已在主机上使用。

Sure you can: in a container, you can run Apache on any port you want.

当然你可以:在一个容器中,你可以在你想要的任何端口上运行Apache。

but when you do docker run, then you need to map this container port to a host port (which won't be 80, since it is already taken, but for instance 8080

但是当您执行docker run时,则需要将此容器端口映射到主机端口(不会是80,因为它已经被占用,但是例如8080

docker run -d -p 8080:80 yourImage

My goal would be that the people could access siteA.com, siteB.com, siteC.com and siteZ.com

我的目标是人们可以访问siteA.com,siteB.com,siteC.com和siteZ.com

That is called reverse proxy, and you could run on port 80 a NGiNX (in a container or not) which would then reverse proxy back to siteA, B or C (each running on different port, in container or not).
See for instance "Nginx reverse proxy with multiple ssl domain".

这被称为反向代理,您可以在端口80上运行NGiNX(在容器中或不在容器中),然后将代理反向回到siteA,B或C(每个都在不同的端口上运行,在容器中或不在容器中)。例如,参见“具有多个ssl域的Nginx反向代理”。

Your main Apache wouldn't run directly on port 80 anymore (or it could, if you put it in a container!)

您的主Apache不再直接在端口80上运行(或者,如果您将它放在容器中,它可以!)

The goal behind putting everything in its own container is isolation.
Not just filesystem isolation with chroot, or memory isolation, but also configuration isolation: in a container, an Apache always run (if you want) in 80/443, not matter how many Apache containers are running.
You just launch them with the proper host port mapping, but inside a container, the config remains fixed and identical.

将所有东西放在自己的容器中的目标是隔离。不仅仅是chroot的文件系统隔离,或内存隔离,还有配置隔离:在容器中,Apache始终在80/443中运行(如果需要),无论运行多少个Apache容器。您只需使用正确的主机端口映射启动它们,但在容器内,配置保持固定且相同。

#2


9  

Thanks to VonC's answer I managed to get it working but I slightly changed my architecture, resulting in 3 containers instead of only 1.

感谢VonC的回答,我设法让它工作但我稍微改变了我的架构,导致3个容器而不是1个。

I have one container for each Apache / PHP version, and one container with Nginx as reverse proxy. I think you can easily adapt this to install Nginx on the host and change it's configuration to match the architecture I described in my question.

我有一个容器用于每个Apache / PHP版本,一个容器用Nginx作为反向代理。我认为您可以轻松地调整它以在主机上安装Nginx并更改它的配置以匹配我在我的问题中描述的架构。

Note that as I'm new to Docker, and a noob regarding Linux system administration, their's probably some mistakes and things that doesn't make any sense in the following scripts, but it's working for me. Feel free to improve it :)

请注意,由于我是Docker的新手,而且是关于Linux系统管理的新手,他们可能会遇到一些错误以及在以下脚本中没有任何意义的事情,但它对我有用。随意改进它:)


Nginx Reverse Proxy image

The Dockerfile :

Dockerfile:

FROM debian:jessie

MAINTAINER AntoineB version: 0.1

RUN apt-get update && \
    apt-get install -y --force-yes \
            nginx \
        nano

EXPOSE 80
EXPOSE 443

ADD ./proxy.conf /etc/nginx/conf.d/proxy.conf

CMD ["nginx"]

Here's the referenced proxy.conf file :

这是引用的proxy.conf文件:

proxy_redirect          off;
proxy_set_header        Host            $host;
proxy_set_header        X-Real-IP       $remote_addr;
proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size    10m;
client_body_buffer_size 128k;
client_header_buffer_size 64k;
proxy_connect_timeout   90;
proxy_send_timeout      90;
proxy_read_timeout      90;
proxy_buffer_size   16k;
proxy_buffers       32   16k;
proxy_busy_buffers_size 64k;

And I run it using the following bash script :

我使用以下bash脚本运行它:

docker run -ti -d -p 80:80 -v /home/antoineb/Docker/images/nginxproxy/virtualhosts:/etc/nginx/sites-enabled --name nginxproxy nginxproxy /bin/bash

I have a /home/antoineb/Docker/images/nginxproxy/virtualhosts folder on my host that contains the following default file :

我的主机上有/ home / antoineb / Docker / images / nginxproxy / virtualhosts文件夹,其中包含以下默认文件:

server {
       listen 80;

       server_name  siteZ.com;
       location / {
            proxy_pass http://apache22php53:80;
       }
}

server {
       listen 80;

       server_name  siteA.com;
       location / {
            proxy_pass http://apache24php56:80;
       }
}
server {
       listen 80;

       server_name  siteB.com;
       location / {
            proxy_pass http://apache24php56:80;
       }
}

Apache 2.2 + PHP 5.3 image

Dockerfile :

Dockerfile:

FROM debian:wheezy

MAINTAINER AntoineB version: 0.1

RUN apt-get update

RUN echo "deb http://packages.dotdeb.org squeeze all" > /etc/apt/sources.list.d/dotdeb_squeeze.list
RUN echo "deb-src http://packages.dotdeb.org squeeze all" >> /etc/apt/sources.list.d/dotdeb_squeeze.list
RUN echo "deb http://ftp.debian.org/debian/ squeeze main contrib non-free" >> /etc/apt/sources.list.d/dotdeb_squeeze.list

RUN echo "Package: *php*" > /etc/apt/preferences.d/php53.pref
RUN echo "Pin: release o=packages.dotdeb.org,n=squeeze" >> /etc/apt/preferences.d/php53.pref
RUN echo "Pin-Priority: 989" >> /etc/apt/preferences.d/php53.pref

RUN apt-get update && \
    apt-get install -y --force-yes \
            apache2 \
        php5 \
        php5-curl \
        php5-gd \
        php5-mysql \
        nano

RUN a2enmod \
            php5 \
        rewrite

ENV APACHE_RUN_USER www-data
ENV APACHE_RUN_GROUP    www-data
ENV APACHE_LOG_DIR  /var/log/apache2
ENV APACHE_LOCK_DIR /var/lock/apache2
ENV APACHE_PID_FILE /var/run/apache2.pid

EXPOSE 80
EXPOSE 443

CMD /usr/sbin/apache2ctl -D FOREGROUND

I'm launching it using the following script :

我正在使用以下脚本启动它:

docker run -ti -d -p 2253:80 -v /home:/home -v /home/antoineb/Docker/images/apache22php53/virtualhosts:/etc/apache2/sites-enabled --name apache22php53 apache22php53 /bin/bash

My websites are stored in /home/website.com/www, and my apache virtualhosts are stored on the host in /home/antoineb/Docker/images/apache22php53/virtualhosts.

我的网站存储在/home/website.com/www中,我的apache虚拟主机存储在/ home / antoineb / Docker / images / apache22php53 / virtualhosts中的主机上。


Apache 2.4 + PHP 5.6.9 image

Dockerfile :

Dockerfile:

FROM debian:jessie

MAINTAINER AntoineB version: 0.1

RUN apt-get update && \
    apt-get install -y --force-yes \
            apache2 \
        php5 \
        php5-curl \
        php5-gd \
        php5-mysql \
        nano

RUN a2enmod \
            php5 \
        rewrite

ENV APACHE_RUN_USER www-data
ENV APACHE_RUN_GROUP    www-data
ENV APACHE_LOG_DIR  /var/log/apache2
ENV APACHE_LOCK_DIR /var/lock/apache2
ENV APACHE_PID_FILE /var/run/apache2.pid

EXPOSE 80
EXPOSE 443

CMD /usr/sbin/apache2ctl -D FOREGROUND

My running script :

我的运行脚本:

docker run -ti -d -p 2456:80 -v /home:/home -v /home/antoineb/Docker/images/apache24php56/virtualhosts:/etc/apache2/sites-enabled --name apache24php56 apache24php56 /bin/bash

Again, my websites are stored in /home/website.com/www, and my apache virtualhosts are stored on the host in /home/antoineb/Docker/images/apache24php56/virtualhosts.

同样,我的网站存储在/home/website.com/www中,我的apache虚拟主机存储在/ home / antoineb / Docker / images / apache24php56 / virtualhosts中的主机上。

#3


0  

You can use host-based routing in docker glue

您可以在docker glue中使用基于主机的路由

https://github.com/muayyad-alsadi/docker-glue

https://github.com/muayyad-alsadi/docker-glue

it's a light-weight daemon that generates haproxy templates on the fly (you can define nginx template if you like) that watch container labels like this

它是一个轻量级的守护进程,可以动态生成haproxy模板(如果你愿意,你可以定义nginx模板),监视像这样的容器标签

docker run -d --name wp1 -l glue_http_80_host='wp1.example.com' mywordpress/wordpress 
docker run -d --name wp2 -l glue_http_80_host='wp2.example.com' mywordpress/wordpress 

in this setup the glue daemon will generate haproxy config so that traffic to wp1.example.com goes to wp1 container

在此设置中,胶水守护程序将生成haproxy配置,以便流向wp1.example.com的流量转到wp1容器

#1


9  

I can't run Apache in the container, since the port 80 is already in use on the host.

我无法在容器中运行Apache,因为端口80已在主机上使用。

Sure you can: in a container, you can run Apache on any port you want.

当然你可以:在一个容器中,你可以在你想要的任何端口上运行Apache。

but when you do docker run, then you need to map this container port to a host port (which won't be 80, since it is already taken, but for instance 8080

但是当您执行docker run时,则需要将此容器端口映射到主机端口(不会是80,因为它已经被占用,但是例如8080

docker run -d -p 8080:80 yourImage

My goal would be that the people could access siteA.com, siteB.com, siteC.com and siteZ.com

我的目标是人们可以访问siteA.com,siteB.com,siteC.com和siteZ.com

That is called reverse proxy, and you could run on port 80 a NGiNX (in a container or not) which would then reverse proxy back to siteA, B or C (each running on different port, in container or not).
See for instance "Nginx reverse proxy with multiple ssl domain".

这被称为反向代理,您可以在端口80上运行NGiNX(在容器中或不在容器中),然后将代理反向回到siteA,B或C(每个都在不同的端口上运行,在容器中或不在容器中)。例如,参见“具有多个ssl域的Nginx反向代理”。

Your main Apache wouldn't run directly on port 80 anymore (or it could, if you put it in a container!)

您的主Apache不再直接在端口80上运行(或者,如果您将它放在容器中,它可以!)

The goal behind putting everything in its own container is isolation.
Not just filesystem isolation with chroot, or memory isolation, but also configuration isolation: in a container, an Apache always run (if you want) in 80/443, not matter how many Apache containers are running.
You just launch them with the proper host port mapping, but inside a container, the config remains fixed and identical.

将所有东西放在自己的容器中的目标是隔离。不仅仅是chroot的文件系统隔离,或内存隔离,还有配置隔离:在容器中,Apache始终在80/443中运行(如果需要),无论运行多少个Apache容器。您只需使用正确的主机端口映射启动它们,但在容器内,配置保持固定且相同。

#2


9  

Thanks to VonC's answer I managed to get it working but I slightly changed my architecture, resulting in 3 containers instead of only 1.

感谢VonC的回答,我设法让它工作但我稍微改变了我的架构,导致3个容器而不是1个。

I have one container for each Apache / PHP version, and one container with Nginx as reverse proxy. I think you can easily adapt this to install Nginx on the host and change it's configuration to match the architecture I described in my question.

我有一个容器用于每个Apache / PHP版本,一个容器用Nginx作为反向代理。我认为您可以轻松地调整它以在主机上安装Nginx并更改它的配置以匹配我在我的问题中描述的架构。

Note that as I'm new to Docker, and a noob regarding Linux system administration, their's probably some mistakes and things that doesn't make any sense in the following scripts, but it's working for me. Feel free to improve it :)

请注意,由于我是Docker的新手,而且是关于Linux系统管理的新手,他们可能会遇到一些错误以及在以下脚本中没有任何意义的事情,但它对我有用。随意改进它:)


Nginx Reverse Proxy image

The Dockerfile :

Dockerfile:

FROM debian:jessie

MAINTAINER AntoineB version: 0.1

RUN apt-get update && \
    apt-get install -y --force-yes \
            nginx \
        nano

EXPOSE 80
EXPOSE 443

ADD ./proxy.conf /etc/nginx/conf.d/proxy.conf

CMD ["nginx"]

Here's the referenced proxy.conf file :

这是引用的proxy.conf文件:

proxy_redirect          off;
proxy_set_header        Host            $host;
proxy_set_header        X-Real-IP       $remote_addr;
proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size    10m;
client_body_buffer_size 128k;
client_header_buffer_size 64k;
proxy_connect_timeout   90;
proxy_send_timeout      90;
proxy_read_timeout      90;
proxy_buffer_size   16k;
proxy_buffers       32   16k;
proxy_busy_buffers_size 64k;

And I run it using the following bash script :

我使用以下bash脚本运行它:

docker run -ti -d -p 80:80 -v /home/antoineb/Docker/images/nginxproxy/virtualhosts:/etc/nginx/sites-enabled --name nginxproxy nginxproxy /bin/bash

I have a /home/antoineb/Docker/images/nginxproxy/virtualhosts folder on my host that contains the following default file :

我的主机上有/ home / antoineb / Docker / images / nginxproxy / virtualhosts文件夹,其中包含以下默认文件:

server {
       listen 80;

       server_name  siteZ.com;
       location / {
            proxy_pass http://apache22php53:80;
       }
}

server {
       listen 80;

       server_name  siteA.com;
       location / {
            proxy_pass http://apache24php56:80;
       }
}
server {
       listen 80;

       server_name  siteB.com;
       location / {
            proxy_pass http://apache24php56:80;
       }
}

Apache 2.2 + PHP 5.3 image

Dockerfile :

Dockerfile:

FROM debian:wheezy

MAINTAINER AntoineB version: 0.1

RUN apt-get update

RUN echo "deb http://packages.dotdeb.org squeeze all" > /etc/apt/sources.list.d/dotdeb_squeeze.list
RUN echo "deb-src http://packages.dotdeb.org squeeze all" >> /etc/apt/sources.list.d/dotdeb_squeeze.list
RUN echo "deb http://ftp.debian.org/debian/ squeeze main contrib non-free" >> /etc/apt/sources.list.d/dotdeb_squeeze.list

RUN echo "Package: *php*" > /etc/apt/preferences.d/php53.pref
RUN echo "Pin: release o=packages.dotdeb.org,n=squeeze" >> /etc/apt/preferences.d/php53.pref
RUN echo "Pin-Priority: 989" >> /etc/apt/preferences.d/php53.pref

RUN apt-get update && \
    apt-get install -y --force-yes \
            apache2 \
        php5 \
        php5-curl \
        php5-gd \
        php5-mysql \
        nano

RUN a2enmod \
            php5 \
        rewrite

ENV APACHE_RUN_USER www-data
ENV APACHE_RUN_GROUP    www-data
ENV APACHE_LOG_DIR  /var/log/apache2
ENV APACHE_LOCK_DIR /var/lock/apache2
ENV APACHE_PID_FILE /var/run/apache2.pid

EXPOSE 80
EXPOSE 443

CMD /usr/sbin/apache2ctl -D FOREGROUND

I'm launching it using the following script :

我正在使用以下脚本启动它:

docker run -ti -d -p 2253:80 -v /home:/home -v /home/antoineb/Docker/images/apache22php53/virtualhosts:/etc/apache2/sites-enabled --name apache22php53 apache22php53 /bin/bash

My websites are stored in /home/website.com/www, and my apache virtualhosts are stored on the host in /home/antoineb/Docker/images/apache22php53/virtualhosts.

我的网站存储在/home/website.com/www中,我的apache虚拟主机存储在/ home / antoineb / Docker / images / apache22php53 / virtualhosts中的主机上。


Apache 2.4 + PHP 5.6.9 image

Dockerfile :

Dockerfile:

FROM debian:jessie

MAINTAINER AntoineB version: 0.1

RUN apt-get update && \
    apt-get install -y --force-yes \
            apache2 \
        php5 \
        php5-curl \
        php5-gd \
        php5-mysql \
        nano

RUN a2enmod \
            php5 \
        rewrite

ENV APACHE_RUN_USER www-data
ENV APACHE_RUN_GROUP    www-data
ENV APACHE_LOG_DIR  /var/log/apache2
ENV APACHE_LOCK_DIR /var/lock/apache2
ENV APACHE_PID_FILE /var/run/apache2.pid

EXPOSE 80
EXPOSE 443

CMD /usr/sbin/apache2ctl -D FOREGROUND

My running script :

我的运行脚本:

docker run -ti -d -p 2456:80 -v /home:/home -v /home/antoineb/Docker/images/apache24php56/virtualhosts:/etc/apache2/sites-enabled --name apache24php56 apache24php56 /bin/bash

Again, my websites are stored in /home/website.com/www, and my apache virtualhosts are stored on the host in /home/antoineb/Docker/images/apache24php56/virtualhosts.

同样,我的网站存储在/home/website.com/www中,我的apache虚拟主机存储在/ home / antoineb / Docker / images / apache24php56 / virtualhosts中的主机上。

#3


0  

You can use host-based routing in docker glue

您可以在docker glue中使用基于主机的路由

https://github.com/muayyad-alsadi/docker-glue

https://github.com/muayyad-alsadi/docker-glue

it's a light-weight daemon that generates haproxy templates on the fly (you can define nginx template if you like) that watch container labels like this

它是一个轻量级的守护进程,可以动态生成haproxy模板(如果你愿意,你可以定义nginx模板),监视像这样的容器标签

docker run -d --name wp1 -l glue_http_80_host='wp1.example.com' mywordpress/wordpress 
docker run -d --name wp2 -l glue_http_80_host='wp2.example.com' mywordpress/wordpress 

in this setup the glue daemon will generate haproxy config so that traffic to wp1.example.com goes to wp1 container

在此设置中,胶水守护程序将生成haproxy配置,以便流向wp1.example.com的流量转到wp1容器