Docker commands on Triton

Triton uses the native Docker API to make spinning up containers easy using the Docker tools of your choice. Using the Triton Docker CLI tool on your laptop you can deploy Docker containers across an entire Triton data center. You can do the same with Triton-Compose.

The Triton Docker API implementation on Triton runs parallel with Triton's CloudAPI, and the containers you provision using the Docker API run along side the infrastructure containers and hardware VMs you can start using CloudAPI.

Docker API and CloudAPI on Triton

The Triton Docker API can only be used to start and manage Docker containers on Triton, but the Triton CLI tool gives you control over all types of compute instances (though the Triton CLI cannot do all operations on Docker containers, see details in context below).

On Triton, you can have a single view of your bare-metal Docker containers, infrastructure containers, and hardware VMs.

Docker commands on Triton

When deploying containers on Triton, you'll be using Joyent's implementation of the Triton Docker API and Triton CloudAPI. Most Docker commands work on your local machine and within the Triton environment. There are some unimplemented commands, and some operational practices that you'll need to reconsider, but most things just work. Doing a triton-docker run just works, even if you haven't created a VM for the container to run in. That's because Docker containers on Triton run on bare metal, with no need to setup and maintain a host.

We recently deployed the Triton Docker CLI, which will ensure you're using known good, tested versions of Docker on Triton. You can install that by running:

sudo curl -o /usr/local/bin/triton-docker https://raw.githubusercontent.com/joyent/triton-docker-cli/master/triton-docker && chmod +x /usr/local/bin/triton-docker && ln -Fs /usr/local/bin/triton-docker /usr/local/bin/triton-compose && ln -Fs /usr/local/bin/triton-docker /usr/local/bin/triton-docker-install

That command will copy the triton-docker shell script from this repo, and link it as triton-compose and triton-docker-install.

To complete the installation, run sudo triton-docker-install to install the platform-specific versions of the Docker and Docker Compose CLI tools. These versions will not replace any existing Docker or Docker Compose versions you may have installed.

Docker on Triton

Docker commands only work with Docker instances. To work with other infrastructure containers and hardware VMs, you must use CloudAPI.

Start containers with triton-docker run or triton-docker container start

When you execute triton-docker run, an individual container is spun up with its own file system, networking, and process tree. Each Docker container runs on bare metal in your selected data center, with no need to setup or maintain hosts.

docker run on Triton

The triton-docker run command is often composed of many parts. For example, let's create an Nginx container.

$ triton-docker run -d -p 80 --name webserver nginx

Within this command:

  • triton-docker run tells your application to start running
  • -d detaches from the container, meaning your application runs in the background and not the foreground
  • -p 80 tells Triton to give the container an interface on the public internet and expose port 80
  • webserver is the name of your new container
  • nginx is the image that will be built into a container

Every time you triton-docker run, your container is provisioned on an available server in that data center. If you do five triton-docker runs, your five containers will probably be running on five different physical servers. You can get some control over where in the data center your container runs by using affinity filters. You can add an affinity filter with either environment variables or with a label.

There are several other ways to modify triton-docker run to customize your container. You can set the RAM, CPU, and storage for each container, as well as specify networks and ports.

As of Docker version 1.13, triton-docker container start was introduced and works the same was as triton-docker run. The above command would become the following:

$ triton-docker container start -d -p 80 --name webserver nginx

On Triton, triton-docker run and triton-docker container start are similar to triton instance start, although triton instance start cannot start Docker containers and the triton-docker commands cannot start hardware VMs or infrastructure containers.

Start and manage multiple containers with Docker Compose

Docker Compose is a tool for defining and running applications with multiple containers. A docker-compose.yml file configures the application services. Triton Compose is the version of Docker Compose which you can use to scale or start applications on Triton.

Instead of using triton-docker run three, four, or five times in order to start containers or scale your application, a compose file does the hard work for you. On Triton, your containers will run on different physical servers across the cloud.

Triton Compose in action

We built an Autopilot Pattern WordPress application which uses Docker Compose to spin up several different containers including WordPress, Nginx, MySQL, and more. The application is infinitaly more easy to scale with Docker Compose. Instead of having to use triton-docker run with every different container to spin up a new instance, you can run triton-compose scale with the name of the instance and the number of instances you want to exist.

If we decided to scale WordPress, Nginx, and MySQL, the command would look like this:

$ triton-compose scale wordpress=3 nginx=3 mysql=3

Scaling back down is the same command, just with fewer instances— for the above example, that could look like triton-compose scale wordpress=2 nginx=2 mysql=2.

