nginx: [emerg] open() "/run/nginx.pid" failed (13: Permission denied) - docker

I have the following Dockerfile that i have set up to use a new user rather than using root for my nginx server. The nginx server is built upon Redhat UBI image.
The image builds fine, however when I run the container I get the following error: nginx: [nginx: [emerg] open() "/run/nginx.pid" failed (13: Permission denied)
Below is my dockerfile.
USER root
RUN microdnf --setopt=tsflags=nodocs install -y nginx procps shadow-utils net-tools ca-certificates dirmngr gnupg wget vim\
&& microdnf clean all \
&& rpm -q procps-ng
ENV NGINX_USER="api-gatway" \
NGINXR_UID="8987" \
NGINX_GROUP="api-gatway" \
NGINX_GID="8987"
RUN set -ex; \
groupadd -r --gid "$NGINX_GID" "$NGINX_GROUP"; \
useradd -r --uid "$NGINXR_UID" --gid "$NGINX_GID" "$NGINX_USER"
COPY nginx.conf /etc/nginx/nginx.conf
RUN mkdir -p /var/lib/nginx/tmp /var/log/nginx \
&& chown -R api-gatway:api-gatway /var/lib/nginx /var/log/nginx \
&& chmod -R 755 /var/lib/nginx /var/log/nginx
EXPOSE 1080
USER api-gatway
CMD ["nginx", "-g", "daemon off;"]
When i build the image, it builds without any errors, but when i deploy on my K8 cluster using helm, it gives me the following errors.
nginx: [emerg] open() "/run/nginx.pid" failed (13: Permission denied)
Here is my nginx.conf file that I have set up
worker_processes 1;
error_log /tmp/error.log;
pid /run/nginx.pid;
events {
worker_connections 1024;
}
http {
server {
listen 1080;
server_name localhost 127.0.0.1;
access_log /tmp/access.log;
client_max_body_size 0;
set $allowOriginSite *;
proxy_pass_request_headers on;
proxy_pass_header Set-Cookie;
# External settings, do not remove
#ENV_ACCESS_LOG
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
proxy_redirect off;
proxy_buffering off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass_header Set-Cookie;
proxy_set_header X-Forwarded-Proto $scheme;
location /search/ {
proxy_pass http://*******-svc:8983/***/;
}
location /auth/ {
proxy_pass http://********:8080;
}
location /mapbox {
rewrite ^/mapbox(.*)https://****$1 break;
}
}
}
How can I fix nginx: [emerg] open() "/var/run/nginx.pid" failed (13: Permission denied) and what have i done wrong in my configurations?

UPDATE
In order to fix my "/var/run/nginx.pid" permission denied error.
I had to add nginx.pid permission errors inside my dockerfile for the new user to work.
Below are the changes i made in my dockerfile
RUN touch /run/nginx.pid \
&& chown -R api-gatway:api-gatway /run/nginx.pid /cache/nginx

Related

How to pass environment variable to nginx.conf file in docker?

I am trying to setup ruby on rails with docker everything is good but i want dynamic domain pass as environment variable to nginx.conf file during build image by docker-compose command but i don't know how to do it.
i trying to use this command
Docker-compose build
dcoker-compose up
Docker File
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 File
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 e.g
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 Compose File
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
nginx Docker image can extract environment variables before it starts, but it's a bit tricky. One solution is to:
Add env variables to your nginx.conf file.
Copy it to /etc/nginx/templates/nginx.conf.template in the container (as opposed to your normal /etc/nginx) in the build step or as a volume.
Set the NGINX_ENVSUBST_OUTPUT_DIR: /etc/nginx environment variable in docker-compose.yml.
This will cause the nginx.conf.template file to be copied to /etc/nginx as nginx.conf and the environment variables will be replaced with their values.
There is one caveat to keep in mind: using command property in docker-compose.yml seems to be disabling the extraction functionality. If you need to run a custom command to start-up nginx, you can use the Dockerfile version.
I created a repo with the full setup, but in case it's not available:
# 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;"]
Run no Dockerfile version: docker compose up nginx-no-dockerfile
Run Dockerfile version:
docker compose build nginx-with-dockerfile
docker compose up nginx-with-dockerfile
Make sure to also have index.html file in the site folder.
The recommended approach Nginx seems to be to use the envsubst utility. You would need to create a template file with the variable placed inside as $Variable or {Variable}. You could then pass into envsubst the template file which would render the variable from the environment.
This has a few downsides in that it can potentially replace nginx variables unintentionally so I would make sure to pass in the specific variables you would want to replace.
See this question which addresses a similar problem for more details: https://serverfault.com/questions/577370/how-can-i-use-environment-variables-in-nginx-conf

ruby on rails setup issue on production with docker

docker file
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 apt-get update -qq && apt-get install -y build-essential \
git \
libxml2-dev \
libpq-dev \
libxslt-dev \
nodejs \
yarn \
imagemagick \
tzdata \
less \
&& rm -rf /var/cache/apk/*
RUN gem install bundler --version "$BUNDLE_VERSION"
RUN bundle config set path $BUNDLE_PATH
RUN mkdir -p $RAILS_ROOT
WORKDIR $RAILS_ROOT
ADD Gemfile Gemfile
ADD Gemfile.lock Gemfile.lock
RUN bundle install
EXPOSE $RAILS_PORT
RUN ln -s $RAILS_ROOT/config/systemd/puma.service /etc/systemd/system/current
COPY . .
ENTRYPOINT ["entrypoint.sh"]
CMD ["bundle", "exec", "puma", "-C", "config/puma.rb"]
docker compose file
version: '2.2'
services:
app:
build:
context: .
dockerfile: ./Dockerfile
command: ['bundle','exec','rails','s','-p','5000','-e','production', '-b', '0.0.0.0']
volumes:
- /var/wwww/quickcard
ports:
- "5000:5000"
sidekiq:
build: .
command: bundle exec sidekiq -C config/sidekiq.yml
volumes:
- '/var/wwww/quickcard/tmp'
nginx:
build:
context: .
dockerfile: ./nginx.Dockerfile
ports:
- 80:80
links:
- app
nginx conf file
upstream app {
server app:5000;
}
server {
listen 80;
server_name quickcard;
index index.html index.htm;
try_files $uri $uri/ /index.html =404;
location / {
root /var/www/quickcard/public;
proxy_pass http://app;
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://app;
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;
}
I want everything on production with docker there are not a single puma configuration or service file on production then how to check puma status if puma start or not?
if i am hit ip of server then there is an error site can't be reached. how to configure nginx with application and with puma on production with docker-file. i don't want to set everything manually like puma service file

Assets not working in rails containerised app

I am trying to setup ruby on rails application from docker everything is fine there is only one issue assets not load in application in docker. Please tell me how to resolve this issue.
Asset compile log
** Execute assets:precompile
I, [2022-06-21T14:19:36.070795 #8] INFO -- : Writing /var/www/quickcard/public/assets/admins_stylesheet-ee5c0de3bf28ba61ee5aae648b5394561912c52f237e45b9afd8b1dbaba97ddd.css
I, [2022-06-21T14:19:36.071640 #8] INFO -- : Writing /var/www/quickcard/public/assets/admins_stylesheet-ee5c0de3bf28ba61ee5aae648b5394561912c52f237e45b9afd8b1dbaba97ddd.css.gz
I, [2022-06-21T14:19:36.072396 #8] INFO -- : Writing /var/www/quickcard/public/assets/flags-38025784bedeb5e4cae496b131c85cabbd95ae0b1c0a3c9d9cb474d7262db04b.png
I, [2022-06-21T14:19:36.074876 #8] INFO -- : Writing /var/www/quickcard/public/assets/flags#2x-e21becc4db003c08194a77f3311709fc0002a99be5dd18e8a5ba661c0472dc35.png
I, [2022-06-21T14:19:36.582968 #8] INFO -- : Writing /var/www/quickcard/public/assets/application-4bcda1a2ad86133d1f3e33b2c53561990c0bd5c5e237e227357708bb00a21e7d.css
I, [2022-06-21T14:19:36.583732 #8] INFO -- : Writing /var/www/quickcard/public/assets/application-4bcda1a2ad86133d1f3e33b2c53561990c0bd5c5e237e227357708bb00a21e7d.css.gz
I, [2022-06-21T14:19:36.585850 #8] INFO -- : Writing /var/www/quickcard/public/assets/img/main3-9d715e6c156473fea20e2df822b880ce16f8d57b2de6e50e56d0bea18e9f2a27.jpg
Docker File
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 \
&& rm -rf /var/cache/apk/*
RUN gem install bundler --version "$BUNDLE_VERSION"
RUN bundle config set path $BUNDLE_PATH
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 yarn install
RUN yarn install --check-files
RUN bundle exec rake assets:precompile --trace
RUN ls /var/www/quickcard/public
ENTRYPOINT ["entrypoint.sh"]
CMD ["bundle", "exec", "puma", "-C", "config/puma.rb"]
Compose File
version: '2.2'
services:
app:
build:
context: .
dockerfile: ./Dockerfile
command: ['bundle','exec','rails','s','-p','5000','-e','development', '-b', '0.0.0.0']
# 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
nginx:
build:
context: .
dockerfile: ./nginx.Dockerfile
volumes:
- ./log-nginx:/var/log/nginx/
ports:
- 80:80
Nginx conf file
upstream puma {
server app:5000 fail_timeout=0;
}
server {
listen 80 default_server deferred;
index index.html index.htm;
access_log /var/www/quickcard/log/nginx.access.log;
error_log /var/www/quickcard/log/nginx.error.log;
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/ {
rewrite /var/www/quickcard(/assets/.*) $1;
root /var/www/quickcard/public/;
gzip_static on;
expires max;
add_header Cache-Control public;
add_header Strict-Transport-Security "";
}
# 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;
}

Flask url_for generates http instead of https when running by docker

I have a flask app running in docker, and setup nginx with Let’s Encrypt. I've added proxy_set_header X-Forwarded-Proto $scheme; to my nginx config, but url_for still returns http url instead https url. But the issue only occurs when running in docker.
This is my nginx config:
server {
listen 443 ssl default_server;
ssl_certificate /etc/letsencrypt/live/markote.app/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/markote.app/privkey.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';
location / {
proxy_pass http://127.0.0.1:5000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
and my docker file:
FROM python:3.6-slim
WORKDIR /app
ADD . /app
RUN apt update
RUN apt install -y curl sudo gnupg libcairo2-dev
RUN pip install gunicorn
RUN curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash -
RUN sudo apt-get install -y nodejs
RUN python setup.py install
RUN npm install
RUN npm run build
EXPOSE 5000
CMD [ "gunicorn", "-c", "gunicorn.py", "wsgi:app" ]
If I run gunicorn -c gunicorn.py wsgi:app & instead of sudo docker run -d -p 5000:5000 my/repo, url_for can generate https successfully. Do I miss something?
I know it's been a while but you could try url_for('endpoint', _schema='https')

Semantic media wiki in docker

I am trying to get the SMW running in a Docker container. I get the
main page up, but it will not let me log in. It says:
Login error
Knowledgebase uses cookies to log in users. You have cookies disabled.
Please enable them and try again.
My browser does have cookies enabled.
Anyone here run SMW in Docker and/or have a clue on how I can fix this issue?
Dockerfile:
FROM centos:centos7
ENV HOME /opt/smw
ADD . $HOME
RUN chmod 777 $HOME
# Add the ngix and PHP dependent repository
ADD nginx.repo /etc/yum.repos.d/nginx.repo
# Installing packages
RUN yum -y install nginx
# Installing PHP
RUN yum -y --enablerepo=remi,remi-php56 install nginx php-fpm php-common php-mysql php-xml
# Installing MySQL
RUN yum -y install wget && \
wget http://repo.mysql.com/mysql-community-release-el7-5.noarch.rpm && \
rpm -ivh mysql-community-release-el7-5.noarch.rpm && \
yum -y update && \
yum -y install mysql-server
# Installing supervisor
RUN yum install -y python-setuptools
RUN easy_install pip
RUN pip install supervisor
# Adding the configuration file of the nginx
ADD nginx.conf /etc/nginx/nginx.conf
ADD default.conf /etc/nginx/conf.d/default.conf
# Adding the configuration file of the Supervisor
ADD supervisord.conf /etc/
# Config MySQL
RUN chmod 755 $HOME/config_mysql.sh
RUN $HOME/config_mysql.sh
VOLUME ["/opt/smw"]
VOLUME ["/var/lib/mysql"]
EXPOSE 80
CMD ["/opt/smw/run.sh"]
supervisord.conf:
[supervisord]
;logfile=/var/log/supervisor/supervisord-nobody.log ; (main log file;default $CWD/supervisord.log)
;logfile_maxbytes=50MB ; (max main logfile bytes b4 rotation;default 50MB)
;logfile_backups=10 ; (num of main logfile rotation backups;default 10)
;loglevel=info ; (log level;default info; others: debug,warn,trace)
;pidfile=/var/run/supervisord.pid ; (supervisord pidfile;default supervisord.pid)
nodaemon=true ; (start in foreground if true;default false)
;user=nobody
[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
[program:php5-fpm]
command=/usr/sbin/php-fpm -c /etc/php-fpm.d
numprocs=1
autostart=true
autorestart=true
[program:php5-fpm-log]
command=tail -f /var/log/php5-fpm.log
stdout_events_enabled=true
stderr_events_enabled=true
[program:nginx]
command=/usr/sbin/nginx
numprocs=1
autostart=true
autorestart=true
nginx config:
server {
listen 80;
root /opt/smw;
index index.html index.htm index.php;
# Make site accessible from http://set-ip-address.xip.io
server_name localhost;
access_log /var/log/nginx/localhost.com-access.log;
error_log /var/log/nginx/localhost.com-error.log error;
charset utf-8;
location / {
try_files $uri $uri/ /index.html /index.php?$query_string;
}
location = /favicon.ico { log_not_found off; access_log off; }
location = /robots.txt { access_log off; log_not_found off; }
error_page 404 /index.php;
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
# Deny .htaccess file access
location ~ /\.ht {
deny all;
}
Instead of installing remi-php56 I installed just plain php and then I did not have the issue.

Resources