Heroku(Docker)在nginx中的PORT环境变量

时间:2018-03-07 08:37:32

标签: docker nginx heroku dockerfile

我只是对Dockerfile进行了一些修改,以便在Heroku上使用nginx运行它。关于Heroku的一些特别之处在于,一切都以非root身份运行。第二个特定行为是使用来自Heroku本身的随机端口,您无法修改。它们提供了你应该绑定到nginx的env $ PORT。如果Heroku意识到某些东西没有绑定到该端口,则它会停止整个容器。问题是:

如何将nginx绑定到给定的env变量,以便在nginx-site.conf中拥有动态端口? 我尝试在 Dockefile 中使用以下内容:

nginx.conf 中的

env PORT; nginx-site.conf 中的listen PORT_from_env; 还尝试了 nginx-site.conf 中的listen 80; Dockerfile 中的RUN /bin/sed -i "s/listen 80/listen ${PORT}/" /etc/nginx/sites-available/default.conf

我绝对超越自己的能力。有人有想法或可以提供帮助吗?这非常有帮助!

更多信息:

3 个答案:

答案 0 :(得分:2)

通过遵循this example,我就可以在我的应用中使用它了:

步骤1:$PORT中的default.conf.template

server {
  listen $PORT default_server;

  location / {
    root   /usr/share/nginx/html;
    index  index.html;
  }
}

步骤2:将此指令添加到您的Dockerfile

COPY default.conf.template /etc/nginx/conf.d/default.conf.template

步骤3:将此添加到您的Dockerfile

结尾
CMD /bin/bash -c "envsubst '\$PORT' < /etc/nginx/conf.d/default.conf.template > /etc/nginx/conf.d/default.conf" && nginx -g 'daemon off;'

答案 1 :(得分:0)

您需要在启动时更新nginx配置 请参阅this buildpack作为示例(我没有测试它是否有效)。

答案 2 :(得分:0)

我将展示一个不需要编写新Dockerfile的解决方案,您可以使用官方的nginx映像。

就像@Jimmy的解决方案一样,我们将使用envsubst命令,该命令将环境变量替换为Shell格式字符串。
offical nginx image和高山版本都可以使用此命令。

第1步
在模板文件中编写您的nginx配置-我们称其为:site.template

server {
    listen       ${PORT};
    server_name  localhost;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }
}

请注意PORT占位符。

步骤2-使用docker编写
将其挂载在/etc/nginx/conf.d目录中,然后执行envsubst命令以将该模板用作default.conf的引用:

web:
  image: nginx:alpine
  volumes:
   - ./site.template:/etc/nginx/conf.d/site.template
  ports:
   - "3000:8080"
  environment:
   - PORT=8080
  command: /bin/sh -c "envsubst < /etc/nginx/conf.d/site.template > /etc/nginx/conf.d/default.conf && exec nginx -g 'daemon off;'"

请注意:
 1.之后,您需要执行nginx守护程序。
 2.我使用/bin/sh而不是/bin/bash,因为我的基本图像是高山的。


第2步(另一个选项)-内联docker run
如果由于某种原因您不想使用docker-compose,则可以使用以下bash脚本:

#!/usr/bin/env bash

##### Variables #####
PORT=8080 #Or $1 if you pass it from command line
TEMPLATE_DIR=$(pwd)/site.template
TEMPLATE_REMOTE_DIR=/etc/nginx/conf.d/site.template
IMAGE_NAME=nginx:alpine

echo "Starting nginx on port: $PORT ..."

##### The docker command #####
docker run -p 3000:$PORT -v $TEMPLATE_DIR:$TEMPLATE_REMOTE_DIR $IMAGE_NAME \
/bin/sh -c "envsubst < $TEMPLATE_REMOTE_DIR > /etc/nginx/conf.d/default.conf && exec nginx -g 'daemon off;'"