alpinelinux / alpine-make-rootfs Goto Github PK
View Code? Open in Web Editor NEWMake customized Alpine Linux rootfs (base image) for containers
License: MIT License
Make customized Alpine Linux rootfs (base image) for containers
License: MIT License
Preconditions:
<dest>
is a mountpoint.--script-chroot
is usedAt the end of the execution of the script. All the required devices gets unmounted from the chroot destination by finding everything that is mounted under <dest>
(included).
The problem is that <dest>
gets unmounted too and the rest of the program fails.
Currently we've faced some segfault if use busybox as linux init system.
So we want to rebuild the busybox with backtrace to debug the problem.
Is this script capable of building a rootfs for aarch64 using the files in http://dl-2.alpinelinux.org/alpine/v3.12/main/aarch64/? Does it have to be run from an aarch64 host to do so? It seems like there's a reference to an x64 specific package in
I know this exists, but I would love to be able to build my own using your script:
alpine-minirootfs-3.12.0-aarch64.tar.gz
Any hints as to how to use or modify the script to support aarch64 would be greatly appreciated, thank you!
I just wander the way to configure a rootfs for python function, is that ok?
Specifically, why is this link created?
ln -sf /run "$rootfs"/var/run
I cannot find any specification that calls for this.
edit: nvm I understand, fairly common link required by the distro
In any case, I believe it's somewhat confusing as I expected the alpine-base package to produce a completed filesystem. The before mentioned code is then at best redundant; which is at least the case for v3.8.
Creating the link fails due to permission reasons specific to my setup that I would not like to get too deep into. For the time being I will just fork it out. You can just close this issue.
The README contains the following example:
sudo ./alpine-make-rootfs \ # (1)
--branch v3.8 \ # (2)
--packages 'ruby ruby-bigdecimal sqlite' \ # (3)
--timezone 'Europe/Prague' \ # (4)
--script-chroot \ # (5)
example-$(date +%Y%m%d).tar.gz - <<'SHELL' # (6)
# Copy some file from the repository root to the rootfs.
install -D -m 755 examples/hello_world.rb /app/hello_world.rb
# Install some dev packages and gem mailcatcher.
apk add --no-progress -t .make build-base ruby-dev sqlite-dev
gem install --no-document mailcatcher
# Clean-up dev packages. (7)
apk del --no-progress .make
SHELL
I cannot get something like this to work, and here is what I think is happening: when reading the script from stdin, it gets written to a temporary file and the SCRIPT
variable gets set to the path of that file:
alpine-make-rootfs/alpine-make-rootfs
Lines 335 to 337 in 8516728
SCRIPT
is in (so, in this case, the temp directory, likely /tmp
) gets mounted into the chroot's /mnt
: alpine-make-rootfs/alpine-make-rootfs
Line 430 in 8516728
install ...
will not work.
I am not sure if I am missing something here? I was also wondering if #1 was potentially related, but it is a little... sparse on details ๐
When using an actual file as script, everything works as expected. But of course only as long as that script is in the same directory as the files I want to copy. I suppose this is mainly a documentation issue? Also, I wanted to make sure I am not mistaken about anything. Any hints would be much appreciated, I'd even volunteer for a PR once I know the desired state of this.
This tool is useful for backup because it will halt any filesystem operation, so we can resume service quickly after say like velero backup finished. I know the right way is to use an immutable data structure that we can copy at any point in time but for some adhoc services such as Gitea we have no choice
I'm wondering if alpine-make-rootfs can be used to create a 'distroless' rootfs (to use in a docker image), without a shell (no busybox). Or an image with dash and coreutils instead of busybox. But I always end up with busybox being installed. Looked like the --no-default-pkgs
is made for this. Is busybox still installed because dash/coreutils depend on it? That would be a bummer, since they are alternatives to the tools provided by busybox. Is there a way around this?
./alpine-make-rootfs --branch v3.17 --no-default-pkgs --packages 'dash coreutils' test.tar
> apk not found, downloading static apk-tools
2023-03-25 13:40:59 URL:https://gitlab.alpinelinux.org/api/v4/projects/5/packages/generic/v2.12.10/x86_64/apk.static [2689064/2689064] -> "apk.static" [1]
apk.static: OK
> Installing system
fetch http://dl-cdn.alpinelinux.org/alpine/v3.17/main/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.17/community/x86_64/APKINDEX.tar.gz
(1/9) Installing musl (1.2.3-r4)
(2/9) Installing busybox (1.35.0-r29)
Executing busybox-1.35.0-r29.post-install
(3/9) Installing busybox-binsh (1.35.0-r29)
(4/9) Installing libacl (2.3.1-r1)
(5/9) Installing libattr (2.5.1-r2)
(6/9) Installing skalibs (2.12.0.1-r0)
(7/9) Installing utmps-libs (0.1.2.0-r1)
(8/9) Installing coreutils (9.1-r0)
(9/9) Installing dash (0.5.11.5-r2)
Executing dash-0.5.11.5-r2.post-install
Executing busybox-1.35.0-r29.trigger
OK: 3 MiB in 9 packages
(1/2) Installing alpine-keys (2.4-r1)
(2/2) Installing alpine-release (3.17.2-r0)
OK: 3 MiB in 11 packages
> Cleaning-up rootfs
> Creating rootfs archive
-rw-r--r-- 1 root root 3256320 Mar 25 13:41 test.tar
While preparing rootfs, I need to manually specify the branch to use. Is there any way so that the script always uses the latest Alpine release?
$ sudo ./alpine-make-rootfs --branch v3.8 --repositories-file repositories --packages 'musl busybox alpine-baselayout openrc alpine-conf libressl ssl_client busybox-suid busybox-initscripts scanelf musl-utils libc-utils alpine-keys alpine-base bash apt' alpine-busybox-rootfs2.tar.gz
> apk not found, downloading static apk-tools
2022-09-18 22:31:24 URL:https://gitlab.alpinelinux.org/api/v4/projects/5/packages/generic/v2.12.10/x86_64/apk.static [2689064/2689064] -> "apk.static" [1]
apk.static: OK
> Installing system
fetch http://dl-cdn.alpinelinux.org/alpine/v3.8/main/x86_64/APKINDEX.tar.gz
ERROR: unable to select packages:
apt (no such package):
required by: world[apt]
ubuntu@VM-0-8-ubuntu:~/projects/go_learning/alpine Sun Sep 18 22:32:55
See also #10.
It looks like there are two unreported error conditions that need checking:
In docker, it's very natural to try to put the script in /, so that last one really needs handling better.
I couldn't use the spiffy 'postinst script on stdin' feature, as I was already using stdin to pipe a tarball into the postinst script. (I suppose I could have used a self-extracting tarball... shudder. Or better, I could have used fd 4 for my tarball... but that's kind of esoteric.)
To work around those two, I ended up doing something like
mkdir -p tmp
cp postinst.sh tmp
chmod +x tmp/postinst.sh
alpine-make-vm-image --script-chroot ... $(pwd)/tmp/postinst.sh
rm tmp/postinst.sh
After that, it did manage to find and run the script.
Believe it or not, it took me several hours to figure this out.
I would like to know how to build exactly the same image as the official one ?
When I use the alpine-make-rootfs script, it doesn't give me the same hash as the official alpine-minirootfs-3.14.0-x86_64.tar.gz
I tried different options with the script, but the hash is always different.
Official (3.14):
d90ddc3346c1ee1dc3de17fa8b03a3450fa08e8ceda73be2fadab2de55db232cffffab227b7eaa61f11f54f515232d01bd495a302dd5c70bb5ed8f1b7e30325e
My rootfs (3.14):
1e9f3551cfaafecb3d213d91b4e1be1a928c19b87c49bb6329fc1989677e95e4acb7f794879bbe153e9243d009ccddc654bb4c48389d6b7a8cc38ebb066e740d
I used this command:
sudo ./alpine-make-rootfs --branch v3.14 --timezone 'Europe/Prague' --packages 'openssl-dev' --script-chroot rootfs.tar.gz
how do we do it for other architectures? via qemu ?
Hello,
in order to generate delta updates I've been looking at making the archive generated by alpine-make-rootfs reproducible today.
In my experience there are two places that weren't reproducible:
/lib/apk/db/scripts.tar
when installing packages.SOURCE_DATE_EPOCH
so setting that appropriately works and is enough. (more on the variable later)--sort=name --mtime=@$SOURCE_DATE_EPOCH --clamp-mtime --pax-option=exthdr.name=%d/PaxHeaders/%f,delete=atime,delete=ctime
to the tar creation line.Now the big question is what would SOURCE_DATE_EPOCH should be.
The simplest approach is to say, if it's set from outside of alpine-make-rootfs we should just use it (that is true even if we add some detection later), so we probably should add the tar creation option conditionally on that.
As for setting it automatically, I think we could fetch the APKINDEX of the repos we're installing from and taking the latest timestamp in there... It's a bit annoying because we need to set it before running apk, and apk is the one getting the APKINDEX, so it's a bit of a chicken and egg problem... I need to check if we can just regenerate scripts.db later maybe...
What do you think?
I did not change anything.
It fails when I run.
wks-40-824:~/alpine-make-rootfs# ./alpine-make-rootfs ../
./alpine-make-rootfs: 274: shift: can't shift that many
Do I need to change something or am I missing something?
The "official" Alpine container rootfs's have their root password locked in /etc/shadow (see https://git.alpinelinux.org/aports/tree/scripts/genrootfs.sh#n44). I think that might be a reasonable choice for alpine-make-rootfs as well: this is one of the very few differences between those two.
Have a VM that's running Xenial 64 bit. Pull down the repository and run it as follows:
sudo ./alpine-make-rootfs --branch v3.8 myimage.tar.gz - <<'SHELL'
SHELL
Unfortunately, this fails (see attached file)
I am a newbie with this and any help in resolving this will be appreciated.
Is it possible to create an arm64 rootfs on an amd64 host? currently I'm trying to build inside a docker container but I'm having a bit of trouble with that.
To avoid the XY problem, my ultimate goal is to create a root filesystem for another device (a nvidia jetson nano, it doesn't boot traditionally and so I can't install alpine normally) that it will eventually boot from. Kernel and initrd generation are handled elsewhere, so no need to worry about that, but the rootfs nvidia provides is ~10G and I'd like to use alpine instead, only problem right now is generating a rootfs for the other device to boot from.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.