【问题标题】:Docker phoenix with ssl on port 443 is not receiving anything在端口 443 上使用 ssl 的 Docker phoenix 没有收到任何内容
【发布时间】:2020-05-11 20:43:47
【问题描述】:

各位开发者,

出于对一切的热爱,我似乎无法让它工作......我有一个 docker 容器,其中运行着一个 phoenix 应用程序。它托管在子域“sub.example.com”上,我需要使用 https 来提供它。

所以我给自己弄了一个通配符 SSL 证书,安装了它,配置了生产文件并暴露了 docker 容器的 80 和 443 端口。

试过了,端口 80 工作正常,但 443 总是返回“ERR_CONNECTION_RESET”。日志在 443 上没有显示任何内容,但 80 工作正常。

已经尝试了一段时间,现在我需要你的帮助。有什么想法吗?检查下面的代码:

Dockerfile

FROM bitwalker/alpine-elixir-phoenix:latest

# create app folder
RUN mkdir /app
WORKDIR /app
COPY . .

# setting the port and the environment (prod = PRODUCTION!)
EXPOSE 80
EXPOSE 443

# install dependencies (production only)
RUN mix local.rebar --force
RUN mix deps.get --only prod
RUN mix compile

prod.exs

config :example, ExampleWeb.Endpoint,
  http: [port: 80],
  url: [host: "sub.example.com"],
  cache_static_manifest: "priv/static/cache_manifest.json",
  https: [
    cipher_suite: :strong,
    otp_app: :example,
    port: 443,
    keyfile: System.get_env("SSL_KEY_PATH"),
    certfile: System.get_env("SSL_CERT_PATH"),
    cacertfile: System.get_env("SSL_CHAINED_CERT_PATH")
  ]

curl https://sub.example.com/ --verbose 结果:

*   Trying 64.225.24.82...
* TCP_NODELAY set
* Connected to sub.example.com (64.225.24.82) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/cert.pem
  CApath: none
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* LibreSSL SSL_connect: SSL_ERROR_SYSCALL in connection to sub.example.com:443
* Closing connection 0
curl: (35) LibreSSL SSL_connect: SSL_ERROR_SYSCALL in connection to sub.example.com:443

编辑: 我正在手动设置容器内的 ENV 变量。例如在 bash 中:

SSL_KEY_PATH=path/example.key SSL_CERT_PATH=path/example.crt SSL_CHAINED_CERT_PATH=path/example_chained.crt MIX_ENV=prod mix phx.server

【问题讨论】:

  • 您使用的是什么版本的 Phoenix?您在哪里设置 ENV 变量(SSL_KEY_PATHSSL_CERT_PATHSSL_CHAINED_CERT_PATH)?
  • 您的docker run 命令是什么样的?您是否正确地将 EXPOSEd 端口映射到主机上的端口?您是否尝试将urlruntime config 设置为也包括schemeport
  • @Everett 我目前正在使用phoenix 1.4.13。我在启动时设置 ENV 变量。我的命令看起来像:SSL_KEY=path/to/it SSL_CERT=path/to/it mix phx.server.
  • @jamesvl 我的 docker 运行命令是 docker run -it -p 80:80 -p 443:443 --entrypoint=bash --name example-app example:1.0。我也尝试过设置schemeport。但没有成功:(。我一直在环顾四周,似乎我必须使用像 nginx 之类的代理服务器?
  • 当你运行 mix phx.server 时,你是从你的主机操作系统运行它,还是你在 Dockerfile 的某个地方指定 ENTRYPOINT?因为我没有看到您的 Docker 容器从哪里获取这些 ENV 值...

标签: docker ssl https elixir phoenix-framework


【解决方案1】:

您的 Dockerfile 未指定 MIX_ENV,因此可能正在使用默认的 MIX_ENV=dev 构建和运行。

它也没有指定用于运行实际应用程序的命令,通常是本地mix phx.server

这是我用来在本地运行应用程序的示例 Dockerfile;这没有针对大小或构建速度进行了优化,不应该在生产中使用(为此做一个完整的混合版本),但如果它有帮助:

FROM elixir:1.10.1-alpine AS dev_img

# Environment
ENV MIX_ENV prod
ENV PORT 4000
ENV SSL_PORT 4001

# Install required system dependencies
RUN apk update; \
  apk upgrade --no-cache; \
  apk add --no-cache libsodium libsodium-dev nodejs npm curl git inotify-tools build-base; \
  mix local.rebar --force; \
  mix local.hex --force

WORKDIR /opt/app
COPY . .

RUN mix do deps.get, compile

RUN cd assets; \
  npm ci; \
  cd ..

ENV PG_DB_PORT 5432
ENV PG_DB_HOST db-container-name
ENV SSL_KEY_PATH
ENV OTHER_VARS

CMD ["mix", "phx.server"]

【讨论】:

  • 感谢您的回答,但我正在使用 MIX_ENV=prop SSL_PATH=example ETC=example mix phx.server 在容器内手动设置 ENV 变量
【解决方案2】:

经过几天的搜索、试验和错误以及与其他开发人员的争吵。我已经使用带有 nginx 的代理服务器解决了这个问题。以下是实现这一切的配置!

凤凰 - prod.exs

config :example, ExampleWeb.Endpoint,
  http: [port: 5000],
  url: [host: "sub.example.com", port: 5000]

nginx 配置

upstream phoenix {
  server 0.0.0.0:5000;
}

map $http_upgrade $connection_upgrade {
  default upgrade;
  '' close;
}

server {
  server_name sub.example.com;
  listen 443 ssl http2;
  listen [::]:443 ssl http2;

  ssl_certificate /etc/nginx/ssl/example_chained.pem;
  ssl_certificate_key /etc/nginx/ssl/example.pem;

  large_client_header_buffers 4 16k;

  location ~ live/websocket {
    proxy_http_version 1.1;
    proxy_set_header Origin '';
    proxy_set_header X-Forwarded-Host $proxy_add_x_forwarded_for;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "Upgrade";
    proxy_ssl_server_name on;
    proxy_pass http://0.0.0.0:5000;
    break;
  }

  location / {
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_redirect off;
    proxy_ssl_server_name on;
    proxy_pass http://0.0.0.0:5000;
    break;
  }
}

在此处找到进一步的讨论:

https://elixirforum.com/t/phoenix-app-in-docker-with-ssl-not-receiving-anything-on-port-443/31229

【讨论】:

    猜你喜欢
    • 2021-06-09
    • 1970-01-01
    • 2015-05-12
    • 1970-01-01
    • 1970-01-01
    • 2019-04-19
    • 1970-01-01
    • 2017-10-07
    • 2013-12-06
    相关资源
    最近更新 更多