Here are some other examples of projects using Docker Compose:

List containers with triton-docker ps or triton-docker container list

In order to see all of your provisioned Docker containers, running and stopped, you can run triton-docker ps -a or triton-docker container list -a. The -a modifier is what ensures all containers are listed.

$ triton-docker ps -aCONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                    PORTS                         NAMES828ef84a23d0        nginx               "nginx -g 'daemon off"   3 days ago          Exited (0) 25 hours ago   0.0.0.0:80->80/tcp, 443/tcp   ecstatic_stallman78de959d7c96        ubuntu              "/bin/bash"              3 days ago          Exited (0) 3 days ago                                   compassionate_goodall27d747a35429        ubuntu              "/bin/bash"              2 days ago                                                                  cranky_jepsen  

On Triton, triton-docker ps and triton-docker container list is similar to triton instances, although triton-docker commands will only return your Docker containers and triton instances will show all of your containers and VMs.

List your instances

Learn about your containers with triton-docker inspect

You can learn a lot of information about your containers with triton-docker inspect. Either the name or ID can be used to identify the container. The results will be a JSON array of general information.

Below is a truncated version of the JSON array received from an Nginx container:

$ triton-docker inspect nginx01$ [    {        "Id": "2054611bb39944009bcfdf2eeabd9eb4f1d191b06fa34f23863c233211f48e77",        "Created": "2016-08-08T19:03:03.682Z",        [...]        "Driver": "sdc",        "ExecDriver": "sdc-0.1",        "HostConfig": {            "Binds": null,            "CapAdd": null,            "CapDrop": null,            "ContainerIDFile": "",            "Devices": [],            "Dns": [                "8.8.8.8",                "8.8.4.4"            ],            [...]        },        "Volumes": null,        "VolumesRW": null,        "RestartCount": 0,        "HostnamePath": "/etc/hostname",        "HostsPath": "/etc/hosts",        "Image": "6685b215489379f00c1b399db75a4e4aa6546e4f2a3519145c14a2c7d5612be7",        "MountLabel": "",        "Name": "/nginx01",        "NetworkSettings": {            "Bridge": "eth1",            "Gateway": "72.2.118.1",            "IPAddress": "72.2.118.243",            "IPPrefixLen": 23,            "MacAddress": "90:b8:d0:62:26:63",            "PortMapping": null,            "Ports": {                "443/tcp": null,                "80/tcp": [                    {                        "HostIp": "0.0.0.0",                        "HostPort": "80"                    }                ]            }        },        [...]    }]

Included in the array is low level information such as the container ID, image ID, network settings, and more. It is possible to filter a specific piece of information with Go templating or by using grep.

For example, to get just the ID of a specific container, you would run triton-docker inspect | grep Id.

Compare that Docker command to triton instance get which tells you specific information about your containers on Triton. For example, your command results may look like this:

$ triton instance get {    "id": "2054611b-b399-4400-9bcf-df2eeabd9eb4",    "name": "nginx01",    "type": "smartmachine",    "brand": "lx",    "state": "running",    "image": "77b85e3d-f205-363b-03c3-ddfa5e79192e",    "ips": [        "192.168.128.31",        "72.2.118.243"    ],    "memory": 1024,    "disk": 25600,    [...]    "primaryIp": "72.2.118.243",    "firewall_enabled": true,    "compute_node": "44454c4c-4400-1057-804c-b5c04f383432",    "package": "g4-highcpu-1G",    "dns_names": [        "2054611b-b399-4400-9bcf-df2eeabd9eb4.inst.d9a01feb-be7d-6a32-b58d-ec4a2bf4ba7d.us-east-1.cns.joyent.com",        "nginx01.inst.d9a01feb-be7d-6a32-b58d-ec4a2bf4ba7d.us-east-1.cns.joyent.com",        "2054611b-b399-4400-9bcf-df2eeabd9eb4.inst.d9a01feb-be7d-6a32-b58d-ec4a2bf4ba7d.us-east-1.triton.zone",        "nginx01.inst.d9a01feb-be7d-6a32-b58d-ec4a2bf4ba7d.us-east-1.triton.zone"    ]}

Although the purpose of triton instance get is the same as triton-docker inspect, the triton command gives you additional details about your Docker containers including all of the network interfaces and automated DNS details from Triton CNS, the amount of memory allocated, disk space, etc. This information will help you understand and manage your instances within the context of the Triton Cloud.

List your instances

To parse through that information and get more specific answers, use json. Run triton instance get | json . That label could by memory, package, name, or any other piece of metadata available with triton.

Get your container IP with triton-docker inspect

