Using Packer to Build Alpine Linux Box for Vagrant
Posted on June 2, 2017
Auto-installing Alpine thru VirtualBox may fail if the build takes too long to complete. Conservative delays are used, but they make the build long. To make the build less strenuous, install from ISO and provisioning (installing packages, configuring services, adding users, etc) are two separate steps (eg, separate packer builds).
Here is the first build, the bare minimum install of Alpine from an upstream ISO:
ᐅ packer build alpine-iso-install.json
virtualbox-iso output will be in this color.
==> virtualbox-iso: Downloading or copying ISO
virtualbox-iso: Downloading or copying: https://nl.alpinelinux.org/alpine/v3.6/releases/x86_64/alpine-virt-3.6.1-x86_64.iso
==> virtualbox-iso: Starting HTTP server on port 8835
==> virtualbox-iso: Creating virtual machine...
==> virtualbox-iso: Creating hard drive...
==> virtualbox-iso: Creating forwarded port mapping for communicator (SSH, WinRM, etc) (host port 3883)
==> virtualbox-iso: Executing custom VBoxManage commands...
virtualbox-iso: Executing: modifyvm alpine-amd64-3.6.1 --memory 512
virtualbox-iso: Executing: modifyvm alpine-amd64-3.6.1 --cpus 1
==> virtualbox-iso: Starting the virtual machine...
==> virtualbox-iso: Waiting 30s for boot...
==> virtualbox-iso: Typing the boot command...
==> virtualbox-iso: Waiting for SSH to become available...
==> virtualbox-iso: Connected to SSH!
==> virtualbox-iso: Uploading VirtualBox version info (5.0.10)
==> virtualbox-iso: Gracefully halting virtual machine...
==> virtualbox-iso: Preparing to export machine...
virtualbox-iso: Deleting forwarded port mapping for the communicator (SSH, WinRM, etc) (host port 3883)
==> virtualbox-iso: Exporting virtual machine...
virtualbox-iso: Executing: export alpine-amd64-3.6.1 --output output-virtualbox-iso/alpine-amd64-3.6.1.ovf
==> virtualbox-iso: Unregistering and deleting virtual machine...
==> virtualbox-iso: Running post-processor: vagrant
==> virtualbox-iso (vagrant): Creating Vagrant box for 'virtualbox' provider
virtualbox-iso (vagrant): Copying from artifact: output-virtualbox-iso/alpine-amd64-3.6.1-disk1.vmdk
virtualbox-iso (vagrant): Copying from artifact: output-virtualbox-iso/alpine-amd64-3.6.1.ovf
virtualbox-iso (vagrant): Renaming the OVF to box.ovf...
virtualbox-iso (vagrant): Compressing: Vagrantfile
virtualbox-iso (vagrant): Compressing: alpine-amd64-3.6.1-disk1.vmdk
virtualbox-iso (vagrant): Compressing: box.ovf
virtualbox-iso (vagrant): Compressing: metadata.json
Build 'virtualbox-iso' finished.
==> Builds finished. The artifacts of successful builds are:
--> virtualbox-iso: VM files in directory: output-virtualbox-iso
--> virtualbox-iso: 'virtualbox' provider box: out/alpine-clean-3.6.1.box
That build produces a box that can be loaded up into Vagrant with: vagrant box add alpine-clean-3.6.1 out/alpine-clean-3.6.1.box
.
We can now use this OVF to run another build to complete the provisioning process:
ᐅ packer build alpine-base.json
virtualbox-ovf output will be in this color.
==> virtualbox-ovf: Downloading or copying OVF/OVA
virtualbox-ovf: Downloading or copying: file:///src/packer-alpine/00-iso-install/output-virtualbox-iso/alpine-amd64-3.6.1.ovf
==> virtualbox-ovf: Importing VM: /src/packer-alpine/00-iso-install/output-virtualbox-iso/alpine-amd64-3.6.1.ovf
==> virtualbox-ovf: Creating forwarded port mapping for communicator (SSH, WinRM, etc) (host port 2595)
==> virtualbox-ovf: Executing custom VBoxManage commands...
virtualbox-ovf: Executing: modifyvm alpine-amd64-3.6.1 --memory 512
virtualbox-ovf: Executing: modifyvm alpine-amd64-3.6.1 --cpus 1
==> virtualbox-ovf: Starting the virtual machine...
==> virtualbox-ovf: Waiting 30s for boot...
==> virtualbox-ovf: Typing the boot command...
==> virtualbox-ovf: Waiting for SSH to become available...
==> virtualbox-ovf: Connected to SSH!
==> virtualbox-ovf: Uploading VirtualBox version info (5.0.10)
==> virtualbox-ovf: Provisioning with shell script: scripts/00-apk.sh
virtualbox-ovf: + set -exu
virtualbox-ovf: + apk upgrade -U --available
virtualbox-ovf: fetch http://dl-5.alpinelinux.org/alpine/v3.6/main/x86_64/APKINDEX.tar.gz
virtualbox-ovf: OK: 98 MiB in 37 packages
virtualbox-ovf: + source /etc/os-release
virtualbox-ovf: + NAME=Alpine Linux
virtualbox-ovf: + ID=alpine
virtualbox-ovf: + VERSION_ID=3.6.1
virtualbox-ovf: + PRETTY_NAME=Alpine Linux v3.6
virtualbox-ovf: + HOME_URL=http://alpinelinux.org
virtualbox-ovf: + BUG_REPORT_URL=http://bugs.alpinelinux.org
virtualbox-ovf: + apk add bash ca-certificates wget curl
virtualbox-ovf: (1/10) Installing ncurses-terminfo-base (6.0-r7)
virtualbox-ovf: (2/10) Installing ncurses-terminfo (6.0-r7)
virtualbox-ovf: (3/10) Installing ncurses-libs (6.0-r7)
virtualbox-ovf: (4/10) Installing readline (6.3.008-r5)
virtualbox-ovf: (5/10) Installing bash (4.3.48-r1)
virtualbox-ovf: Executing bash-4.3.48-r1.post-install
vf: (6/10) Installing ca-certificates (20161130-r2)
virtualbox-ovf: (7/10) Installing libssh2 (1.8.0-r1)
virtualbox-ovf: (8/10) Installing libcurl (7.54.0-r0)
virtualbox-ovf: (9/10) Installing curl (7.54.0-r0)
virtualbox-ovf: (10/10) Installing wget (1.19.1-r2)
virtualbox-ovf: Executing busybox-1.26.2-r4.trigger
virtualbox-ovf: Executing ca-certificates-20161130-r2.trigger
virtualbox-ovf: OK: 108 MiB in 47 packages
==> virtualbox-ovf: Provisioning with shell script: scripts/01-sshd.sh
virtualbox-ovf: + set -eux
virtualbox-ovf: + sed -i /^PermitRootLogin yes/d /etc/ssh/sshd_config
virtualbox-ovf: + echo UseDNS no
==> virtualbox-ovf: Provisioning with shell script: scripts/02-vagrant.sh
virtualbox-ovf: + set -exu
virtualbox-ovf: + date
virtualbox-ovf: + adduser -D vagrant
virtualbox-ovf: + chpasswd
virtualbox-ovf: + echo vagrant:vagrant
virtualbox-ovf: chpasswd: password for 'vagrant' changed
virtualbox-ovf: + mkdir -pm 700 /home/vagrant/.ssh
virtualbox-ovf: + chown -R vagrant:vagrant /home/vagrant/.ssh
virtualbox-ovf: + chmod -R go-rwsx /home/vagrant/.ssh
==> virtualbox-ovf: Provisioning with shell script: scripts/03-sudo.sh
virtualbox-ovf: + set -eux
virtualbox-ovf: + apk add sudo
virtualbox-ovf: (1/1) Installing sudo (1.8.19_p2-r0)
virtualbox-ovf: Executing busybox-1.26.2-r4.trigger
virtualbox-ovf: OK: 109 MiB in 48 packages
virtualbox-ovf: + adduser vagrant wheel
virtualbox-ovf: + echo Defaults exempt_group=wheel
virtualbox-ovf: + echo %wheel ALL=NOPASSWD:ALL
==> virtualbox-ovf: Provisioning with shell script: scripts/98-cleanup.sh
virtualbox-ovf: + rm -rf /var/cache/apk/APKINDEX.3029cfab.tar.gz
virtualbox-ovf: + rm -rf /etc/ssh/ssh_host_dsa_key /etc/ssh/ssh_host_dsa_key.pub /etc/ssh/ssh_host_ecdsa_key /etc/ssh/ssh_host_ecdsa_key.pub /etc/ssh/ssh_host_ed25519_k
ey /etc/ssh/ssh_host_ed25519_key.pub /etc/ssh/ssh_host_rsa_key /etc/ssh/ssh_host_rsa_key.pub
==> virtualbox-ovf: Provisioning with shell script: scripts/99-minimize.sh
virtualbox-ovf: + set -ux
virtualbox-ovf: + dd if=/dev/zero of=/EMPTY bs=1M
virtualbox-ovf: dd: writing '/EMPTY': No space left on device
virtualbox-ovf: 525+0 records in
virtualbox-ovf: 523+1 records out
virtualbox-ovf: + rm -f /EMPTY
virtualbox-ovf: + sync
virtualbox-ovf: + sync
virtualbox-ovf: + sync
virtualbox-ovf: + exit 0
==> virtualbox-ovf: Gracefully halting virtual machine...
==> virtualbox-ovf: Preparing to export machine...
virtualbox-ovf: Deleting forwarded port mapping for the communicator (SSH, WinRM, etc) (host port 2595)
==> virtualbox-ovf: Exporting virtual machine...
virtualbox-ovf: Executing: export alpine-amd64-3.6.1 --output output-virtualbox-ovf/alpine-amd64-3.6.1.ovf
==> virtualbox-ovf: Unregistering and deleting imported VM...
==> virtualbox-ovf: Running post-processor: vagrant
==> virtualbox-ovf (vagrant): Creating Vagrant box for 'virtualbox' provider
virtualbox-ovf (vagrant): Copying from artifact: output-virtualbox-ovf/alpine-amd64-3.6.1-disk1.vmdk
virtualbox-ovf (vagrant): Copying from artifact: output-virtualbox-ovf/alpine-amd64-3.6.1.ovf
virtualbox-ovf (vagrant): Renaming the OVF to box.ovf...
virtualbox-ovf (vagrant): Compressing: Vagrantfile
virtualbox-ovf (vagrant): Compressing: alpine-amd64-3.6.1-disk1.vmdk
virtualbox-ovf (vagrant): Compressing: box.ovf
virtualbox-ovf (vagrant): Compressing: metadata.json
Build 'virtualbox-ovf' finished.
==> Builds finished. The artifacts of successful builds are:
--> virtualbox-ovf: VM files in directory: output-virtualbox-ovf
--> virtualbox-ovf: 'virtualbox' provider box: out/alpine-base-3.6.1.box
How small is the image?
ᐅ ls -lh out/alpine-base-3.6.1.box
-rw-r--r-- 1 user user 37M Jun 2 22:22 out/alpine-base-3.6.1.box
WOW, 37M without a lot of trouble.
We can now add that box to vagrant
with:
ᐅ vagrant box add alpine-base-3.6.1 out/alpine-base-3.6.1.box
==> box: Box file was not detected as metadata. Adding it directly...
==> box: Adding box 'alpine-base-3.6.1' (v0) for provider:
box: Unpacking necessary files from: file:///src/packer-alpine/01-alpine-base/out/alpine-base-3.6.1.box
==> box: Successfully added box 'alpine-base-3.6.1' (v0) for 'virtualbox'!
See the full code here.