Gabriel Araujo
Gabriel Araujo

Reputation: 769

Running nginx as non-root user on Openshift and listening on port 80

I've tried for several consecutive days to configure a nginx container running on Openshift, and until now, didn't get it working.

I've read about the use of a non-root user for secuity reasons. However, be either root or non-root user, openshift doesn't allow me to create a bind in container at port 80.

2017/06/22 21:18:57 [emerg] 1#1: bind() to 0.0.0.0:80 failed (13: Permission denied)
nginx: [emerg] bind() to 0.0.0.0:80 failed (13: Permission denied)

On my local machine I can successfully bind to higher ports on container (8081 for example) and then create a map for access in the host maschine (docker run --rm -d -p 9000:8081 mynginx). This way I can successfully reach the website on the host address localhost:9000, but I have no ideia how I could achieve something similar on openshit.

I wish I could deploy my image with non-root user and nginx listening on a higher port (8081), at the same time that openshift forwards all incoming traffic for port 80 of server to port 8081 of container (nginx). My currently setup is as follows:

Dockerfile:

FROM nginx:alpine

COPY nginx.conf /etc/nginx/nginx.conf
COPY dist /usr/share/nginx/html

RUN chmod -R 777 /var/log/nginx /var/cache/nginx /var/run \
     && chgrp -R 0 /etc/nginx \
     && chmod -R g+rwX /etc/nginx \
     && rm /etc/nginx/conf.d/default.conf

EXPOSE 8081

and my nginx.conf file:

worker_processes 4;
error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;

events { worker_connections 1024; }

http {

  ssl_session_cache   shared:SSL:10m;
  ssl_session_timeout 30m;

  #See http://blog.argteam.com/coding/hardening-node-js-for-production-part-2-using-nginx-to-avoid-node-js-load
  proxy_cache_path        /var/cache/nginx levels=1:2 keys_zone=one:8m max_size=3000m inactive=600m;
  proxy_temp_path         /var/tmp;
  include                 mime.types;
  default_type            application/octet-stream;
  sendfile                on;
  keepalive_timeout       65;

  gzip                    on;
  gzip_comp_level         6;
  gzip_vary               on;
  gzip_min_length         1000;
  gzip_proxied            any;
  gzip_types              text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
  gzip_buffers 16 8k;

  server {
    listen        8081;
    server_name   localhost;

    location / {
      root   /usr/share/nginx/html;
      index  index.html;
      expires -1;
      add_header Pragma "no-cache";
      add_header Cache-Control "no-store, no-cache, must-revalidate, post-check=0, pre-check=0";
      try_files $uri$args $uri$args/ $uri $uri/ /index.html =404;
    }
  }
}

Obs: the deploy happens automatically in the pipeline process. I'm using a custom docker image from gitlab that take care of deployment to openshift. This custom image uses openshift origin CLI for handle the deployment.

Upvotes: 1

Views: 12127

Answers (1)

Graham Dumpleton
Graham Dumpleton

Reputation: 58523

Use port 8080 to listen on. When you expose the service for the web server outside of OpenShift the external route will use port 80 by default anyway and ensure traffic is routed through to port 8080 of your web server internally. If contacting service internally to OpenShift, you will need to contact it on port 8080 though.

Also, be aware that a S2I builder for nginx is available if all you want to do is host some static files.

At the minimum see how it does things.

Upvotes: 6

Related Questions