【问题标题】:How to pass environment variable to nginx.conf file in docker?如何将环境变量传递给 docker 中的 nginx.conf 文件?
【发布时间】:2023-01-20 20:02:11
【问题描述】:

我正在尝试使用 docker 在 rails 上设置 ruby​​ 一切都很好,但我希望在通过 docker-compose 命令构建映像期间将动态域作为环境变量传递给 nginx.conf 文件,但我不知道该怎么做。 我试图使用这个命令 Docker-compose构建 dcoker-撰写

码头文件

FROM ruby:2.7.2
ENV RAILS_ROOT /var/www/quickcard
ENV BUNDLE_VERSION 2.1.4
ENV BUNDLE_PATH usr/local/bundle/gems
ENV RAILS_LOG_TO_STDOUT true
ENV RAILS_PORT 5000
COPY ./entrypoint.sh /usr/local/bin/entrypoint.sh
RUN chmod +x /usr/local/bin/entrypoint.sh
RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
RUN echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list
RUN apt-get update -qq && apt-get install -y build-essential \
git \
libxml2-dev \
libpq-dev \
libxslt-dev \
nodejs \
yarn \
imagemagick \
tzdata \
less \
cron \
&& rm -rf /var/cache/apk/*
RUN gem install bundler --version "$BUNDLE_VERSION"
RUN mkdir -p $RAILS_ROOT
WORKDIR $RAILS_ROOT
ADD Gemfile Gemfile
ADD Gemfile.lock Gemfile.lock
COPY yarn.lock yarn.lock
RUN bundle install
EXPOSE $RAILS_PORT
RUN ln -s $RAILS_ROOT/config/systemd/puma.service /etc/systemd/system/quickcard
COPY . .
RUN crontab -l | { cat; echo ""; } | crontab -
RUN yarn install
RUN yarn install --check-files
RUN ls /var/www/quickcard/public
ENTRYPOINT ["entrypoint.sh"]
CMD ["bundle", "exec", "puma", "-C", "config/puma.rb"]

Nginx Docker 文件

FROM nginx
RUN apt-get update -qq && apt-get -y install apache2-utils
ENV RAILS_ROOT /var/www/quickcard
WORKDIR $RAILS_ROOT
RUN mkdir log
COPY public public/

COPY ./nginx.conf /etc/nginx/conf.d/default.conf
COPY ./multi_quickcard.key /etc/nginx/multi_quickcard.key
COPY ./quickcard-ssl-test.pem /etc/nginx/quickcard-ssl-test.pem

EXPOSE 80 443
CMD [ "nginx", "-g", "daemon off;" ]

Nginx.conf 例如

upstream puma {
    # Path to Puma SOCK file, as defined previously
    server app:5000 fail_timeout=0;
}

server {
    listen 80;
    server_name default_server;

    index index.html index.htm;
    try_files $uri $uri/ /index.html =404;

    location / {
        root /var/www/quickcard/public/;
        proxy_pass http://puma;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_redirect off;
    }

    location /api {
        root /var/www/quickcard/public/;
        proxy_pass http://puma;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_redirect off;
    }

    location ^~ /assets/ {
        root /var/www/quickcard/public/;
        gzip_static on;
        expires max;
        add_header Cache-Control public;
    }

    error_page 500 502 503 504 /500.html;
    client_max_body_size 4G;
    keepalive_timeout 10;
}

Docker 组合文件

version: '2.2'
services:
  app:
    build: 
      context: .
      dockerfile: ./Dockerfile
    command: bash -c "bundle exec rails s -p 5000 -e production -b 0.0.0.0 &&  RAILS_ENV=production bundle exec rake assets:precompile"
    environment:
      RAILS_ENV: production
    volumes:
      - /var/wwww/quickcard
      - /var/wwww/quickcard/public
    ports:
      - 5000:5000
  sidekiq:
    build: .
    command: bundle exec sidekiq -C config/sidekiq.yml
    environment:
      RAILS_ENV: production
    volumes:
      - /var/wwww/quickcard/tmp
  cron_job:
    build: .
    command: cron -f
  nginx:
    build:
      context: .
      dockerfile: ./nginx.Dockerfile
    volumes:
      - ./log-nginx:/var/log/nginx/
    restart: always
    ports:
      - 80:80
      - 443:443

【问题讨论】:

    标签: docker nginx


    【解决方案1】:

    Nginx 推荐的方法似乎是使用 envsubst 实用程序。您需要创建一个模板文件,其中的变量为$Variable{Variable}。然后,您可以将模板文件传递给 envsubst,该文件将从环境中渲染变量。

    这有一些缺点,因为它可能会无意中替换 nginx 变量,所以我会确保传递您想要替换的特定变量。

    有关更多详细信息,请参阅解决类似问题的此问题:https://serverfault.com/questions/577370/how-can-i-use-environment-variables-in-nginx-conf

    【讨论】:

      【解决方案2】:

      nginx Docker image 可以extract environment variables before it starts,但是有点取巧。一种解决方案是:

      1. 将环境变量添加到您的nginx.conf 文件。
      2. 在构建步骤中或作为卷将其复制到容器中的/etc/nginx/templates/nginx.conf.template(而不是您正常的/etc/nginx)。
      3. docker-compose.yml中设置NGINX_ENVSUBST_OUTPUT_DIR: /etc/nginx环境变量。

        这将导致 nginx.conf.template 文件被复制到 /etc/nginx 作为 nginx.conf 并且环境变量将被替换为它们的值。

        有一点需要牢记:在docker-compose.yml 中使用command 属性似乎会禁用提取功能。如果需要运行自定义命令启动nginx,可以使用Dockerfile版本。

        我创建了一个repo with the full setup,但如果它不可用:

        # docker-compose.yml
        
        version: "3"
        services:
          nginx-no-dockerfile:
            container_name: nginx-no-dockerfile
            image: nginx:1.23.1-alpine
            ports:
              - 8081:80
            volumes:
              - ./site/index.html:/usr/share/nginx/html/index.html
              - ./site/nginx.conf:/etc/nginx/templates/nginx.conf.template
            working_dir: /usr/share/nginx/html
            environment:
              NGINX_ENVSUBST_OUTPUT_DIR: /etc/nginx
              API_URL: http://example.com
        
        
          nginx-with-dockerfile:
            container_name: nginx-with-dockerfile
            build:
              context: ./site
              dockerfile: ./Dockerfile
            ports:
              - 8082:80
            volumes:
              - ./site/index.html:/usr/share/nginx/html/index.html
            environment:
              NGINX_ENVSUBST_OUTPUT_DIR: /etc/nginx
              API_URL: http://example.com
        
        # site/nginx.conf
        
        worker_processes auto;
        
        events {
        }
        
        http {
          include /etc/nginx/mime.types;
        
          server {
            listen 80;
        
            root /usr/share/nginx/html;
            index index.html index.htm;
        
            location / {
              try_files $uri $uri/ /index.html;
            }
        
            location /example {
              proxy_pass $API_URL;
            }
          }
        }
        
        # site/Dockerfile
        
        FROM nginx:1.23.1-alpine
        
        WORKDIR /usr/share/nginx/html
        COPY ./nginx.conf /etc/nginx/templates/nginx.conf.template
        
        EXPOSE 80
        CMD ["nginx", "-g", "daemon off;"]
        

        运行无 Dockerfile 版本:docker compose up nginx-no-dockerfile

        运行 Dockerfile 版本:

        docker compose build nginx-with-dockerfile
        docker compose up nginx-with-dockerfile
        
        

        确保站点文件夹中也有 index.html 文件。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-11-07
        • 1970-01-01
        • 2015-08-10
        • 2018-08-23
        • 2019-06-02
        • 2018-03-24
        • 2015-09-18
        • 1970-01-01
        相关资源
        最近更新 更多