There are also other ways to build container images. You can use Nix to create a filesystem image and then put it inside the image using Dockerfile's COPY instruction, for example. Going further, you can prepare a filesystem image by any other means and then import it as a base container image using docker import.
Choose whichever solution fits your particular needs. Keep in mind that building with a Dockerfile using docker build is the most popular approach and hence it is the best-documented one and the best supported. Going with Buildah is more flexible and allows you to better fit creating container images into your build process. Finally, ansible-bender may be a good solution if you're already heavily invested in Ansible and you want to reuse already available modules.