Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tomcat: rewrite module #84377

Closed
wants to merge 1 commit into from
Closed

tomcat: rewrite module #84377

wants to merge 1 commit into from

Conversation

aanderse
Copy link
Member

@aanderse aanderse commented Apr 5, 2020

Motivation for this change

The current tomcat module suffers from a few shortcomings, such as

Things I'm proposing

A rewrite of the module which lists tomcat use cases and then provides solutions to these use cases, addressing the above mentioned shortcomings of the current module.

After identifying some common use cases of tomcat that are relevant to me I have taken a very rough (and extremely incomplete) first pass at rewriting the module. Many options description values are empty or incorrect (copy+paste from another module), but I wanted to start a conversation with interested parties to see how we might improve tomcat on NixOS.

Here is what I came up with:

  • local development, ssl doesn't matter, you want to serve over port 8080 as is the default expressed in server.xml from upstream
# quick and easy, up and running on port 8080, the developer can work from appBase
services.tomcat.enable = true;
services.tomcat.virtualHosts.localhost = {
  appBase = "/var/www/tomcat";
};
  • run tomcat as a full featured web server on ports 80 and 443, PEM certificates provisioned by Let's Encrypt, requiring no keystore password in the nix store
# full Let's Encrypt integration out of the box, easy to host multiple sites, sane defaults but power to override most settings through various module options
services.tomcat.enable = true;
services.tomcat.virtualHosts."blog.example.org" = {
  enableACME = true;
  forceSSL = true;
  appBase = localpkgs.my-blog-war-file;
};
services.tomcat.virtualHosts."forum.example.org" = {
  enableACME = true;
  onlySSL = true;
  appBase = "/var/www/forum.example.org";
  sslHostConfig = {
      disableCompression = false;
      disableSessionTickets = true;
      honorCipherOrder = false;
  };
};
  • serve java content through a web server like nginx or apache-httpd via mod_jk or reverse proxy, where tomcat is installed on the same machine as your web server
# I'm not so familiar with AJP so I need to research this more
services.tomcat.enable = true;
services.tomcat.connectors = [
  { port = 8080; protocol = "HTTP/1.1"; }
  { port = 9009; protocol="AJP/1.3"; }
];
services.tomcat.virtualHosts.localhost = {
  appBase = "/webapps";
};
# configure your web server to connect to tomcat over the appropriate port, depending on reverse proxy or mod_jk
  • run several instances of tomcat over multiple servers and use something like apache-httpd or nginx to load balance them, possibly using a self signed certificate
# example to follow
What I want from you

@danbst @pvgoran @deliciouslytyped @tomberek @abathur as potentially interested individuals
Opinions, thoughts, comments, your use cases, module requests, examples, discussion of what I'm proposing is a good path forward or not. Minor review of code so far if you feel like it, keeping in mind it outs not complete. I have tested a few workflows, but not all yet.

Things done
  • Tested using sandboxing (nix.useSandbox on NixOS, or option sandbox in nix.conf on non-NixOS linux)
  • Built on platform(s)
    • NixOS
    • macOS
    • other Linux distributions
  • Tested via one or more NixOS test(s) if existing and applicable for the change (look inside nixos/tests)
  • Tested compilation of all pkgs that depend on this change using nix-shell -p nixpkgs-review --run "nixpkgs-review wip"
  • Tested execution of all binary files (usually in ./result/bin/)
  • Determined the impact on package closure size (by running nix path-info -S before and after)
  • Ensured that relevant documentation is up to date
  • Fits CONTRIBUTING.md.

@abathur
Copy link
Member

abathur commented Apr 5, 2020

Responding so you know I'm not ignoring you :)

I don't think I've used Tomcat via Nix or otherwise, but guessing you found me via #17879. Not sure I'll have much to add directly (since my interest is just transitively in finding out if Guacamole is a viable Teamviewer alternative), but @Shados and @jraygauthier may have thoughts arising from #48140.

@aanderse aanderse changed the title Tomcat tomcat: rewrite module Apr 6, 2020
@pvgoran
Copy link
Contributor

pvgoran commented Apr 6, 2020

