Answer a question

I'm running a Ruby on Rails web application using docker and docker compose. I had 3 containers functioning on the ip address at port 3000. I am now trying to set this up on the ip address/domain name rather than port 3000. To do this, I am trying to use nginx as a proxy server with this image (https://hub.docker.com/r/staticfloat/nginx-certbot/) so that I can also have an SSL cert.

My issue is that I still can't access the application from the ip address without port 3000. Also, it can only be accessed with http rather than https.

I'm receiving the following output from the nginx container when I run 'docker-compose up':

frontend_1       | templating scripts from /etc/nginx/user.conf.d to /etc/nginx/conf.d
frontend_1       | Substituting variables
frontend_1       |  -> /etc/nginx/user.conf.d/*.conf
frontend_1       | /scripts/util.sh: line 125: /etc/nginx/user.conf.d/*.conf: No such file or directory
frontend_1       | Done with startup
frontend_1       | Run certbot
frontend_1       | ++ parse_domains
frontend_1       | ++ for conf_file in /etc/nginx/conf.d/*.conf*
frontend_1       | ++ xargs echo
frontend_1       | ++ sed -n -r -e 's&^\s*ssl_certificate_key\s*\/etc/letsencrypt/live/(.*)/privkey.pem;\s*(#.*)?$&\1&p' /etc/nginx/conf.d/certbot.conf
frontend_1       | + auto_enable_configs
frontend_1       | + for conf_file in /etc/nginx/conf.d/*.conf*
frontend_1       | + keyfiles_exist /etc/nginx/conf.d/certbot.conf
frontend_1       | ++ parse_keyfiles /etc/nginx/conf.d/certbot.conf
frontend_1       | ++ sed -n -e 's&^\s*ssl_certificate_key\s*\(.*\);&\1&p' /etc/nginx/conf.d/certbot.conf
frontend_1       | + return 0
frontend_1       | + '[' conf = nokey ']'
frontend_1       | + set +x

I think that the below output relates to my issue. However, I still haven't been able to figure this out.

/scripts/util.sh: line 125: /etc/nginx/user.conf.d/*.conf: No such file or directory

I have two .conf files which are both located at myapp/config/nginx/user.conf.d/

Here are the two .conf files:

upstream docker {
    server web:3000 fail_timeout=0;
}

server {
    listen              443 ssl;
    server_name         myapp.com;
    ssl_certificate     /etc/letsencrypt/live/myapp.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/myapp.com/privkey.pem;
    try_files $uri/index.html $uri @docker;
    client_max_body_size 4G;

    location @docker {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_redirect off;
        proxy_pass http://docker;
    }
}

and

upstream docker {
    server web:3000 fail_timeout=0;
}

server {
    listen              443 ssl;
    server_name         myapp.ie;
    ssl_certificate     /etc/letsencrypt/live/myapp.ie/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/myapp.ie/privkey.pem;
    try_files $uri/index.html $uri @docker;
    client_max_body_size 4G;

    location @docker {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_redirect off;
        proxy_pass http://docker;
    }
}

Here's my dockerfile:

# Use the Ruby 2.7.2 image from Docker Hub as the base image (https://hub.docker.com/_/ruby)
FROM ruby:2.7.2-buster

# The directory to store this application's files.
RUN mkdir /myapp
RUN mkdir -p /usr/local/nvm
WORKDIR /myapp

# Install 3rd party dependencies.
RUN apt-get update -qq && \
    apt-get install -y curl \
    build-essential \
    libpq-dev \
    postgresql \
    postgresql-contrib \
    postgresql-client

# # The directory to store this application's files.
# RUN mkdir /myapp
# RUN mkdir -p /usr/local/nvm
# WORKDIR /myapp

RUN curl -sL https://deb.nodesource.com/setup_15.x | bash -
RUN apt-get install -y nodejs
RUN node -v
RUN npm -v

# Copy Gems.
COPY Gemfile Gemfile.lock package.json yarn.lock ./

# Run bundle install to install the Ruby dependencies.
RUN gem install bundler && bundle update --bundler && bundle install
RUN npm install -g yarn && yarn install --check-files

# Copy all the application's files into the /myapp directory.
COPY . /myapp

# Compile assets
ENV RAILS_ENV production
ENV RAILS_SERVE_STATIC_FILES true
RUN bundle exec rake assets:precompile

# Add a script to be executed every time the container starts.
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000

# Start the main process by setting "rails server -b 0.0.0.0" as the command to run when this container starts.
CMD ["bundle", "exec", "rails", "server", "-b", "0.0.0.0"]

Here's my entrypoint.sh file:

#!/bin/bash
set -e

# For development check if the gems as installed, if not, then uninsstall them.
if ! [ bundle check ] ; then
    bundle install
fi

# Remove a potentially pre-existing server.pid for Rails.
rm -f /myapp/tmp/pids/server.pid

# # Yarn - Check Files.
yarn install --check-files

# Run the command - runs any arguments passed into this entrypoint file.
exec "$@"

Here's my docker-compose.yml ile:

version: "3.8"
services:
  web:
    restart: unless-stopped
    build:
      context: .
      dockerfile: Dockerfile
    volumes:
      - bundle-volume:/usr/local/bundle
    ports:
      - "3000:3000"
    depends_on:
      - database
      - elasticsearch
    environment:
      RAILS_ENV: production
      DATABASE_NAME: myapp_production
      DATABASE_USER: postgres
      DATABASE_PASSWORD: **********
      POSTGRES_PASSWORD: **********
      DATABASE_HOST: database
      ELASTICSEARCH_URL: http://elasticsearch:9200

  database:
    restart: unless-stopped
    image: postgres:12.3
    container_name: database
    volumes:
      - db_volume:/var/lib/postgresql/data
      - ./init.sql:/docker-entrypoint-initdb.d/init.sql
    ports:
      - 5432:5432
    environment: 
      DATABASE_PASSWORD: **********
      POSTGRES_PASSWORD: **********

  elasticsearch:
    restart: unless-stopped
    image: docker.elastic.co/elasticsearch/elasticsearch:7.9.3
    volumes:
      - ./docker_data/elasticsearch/data:/usr/share/elasticsearch/data
    environment:
      - cluster.name=docker-cluster
      - bootstrap.memory_lock=true
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
      - discovery.type=single-node
    ports:
      - 9200:9200
    ulimits:
      memlock:
        soft: -1
        hard: -1

  frontend:
    restart: unless-stopped
    image: staticfloat/nginx-certbot
    ports:
        - 80:80/tcp
        - 443:443/tcp
    depends_on:
      - web
    environment:
        CERTBOT_EMAIL: myapp@gmail.com
    volumes:
      - /etc/nginx/user.conf.d:/etc/nginx/user.conf.d:ro
      - letsencrypt:/etc/letsencrypt

volumes:
  bundle-volume:
    external: false
  db_volume:
  data:
  letsencrypt:
    external: false

Appreciate any help.

Answers

As you mention you have two .conf files which are both located at myapp/config/nginx/user.conf.d/.

Please move these both files to the to '/etc/nginx/user.conf.d', this directory as I can see you have mounted this directory to the docker. After moving these files to the above location bring down the docker and bring up then see if it resolves the issue. Please let me know if I can help more with this.

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