当我lynx localhost:14080
从主机执行此操作时,它起作用了。该网站从容器中加载。
当我lynx localhost:14433
从主机执行此操作时,它不起作用。
当我lynx https://localhost:14433
从主机执行此操作时,它不起作用。错误:无法与远程主机建立安全连接。
容器运行在桥接网络上,由docker-compose启动,容器的IP为:172.21.0.2。
但是,当我lynx https://172.21.0.2
这样做时,它有效......
...该网站使用 https 和 SSL 证书从容器加载。我只收到 SSL 警告:
172.21.02!=cert(CN<example.com>)-继续?
...这意味着证书的 CN 与我尝试打开的 IP 不匹配,但我仍然可以忽略此警告并继续打开该网站。
这意味着 http 在 localhost 上运行(当我使用容器 IP 时它也能运行)。
但是仅当我尝试使用容器 IP 连接时 https 才起作用,而当我使用 localhost 时它不起作用。
这就是我认为docker创建的网络的端口绑定有错误的原因。
我希望能够使用 localhost 连接到容器,这样我就不需要在每次重新启动容器时指定容器的新 IP,因为我计划在主机上设置反向 apache2 代理,以便外界可以使用 https 连接到容器中的网站。
这是我在主机上的 apache2 设置:
我的主机 apache conf 中的文件 example.com.conf:
<VirtualHost *:80>
ServerName example.com
ServerAlias www.example.com
ServerAdmin [email protected]
CustomLog /var/www/docker/example.com/log/host/custom.log combined
ErrorLog /var/www/docker/example.com/log/host/error.log
Redirect permanent / https://example.com/
ProxyRequests off
ProxyPreserveHost On
ProxyPass "/" "http://172.21.0.2/"
ProxyPassReverse "/" "http://172.21.0.2/"
</VirtualHost>
我的主机 apache conf 中的文件 example.com-le-ssl.conf:
<IfModule mod_ssl.c>
ErrorLog /var/www/docker/example.com/log/host/error.log
LogLevel debug
<VirtualHost *:443>
ServerName example.com
ServerAlias www.example.com
ProxyPreserveHost on
ServerAdmin [email protected]
LogLevel debug
CustomLog /var/www/docker/example.com/log/host/custom.log combined
ErrorLog /var/www/docker/example.com/log/host/error.log
<If "%{HTTP_HOST} == 'www.example.com'">
Redirect permanent / https://example.com/
</If>
Include /etc/letsencrypt/options-ssl-apache.conf
SSLProxyEngine on
SSLEngine on
ProxyRequests off
SSLProxyVerify none
SSLProxyCheckPeerCN off
SSLProxyCheckPeerName off
SSLProxyCheckPeerExpire off
<Proxy *>
Order allow,deny
Allow from all
</Proxy>
ProxyPass "/" "http://172.21.0.2/"
ProxyPassReverse "/" "http://172.21.0.2/"
SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
</VirtualHost>
</IfModule>
这是我容器中的 apache 配置:
我的主机 apache conf 中的文件 default-ssl.conf:
ServerName example.com
<VirtualHost _default_:80>
ServerName example.com
ServerAlias www.example.com
ServerADmin [email protected]
DocumentRoot /var/www/html/www
ErrorLog /var/log/container/error.log
CustomLog /var/log/container/custom.log combined
</VirtualHost>
<IfModule mod_ssl.c>
LogLevel debug
<VirtualHost _default_:443>
ServerName example.com
ServerAlias www.example.com
ServerAdmin [email protected]
DocumentRoot /var/www/html/www
LogLevel debug
ErrorLog /var/log/container/error.log
CustomLog /var/log/container/custom.log combined
Include /etc/letsencrypt/options-ssl-apache.conf
SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
</VirtualHost>
</IfModule>
这是我的 docker-compose.yml 文件:
version: '3.7'
networks:
examplewebapp:
driver: bridge
services:
referental:
container_name: examplewebapp
build:
context: ./
dockerfile: Dockerfile
target: dev
image: examplewebapp
restart: unless-stopped
networks:
- examplewebapp
ports:
**- "14433:433"
- "14080:80"**
working_dir: /var/www/html
volumes:
- ./container_apache_conf:/etc/apache2/sites-available
- ./api:/var/www/html/api
- ./archive:/var/www/html/archive
- ./log/container:/var/log/container
- ./log/host:/var/log/host
- ./etc/letsencrypt:/etc/letsencrypt
- ./www:/var/www/html/www
这是我的 Dockerfile:
FROM php:7.4-apache AS base
RUN apt-get update
RUN mkdir -p /var/www/html/www # website will be saved here
RUN mkdir -p /var/log/container # apache logs will be saved here
# mysql connectivity and internationalization for php
RUN docker-php-ext-install mysqli
RUN docker-php-ext-enable mysqli
RUN apt-get install -y libicu-dev
RUN docker-php-ext-configure intl
RUN docker-php-ext-install intl
# enables https for apache
RUN a2enmod ssl
RUN a2ensite default-ssl.conf
FROM base AS dev
RUN pecl install xdebug-3.1.1
RUN docker-php-ext-enable xdebug
FROM base AS test
FROM base AS prod
这是由以下因素生成的:
docker network inspect examplecom_example
[
{
"Name": "examplecom_example",
"Id": "7311d1a7254466bd6ab44833362460cde4336ade622bca87def62bb3d840ef3f" ,
"Created": "2022-02-13T21:16:34.861655456Z",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": null,
"Config": [
{
"Subnet": "172.21.0.0/16",
"Gateway": "172.21.0.1"
}
]
},
"Internal": false,
"Attachable": true,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {
"be53d5b37e2fbcaae49bb111b921dfd4caf5db20ed680403083333ffac983b93": {
"Name": "example",
"EndpointID": "fb1428d29e2fc9564b3e1758a7efac15909a897021320b15f 1df8c1d600efd89",
"MacAddress": "00:00:00:00:00:00",
"IPv4Address": "172.21.0.2/16",
"IPv6Address": ""
},
}
]
这是 docker ps 的输出:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
be53d5b37e2f example "docker-php-entrypoi…" 11 hours ago Up 11 hours 443/tcp, 0.0.0.0:14080->80/tcp, :::14080->80/tcp, 0.0.0.0:14433->433/tcp, :::14433->433/tcp example
我正在使用官方的 php docker 镜像。
在 docker compose 中我正在创建一个桥接网络并且正在映射:
- “14433:433”
- “14080:80”
我的问题是:
为什么我可以使用 http 从我的主机连接到我的容器http://127.0.0.1:14080,但没有使用 httpshttps://127.0.0.1:14433,即使 http 和 https 的两个端口(14080:80 和 14433:433)应该以相同的方式映射?为什么当我使用 https 连接到容器时 https 仍然有效https://172.21.0.2。
我应该怎么做才能使用 localhost 将 https 流量从我的主机 apache(作为反向代理)重定向到我的容器 apache,即https://127.0.0.1:14433/- 这样我的容器就可以从互联网访问,也可以使用 https,所以我不需要在我的宿主 apache 的反向 https 代理配置中指定容器的 IP?
答案1
为什么会有这些*?
**- "14433:433"
- "14080:80"**
尝试一下
version: '3.7'
networks:
examplewebapp:
driver: bridge
services:
referental:
container_name: examplewebapp
build:
context: ./
dockerfile: Dockerfile
target: dev
image: examplewebapp
restart: unless-stopped
networks:these
- examplewebapp
ports:
- "14433:433"
- "14080:80"
working_dir: /var/www/html
volumes:
- ./container_apache_conf:/etc/apache2/sites-available
- ./api:/var/www/html/api
- ./archive:/var/www/html/archive
- ./log/container:/var/log/container
- ./log/host:/vatheser/log/host
- ./etc/letsencrypt:/etc/letsencrypt
- ./www:/var/www/html/www
并且请显示的输出docker ps
。
对于 Apache 作为代理,尽管我听说 nginx 是当今的首选,但您可以使用这样的配置。
<VirtualHost *:80>
ServerName your.vhost.tld
RewriteEngine on
RewriteCond %{HTTPS} !=on
# This checks to make sure the connection is not already HTTPS
RewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [R,L]
ErrorLog ${APACHE_LOG_DIR}/your.vhost.tld-error.log
CustomLog ${APACHE_LOG_DIR}/your.vhost.tld-access.log vhost_combined
</VirtualHost>
<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerName your.vhost.tld
<Proxy *>
order deny,allow
Allow from all
</Proxy>
SSLEngine on
SSLCertificateFile /etc/apache2/ssl/your.vhost.tld/certificate.crt
SSLCertificateKeyFile /etc/apache2/ssl/your.vhost.tld/certificate.key
#SSLCACertificateFile /etc/apache2/ssl/your.vhost.tld/cert.cabundle
SetEnv force-proxy-request-1.0 1
SetEnv proxy-nokeepalive 1
SetEnv proxy-initial-not-pooled 1
ErrorLog ${APACHE_LOG_DIR}/your.vhost.tld-error.log
CustomLog ${APACHE_LOG_DIR}/your.vhost.tld-access.log vhost_combined
ProxyTimeout 600
SSLProxyEngine On
#ProxyRequests On
#ProxyPreserveHost On
RewriteEngine off
#PROXY's
ProxyRequests Off
<Location "/">
ProxyPreserveHost On
ProxyPass https://localhost:14443
ProxyPassReverse https://localhost:14443
</VirtualHost>
</IfModule>