The tomcat module is, indeed, quite limited, and arguably flawed, and rewriting it seems like a good idea. But I see multiple challenges/problems here.

  1. First and foremost, existing configurations should remain working as they are, for at least one release cycle. Since the module's logic is completely replaced, probably the best way to achieve this would be to leave the existing module in place, and create a new one. (I'm not sure if this fits the establishes practices of NixOS.)
  2. The old module uses tomcat's default configuration files and modifies them. The new module rebuilds the configuration files from scratch. There is a danger here that a new version of Tomcat may introduce some important contents in the default configuration file, NixOS may not notice this and use the old contents, and NixOS's tomcat instances would then lack this (presumingly important) configuration. I know that this is highly hypothetical scenario, but still it's possible, and has a potential of causing big problems.
  3. Minor but important: the new module must escape XML attribute names and values. (Maybe introduce a new escaping function in lib/strings.nix?)
  4. The location of Tomcat's stateful data shouldn't change for existing installations. (It won't be a problem if the old module is left in place, as suggested in (1).) At least, Tomcat should continue to write its logs to /var/tomcat/log, and store its session files in /var/tomcat/work.
    4a. It would be good to allow specifying the location of stateful data (at least logs) via attributes. At the same time, it would to read these locations. (For example, I'm using something like "${config.services.tomcat.baseDir}/logs" to determine where the logs are, and to configure my log rotation scripts; after upgrade, I would use config.services.tomcat.logsDir.)
  5. Minor: I don't like unconditional use of tomcat-native. Maybe it doesn't hurt, but I'm used to steer away from it. (It uses special kinds of connectors with unfamiliar, and possibly undesirable, properties.)
  6. I'm using custom catalinaOpts and commonLibs, so I would like to see them configurable. (For completeness, sharedLibs and javaOpts should be configurable as well.)

(Also, the descriptions of extraConfig and logFormat currently refer to Apache.)

I don't have much time available, but I would like to follow the development of this module rewrite, and to help (at least by commenting/reviewing/testing).

@aanderse
Copy link
Member Author

aanderse commented Apr 6, 2020

@pvgoran thanks for taking the time to comment. A couple questions:

  • are you using the tomcat module in production?
  • are you using tomcat directly as a web server, or are you using it with a reverse proxy, etc...?
  • are you storing any secrets in the nix store with this module?
  • what connectors and ports are you using?

@pvgoran
Copy link
Contributor

pvgoran commented Apr 6, 2020

are you using the tomcat module in production?

Yes.

are you using tomcat directly as a web server, or are you using it with a reverse proxy, etc...?

With a reverse proxy which lives on another machine connected via VPN. I'm also making local requests directly to Tomcat.

are you storing any secrets in the nix store with this module?

I don't think so. (SSL is handled by the reverse proxy.)

what connectors and ports are you using?

HTTP on 8080.

@aanderse
Copy link
Member Author

Thanks for your comments @danbst. I've had some higher priority stuff get in the way of this lately but will eventually circle back around.

@aanderse
Copy link
Member Author

@pvgoran thanks for your feedback. I've finally come back around to this PR. While still heavily WIP I'm making some progress and can somewhat address your points now.

  1. I understand. Fortunately NixOS makes it trivial to pin modules so you can take as long as you need to migrate. See https://nixos.org/nixos/manual/#sec-replace-modules for details if you aren't already familiar with this.

  2. tomcat is established and stable enough that dramatic changes aren't frequent. diff is a pretty solid tool for maintainers to guard against the type of problems you mention. Building server.xml the way this new module does is much more flexible and just as robust as the use of sed (which is scary! 😱) in the current module.

  3. That could be useful, though not strictly required. Something to keep in mind.

  4. I'm glad you mention the logs here. I hadn't added this option into my rewrite yet, but definitely should have. I have now added a logDir option which will store tomcat access logs. I'm still looking into the implications of the work directory. The way the current module copies configuration into stateful directories is bad. The new module has separated configuration from stateful data so configuration can be truly immutable, which is not only much cleaner, but a big win.

  5. You are definitely correct - this shouldn't be forced upon users who don't want/need it. I have fixed this now. The idea is that if you are using tomcat as an actual web server (as opposed to pairing with nginx/httpd) you want to pull in tomcat-native, otherwise you don't.

  6. catalinaOpts and javaOpts have been added back in 👍. Upstream suggests NOT using sharedLibs and commonLibs to a point where they have removed the way this worked in tomcat versions 6 or 7. Upstream suggests including jar files in your web application, which seems to fit the nix way of doing things reproducibly (build your apps with maven/gradle and specify all dependencies exactly). There is still the ability to do this (and I'll document it, it is relatively elegant) using catalina.properties but I don't think as a distro we want to promote things upstream is suggesting users steer clear of.

More to come.

@pvgoran
Copy link
Contributor

pvgoran commented Jun 3, 2020

@aanderse I didn't find time to reply yet. :(
But I'm going to do it.

''
;

serverXmlFile = pkgs.writeText "server.xml" ''
Copy link
Member

@Mic92 Mic92 Jun 3, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

by the way builtins.toXML does not work for cases like this?
Than escaping would come for free and it might be also faster since it is directly implemented as a native function.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll have to give that a try. Thanks @Mic92!

@stale
Copy link

stale bot commented Dec 2, 2020

I marked this as stale due to inactivity. → More info

@stale stale bot added the 2.status: stale https://github.com/NixOS/nixpkgs/blob/master/.github/STALE-BOT.md label Dec 2, 2020
@Mic92
Copy link
Member

Mic92 commented Dec 3, 2020

There is an temporary editor file committed that should be removed as well.

@stale stale bot removed the 2.status: stale https://github.com/NixOS/nixpkgs/blob/master/.github/STALE-BOT.md label Dec 3, 2020
@stale
Copy link

stale bot commented Jun 2, 2021

I marked this as stale due to inactivity. → More info

@stale stale bot added the 2.status: stale https://github.com/NixOS/nixpkgs/blob/master/.github/STALE-BOT.md label Jun 2, 2021
@aanderse aanderse mentioned this pull request Jun 17, 2021
11 tasks
@aanderse
Copy link
Member Author

Unfortunately I don't have reason to finish this.

@aanderse aanderse closed this Jan 17, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants