paketo-buildpacks / nginx

Apache License 2.0
20 stars 14 forks source link

Container fails to start with read-only file system #2 #463

Open ajdergute opened 1 year ago

ajdergute commented 1 year ago

I run this buildpack via helm chart and configured my security context like so:

securityContext:
  readOnlyRootFilesystem: true
  runAsNonRoot: true
volumes:
  - emptyDir: {}
    name: tmpdir
podVolumeMounts: 
  - mountPath: /tmp
    name: tmpdir

As the only exception I made /tmp writeable. Therefore I used an own nginx.conf with some templated values. See:

daemon off;
worker_processes {{env "NGINX_WORKERS"}};
...
http {
  ...
  access_log /dev/stdout;
  error_log stderr;
  client_body_temp_path {{ tempDir }}/client_body_temp;
  proxy_temp_path {{ tempDir }}/proxy_temp;
  fastcgi_temp_path {{ tempDir }}/fastcgi_temp;
  ...
  server {
    listen 8080;
    server_name _;
    client_max_body_size {{env "NGINX_CLIENT_MAX_BODY_SIZE"}}M;
    root ./{{env "NGINX_ROOT"}};
    ...
    location / {
      try_files $uri $uri/ /index.html;
      add_header Last-Modified "{{ env "NGINX_LAST_MODIFIED_HEADER" }}";
      # switch ETag off, since file modification time is always 01-01-1980
      etag off;
    }
  }
}

Expected Behavior

Nginx is up and running serving my content.

Current Behavior

Nginx doesn't start, because configure-0 tries to write on a read-only location. This was already reported #385

failed to create nginx.conf: open /workspace/nginx.conf: read-only file system
ERROR: failed to launch: exec.d: failed to execute exec.d file at path '/layers/paketo-buildpacks_nginx/nginx/exec.d/0-configure': exit status 1

Possible Solution

In this issue I try to focus on templating issues with nginx.conf. Configure nginx to not write anything should be addressed at nginx team. Not using templating in nginx.conf was already discussed and is still one workaround. For me this is not an option. E.g. we're using a dynamic URL to proxy our backend depending on our actual environment.

Solutions:

  1. (preferred) Do not perform an replacement of nginx.conf. Instead use the input file as template and write the output file to a user specified location. If BPL_NGINX_CONF_LOCATION is set this configuration is written and used.
  2. A user is responsible to copy nginx.conf to a build/run writeable location e.g. /tmp. Additionally set BP_NGINX_CONF_LOCATION=/tmp/nginx.conf. To make configure-0 working a user must also copy it's nginx.conf at runtime to tmp. Maybe by mounting a ConfigMap to a volume or by other means.

Steps to Reproduce

  1. Deploy an image via helm chart with this values:
securityContext:
  readOnlyRootFilesystem: true
  runAsNonRoot: true

Motivations

As already mentioned we strive to run our images as secure as possible. To do so we try to run a container read-only with some exceptions. This is described here

Running a read-only file system in your containers forces your containers to be immutable. Not only does this mitigate some old (and risky) practices such as hot patching, but also helps you prevent the risks of malicious processes storing or manipulating data inside a container.

GijsvanDulmen commented 8 months ago

Is there any update on this?

mgilham commented 6 months ago

I hit this issue as well. It seems bad to require that the workspace directory is writable at runtime. Are there any caveats to solution 1 as proposed by @ajdergute ?