在Docker中启用Apache SSL进行本地开发

24

我正在将我们目前的旧应用程序进行Docker化。我们使用了几个服务,但我遇到问题的是php、apache,尤其是apache的https。我正在使用“php:5.6.30-apache”镜像,因此我预先安装了php和apache。

现在我已经更改了“000-default.conf”的内容:

<VirtualHost *:80>
    ServerAdmin admin@admin.io
    DocumentRoot /var/www/html/app/htdocsAdmin
    ServerName admin.local.app.io
    CustomLog /var/log/apache2/app.admin.access.log "trueip_combined"
    ErrorLog /var/log/apache2/app.admin.error.log
    <Directory /var/www/html/app/htdocsAdmin>
        AllowOverride Options FileInfo AuthConfig
        Require all granted
    </Directory>
</VirtualHost>

这是我的 Docker 文件:

FROM php:5.6.30-apache

MAINTAINER Tzook Bar Noy

ADD default /etc/apache2/sites-available/000-default.conf


RUN apt-get update \
  && apt-get install -y apt-utils \
  && apt-get install -y php5-dev php5-memcached \
  && apt-get install -y memcached



RUN apt-get update && apt-get install -y apt-utils
RUN apt-get install -y libz-dev libmemcached-dev
RUN pecl install memcached-2.2.0
RUN echo extension=memcached.so >> /usr/local/etc/php/conf.d/memcached.ini

RUN a2enmod rewrite
RUN a2enmod ssl


EXPOSE 80
EXPOSE 443

不要在意memcached的东西,只看我开启了"ssl"并将80和443端口暴露出来

这是通过docker-compose运行的:

php:
build:
  context: ./php
  dockerfile: Dockerfile
ports:
  - "80:80"
  - "443:443"
volumes:
  - ./../../:/var/www/html
networks:
  - appnet
tty: true

但即使经历了所有这些,我仍然从Chrome中看到了这个:

"ERR_SSL_PROTOCOL_ERROR"

根据评论要求,这是我的 "docker ps" 响应:在此输入图片描述


两件事情:你在dockerfile中重复了相同的命令;你需要展示你使用的docker run命令。 - Burhan Khalid
@BurhanKhalid 哪个命令?我是用docker-compose运行的,这里只粘贴了相关部分。 - Tzook Bar Noy
运行 docker-compose up -d 后,您的 Apache 容器的日志文件和 docker ps 命令的输出是什么? - Burhan Khalid
1
你是如何在不上传任何证书到服务器的情况下配置SSL的? - Burhan Khalid
@BurhanKhalid 我是那么愚蠢吗,即使我并不真的在意它,而且它只是用于本地使用,我也必须添加它们吗? - Tzook Bar Noy
显示剩余3条评论
2个回答

34
除了启用 SSL 并开放 443 端口外,您还需要创建(自签名的)证书+私钥,并确保 Apache 有权访问这些内容。
我建议使用 OpenSSL 创建自签名证书:
openssl req -new -newkey rsa:4096 -days 3650 -nodes -x509 -subj \
    "/C=../ST=...../L=..../O=..../CN=..." \
    -keyout ./ssl.key -out ./ssl.crt

不要使用省略号(...),而是填写你的2位字母国家代码(/C),你所在州或省的名称(/ST),你所在地区的名称(/L),你的组织机构名称(/O)和你的服务器FQDN(/CN)。

然后将以下行添加到你的docker文件中:

COPY ./path/to/ssl.crt /etc/apache2/ssl/ssl.crt
COPY ./path/to/ssl.key /etc/apache2/ssl/ssl.key
RUN mkdir -p /var/run/apache2/

我不确定最后一行是否真的必要,但在我的Docker容器中,该文件夹尚不存在,导致Apache启动失败。

最后,在您的000-default.conf文件中,您需要添加类似于以下内容的代码:

<VirtualHost *:443>
  SSLEngine on
  SSLCertificateFile /etc/apache2/ssl/ssl.crt
  SSLCertificateKeyFile /etc/apache2/ssl/ssl.key
  ....
</VirtualHost>
注意,当您使用自签名证书时,大多数浏览器会警告您“您的连接不安全”(Firefox)或“无效证书”(Chrome)。这是因为没有有效的安全链到受信任的CA。大多数浏览器允许您继续请求或将网站添加为异常情况,以便不再显示警告。

在我的情况下,我使用了default-ssl.conf文件,但是忘记启用该站点(a2ensite default-ssl)。这导致我在访问该站点时出现了错误SSL_ERROR_RX_RECORD_TOO_LONG。希望这能帮助遇到同样问题的人。 :) - Ricardo Martins
./path/to/ssl.crt 是什么意思?是什么决定了路径?这是 Docker 运行的 DIR 吗?还是我的 WORKDIR? - James
1
@James 这里的假设是Docker正在运行创建ssl文件的设备上,因此COPY命令将这些文件从创建它们的位置复制到Docker容器中的Apache文件夹中。 - THelper

18

以下是我如何在 Docker 中启用本地开发的 Apache SSL。这是在 macOS 上运行 Ubuntu 镜像的 Docker(尽管 mkcert 也可在 Linux 和 Windows 上使用):

• 在 macOS 上,安装 mkcert

brew install mkcert
brew install nss # if you use Firefox

mkcert 可以轻松地创建并安装用于本地开发的 SSL 证书。

• 创建 SSL 证书:

mkcert mysite.localhost someothersite.localhost localhost 127.0.0.1 ::1

这将在macOS上为您安装它们,但也会在当前工作目录中留下一个副本:

mysite.localhost+4-key.pem
mysite.localhost+4.pem

• 将这两个 .pem 文件提供给您的Docker容器。例如:将它们与容器的配置文件一起移动,并添加以下内容:

- ./config/ssl:/etc/apache2/ssl/

• 在容器的docker-compose中打开端口443

- "443:443"

(同时,在镜像中也应该EXPOSE 443,尽管出于某些原因,我在不这样做的情况下也能正常工作。)(编辑:EXPOSE仅仅是文档说明,根据文档不会执行任何操作)

• 在Apache中启用SSL:

RUN ln -s /etc/apache2/mods-available/ssl.load  /etc/apache2/mods-enabled/ssl.load

虽然从技术上讲,我首先在我的运行容器中做了这个,随后是apachectl restart。这样做可以更轻松地测试并确保一切正常,然后再提交重建镜像。

• 通过编辑mysite.localhost和你想要使用SSL的任何其他域,在Apache中配置你的网站以使用SSL:

<VirtualHost *:443>
    …
    SSLEngine on
    SSLCertificateFile "/etc/apache2/ssl/clickandspeak.localhost+4.pem"
    SSLCertificateKeyFile "/etc/apache2/ssl/clickandspeak.localhost+4-key.pem"
    …
</VirtualHost>

只需复制您旧的配置,从<VirtualHost *:80>更改端口为443,并添加上面的三行即可。

根据需要重建镜像并重新启动容器。

…et voilà!


1
非常感谢。我必须添加以下内容以启用SSL:COPY ./config/default-ssl.conf /etc/apache2/sites-available/default-ssl.conf RUN ln -s /etc/apache2/mods-available/ssl.load /etc/apache2/mods-enabled/ssl.load RUN a2ensite default-ssl.conf - CZ54

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接