You can quickly get your container's IP address is with triton-docker inspect. One way to use triton-docker inspect is with Go templating.

$ triton-docker inspect --format '{{ .NetworkSettings.IPAddress }}' 165.225.173.195

It is also possible to use grep to get the same information. triton-docker inspect | grep IPAddress will give you the same results, formatted differently.

$ triton-docker inspect  | grep IPAddress"IPAddress": "165.225.173.195"

This command will give you the container's IPAddress address. This IP address may be public, meaning it is accessible over the public internet, or private, meaning the IP is only accessible to your other containers. Docker containers on Triton are always assigned a private IP and have public IP addresses if requested by adding -p or -P to triton-docker run.

On Triton, triton ip will give you the primary IP number, without having to sort through all of the instance details. If you want all of the IPs assigned to your container, use triton instance get .

To better understand networking on Triton, read What's my IP? Understanding networking on Triton.

Run commands or get a shell in the container with triton-docker exec

"Servers," whether they're bare metal, or a VM, or even an infrastructure container typically have a number of different daemons running, including SSH. Even in the most automated of environments, most of us depend on being able to "get in" to the server via SSH to take a look at problems, trigger a database dump, or any number of other tasks that need doing.

But, typical Docker containers don't have SSH running, meaning we can't get in that way. That focus on running just one service per container is a good thing, but it means we've got to use a different method to do the ad-hoc maintence and investiations that are inevitable in the operation of any application.

The solution is triton-docker exec .

The nearest equivilent of SSHing into a Docker container is to triton-docker exec -it bash (you may have to specify a different shell or a complete path if bash is not in your path). However, you can run any executable in the container.

Consider the following examples:

# get an interactive shell in the containertriton-docker exec -it  bash# do a database dump from a MySQL container to your local computertriton-docker exec  sh -c 'exec mysqldump --all-databases -uroot -p"$MYSQL_ROOT_PASSWORD"' > all-databases.sql

There are some things to be aware of:

  • If the container is stopped, triton-docker exec will fail with an error.
  • Take careful note of shell parsing, both your local and remote shells. The MySQL example is worthy of special attention in that respect.

Stop and remove containers with triton-docker stop, triton-docker container stop, and triton-docker rm

With triton-docker stop and triton-docker container stop, a container is given a graceful shutdown. This could be useful if your container is not responsive, or if you need to restart the container in order to upgrade or migrate to another host. Docker automatically gives your container 10 seconds to stop, and if it does not comply, the process is forcibly killed. It is possible to allocate a specific amount of time for the shutdown by adding --time= before the container name. For example, triton-docker stop --time=30 would give the container 30 seconds to stop gracefully before it is forcibly killed.

The companion triton command, triton instance stop, is similar to triton-docker stop and will stop your instances.

To remove a container you're no longer using, execute triton-docker rm or triton-docker container rm . If you want to remove a container that is not already stopped, you can force stop and remove the container with triton-docker rm -f .

On Triton, triton instance delete can remove any container, including Docker containers.

You will be billed for all provisioned containers, including those which are stopped. To avoid charges for containers which you may no longer be using, be sure to remove them.

Get new images with triton-docker pull

Triton caches Docker images in each data center. The first time you run an image, it will automatically try pulling it for you. You can do explicit triton-docker pulls to check for updates to the image.

$ triton-docker pull nginx$ triton-docker pull mysql$ triton-docker pull jenkins

Docker images can come from a number registries. Docker Hub is the global default registry, but other registries can be used by specifying them in the image name. Be sure to login of the appropriate registry before pulling the image.

For example, if you use Quay to pull Docker images, your pull may look like this:

$ triton-docker pull quay.io//

You can also create your own private registry to distribute Docker images.

Get your private Docker images by connecting to a private registry with login and logout

Some registries and image repositories are public and require no login; others are not. In order to pull images from your private repository, you'll need to login to Docker. Execute triton-docker login to access those services in the terminal. The command line will prompt for your username and password.

To logout of your Docker account, use triton-docker logout .

If no registry URI is specified, Docker will assume you intend to use or log out from Docker Hub.

Triton comes with several images built-in. You can view the available list with triton images. Some of these images are for Docker, some are for infrastructure containers, and some are for hardware VMs.

Please also consult the blog post optimizing Docker operations on Triton.

Wrapping up

We know how powerful containers are and how ubiquitous Docker is becoming. In fact, we share Docker's vision for a containerized future. That's the reason we built Triton. By knowing how to use the Docker API—alongside CloudAPI—you'll be better prepared to provision containers on Triton.



Post written by Alexandra White