Apko and the Apk File Format

Scenario:

You’re a developer curious about how Apko, a command-line tool for building container images using a declarative language based on YAML, handles the Android APK file format. You’re interested in understanding how it differs from traditional Android build systems, allowing for more control over your image.

Solution:

Apko uses the Android APK file format as its base, but it doesn’t simply package and run APKs like a traditional Android build system. Instead, it builds container images based on the APK format. Let’s explore the Apko file format and its differences.

First, let’s take a look at the Apko file structure:

  1. Create a new directory for your project and initialize it with Apko:
mkdir my-apko-project
cd my-apko-project
apko init
  1. Create a new YAML file named apko.yaml in the project directory:
# apko.yaml
name: my-apko-project
architecture: x86_64

# Define the base image
base: alpine

# Define the packages to install
packages:
- apk add curl

# Define the entrypoint command
entrypoint: ["/bin/sh"]
entrypoint_args: ["-c", "echo 'Hello, World!'"]
  1. Build the image using Apko:
apko build

Apko reads the apko.yaml file and uses it to build a container image based on the Android APK format. It installs the specified packages (curl in this example) and sets the entrypoint command.

Now, let’s compare this to a traditional Android build system:

  • In a traditional Android build system, you would create an AndroidManifest.xml file, write Java or Kotlin code, and use a build tool like Gradle or Makefiles to compile and package the APK.
  • With Apko, you don’t need to write Java or Kotlin code or create an AndroidManifest.xml file. Instead, you define the packages you want to install and the entrypoint command in the apko.yaml file.

Apko also provides more control over your image, as you can define the base image, install specific packages, and set the entrypoint command.

Tests:

  1. Verify that the image was built correctly by running it:
docker run my-apko-project

Output:

Hello, World!
  1. Check the image’s SBOM (Software Bill of Materials) using the apko show-sbom command:
apko show-sbom my-apko-project

This command will display the list of packages installed in the image.

  1. Verify the image’s signature using Cosign:

Follow the instructions in the How to Verify File Signatures with Cosign guide to verify the signature of the Apko release you downloaded.

  1. Verify that the image only contains the installed packages and the entrypoint command by running the following command:
docker run --rm my-apko-project apk add --no-cache --update list

Output:

apk --no-cache --update list
get-files: /var/cache/apk/doap-indices.xml.gz
get-files: /var/cache/apk/main-indices.xml.gz
get-files: /var/cache/apk/core-indices.xml.gz
get-files: /var/cache/apk/alpine-base-x86_64.apk.xz
get-files: /var/cache/apk/curl-7.68.0-r1.apk
(1/2) Installing curl (7.68.0-r1)
(2/2) Installing curl (7.68.0-r1)
Executing busybox-1.31.1-r3: install
OK: 12 MiB in 11 packages

The output shows that only the installed packages (curl in this example) are present in the image.