{"id":31563258,"url":"https://github.com/macmpi/alpine-linux-headless-bootstrap","last_synced_at":"2025-10-05T04:57:38.645Z","repository":{"id":46236840,"uuid":"512021427","full_name":"macmpi/alpine-linux-headless-bootstrap","owner":"macmpi","description":"Headless Alpine Linux bootstrapping scripts","archived":false,"fork":false,"pushed_at":"2025-08-27T12:53:52.000Z","size":293,"stargazers_count":225,"open_issues_count":0,"forks_count":32,"subscribers_count":5,"default_branch":"main","last_synced_at":"2025-09-16T16:53:16.727Z","etag":null,"topics":["alpine-linux","bootstrap","headless","how-to","overlay"],"latest_commit_sha":null,"homepage":"","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/macmpi.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"ko_fi":"macmpi","open_collective":"alpinelinux"}},"created_at":"2022-07-08T20:41:32.000Z","updated_at":"2025-09-13T22:05:18.000Z","dependencies_parsed_at":"2023-11-23T22:30:05.625Z","dependency_job_id":"1d03a060-ee03-4af7-9bc8-b59223003a38","html_url":"https://github.com/macmpi/alpine-linux-headless-bootstrap","commit_stats":null,"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"purl":"pkg:github/macmpi/alpine-linux-headless-bootstrap","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/macmpi%2Falpine-linux-headless-bootstrap","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/macmpi%2Falpine-linux-headless-bootstrap/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/macmpi%2Falpine-linux-headless-bootstrap/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/macmpi%2Falpine-linux-headless-bootstrap/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/macmpi","download_url":"https://codeload.github.com/macmpi/alpine-linux-headless-bootstrap/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/macmpi%2Falpine-linux-headless-bootstrap/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278411255,"owners_count":25982368,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-05T02:00:06.059Z","response_time":54,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["alpine-linux","bootstrap","headless","how-to","overlay"],"created_at":"2025-10-05T04:57:37.002Z","updated_at":"2025-10-05T04:57:38.636Z","avatar_url":"https://github.com/macmpi.png","language":"Shell","readme":"# Bootstrap Alpine Linux on a headless system\n\n[Alpine Linux documentation](https://docs.alpinelinux.org/user-handbook/0.1a/Installing/setup_alpine.html) assumes **initial setup** is carried-out on a system with a keyboard \u0026 display.\\\nHowever, in many cases one might want to deploy a headless system that is only available through a network connection (ethernet, wifi or as USB ethernet gadget).\n\nThis repo provides an **overlay file** to initially bootstrap[^1] such headless system (leveraging Alpine distro's `initramfs` feature): it starts a ssh server to log-into from another Computer, so that actual install on fresh system (or rescue on existing disk-based system[^2]) can then be performed remotely.\\\nAn optional script may also be launched during that same initial bootstrap, to perform fully automated setup.\n\n\n## Setup procedure:\nPlease follow [Alpine Linux Wiki](https://wiki.alpinelinux.org/wiki/Installation#Installation_Overview) to download \u0026 create installation media for the target platform.\\\nTools provided here can be used on any hardware platform to prepare for any install modes (diskless, data disk, system disk).\n\nJust add [**headless.apkovl.tar.gz**](https://is.gd/apkovl_master) overlay file *as-is* at the root of Alpine Linux boot media (or onto any custom side-media) and boot-up the system.\\\nWith default DCHP-based network interface definitions (and [SSID/pass](#extra-configuration) file if using wifi), system can then be remotely accessed with: `ssh root@\u003cIP\u003e`\\\n(system IP address may be determined with any IP scanning tools such as `nmap`).\n\nAs with Alpine Linux initial bring-up, `root` account has no password initially.\\\nFrom there, actual system install can be performed as usual with `setup-alpine` for instance (check Alpine [wiki](https://wiki.alpinelinux.org/wiki/Alpine_setup_scripts#setup-alpine) for details).\n\n## Extra configuration:\nExtra files may be added next to `headless.apkovl.tar.gz` to customise boostrapping configuration (check sample files):\n- `wpa_supplicant.conf`[^3] (*mandatory for wifi*): define wifi SSID, password and regulatory country [code](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2).\n- `unattended.sh`[^3] (*optional*): provide a deployment script to automate setup \u0026 customizations during initial bootstrap.\n- `interfaces`[^3] (*optional*): define network interfaces at will, if defaults DCHP-based are not suitable.\n- `authorized_keys` (*optional*): provide client's public SSH key to secure `root` ssh login.\n- `ssh_host_*_key*` (*optional*): provide server's custom ssh keys to be injected (may be stored), instead of using bundled ones[^4] (not stored). Providing an empty key file will trigger new keys generation (ssh server may take longer to start).\n- `opt-out` (*optional*): dummy file to opt-out internet features (connection status, version check, auto-update) and related links usage anonymous [telemetry](https://is.gd/privacy.php).\n- `auto-updt` (*optional*): enable automatic `headless.apkovl.tar.gz` file update with latest from master branch. If it contains `reboot` keyword all in one line, system will reboot after succesful update (unless ssh session is active or `unattended.sh` script is available).\n\nMain execution steps are logged: `cat /var/log/messages | grep headless`.\n\n## Goody:\nSeamless USB-gadget mode on capable devices (*e.g. on PiZero*): serial console, ethernet and mass-storage\n- Make sure `dwc2` (or `dwc3`) driver is previously loaded on capable device, and configuration is set to **OTG peripheral** mode: this may be driven by hardware (including cable) and/or software.\\\n(on supporting Pi devices, just add `dtoverlay=dwc2,dr_mode=peripheral` in `usercfg.txt` (or `config.txt`) to force both by software)\n- Plug USB cable into host Computer port before booting device.\n  - serial terminal can then be connected-to from host Computer (e.g. `cu -l ttyACM0` on Linux. xon/xoff flow control).\n  - alternatively, with host Computer ECM/RNDIS interface set-up as 10.42.0.1 (sharing internet or not), one can log into device from host with: `ssh root@10.42.0.2`.\n  - volume containing `headless.apkovl.tar.gz` file may be accessed/mounted from host, and config files easily edited. Make sure to unmount properly before removing USB plug.\n\n_Note:_ optionally, same USB-gadget feature may be easily enabled on final system by installing `xg_multi` Alpine [package](https://pkgs.alpinelinux.org/packages?name=xg_multi\u0026branch=edge\u0026repo=\u0026arch=\u0026origin=\u0026flagged=\u0026maintainer=) and service during system setup phase (refer to [`xg_multi`](https://github.com/macmpi/xg_multi/) project).\n\n## Want to tweak more ?\nThis repository may be forked/cloned/downloaded.\\\nMain script file is [`headless_bootstrap`](https://github.com/macmpi/alpine-linux-headless-bootstrap/tree/main/overlay/tmp/.ALHB/headless_bootstrap).\\\nExecute `./make_ALHB.sh` to rebuild `headless.apkovl.tar.gz` after changes.\\\n(requires `busybox`; check `busybox` build options if not running from Alpine or Ubuntu)\n\n\n## Credits\nThanks for the initial guides \u0026 scripts from @sodface and @davidmytton.\n\n[^1]: Initial boot fully preserves system's original state (config files \u0026 installed packages): a fresh system will therefore come-up as unconfigured.\n\n[^2]: Temporarily remove `root=*` statement from kernel command-line parameters list to disable disk-based boot mode.\n\n[^3]: These files are linux text files: Windows/macOS users need to use text editors supporting linux text line-ending (such as [notepad++](https://notepad-plus-plus.org/), BBEdit or any similar).\n\n[^4]: About bundled ssh keys: this overlay is meant to **quickly bootstrap** system in order to then proceed with proper install; therefore it purposely embeds [some ssh keys](https://github.com/macmpi/alpine-linux-headless-bootstrap/tree/main/overlay/tmp/.ALHB) so that bootstrapping is as fast as possible. Those temporary keys are moved in RAM /tmp: they will **not be stored/reused** once actual system install is performed (whether or not ssh server is installed in final setup).\n","funding_links":["https://ko-fi.com/macmpi","https://opencollective.com/alpinelinux"],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmacmpi%2Falpine-linux-headless-bootstrap","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmacmpi%2Falpine-linux-headless-bootstrap","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmacmpi%2Falpine-linux-headless-bootstrap/lists"}