-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Docker Multi Arch Builds Fix #1414
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
Docker Multi Arch Builds Fix #1414
Conversation
.github/workflows/release.yml
Outdated
@@ -9,6 +9,9 @@ jobs: | |||
goreleaser: | |||
runs-on: ubuntu-latest | |||
steps: | |||
- name: Set up QEMU |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is needed for buildx
and goreleaser
to build multi-arch. Also documented in https://goreleaser.com/cookbooks/multi-platform-docker-images/
.github/workflows/release.yml
Outdated
@@ -36,6 +39,10 @@ jobs: | |||
run: | | |||
make dist | |||
|
|||
- name: Check Docker Version |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doesn't harm, is helpful for debugging failed actions
.goreleaser.yml
Outdated
@@ -1,6 +1,8 @@ | |||
env: | |||
- GO111MODULE=on | |||
- CGO_ENABLED=0 | |||
- GITHUB_ORG=knadh |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This allows people to fork and change to their own username and hence test build and publish
.goreleaser.yml
Outdated
- freebsd | ||
- openbsd | ||
- netbsd | ||
# - freebsd |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Obvious. Feel free to remove but I actually like it for clarity reasons.
.goreleaser.yml
Outdated
@@ -41,123 +44,123 @@ dockers: | |||
goos: linux | |||
goarch: amd64 | |||
ids: | |||
- listmonk | |||
- listmonk |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Really not much has changed here. It's all just got better through the variable usage. And because that was properly formatted etc it looks like everything changed but barely anything changed.
README.md
Outdated
@@ -2,7 +2,7 @@ | |||
|
|||
[](https://listmonk.app) | |||
|
|||
listmonk is a standalone, self-hosted, newsletter and mailing list manager. It is fast, feature-rich, and packed into a single binary. It uses a PostgreSQL (⩾ v9.4) database as its data store. | |||
listmonk is a standalone, self-hosted, newsletter and mailing list manager. It is fast, feature-rich, and packed into a single binary. It uses a PostgreSQL (⩾ 12) database as its data store. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This one is kinda funny because I didn't change that version. Do you know why it shows changed?
cmd/init.go
Outdated
) | ||
|
||
// Memory / alloc stats. | ||
runtime.ReadMemStats(&mem) | ||
si.GetSysInfo() // OS info. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the Utsname
replacement basically. It doesn't die on multi-arch.
cmd/install.go
Outdated
@@ -17,7 +17,7 @@ import ( | |||
|
|||
// install runs the first time setup of creating and | |||
// migrating the database and creating the super user. | |||
func install(lastVer string, db *sqlx.DB, fs stuffbin.FileSystem, prompt, idempotent bool) { | |||
func install(lastVer string, db *sqlx.DB, fs stuffbin.FileSystem, prompt, idempotent bool, continueAfterInstall bool) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just passing the flag here
cmd/install.go
Outdated
lo.Println("exiting now (use --continue-after-install to continue)") | ||
os.Exit(0) | ||
} else { | ||
// simply end the function to avoid resetting up the database and pulling queries |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
obvious, see comment.
cmd/main.go
Outdated
os.Exit(0) | ||
install(migList[len(migList)-1].version, db, fs, !ko.Bool("yes"), ko.Bool("idempotent"), ko.Bool("continue-after-install")) | ||
|
||
if !ko.Bool("continue-after-install") { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
making sure old behaviour is kept when the flag is not set.
docker-compose.stack-demo.yml
Outdated
@@ -0,0 +1,75 @@ | |||
version: "3.7" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah this file is the demo file for what is documented in the docs.
Hi, thanks for the contribution. Will test this and get back to you shortly. |
Thanks for the PR. However, this contains many unrelated changes. Please send separate PRs for those.
Unsure if we should introduce yet another flag. Wouldn't |
+1 |
I can surely split the PR but the command you are proposing will truncate the DB completely when docker service restarts. And Docker Service Restarts are amongst the most common thing on earth :) So what you are saying is "run 2 commands and you're fine". If you wanted what you proposed it would look like this:
Now when you need to add config, which is the normal use case when using docker secrets etc. this becomes easily a large and cumbersome command where you are workarounding running "one process" (that is what docker does -> running exactly 1 process) needs to be worked around with something like Running 2 processes in I really really recommend having this in one single process, there's not much need to split those apart. ORM's behave the same way: You startup the single process and it will setup the structure if needed. That is best practice. |
The only other thing I can propose as compromise is making In that case we would get all what we want: Less flags, one process, installs IF not installed yet. What do you prefer? edit: edit 2: Just tell me what of those you want but please don't tell me that running 2 processes is a good way to go because I can tell you: In orchestrated Docker Environments it is definitely not :) |
Ah, we cannot change the meaning of
I think a slightly long and verbose command is a fair trade-off here. |
Can you elaborate what you mean with breaking Because for orchestrated Docker running 2 commands effectively means that you have to use Or do you have any better proposal? Like I really want the docker Where do you see the benefit in installing first and only installing (besides talking about breaking changes now)? If we introduce a new major version update I don't see a problem with having breaking changes. Also I would like to understand what you mean with |
Either way, first things first I will split the PR to make releases work again |
@knadh @Thunderbottom @mr-karan I cleaned up this PR to be only the multi-arch fix. I will open others for the other things. |
However I rename it now because it really isn't real swarm support as I understand it simply because we don't have the aforementioned and discussed |
Hi @activenode. Apologies, there are so many commits and comments now, I'm confused! Please rebase with the latest |
7d3c226
to
ffaba95
Compare
ffaba95
to
f3e9b08
Compare
Okay so here's a few things that have changed but I can confirm it works and it builds because I did both of it.
Here's the ready-built stuff on my HUB: https://hub.docker.com/r/activenode/listmonk/tags
And I also deployed it on my Server to test it, including the new flags. Feel free to do the same.
There are 3 things essentially done in this PR:
I will also add comments to my own PR so you can follow up what is what. Feel free to merge whenever you want. Until then my own pipeline will still be running and pubbing docker images at
activenode/listmonk
.Considering Multi-Arch:
QEMU missing
So when this was merged: #1344 it was a very good intent and good prework but I think the author didn't test this in GitHub Actions because that's where it definitely fails. It needs
QEMU
to even work properly.Multi-Arch Problems 1
Multi-Arch is more than just building on different platforms. Different platforms have different syscalls. And that's where the whole build crashed because
Utsname
is kinda architecture specific. Since it wasn't a biggie, I just added a more universal solution which works fine.Multi-Arch Problems 2
It gets even more complex and harder to maintain if we go beyond Linux. I mean I've seen the
netbsd
building fine but then again withWindows
anddarwin
you open up a different system to a different CPU architecture.I left it there, commented, for the reason of clarity. But I don't think we should keep it and in general there is no benefit (it wasn't there before and no one missed it and even IF you'd be deploying on Windows you could use the Linux Subshell so really there is no benefit).
Considering
docker stack
ordocker swarm
or in general improving Listmonk:I have seen that there are flags undocumented but working fine such as
--yes
and--idempotent
. They totally make sense and I added them to theREADME.md
.Now running a binary twice really is beyond convenient for deployable stacks on docker. It's doable manually for sure but really this isn't how Cloud usually works and makes the process very inefficient.
I noticed that in theory you could run the process twice in one container with using the
--idempotent
together with--install
. But then again: Unnecessary. However also I didn't want to change the default behavior as I find that dangerous in general as it would be a breaking change.So, what I did:
I introduced a new flag
--continue-after-install
which is also passed toinstall.go
. It makes sure thatlistmonk
will run install but then notexit
but keep-alive. Together with--idempotent
this allows for very convenient deployments which I also documented ininstallation.md
and also added a sample for usage with docker secrets as well as providing a downloadable sampledocker-compose.yml
.Considering SMTP Settings UX improvement:
It wasn't clear to me that "Testing" currently only works when the password is unsaved. I find this totally okay but it's UX-wise VERY confusing.
So now if you try to test it you'll get this, which is nice:
