A Docker-based build and deployment system for running Flutter applications on embedded Linux systems using DRM/GBM (Direct Rendering Manager / Generic Buffer Management). Build on macOS, deploy to any Linux server, and create a boot-to-UI experience.
- Build on macOS: Docker-based, reproducible, multi-architecture builds
- Linux Runtime: Complete runtime package with Flutter binary and required libraries
- One-Liner Deploy: SSH-based deployment to any Linux server
- Boot-to-UI: systemd integration for automatic startup on boot
- Multi-Architecture: Support for both x86_64 (Intel/AMD) and ARM64 (Raspberry Pi, etc.)
This system uses flutter-elinux to build Flutter applications that run directly on Linux framebuffer using DRM/GBM, without requiring X11 or Wayland. Perfect for:
- Embedded Linux devices
- Kiosk applications
- Digital signage
- IoT interfaces
- Headless servers with GPU
-
Docker Desktop
brew install --cask docker open -a Docker
Wait for Docker Desktop to start completely.
-
Make (pre-installed on macOS)
make --version # Verify it's installed -
SSH Access to your target Linux server
- Ensure you can SSH without password (use SSH keys)
- Test with:
ssh user@your-server-ip
-
Supported OS: Ubuntu 22.04+ or Debian 12+ (minimal installation)
-
SSH Server running and accessible
-
User with sudo privileges
-
GPU/DRM Support: Physical GPU or virtio-gpu for VMs
- Check with:
ls /dev/dri/card* - Should show at least
/dev/dri/card0
- Check with:
git clone https://github.com/your-username/flutter-linux-os.git
cd flutter-linux-osFor x86_64 servers (most PCs, Intel NUCs, VMs):
make build-amd64For ARM64 servers (Raspberry Pi 4/5 with Ubuntu):
make build-arm64This will:
- Create a Docker container with Flutter and flutter-elinux
- Build your application for Linux DRM/GBM
- Package it into a Docker image
Note: First build takes 10-20 minutes. Subsequent builds are faster.
make artifactsFor ARM64 builds:
make artifacts ARCH=arm64This extracts the compiled application and libraries to dist/linux/flutter_linux_os/.
make deploy HOST=192.168.1.50 USER=ubuntuReplace:
192.168.1.50with your server's IP addressubuntuwith your SSH username
This will:
- Install required system libraries
- Create an
appuser with proper permissions - Copy your application to
/opt/flutter_linux_os - Install and start a systemd service
- Configure the system to boot directly into your Flutter UI
flutter-linux-os/
├── lib/ # Flutter application code
│ └── main.dart # Main application entry point
├── assets/ # Images, fonts, etc.
├── scripts/
│ └── deploy.sh # Deployment automation script
├── systemd/
│ └── flutter-os.service # systemd unit file
├── Dockerfile.elinux # Multi-stage Docker build
├── Makefile # Build automation
├── pubspec.yaml # Flutter dependencies
└── README.md # This file
Run make help to see all available commands:
make build-amd64 # Build for x86_64 (Intel/AMD) servers
make build-arm64 # Build for ARM64 (Raspberry Pi, etc.)
make artifacts # Export built artifacts from Docker image
make clean # Remove build artifacts
make deploy # Deploy to remote server (requires HOST=... USER=...)
make help # Show available targetsEdit files in lib/ and assets/ as you would with any Flutter project.
If you want to test on your Mac during development:
-
Install Flutter on macOS:
brew install --cask flutter flutter doctor
-
Run on macOS:
flutter run -d macos
Note: macOS builds use native macOS rendering, not DRM/GBM.
After making changes:
make build-amd64 # Rebuild
make artifacts # Export artifacts
make deploy HOST=your-server USER=your-userOn your target Linux server, run once:
# Ensure proper drivers are installed
sudo apt update
sudo apt install -y network-manager
# Reboot to ensure all device permissions settle
sudo rebootls -l /dev/dri/Should show something like:
drwxr-xr-x 2 root root 80 Nov 9 12:00 .
drwxr-xr-x 5 root root 360 Nov 9 12:00 ..
crw-rw---- 1 root render 226, 0 Nov 9 12:00 card0
crw-rw---- 1 root render 226, 1 Nov 9 12:00 renderD128
# View logs
sudo journalctl -u flutter-os -f
# Stop the service
sudo systemctl stop flutter-os
# Start the service
sudo systemctl start flutter-os
# Restart the service
sudo systemctl restart flutter-os
# Check status
sudo systemctl status flutter-os
# Disable auto-start on boot
sudo systemctl disable flutter-osWhen the Flutter UI is running on /dev/tty1, you can switch to a text console:
- Ctrl + Alt + F2: Switch to tty2 (text console)
- Ctrl + Alt + F1: Switch back to Flutter UI
Or SSH into the server from another machine.
make build-amd64
make artifacts
make deploy HOST=192.168.1.50 USER=ubuntumake build-arm64
make artifacts ARCH=arm64
make deploy HOST=192.168.1.100 USER=piDocker Buildx will use emulation (QEMU) for cross-platform builds. ARM64 builds from macOS may take longer due to emulation.
Docker not running
open -a Docker # Start Docker DesktopBuild fails with "platform not found"
docker buildx create --use # Create a new buildx builderSSH connection fails
- Verify SSH access:
ssh user@host - Check SSH keys are set up correctly
- Ensure target server is reachable
Service fails to start
Check logs:
ssh user@host 'sudo journalctl -u flutter-os -n 50'Common issues:
- Missing libraries: Re-run deployment
- GPU not accessible: Check
/dev/dri/permissions - Wrong user: Verify
appuser is inrender,video,inputgroups
Black screen on server
Try software rendering:
- Edit
Dockerfile.elinux - Change build line to:
RUN flutter-elinux build elinux --release --target-backend-type=drm --software - Rebuild and redeploy
Application crashes on startup
Check if dependencies are installed:
ssh user@host 'ldd /opt/flutter_linux_os/flutter_linux_os'All libraries should be found (not "not found").
No display output
- Verify
/dev/dri/card0exists - Check user permissions:
groups appshould includerender,video - Try a different TTY: Edit
systemd/flutter-os.serviceand changeTTYPath=/dev/tty2
For local AI inference (LLMs, Whisper, etc.):
- Run a lightweight AI server (e.g., llama.cpp, whisper.cpp) as a separate systemd service
- Expose it on
127.0.0.1:11434 - Your Flutter app connects via HTTP/WebSocket
- See
docs/AI_INTEGRATION.mdfor details (coming soon)
Edit systemd/flutter-os.service and add environment variables:
[Service]
Environment=MY_VAR=value
Environment=API_KEY=your-keyThe systemd service runs the app fullscreen by default. To change:
Edit systemd/flutter-os.service:
ExecStart=/opt/flutter_linux_os/flutter_linux_os --windowed --width=1920 --height=1080Contributions are welcome! Please open an issue or submit a pull request.
MIT License - See LICENSE file for details
For issues and questions:
- GitHub Issues: https://github.com/your-username/flutter-linux-os/issues
- Flutter elinux docs: https://github.com/sony/flutter-elinux