How I should run my Golang process in background?

后端 未结 5 995
小蘑菇
小蘑菇 2021-01-30 12:19

This question is not strictly programming related, but for sure important for programmers.

I wrote a simple smtp server, when I run it from console all is fine, except i

5条回答
  •  天涯浪人
    2021-01-30 12:28

    But the question is, how should I implement my programm it runs in the background and it will be a pleasure for a system administrator to set it up and manage the process ?

    A few thoughts here.

    Provide packages and a repository

    Installing a software is one thing, maintaining and running it is a totally different story. Sure, I can download a zip, unpack it, put the files into the proper directories (keep in mind that packages are usually scattered throughout the file system), create a system user to run the daemon, set the according permissions. But that's tedious, error prone (which will lead to a high influx of tickets like "Bah! Does not run! Fix it!") and hardly practical if the software is going to be installed on many systems.

    So we need a package to lower the hurd of adoption. Providing a repository for those packages usually is no rocket science and makes installation and/or updates much easier. There is a difference between "Download->Distribute->Install/Update" and a single command/server like

    $ awesomePm update coolApplication
    

    Provide at least packages for RedHat and Debian based systems. Personally, I'd go for CentOS (which would make your package compatible to almost any RHEL derivate) and basic Debian. The latter should make it trivial to provide a package for Ubuntu, too. Since I don't use Debian or derivates any more, I am not too sure wether they are really compatible, there have been startup issues when I last built a .deb.

    Provide proper documentation. Document what is installed, where, and why. Provide links to the according documentation. manpage references to dependencies are sufficient. This way, you enable even the most inexperienced admin to configure your package.

    Use the most defensive, sane defaults.

    Special note with regard to golang: Most package build tools strip the binaries contained in the package by default. Go does not support that, so take care here.

    Be complete

    There is nothing more annoying than an incomplete package.

    Use syslog if at all possible and adhere to it's conventions. This way, your logs will be put into places where the system admin expects them and they are taken care of if outdated automatically,preventing your application to cause disks running full. If the system admin wants special treatment of your application's logs, he will configure it this way.

    Do not rotate the logs via your application. It is the users choice on what to do with them (which might be relevant for their SLAs). Even if you make the way logs are rotated configurable, the admin has to learn how to configure it – which introduces unnecessary redundancy.

    If you have to write to a log file, adhere to the target system's logging policy and provide a log rotate configuration file. You don't want you application be the cause of downtime just because the machine ran out of disk space, do you?

    Use system tools instead of reinventing the wheel. If your application needs to do some maintenance, do not bother to use a scheduler inside your application. Write a specialized tool for the maintenance (monolithic applications are so '00s) and utilize cron. Specifically add according files to one of the /etc/cron* directories.

    Provide proper init scripts! This way, the admin can use well known tools like systemctl to mange startup and shutdown of your application. It is pretty annoying when you have to su to a user or use sudo -u to call a shell script on startup. Even when this script is called @onboot, the deviation from standards is annoying. Just because a startup method works it does not mean that it should be used.

    Bonus points for adding an SE-Linux profile!

    It should go without saying, but I have seen misconfigured packages way to often, so: Test your packages! Start with a minimal install of the target OS, install your package and make sure it runs as expected. Check every configuration you provide.

    If you plan to have a package put into the official Debian repositories, you should plan some time: the reason why Debian is as stable is that the requirements on packages are pretty tight, and even when you fulfill all requirements, you have to go all the way from testing via unstable to stable.

    Be precise

    Do not use existing users just because it is convenient. If you create a web application, do not reuse the "apache" or "www" user. Create a user dedicated to your package and add this user to the according groups.

    Adhere to the principle of least necessary permissions. There is hardly a reason to have a binary world executable, much less world writable (which would be an extreme security hole). What you often see here on SO if an application does not run is the suggestion to set the permissions to [0]777, which allows every user to make modifications whatsoever on the file. Actually, there is almost no reason to make a binary writable to any user: root, who does the updates anyway, can always write anything. So the permissions should be 0550 for binaries. The principle also applies to data directories and such. Invest some time and effort here. You don't want your app to be the vector for an successful attack, do you? Even potential security risks tend to fire back on you and your reputation. What I tend to do is to set all data files to 0600 for files that need to be written by the system user of the application, 0400 for read-only files and 0500 for binaries. Then, I do a granular analysis what the group permissions should be. For example: A group might change the individual templates for a web application – but most likely not the directory structure of the resource directory subtree.

    If you put effort into security, you will increase trust. Be aware that packages are often checked for their security impact prior to the decision wether they are adopted.

    Adhere to the FHS(!!)! And even then: just because you can do anything under /opt/yourapplication, it is not always a good idea to do so. Rather install into /usr and /var respectively (assuming your application is not necessary during boot time).

    If you have dependencies, define them. Do not merely assume that a package is present.

    If you have a dependency for a local SMTP server, do not declare a dependency on postfix. Maybe the admin prefers sendmail (for whatever reason that may be). So define a dependency on mail-transport-agent (Debian) or mta (RH, iirc) instead.

    Conclusion

    This is what I expect of a good software – integrating nicely with existing software and to make it easy to install, maintain, configure and run it without having to learn redundant configuration. If I see a SELinux profile for a package, that really gives the vendor a bonus – unless the profile is extremely sloppy, it shows that the vendor takes security very serious.

提交回复
热议问题