Configuring the host firewall

By default, the Container-Optimized OS host firewall allows outgoing connections and accepts incoming connections only through the SSH service. You can see the exact host firewall configuration by running sudo iptables -L on a VM instance running Container-Optimized OS.

Keep in mind that the host firewall is different from Virtual Private Cloud firewall rules, which must also be configured for your applications to work correctly. See the Firewall Rules Overview to learn more about Virtual Private Cloud firewall rules.

Running containers in Docker's default network namespace

If you are deploying a container on Container-Optimized OS that must be accessible over the network and you are not using Docker's --net=host option, run your container with Docker's -p option. With this option, Docker will automatically configure the host firewall to expose your application on the network. See the Docker run reference to learn more about Docker run options.

In the following example, the nginx container will be accessible on the network on port 80:

docker run --rm -d -p 80:80 --name=nginx nginx

Running containers in the host's network namespace

If you are deploying a container on Container-Optimized OS that must be accessible over the network and you are using Docker's --net=host option, you must explicitly configure the host firewall yourself.

You can configure the host firewall with standard iptables commands. As with most GNU/Linux distributions, firewall rules configured with iptables commands will not persist across reboots. To ensure that the host firewall is correctly configured on every boot, configure the host firewall in your cloud-init configuration. Consider the following cloud-init example:

#cloud-config

write_files:
- path: /etc/systemd/system/config-firewall.service
  permissions: 0644
  owner: root
  content: |
    [Unit]
    Description=Configures the host firewall

    [Service]
    Type=oneshot
    RemainAfterExit=true
    ExecStart=/sbin/iptables -A INPUT -p tcp --dport 80 -j ACCEPT
- path: /etc/systemd/system/myhttp.service
  permissions: 0644
  owner: root
  content: |
    [Unit]
    Description=My HTTP service
    After=docker.service config-firewall.service
    Wants=docker.service config-firewall.service

    [Service]
    Restart=always
    ExecStart=/usr/bin/docker run --rm --name=%n --net=host nginx
    ExecStop=-/usr/bin/docker exec %n -s quit

runcmd:
- systemctl daemon-reload
- systemctl start myhttp.service

Using this cloud-init configuration with a VM running Container-Optimized OS will result in the following behaviors on every boot:

  • The host firewall will be configured to allow incoming TCP connections on port 80.
  • An nginx container will listen on port 80 and respond to incoming HTTP requests.

Refer to Creating and configuring instances to learn more about using cloud-init on Container-Optimized OS.