knadh / listmonk

High performance, self-hosted, newsletter and mailing list manager with a modern dashboard. Single binary app.
https://listmonk.app
GNU Affero General Public License v3.0
14.73k stars 1.35k forks source link

Distribute listmonk as Snap #295

Open mdehollander opened 3 years ago

mdehollander commented 3 years ago

It would be nice if we can create a snap package for listmonk: https://snapcraft.io/ Rocket Chat is a good example of a automatically updating snap package that also has a database: https://github.com/RocketChat/Rocket.Chat#instant-server-installation-with-snaps

The docker compose config has to be converted to s snapcraft config. Here is an example for Rocket Chat: https://github.com/RocketChat/Rocket.Chat/blob/develop/.snapcraft/snap/snapcraft.yaml

If you like the idea, I am happy to contribute and test.

mr-karan commented 3 years ago

@mdehollander Listmonk uses Goreleaser to build and release packages. So, if this has to be done, it should be done via changing the goreleaser.yml as mentioned here.

That being said, at one point we did explore the feasibility but there are some questions while packaging a binary with a DB:

1) If the user already has a PostgreSQL installation, what do we do? Rocketchat fails to initialise if there's already a MySQL server running. 2) Would snap need to be defined as a "classic mode" (which breaks out of confinement zone) simply because it needs to read config.toml from a user specified directory?

Alternative:

mdehollander commented 3 years ago

Hi @mr-karan. thanks for your answer. Good to hear that creating a snap package is possible with Goreleaser. That makes integration with the current build process easier I think.

The other points you raised are indeed something to figure out what works out best:

  1. I think with snaps you can run multiple instances of database within different snaps. So running Rocket.Chat next to Nextcloud, who both use bundle the database with the snap should be possible. I would have a preference to create a snap that also includes the database, since this makes it an easier and single click install for the end user. See also https://forum.snapcraft.io/t/recommended-way-of-using-postgresql-inside-snap/18878/2
  2. I think the configuration values can to be provided with the snap set command. Nextcloud handles the configuration in this way: https://github.com/nextcloud/nextcloud-snap#configuration
  3. Another issue bundling Postgres with the snap, is that it needs to be allowed to run as root: https://forum.snapcraft.io/t/snapping-a-rails-app/7179/6, which should be fine because it is running inside the snap. There are a few examples of snap packages that make sure postgres runs as the snap_deamon user using the setpriv command: Kong and Gatekeeper
mr-karan commented 3 years ago

@mdehollander Thanks for the links. Let me explore the options and get back.

mr-karan commented 3 years ago

@mdehollander So, I looked at bunch of things you'd mentioned + some other projects. Doing this as part of Goreleaser is not possible if we need to bundle PG as it requires config options to be set in snapcraft.yml. This might mean we'll have to decouple the release process with Goreleaser, but yeah this is not a blocker. Will attempt doing a basic prototype this week.

knadh commented 3 years ago

I don't think bundling Postgres instance inside the app's snap is a good idea. It's okay if there are two steps involved in the installation, as long as they are simple.

mr-karan commented 3 years ago

+1 I'm of the same opinion. I believe the user can just do sudo snap install postgres (or even apt-get install is trivial enough to run a Postgres instance). If that's the case, then just adding a few more options to goreleaser.yml should be sufficient. Will try this out.

mdehollander commented 3 years ago

Thanks for picking this up. :clap: I see the benefits of having it part of goreleaser and having postgres outside of the snap. Since snap packages are auto-updating, I am wondering how this will work with db migrations etc.

mr-karan commented 3 years ago

Migrations are gonna be tricky with any kind of auto updates, not just snap. The same issue currently exists if someone uses listmonk:latest docker image and does a docker-compose up -d (which will pull the latest version and could break if migrations are required to be run).

In such cases, it's fine to just run ./listmonk --upgrade manually. I don't think it's a big concern to address as of now.

knadh commented 3 years ago

If listmonk is packed as a background service and it gets auto-updated, it will silently fail to start without running --upgrade manually. I don't know how snap handles this, but is there a way to notify users that an update needs manual intervention?

mdehollander commented 3 years ago

Snap used epochs to control stop auto-update if there is a release with changes that needs manual intervention. See https://snapcraft.io/docs/snap-epochs

knadh commented 3 years ago

Any luck with this? :)

1000i100 commented 3 months ago

If a snap like package have to be done, why not use less centralised ones ? I think about Flathub at the nearest or AppImage. more about that : https://hackaday.com/2020/06/24/whats-the-deal-with-snap-packages/ https://www.reddit.com/r/linux/comments/j3ajnf/whats_wrong_with_snaps_why_so_many_people_hate_it/ https://itsfoss.com/flatpak-vs-snap/ https://www.baeldung.com/linux/snaps-flatpak-appimage