Eu tenho um contêiner docker Nginx, configurado em um arquivo docker-compose assim:
my-nginx:
image: nginx:1.26.0
container_name: my-nginx
hostname: my-nginx
restart: always
ports:
- x.x.x.x:8001:6001
networks:
- public
volumes:
- "/opt/docker/volumes/nginx-html:/usr/share/nginx/html"
- "/opt/docker/nginx/nginx.conf:/etc/nginx/conf.d/default.conf"
- "/opt/docker/volumes/logs/nginx-logs:/var/log/nginx/logs"
- "/opt/docker/volumes/certs:/etc/certificates/nginx"
O nginx.conf não tem nada de especial, nenhum proxy, apenas servindo arquivos HTML/JS/CSS/IMG de duas pastas locais:
server {
listen 6001 ssl;
server_name my-nginx;
ssl_certificate /etc/certificates/nginx/my.crt;
ssl_certificate_key /etc/certificates/nginx/my.decrypted.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH;
location / {
root /usr/share/nginx/html/site1;
index index.html;
try_files $uri $uri/ /site1/index.html;
}
location /site2 {
alias /usr/share/nginx/html/site2;
index my.js;
try_files $uri $uri/ /site2/my.js;
}
location /site1 {
alias /usr/share/nginx/html/site1;
index index.html;
try_files $uri $uri/ /site1/index.html;
}
access_log /var/log/nginx/logs/access.log;
error_log /var/log/nginx/logs/error.log warn;
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
Isso está funcionando muito bem, sem problemas. Os arquivos HTML são encontrados e servidos corretamente a partir da pasta de volume montada, assim como os arquivos de configuração e certificado são carregados. A pasta de log também é montada como um volume e posso ver os arquivos de log access.log e error.log criados com sucesso.
Adicionei uma nova pasta chamada external_images
abaixo da /opt/docker/volumes/nginx-html
pasta, que deveria funcionar como uma pasta de upload para arquivos de imagem (de uma fonte interna confiável). Coloquei essa nova pasta na outra pasta de origem html porque essas mesmas imagens precisarão ser veiculadas para outros clientes através de HTTP. A nova configuração da interface de upload é semelhante a esta:
location ~ "/upload/([0-9a-zA-Z-.]*)$" {
alias /usr/share/nginx/html/external_images/$1;
client_body_temp_path /tmp;
dav_methods PUT DELETE MKCOL COPY MOVE;
create_full_put_path on;
dav_access user:rw group:rw all:r;
client_body_in_file_only on;
client_body_buffer_size 128k;
client_max_body_size 100M;
limit_except PUT OPTIONS HEAD { deny all; }
}
Não consigo fazer isso funcionar, nem por minha vida. Continuo recebendo erros de permissão negada:
curl -T test.png https://x.x.x.x:8001/upload/
2024/06/17 16:36:35 [crit] 21#21: *4 open() "/usr/share/nginx/html/external_images/test.png.0000000002" failed (13: Permission denied), client: y.y.y.y, server: my-nginx, request: "PUT /upload/test.png HTTP/1.1", host: "x.x.x.x:8001"
Quando me conecto ao contêiner, sou root internamente, para poder gravar nos arquivos desta pasta sem problemas:
[admin@server docker]$ sudo docker exec -it my-nginx bash
root@voda-nginx:/# echo aaa > /usr/share/nginx/html/external_images/test.png.0000000002
root@voda-nginx:/# exit
exit
[admin@server docker]$ ll volumes/nginx-html/external_images/
total 4
-rw-r--r--. 1 root root 4 Jun 17 18:52 test.png.0000000002
[admin@server docker]$ cat volumes/nginx-html/external_images/test.png.0000000002
aaa
Mas quando tento fazer o mesmo em nome do usuário interno "nginx", recebo permissão negada:
root@my-nginx:/# su -s /bin/bash -c "echo aaa > /usr/share/nginx/html/external_images/test.png.0000000002" - nginx
-bash: line 1: /usr/share/nginx/html/external_images/test.png.0000000002: Permission denied
Tentei o mesmo com a pasta log, onde os arquivos de log já estão sendo gravados pelo nginx com sucesso, e mesmo lá não consegui criar o novo arquivo como usuário "nginx".
o que estou perdendo?
Editar: adicionando detalhes do ambiente
O docker está rodando no RedHat 8.9, com SELinux habilitado, mas não acho que seja um problema do SELinux, porque temos vários containers rodando, cada um deles grava arquivos de log e até arquivos CSV customizados e outros em pastas de volume sem problemas.