Rant: Flutter install and build utterly entangled
I’ve been looking into creating a phone app using Flutter. Like any good developer, I looked for a reproducible environment, and Docker seemed like a reasonable place to find inspiration.
It proved to be harder than expected.
Disclaimer: I don’t have any experience with Flutter or mobile development, not in the slightest. So that might be where the REAL problem is buried.
I’m usually good at these things. But either I’m falling behind, or the Flutter SDK just doesn’t make it easy (or even possible) to implement in an elegant way.
My vision was:
- Leverage Docker for reproducibility
- Install Flutter (and all its friends) as read only for any non-privileged user - locking versions down.
- Allow any user to run
flutterto test and build their project (preferably via bind mount).
It was possible to “redirect” the cache for the Dart package system and Gradle. But regardless, Flutter insists on “checking in” on every command, and updating a timestamp, e.g. in engine.stamp. I could provide a third cache via a bind mount for Flutter (flutter/bin/cache/), but an empty cache triggered Flutter to check (and reinstall) things in flutter/packages/flutter_tools/. It started to feel like a dependency circle with no way to tie down a foundation without breaking something else.
I tried to replace upgrade with get in $DART pub get --suppress-analytics to avoid Flutter updating parts of itself (reproducible builds and all that).
I even looked into disabling pub_upgrade_with_retry found in flutter/bin/internal/shared.sh and ignoring the lockfile outside the cache in flutter/packages/flutter_tools/pubspec.lock - yes, I was desperate.
… and I did get flutter test working for a “Hello World” app, but everything started falling apart when building the APK file, and I didn’t dare imagine what else would break once I moved beyond the “Hello World” stage.
On top, Flutter seems to insist on being able to write in the directory with the code. My naive brain had expected that Flutter would only need read access to my code and then produce its build artifact(s) in a directory of my choice.
In short, you can only use Flutter if:
- you installed it yourself
- and you can (over)write the application source code you are building.
I was disappointed, neither should be required, in my opinion 😮💨
I compromised by building gmeligio/flutter-docker-image where the uid and gid for the flutter user were replaced with my uid and gid on the host system in the file android.Dockerfile.
I have traded elegance for pragmatism. Maintaining the Docker image is suddenly a lot easier. I just hope having write access all over will not bite me.