Self-hosted service
wukongdaily/ImmortalWrt-ImageBuilder avatar
wukongdaily/ImmortalWrt-ImageBuilder

ImmortalWrt-ImageBuilder: a CI workflow for custom ImmortalWrt images

它是一个工作流。可快速构建 可选docker、可选1G~4G固件大小的 immortalWrt。它相当于一个云端的ImageBuilder,属于构建的范畴,不算是编译。目前也支持第三方插件的按需集成。

2,663 stars9,268 forksShellGPL-3.0

At a glance

What is it?
wukongdaily/ImmortalWrt-ImageBuilder builds ImmortalWrt firmware in GitHub Actions rather than on your own machine. It is aimed at router owners who want a chosen image size, optional Docker, and third-party packages, and who do not want to run a full build environment.
Who is it for?
Fork it if you want a custom ImmortalWrt image without maintaining a build host, and you accept that the ISO path and the 99-custom.sh defaults are where your own configuration lives. Skip it if you need a supported upstream build, or if your device is not in SUPPORT.md.
Can I use it commercially?
Yes, with conditions. GPL-3.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
Is it still maintained?
Yes. The repository last received commits 14 days ago.
What is it written in?
Mainly Shell, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 24, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What ImmortalWrt-ImageBuilder actually solves

Building OpenWrt or ImmortalWrt from source needs a Linux host, a large toolchain download, and hours of CPU time. The ImageBuilder avoids the toolchain but still expects you to run it somewhere. This project moves that step into GitHub Actions: you fork the repository, open the Actions tab, pick a workflow, and run it. The README calls the result "a cloud ImageBuilder" and draws a line between building and compiling, which is a fair distinction. Nothing here compiles packages from source; it assembles a firmware image from prebuilt packages.

The audience is narrow and specific. It is for people who own a supported router or a virtual machine and want an image with a fixed root filesystem size, optional Docker, and a set of extra packages. The README recommends 1G to 2G for the size setting and warns against going much larger, noting that a resize plugin can expand storage later. If you are happy with the stock ImmortalWrt release for your device, this workflow adds nothing you need.

How the workflow assembles an image

The repository is organised by target, not by application code. Top-level directories include x86-64, rockchip, sunxi-cortexa53, armsr-armv8, mediatek-filogic, raspberrypi, n1, glinet and arch, each holding the files for that family of devices. A shell/ directory and a files/ directory sit alongside them. The actual customisation lives in files/etc/uci-defaults/99-custom.sh, which the README points to as the place where the default network behaviour is set and can be changed.

A run therefore does three things: it selects the ImageBuilder for the target you chose, it adds the packages you asked for, and it writes the resulting image back as a release artifact. The README describes the ISO path as two stages, first the firmware and then the wrapper that turns it into an ISO installer, with a stated total of roughly seven to eight minutes. That is a stated figure from the project, not a measured one, and it will move with queue times on GitHub's runners.

The default network behaviour is worth knowing before you flash anything. On a single-port device the image comes up in DHCP mode and takes an address from your existing router, the way a NAS does. On a multi-port device, eth0 is WAN and the remaining ports are LAN, with the LAN address set to 192.168.100.1. If you tick the dial-up option, WAN switches to pppoe. All of this is adjustable through 99-custom.sh.

Forking and running your first build

There is no local installation step. The README's basic usage is two actions: fork the repository, then open the Actions tab in your fork and run the workflow you need. Everything below happens in the GitHub web interface, so the only prerequisite is a GitHub account.

Start by forking the repository and enabling workflows in your fork. In the Actions tab, choose the workflow that matches your hardware. The README directs virtual machine users to the ISO workflow and notes that it runs in two stages.

bash
# after the ISO boots and finishes scrolling, at the console:
ddd

The README states that typing ddd at the prompt starts the guided write of ImmortalWrt onto the virtual disk, and that leftover disk space can be allocated afterwards. For physical machines, the README suggests Ventoy on Windows or balenaEtcher on macOS to put the ISO on a USB stick, then booting from it and running the same ddd command.

If you want to change the LAN address or the WAN mode, edit the customisation script in your fork before running the workflow. The README is explicit that the IP setting is for multi-port devices only.

bash
# files/etc/uci-defaults/99-custom.sh
# the README says the WAN inbound firewall rule is set at the top of this file

After the run finishes, download the artifact from the workflow run and flash it with the method that matches your device. The README's troubleshooting note for dial-up users is to reboot the optical modem before use.

The side-router mistake and other limits

The README devotes a section to a misunderstanding it has clearly seen often: users editing the default IP in the configuration file and expecting that to set up a bypass router. It does not work that way. A bypass setup should be treated as a single-port device, which means DHCP mode and no fixed address. You find the address the device received by looking at the upstream router, then set the bypass address inside the ImmortalWrt web interface. Changing the workflow's IP field for a single-port machine breaks the addressing.

