6

I have a Java app - although the answer here should be the same regardless of whether it is Java, Ruby, Python, etc. - that I would like to distribute in such a way that when devops folk go to install it, it automagically runs as a daemon, with zero config on their side. My inspiration for this comes from the Docker daemon, which is written in Go but that automagically configures itself as a daemon on Ubuntu machines. I want to do the same, but have no clue where to even begin.

I would imagine that either:

  • I need to somehow package my app inside a deb; or
  • Ship my app executable with necessary init/systemd/upstart/etc. scripts that somehow get installed locally without the end user having to run them. However, in this case, I’m not sure how to select which scripts to install as the user may have any one of several init-like tools setup.

Any ideas?

1 Answer 1

3
+100

On Ubuntu (and Debian), creating a deb package would be the best way to go, as everything can be automated, so that no end-user intervention is needed. The only cases where package installation or upgrades are not automated are if the package has some configuration options that need input from the user (mainly during installation only) or if a configuration file was modified by the user and is also modified by a newer version of the package (during upgrading). In addition, after installing/upgrading a package, any startup scripts it installs are automatically started.

You can have multiple init scripts be installed, and have everything still work. In the case of systemd being installed and used on the user's computer, if there is both an init script and a systemd script for the same service, then the init script is ignored and the systemd script is used.

In terms of the packaging itself, Debian provides helper scripts that (among other things) automatically install any startup scripts you provide (I don't think upstart is supported by their helper scripts, since this is only used on Ubuntu) and start the service. For an example of the packaging, see this debian folder for the dump1090-mutability package. (Disclaimer: this is my Github account) Note that the dump1090-mutability.init file contains the init script while the dump1090-mutability.service file contains the systemd script. Note that the names of these files should be package-name.init and package-name.service, where package-name is the name of the binary package being created. (See man dh_systemd_enable and man dh_systemd_start for the systemd case.)

On packaging, both of these files are placed in the appropriate directories on the user's system, and the service is then started. For the rules file, I recommend that you have something like the following, so that you benefit from the automation (see this for the --with systemd part):

#!/usr/bin/make -f
%:
        dh $@ --with systemd

override_dh_auto_build:
        # Specify how to build the Java files here, if there is no Makefile provided

override_dh_auto_install:
        # Specify how to install the Java files here, if there is no `install` target in the Makefile. Don't worry about anything in the `debian` directory unless you need to install some icons.
  • If your app doesn't have a Makefile and is just a collection of Java source files, fill out override_dh_auto_build (where the source files are compiled and packaged into a JAR) and override_dh_auto_install (where the JAR is installed).
  • If your app has a Makefile, but doesn't have an install target, remove the override_dh_auto_build target and fill out override_dh_auto_install.
  • If your app has a Makefile and it has an install target (that can be used), remove both targets.
  • If your app is just a JAR file, remove override_dh_auto_build, and fill out override_dh_auto_install.
5
  • Thanks @saiarcot895 (+1) - ideally I would not have to distribute sources and could just have the deb install the packaged JAR - is this possible? Either way, could you please update your answer to include a sample of what the directory structure would look like for the ZIP/TAR that I would ultimately distribute? I'd imagine this ZIP/TAR would contain the deb package, the install scripts, and the JAR, but am still fuzzy on how this would all look. Thanks again!
    – smeeb
    Jul 29, 2015 at 13:30
  • 1
    Yes, you can choose to ship just the JAR file. See the last bullet point above. The deb file contains everything; you won't have any other files outside of the deb file to ship, so you don't need to put it in a zip/tar file. Jul 29, 2015 at 16:36
  • Thanks again @saiarcot895 (+1) - last followup question, I promise! Is all of this Ubuntu-compatible, or does it just run on Debian? Thanks again!
    – smeeb
    Jul 29, 2015 at 17:01
  • Even better: it's Ubuntu and Debian compatible. Jul 29, 2015 at 17:01
  • The building of the package itself will have to be on Ubuntu 15.04 or Debian Jessie (or newer), because of the --with systemd part, but, if needed, with a little more code, you can choose to compile on Ubuntu 14.04+ or Debian Wheezy and have the resulting package work on both init and systemd systems. Jul 29, 2015 at 17:03

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .