Creating and configuring instances

There are two ways to create and configure Compute Engine instances running Container-Optimized OS from Google.

For simple scenarios where you want to run a single container on a VM or on each VM in a managed instance group, you can specify a container image and optional configuration parameters when you define the instance or instance template. Compute Engine creates the instance with the latest version of Container-Optimized OS and launches the specified container when the VM starts.

For advanced scenarios where you can deploy multiple containers and configure Docker options using cloud-init, you can create a Compute Engine instance with your choice of Container-Optimized OS image then proceed to configure it as needed.

Creating a simple instance

Use this method to deploy a single container on a VM using the latest version of Container-Optimized OS.


  1. Go to the VM instances page.

    Go to the VM instances page

  2. Click Create instance.
  3. Specify a Name for your instance.
  4. In the Container section, select the Deploy a container image to this VM instance checkbox.
  5. Specify the Container image to use.
    • For example, you can specify to select an NGINX 1.12 container image from Cloud Launcher.
    • If you use a container image from Docker Hub, always specify the full Docker image name. For example, specify the following image name to deploy an Apache container image:
  6. Optionally, click Advanced container options. For more information, see Configuring Options to Run Your Container.
  7. Click Create to create the instance, boot the instance, and launch the container.


Use the gcloud beta compute instances create-with-container command:

 gcloud compute instances create-with-container [INSTANCE_NAME] \
     --container-image [CONTAINER_IMAGE]


  • [INSTANCE_NAME] is the name for the new instance.
  • [CONTAINER_IMAGE] is the name of the container image.

For example, the following command creates a new VM instance named nginx-vm which will launch and run the container image,

 gcloud compute instances create-with-container nginx-vm \

When using a container image from Docker Hub, you must always specify a full Docker image name. For example, specify the following image name to deploy an Apache container image:

To run a single container on each VM in a managed instance group, specify the container image name when defining the instance template. See Creating an instance template with a container image for more information.

Creating an instance for advanced scenarios

Use this method to select a specific Container-Optimized OS image, to deploy multiple containers, and to use cloud-init for advanced configuration.

Viewing available images

Container-Optimized OS images are available on Google Cloud Console's list of images with the prefix cos. These are hosted under the cos-cloud project. You can also see all currently available releases on command line by running:

gcloud compute images list \
    --project cos-cloud \

The output is similar to the following:

NAME                      PROJECT            FAMILY         STATUS
cos-beta-56-9000-66-0     cos-cloud          cos-beta       READY
cos-dev-57-9196-0-0       cos-cloud          cos-dev        READY
cos-stable-55-8872-76-0   cos-cloud          cos-stable     READY

Creating an instance


To run a Compute Engine instance with a Container-Optimized OS and Docker installed, follow these steps:

  1. Open the Compute Engine instance creation page on Google Cloud Console. Create a new Compute Engine instance
  2. Specify a Name for your instance.
  3. In the Containers section, clear the Deploy a container image to this VM instance checkbox. This option is useful if you want to deploy a single container on the VM.
  4. In the Boot disk section, select a Container-Optimized OS image.
  5. Click Create to create and boot the instance.


Review the currently available images, then use the gcloud compute instances create command with the --image and --image-project flags to create a cos node image instance.

gcloud compute instances create INSTANCE_NAME \
    --image cos-beta-67-10575-13-0 \
    --image-project cos-cloud \
    --zone us-east1-d \
    --machine-type n1-standard-1

In the above example, cos-beta-51-8172-26-0 is one of the available cos releases.

If you want the latest available dev, beta, or stable Container-Optimized OS, use the --image-family flag.

gcloud compute instances create INSTANCE_NAME \
    --image-family cos-beta \
    --image-project cos-cloud \
    --zone us-east1-d \
    --machine-type n1-standard-1

You can add the --preemptible flag for one-off, experimental instances.


In the API, construct a normal request to create an instance, but include a Container-Optimized OS source image. For example:


  'machineType': 'zones/[ZONE]/machineTypes/[MACHINE_TYPE]',
  'name': '[INSTANCE_NAME]',
  'networkInterfaces': [
      'accessConfigs': [
          'type': 'ONE_TO_ONE_NAT',
          'name': 'External NAT'
      'network': 'global/networks/default'
  'disks': [
      'type': 'PERSISTENT',
      'boot': true,
      'autoDelete': true,
      'initializeParams': {
        'sourceImage': 'projects/cos-cloud/global/images/family/cos-stable'

Configuring an instance

In some cases, you might want to do additional configuration when the instance boots. You can use the cloud-init tool with Container-Optimized OS to apply configuration information that you supply in a cloud-config format.

Using cloud-init

The cos node image includes cloud-init as a way to configure your instance when it boots up. Cloud-init reads value by the key user-data from the instance metadata. There are multiple formats for that field that Cloud-init understands. Below is a sample value for the user-data in cloud-config format that creates a user account and adds a systemd service:


- name: cloudservice
  uid: 2000

- path: /etc/systemd/system/cloudservice.service
  permissions: 0644
  owner: root
  content: |
    Description=Start a simple docker container

    ExecStart=/usr/bin/docker run --rm -u 2000 --name=mycloudservice busybox:latest /bin/sleep 3600
    ExecStop=/usr/bin/docker stop mycloudservice
    ExecStopPost=/usr/bin/docker rm mycloudservice

- systemctl daemon-reload
- systemctl start cloudservice.service

# Optional once-per-boot setup. For example: mounting a PD.
- fsck.ext4 -tvy /dev/[DEVICE_ID]
- mkdir -p /mnt/disks/[MNT_DIR]
- mount -t ext4 -O ... /dev/[DEVICE_ID] /mnt/disks/[MNT_DIR]

When creating an instance use --metadata-from-file to set cloud-init metadata:

gcloud compute instances create INSTANCE_NAME \
    --image IMAGE_NAME \
    --metadata-from-file user-data=FILENAME

Other metadata flags

Metadata Key Description Default Behavior
cos-update-strategy Specifies update behavior. The only value accepted is: update_disabled. If not set all updates from the current channel are automatically downloaded and installed.
cos-metrics-enabled Enables crash dump collection. Values could be:
false (default).
Disabled by default

Connecting to an instance

You can SSH into your VM instance running the cos node image the same way you SSH into other Google Compute Engine instances. For example:

gcloud compute ssh INSTANCE_NAME \
    --project PROJECT \
    --zone ZONE

Running startup scripts

You can specify a startup script through the metadata server, using the startup-script metadata key. You can use the gcloud command-line tool, the API, or Cloud Console to provide a startup script. Refer to Running Startup Scripts for details.

Starting and stopping systemd services

To start the service specified in the hello.service file:

sudo systemctl start hello.service

To stop the above service:

sudo systemctl stop hello.service

Changing the time zone

The default time zone of Container-Optimized OS is UTC0. Create a symbolic link to your desired time zone as in the following example:

sudo rm /etc/localtime
sudo ln -s /usr/share/zoneinfo/US/Pacific /etc/localtime

Note that /etc is stateless, so the timezone will be reset to the default (UTC0) every reboot.

Disabling automatic updates

There are two ways to disable automatic updates. The preferred method is to use the cos-update-strategy metadata key:

--metadata cos-update-strategy=update_disabled

You can also disable automatic updates on a running instance with systemctl:

sudo systemctl stop update-engine
sudo systemctl mask update-engine