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

Would you be so kind as to include stack? #26

Open
why-not-try-calmer opened this issue Jul 25, 2022 · 6 comments
Open

Would you be so kind as to include stack? #26

why-not-try-calmer opened this issue Jul 25, 2022 · 6 comments

Comments

@why-not-try-calmer
Copy link

why-not-try-calmer commented Jul 25, 2022

I was enthusiast when I read that Images come with ghc and cabal executables alongside with commonly used libraries and build tools. Finding out that stack must be manually installed was disappointing. Of course, it's quite simple for the end user to add stack, but I think this does not honor the promise made in the sentence quoted.

Let's not forget all those who enjoy easy builds from Stackage snapshots... :)

edit: I realize there is a Stack workflow that is already supported, i.e using Stack from the host to build the target image. But you base image also allows to produce nice statically linked executables from outside the host, i.e. from a CI/CD runner. It is in particular in this context that it would be appreciable to have Stack pre-installed, so as to be able to use the image you offer as a build context to copy an executable from.

@why-not-try-calmer why-not-try-calmer changed the title Would you be kind enough to include stack? Would you be so kind as to include stack? Jul 25, 2022
@TravisCardwell
Copy link
Collaborator

Indeed, Stack usage is currently supported via Stack's Docker integration, where Stack on a host can use a ghc-musl container to build static executables. I support Stack in my projects, so this is well tested.

Including Stack in the container image should not be a problem. It can be configured to use the GHC that is already installed within the container, so adding it should result in only a ~77MB increase in the image size. I will test this as soon as I get a chance, hopefully soon.

TravisCardwell added a commit to TravisCardwell/ghc-musl that referenced this issue Jul 31, 2022
With this commit, Stack is installed in the image, to allow users to use
the image for CI builds.  Stack is configured to use the system GHC.  As
with Cabal, it is up to users to ensure that build configuration matches
the version of GHC in the image.

Implementation details:

* I replaced the `ghcup` and `ghc` targets with a single `haskell`
  target that installs GHCup, Cabal, GHC, and Stack.  Separate targets
  are not used in order to minimize Docker layers.
* The existing `test-stack` target is renamed to `task-stack-docker`.
  It tests using Stack Docker support.
* A new `test-stack` target tests using the Stack installed in the
  image.
* The `image` target now has three argument test flags: `TEST_CABAL` to
  enable/disable the `test-cabal` target, `TEST_STACK` to enable/disable
  the `test-stack` target, and `TEST_STACK_DOCKER` to enabled/disable
  the `test-stack-docker` target.
* I added the appropriate `ld-options` to the `.cabal` file for the
  example project, so that they do not have to passed via the command
  line.  Note that my future documentation changes will provide
  information about how to configure static builds using both Cabal and
  Stack.
* The example project that is used for testing has a `stack.yaml` file
  that sets `skip-ghc-check` to true so that the project will build no
  matter what version of GHC is available, even when it does not match
  the version specified by the resolver.  This continues to work for
  this test project.
@TravisCardwell
Copy link
Collaborator

I implemented this in the above-linked commit. Looking at the image sizes (for GHC 9.2.4), it results in ~1.69 GB increase. So much for my ~77MB estimate! 😆 That ~77MB is for the Stack installation, but quite a bit is stored in the .stack directory even without installing (another) GHC.

~/.stack # du -h
878.2M  ./pantry/hackage
1.5G    ./pantry
1.5G    .

@utdemir What do you think? If you would like to include this, I suggest the following steps:

  1. Merge Upgrade packages, change tag/target syntax (#23) #27
  2. I will rebase my stack branch and create a PR
  3. Merge that new PR
  4. Release
    • update-readme.sh
    • Build/push new images

By the way, I hope to resume/restart my new documentation changes soon, but I doubt I will have time to get to it this weekend.

@utdemir
Copy link
Owner

utdemir commented Jul 31, 2022

@TravisCardwell thank you for working on this and your investigations!

I feel pretty much the same with you, having stack would be useful within the docker containers, however I don't think I'd be willing to add 2 gigabytes to each image.

I wonder if there can be a compromise. What if we were to include stack within the image, but not do a stack update? This way, hopefully we wouldn't have the .stack directory. So if someone were to use stack within the image, they'd need to do a stack update themselves, but at least it'd be simpler than installing stack.

@why-not-try-calmer what do you think? Does having stack in the images, but still having to do a stack update works for you?

@TravisCardwell otherwise, I'm happy with the steps you suggested.

@TravisCardwell
Copy link
Collaborator

TravisCardwell commented Jul 31, 2022

I have been thinking along the same lines. I can add a flag so that stack update is not run by default, resulting in smaller images on Docker Hub. Users who build their own images can enable stack update using a build argument.

Running stack update in a CI job increases the run time and network usage of the job. Providing a flag will allow people to avoid this cost in cases where it is an issue.

Would you like to do the same with Cabal, by chance?

~/.cabal # du -h
884.9M	./packages/hackage.haskell.org
884.9M	./packages
884.9M	.

TravisCardwell added a commit to TravisCardwell/ghc-musl that referenced this issue Jul 31, 2022
This commit adds `CABAL_UPDATE` and `STACK_UPDATE` flags.  These flags
can be used to enable/disable running `cabal update` and `stack update`
respectively.  Currently, `cabal update` is enabled by default and
`stack update` is disabled by default, but users can use build arguments
to specify otherwise.

Here are the resulting sizes (for GHC 9.2.4 and Alpine 3.16.1):

| `cabal update` | `stack update` | Image Size | Relative Image Size |
| :------------- | :------------- | ---------: | ------------------: |
| Disabled       | Disabled       | 2.83GB     | 100%                |
| Enabled        | Disabled       | 3.76GB     | 133%                |
| Enabled        | Enabled        | 5.37GB     | 190%                |

Implementation details:

* These new flags are defined at the top level, not within the `haskell`
  context.  The reason for this is that Cabal fails when attempting to
  build before updating.  By defining the flags at the top level, we are
  able to run `cabal update` within the `cabal-test` target only when it
  was not already run within the `haskell` target.
@TravisCardwell
Copy link
Collaborator

Here is the table from the above commit message, so that GitHub will render it:

cabal update stack update Image Size Relative Image Size
Disabled Disabled 2.83GB 100%
Enabled Disabled 3.76GB 133%
Enabled Enabled 5.37GB 190%

@why-not-try-calmer
Copy link
Author

why-not-try-calmer commented Jul 31, 2022

@TravisCardwell thank you for working on this and your investigations!

I feel pretty much the same with you, having stack would be useful within the docker containers, however I don't think I'd be willing to add 2 gigabytes to each image.

I wonder if there can be a compromise. What if we were to include stack within the image, but not do a stack update? This way, hopefully we wouldn't have the .stack directory. So if someone were to use stack within the image, they'd need to do a stack update themselves, but at least it'd be simpler than installing stack.

@why-not-try-calmer what do you think? Does having stack in the images, but still having to do a stack update works for you?

@TravisCardwell otherwise, I'm happy with the steps you suggested.

Hello, thanks for working on this, I think it's very reasonable to expect the end user to run stack upgrade (in fact that's how it's done with most project / dependency managers in most languages nowadays). Also this is exactly how I did it for my personal use case (I committed to your official image an extra ghcup install stack but didn't include update).

So thanks a lot guys, really appreciated! Looking forward to using these brand new images.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants