Build an Ubuntu Core image for Docker deployments

To ship containerized applications with Ubuntu Core, you need to create a custom image. The custom image can then be used to create bootable media and can automate deployment of a production system.

To create a custom Ubuntu Core image with one or more containerized Docker applications, the applications are first packaged as Docker companion snaps, listed in the model assertion along with the Docker snap, and given the right permissions to operate.

The image may also include container configurations.

Create a model assertion

Create a model assertion, and add the Docker snap and all other companion snaps to the list:

{
    "name": "docker",
    "type": "app",
    "default-channel": "latest/stable",
    "id": "sLCsFAO8PKM5Z0fAKNszUOX0YASjQfeZ"
},
{
    "name": "<my-companion-snap>",
    "type": "app",
    "default-channel": "<channel>",
    "id": "<snap-id>"
}

This example only lists one companion snap, available in a snap store. A single companion snap could manage multiple Docker containers.

Grant access to the Docker snap

Each companion snap needs access to the Docker snap to operate. We grant the access via snap interface connections between the snaps. In order to automate the granting of access, each companion snap must be published to a store and have an ID. There are two ways to configure this automated interface connection: via an auto-connection assertion defined in a snap store, or via a custom gadget. Here we cover the method via a custom gadget.

Read the gadget snaps documentation to get familiar with the concepts and instructions. Inside the gadget.yaml file, adapt and add the following to connections, for each companion snap:

connections:
    # Needed to communicate with Docker over the Unix socket
    - slot: sLCsFAO8PKM5Z0fAKNszUOX0YASjQfeZ:docker-daemon
      plug: <companion snap id>:docker
    # Needed to use the docker CLI
    - slot: sLCsFAO8PKM5Z0fAKNszUOX0YASjQfeZ:docker-executables
      plug: <companion snap id>:docker-executables

Set container configurations

Container configuration can be passed on to the companion snap via snap configuration options. To set such configurations in the Ubuntu Core image, add them to the same gadget.yaml file, under defaults:

defaults:
  <companion snap id>:
    key: value

Replace default gadget snap

Finally, replace the default gadget snap listed in the model assertion with the custom one that has the connections:

{
    "name": "<custom-gadget>",
    "type": "gadget",
    "default-channel": "<channel>",
    "id": "<gadget snap id>"
}

Omit default-channel and id if you want to build the image using a custom gadget snap that hasn’t been uploaded to a store.