There is a second, more serious limitation. This is a personal third-party project, and the README states plainly that it is not affiliated with ImmortalWrt. It uses the official ImageBuilder, but bugs introduced by your own customisation are not ImmortalWrt bugs, and the README asks users not to raise issues in ImmortalWrt's channels. That means your support path is the project's own Discussions page, not the upstream community.

Two smaller points. The firmware ships with the WAN inbound firewall rule enabled for convenience, and the README recommends turning it to reject once you have finished initial setup, through Network, then Firewall, then the WAN zone. And the preinstalled app store option is documented as applying to versions below 24.10.6, so it is not available on every branch you can select.

How this differs from building with the ImageBuilder yourself

The obvious alternative is running ImmortalWrt's own ImageBuilder on your own machine. The difference is where the work happens and what you control. Running it locally means you download the ImageBuilder archive for your target, unpack it, and invoke make image with a package list. You get full control over the package set, you can iterate quickly without pushing commits, and you are not dependent on a third party's repository staying in the shape you expect. The cost is a Linux environment, disk space for the ImageBuilder and package feeds, and time spent managing it.

This project trades that control for convenience. You get a web interface with checkboxes for image size, Docker, the app store, the LuCI version, and the management IP, and you get the build on GitHub's runners. What you give up is the ability to run an arbitrary package selection without going through the project's integration route, and you inherit its defaults, including the enabled WAN inbound rule and the network layout described above. If your device is not in SUPPORT.md, the local ImageBuilder is the path that still works. If you want to understand the full package set before flashing, the README points at the ImmortalWrt package mirror for in-repo packages and at wukongdaily/store for packages outside it.

Maintenance, licence and what it costs to keep up

The repository is not archived, and the last push was on 2026-09-16, so it is being touched. The release list is less reassuring: the two most recent releases are both marked as test builds and carry an explicit instruction not to download them, one for armsr-armv8 rootfs and one for img-installer. That suggests the release channel is used for internal testing rather than for stable distributions, and that you should take your artifacts from your own workflow runs instead.

Upgrade cost is mostly your own attention. The README documents support for 24.10.x and 25.12.x across x86-64-ISO, x86-64, rockchip, sunxi and wireless routers, and it notes that the LuCI version is a selectable option defaulting to 25.12.x. When ImmortalWrt moves, you re-run the workflow and re-flash, or for plugin chasers the README suggests downloading a run file from the RunFilesBuilder project and overwriting with sh xx.run. There is no documented rollback path in the README, so keeping the previous image is on you.

The licence is GPL-3.0. That matters if you redistribute images built here: GPL obligations attach to the firmware and its components, and this project's own scripts are GPL-3.0 as well. It does not mean the project offers any warranty, and the README's disclaimer is clear that customisation bugs are yours. This is a description of the licence, not legal advice.

Editorial conclusion

Fork it if you want a custom ImmortalWrt image without maintaining a build host, and you accept that the ISO path and the 99-custom.sh defaults are where your own configuration lives. Skip it if you need a supported upstream build, or if your device is not in SUPPORT.md. Before flashing, confirm your model on the support list, check whether your device is single-port or multi-port, and read the top of files/etc/uci-defaults/99-custom.sh so you know which default you are overriding.

Frequently asked questions

What is ImmortalWrt?

The README describes ImmortalWrt as the upstream whose official ImageBuilder this project uses to package firmware. It is not the same thing as this repository, which the README states is an independent third-party project with no affiliation to ImmortalWrt.

What is the default IP address for ImmortalWrt built by this workflow?

On multi-port devices the LAN address is 192.168.100.1, with eth0 as WAN and the remaining ports as LAN. Single-port devices get no fixed address at all: they come up in DHCP mode and take an address from the upstream router.

Can I set a bypass router IP in the ImmortalWrt-ImageBuilder workflow?

No. The README calls this a common misunderstanding and states that a bypass setup should use single-port mode, which is DHCP with no fixed address. You set the bypass address afterwards inside the ImmortalWrt web interface, using the address the upstream router assigned.

How do I install the ImmortalWrt-ImageBuilder output on a physical machine?

The README suggests putting the ISO on a Ventoy drive on Windows or writing it to a USB stick with balenaEtcher on macOS, then booting from that drive. After boot, typing ddd at the console starts the guided write to disk.

Where do I report bugs in firmware built with ImmortalWrt-ImageBuilder?

The README asks users not to report them in ImmortalWrt's groups, because this is an independent project and customisation bugs are not upstream bugs. It directs questions and discussion to the project's own Discussions page.

Official sources

  1. License: GPL-3.0
  2. Project website
  3. README
  4. Releases
  5. wukongdaily/ImmortalWrt-ImageBuilder on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/wukongdaily-immortalwrt-imagebuilder.svg)](https://hysenlabs.com/projects/wukongdaily-immortalwrt-imagebuilder)