commercialhaskell / commercialhaskell/stack

Dynamically linked stack release binaries aren't really compatible with stack --docker

Open
#4,087 7 comments 2 reactions 0 assignees View on GitHub
component: docker component: releases
Dominant language
Haskell
Stars
4.1k
Forks
850
Avg merge
10h 37m
Merged PRs (30d)
4

Description

## Summary

`stack --docker` doesn't work reliably across Linux distributions because `stack` is no longer statically linked.

## Why we don't have statically linked executables at the moment

In the past, we provided statically linked stack executables. Those worked fine with `stack --docker`.

We used Alpine Linux to create these stack executables. Unforunately, Alpine Linux doesn't work with GHC >= 8.2 (see https://github.com/commercialhaskell/stack/issues/2387, https://github.com/channable/vaultenv/issues/43#issuecomment-390116575, and https://github.com/alpinelinux/aports/pull/4255).

Stack 1.7 requires GHC >= 8.2. So we don't have staically linked executables for that.

We needed Alpine Linux to create the executables because it provided a full [`musl`](https://www.musl-libc.org/) based toolchain (`musl` is a replacement for `glibc`, and [`glibc` pretty much forbids static linking](https://sourceware.org/glibc/wiki/FAQ#Even_statically_linked_programs_need_some_shared_libraries_which_is_not_acceptable_for_me.__What_can_I_do.3F))

## Why static linking is needed for `stack --docker` to work

When you use `stack --docker build`, the outer stack executable is re-executed inside the docker container.

If that executable is dynamically linked, and the outer `libc` is a different version than the inner `libc`, then stack will fail to run in the container.

Right now, the linked-dynamicall-against-libc [generic `stack` installer](https://docs.haskellstack.org/en/stable/install_and_upgrade/#linux) we provide works on many Linux distributions, and it works in docker images such as `fpco/stack-build:lts-11.13` which is what `stack docker pull` pulls.
But it doesn't work on all distributions, and for those where it doesn't, `stack --docker` support is completely broken right now. Further, as soon as some distro (like Arch) will advance to an incompatible libc earlier than other distros (e.g. Ubuntu), the generic installer will also stop working nicely.

## How it fails

It doesn't fail with a nice error message, leaving the user in doubt:

```
$ stack --docker build
Received ExitFailure 127 when running
```

## Proposed solution

We need to

* [x] get statically linked `stack` back in order to make `stack --docker` work everywhere.
* [ ] tell people that dynamically-linked `stack` doesn't really support `stack --docker`.
* [ ] in a message during `stack` execution so that users don't get confused by the nonexisting error message (see above)
* [ ] in documentation; downstream packagers don't seem to know that they break `stack --docker` when they link stack fully dynamically (see my next comment for how Arch Linux gets it wrong)
* **EDIT:** not necessary, as stack has an automatic fallback to downloading static executables if re-executing the host `stack --version` inside Docker doesn't work, see https://github.com/commercialhaskell/stack/issues/4087#issuecomment-500622630
* [x] improve the [docs](https://github.com/commercialhaskell/stack/blame/952123f43186b43ea5e13ce8b47fd115ebc7fe2d/doc/docker_integration.md#L247-L248) saying `executable must be built on linux-x86_64 and statically linked` (see [comment below](https://github.com/commercialhaskell/stack/issues/4087#issuecomment-397308592))
* #4858

## Scope

This ticket is specifically for `stack --docker` problems; I'll file a separate issue (https://github.com/commercialhaskell/stack/issues/4088) about getting statically linked `stack` back, as that is desiable also for other reasons than Docker.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.