12

I'd like for my webapp which is deployed as a war ROOT.war to have write access to /var/www/html/static/images so that it can write uploaded and converted images to that folder so nginx can serve it statically. Currently it doesn't work and triggers a java.nio.file.FileSystemException exception together with the Filesystem is read-only message.

But the filesystem is not read-only and is in great condition. The folder has already been chmodded 777.

Extra info: The tomcat setup is running on an Ubuntu 18.04 Azure VM with managed disk. The folder is residing on an Ext4 formatted drive

aardbol
  • 1,816
  • 3
  • 26
  • 39
  • I had a similar problem and posted on ServerFault: [Application logging broken under Tomcat 9: permission denied to /var/log/myapp](https://serverfault.com/questions/989150/application-logging-broken-under-tomcat-9-permission-denied-to-var-log-myapp) – Stephen Ostermiller Oct 24 '19 at 10:41

1 Answers1

43

Let's start with: chmod 777 is great for testing, but absolutely unfit for the real world and you shouldn't get used to this setting. Rather set the owner/group correctly, before you give world write permissions.

Edit: A similar question just came up on the Tomcat mailing list, and Emmanuel Bourg pointed out that Debian Tomcat is sandboxed by systemd. Read your /usr/share/doc/tomcat9/README.Debian which contains this paragraph:

Tomcat is sandboxed by systemd and only has write access to the following directories:

  • /var/lib/tomcat9/conf/Catalina (actually /etc/tomcat9/Catalina)
  • /var/lib/tomcat9/logs (actually /var/log/tomcat9)
  • /var/lib/tomcat9/webapps
  • /var/lib/tomcat9/work (actually /var/cache/tomcat9)

If write access to other directories is required the service settings have to be overridden. This is done by creating an override.conf file in /etc/systemd/system/tomcat9.service.d/ containing:

[Service]

ReadWritePaths=/path/to/the/directory/

The service has to be restarted afterward with:

  systemctl daemon-reload
  systemctl restart tomcat9

Edit 2022: Note that these are the 2019 paths - validate if you need to adapt them to the current location of your tomcat whenever you run across this answer (e.g. see Ng Sek Long's comment for Ubuntu 20)

End of edit, continuing with the passage that didn't solve OP's problem, but should stay in:

If - all things tested - Tomcat should have write access to that directory, but doesn't have it, the error message points me to an assumption: Could it be that

  • Tomcat is running as root?
  • The directory is mounted through NFS?

The default configuration for NFS is that root has no permissions whatsoever on that external filesystem (or was it no write-permission? this is ancient historical memory - look up "NFS root squash" to get the full story)

If this is a condition that matches what you are running, you should stop running Tomcat as root, and rather run it as an unprivileged user. Then you can set the permissions on the directory in question to be writeable by your tomcat-user, and readable by nginx, and you're done.

Running Tomcat as root is a recipe for disaster: You don't want a process that's available from the internet to run as root.

If these conditions don't meet your configuration: Elaborate on the configuration. I'd still stand by this description for others who might find this question/answer later.

Olaf Kock
  • 45,059
  • 7
  • 56
  • 86
  • 1
    See the additional paragraph for new wisdom straight from the Tomcat mailing list – Olaf Kock Jul 02 '19 at 07:03
  • 3
    Wonderful! This piece of information was really hard to find though. I've been looking everywhere for a solution and didn't even realize Systemd had MAC type of functionality like AppArmor (which I had disabled already as a possible solution). – aardbol Jul 02 '19 at 14:21
  • @OlafKock You, the saviour! Thanks! – Mohammed shebin Oct 03 '21 at 11:44
  • For whatever reason I can't find, this is not working for me. I even went ahead of myself and added a specific directory (that my app was supposed to create) after I changed the ownership to Tomcat. Then I changed the ownership of the dir and the User and Group for my personal user (which didn't even launched, by the way) but just no luck... of course, using root worked, but that is not a solution even if I trust the layers above my app enough. Gotta keep searching, I guess (This on Tomcat 9.0.31, Ubuntu server 20.04) – Jetto Martínez Jan 20 '22 at 18:40
  • 2
    In current Ubuntu file is here: `sudo vi /etc/systemd/system/multi-user.target.wants/tomcat9.service` – V H Feb 26 '22 at 19:55
  • 1
    Mine (Ubuntu 20) is installed here `/lib/systemd/system/tomcat9.service` smh everybody use a different path. – Ng Sek Long Mar 28 '22 at 08:36
  • Thank you - edited the need to validate paths into my answer – Olaf Kock Mar 28 '22 at 09:29