# Introduction

Welcome the Docker Guide for Coti Nodes. This guide is aimed at node operators who are not necessarily familiar with Docker, but who may be curious and want to learn more. It tries to explain why using Docker could be a beneficial way to run a Coti node, and gives all of the guidance needed to understand how to run and maintain a Coti node using Docker.&#x20;

If you're curious about how Docker works, or why Docker could be a useful way to run your node, check the [Why Docker?](/introduction/why-docker) page.

## How this guide is structured

1. The Basics
   1. [Installing Docker](/the-basics/installing-docker)
   2. [Whoami?](/the-basics/whoami) (A simple Docker example)
   3. [Docker Compose](/the-basics/docker-compose)
2. Installing the Coti Node
   1. [Installing Docker on a Server](/installing-the-coti-node/installing-docker-on-a-server)
   2. [Copying the Configuration Files](/installing-the-coti-node/downloading-the-configuration-files)
   3. [Creating a .env file](/installing-the-coti-node/creating-the-.env-file)
   4. [Launching Your Node](/installing-the-coti-node/launching-your-node)
3. Reference
   1. [Commands](/docker-reference/commands-reference)

## What if I’m already familiar with Docker?

If you’re already familiar with Docker, this guide could still be useful to you. In this case, I suggest either of the following two options:

1. Skip the basics section and follow the [Installing the Coti node](/the-basics/installing-docker) section to launch the Coti Node.
2. Go straight to the [GitHub repository](https://github.com/tomjwells/coti-node), which has its own guide and all the files you need to get started.

<br>


# Why Docker?

Docker helps simplify and organize installing and running software. To understand Docker, it will  first help to understand the concept of a "container".

A container is conceptually similar to a virtual machine. It is an operating system running within the host operating system of your computer - except the software you want to run, is already installed inside.

When you want to run a piece of software, you simply download the image of the container you want, and launch it. No installation step is required.

This means that every application you run, has its own isolated environment, which brings benefits in several areas including security, compatibility, reliability.&#x20;

Below is a screenshot of a post I found by a Reddit user that perfectly describes how I think about containers. The analogy is a bit quirky, but if you bear with it, hopefully it will help you understand why Docker is so useful.

<figure><img src="https://119211556-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FUlo0oxkOkVbZ5QNv6A1Z%2Fuploads%2FBs6MSbBNcI8EPVWeYSeE%2FScreenshot%202023-04-04%20at%2009.07.35.png?alt=media&amp;token=179d8a8c-1344-44c2-b695-8f490901261f" alt=""><figcaption><p>A helpful analogy from a Redditor trying to understand Docker. In the analogy, using containers to serve applications is like using plates to serve food.</p></figcaption></figure>

## The advantages of using Docker

1. No install (or uninstall) step (except for Docker itself)

   • This saves huge amounts of time (for example, no troubleshooting installation errors) and leaves your operating system clean when removing an application.&#x20;
2. Compatibility

   • Docker is compatible with Windows, macOS and any Linux OS

   • Docker works on all popular processor architectures&#x20;
3. Widely used

   • Docker is extremely widely used, which is useful since many different applications can be run using the same tool
4. Run multiple applications on one server

   • Networking is made easy with Docker - for example, routing my-website-1.com to one container and my-website-2.com to another container is simple

   • Running multiple applications on a single server means you can use resources more efficiently

## Should I learn Docker?

Learning Docker could start to make sense if you can see yourself wanting to run a few (or more) services on the web. Since you are on a Coti guide, an obvious example is maybe you want to run a Coti node, but you want to run other applications alongside it, like a dashboard to monitor your node, or a web UI to update your node and view logs. Outside of crypto, there are even more uses of Docker:  maybe you want to host your own [website](https://hub.docker.com/_/wordpress), [blog](https://hub.docker.com/_/ghost), a [forum](https://github.com/discourse/discourse), or a [minecraft](https://hub.docker.com/r/itzg/minecraft-server) server. Using Docker will certainly be easier if you are familiar with the command line.

To give you a sense of just how widely used Docker is, here are a few examples of Docker images for nodes on other cryptocurrency networks:

* [Bitcoin](https://hub.docker.com/r/ruimarinho/bitcoin-core/)
* [Ethereum](https://hub.docker.com/r/ethereum/client-go/)
* [Cardano](https://hub.docker.com/r/inputoutput/cardano-node)
* [Dogecoin](https://hub.docker.com/r/greenbigfrog/dogecoin/tags)
* [Polygon](https://wiki.polygon.technology/docs/operate/full-node-docker/)
* [Solana](https://hub.docker.com/r/solanalabs/solana)

The skills learnt in this guide will be transferable to almost any other piece of software you want to run on the web. In the rare case that a Docker image of something is not available, you can make your own.


# Installing Docker

Docker has a desktop application, which is great for learning Docker on your home computer. In this section, I'll guide you through how to install Docker desktop.

For all of the "The Basics" section, I suggest following this guide on your home laptop/computer. This will make learning Docker easier than following along on a remote server.

## Windows Users

Follow the instructions on [this page](https://docs.docker.com/desktop/install/windows-install/#install-docker-desktop-on-windows) from Docker.

## Mac Users

Download the Docker [Desktop App for Mac](https://docs.docker.com/desktop/install/mac-install/).

## Linux Users

Follow the instructions on [this page](https://docs.docker.com/desktop/install/linux-install/#generic-installation-steps).

## Once Docker is Installed&#x20;

Docker Desktop gives a graphical user interface. The desktop app is useful sometimes, but from now on, I will refer to commands to be run from the command line, since that is also what we will eventually need to run Docker on a server.

<figure><img src="https://119211556-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FUlo0oxkOkVbZ5QNv6A1Z%2Fuploads%2FB7Kk5X6KAwCy9faZZNgd%2FScreenshot%202023-04-18%20at%2022.45.46.png?alt=media&amp;token=ee5eb277-b2f3-47e1-9bc2-d695f42f0a5d" alt=""><figcaption><p>This is an example of the Docker Desktop application with some running containers</p></figcaption></figure>

The next page shows how to run a simple application using Docker.


# Whoami

"Whoami" is the name of a simple image that is great for learning Docker. If you're wondering what an image is, that will be explained below.

Whoami is like the “Hello world!” of Docker. It is a minimal, but realistic example of a service someone might run with Docker. We'll use it in this section to show the basic stages of the lifecycle of a container, which will be exactly the same principles involved in running any application - including our Coti node.&#x20;

On a high level, the steps covered in this page are:

1. [Running a Container](#checking-running-containers-with-docker)
2. [Checking a Container is up](#checking-a-container-is-up)
3. [Stopping a Container](#stopping-a-container)
4. [Removing a Container](#removing-a-container)

## Running a Container <a href="#running-a-container" id="running-a-container"></a>

First, I'll introduce the command to use, show you the output, and then explain what just happened. To run a whoami container, use

```
docker run -p 80:80 containous/whoami
```

What does this mean?&#x20;

* `docker` refers to Docker's command
* `run` tells the docker cli that you want to run a container
* `-p 80:80` tells Docker to map port 80 from the outside of the container, to port 80 on the inside of the container. Ports are closed by default on containers (this is a security feature), which is why we need to tell it which port to open.
* `containous/whoami` refers to the "whoami" Docker image. You can find it on [Dockerhub](https://hub.docker.com/r/containous/whoami). "containous" is the organization that created the image, and "whoami" is the name of the image. Dockerhub is an example of an image registry. You can think of an image registry as like a library for container images. Dockerhub is not the only image registry, although it is generally the most popular one.

When I ran the command above, this was the output:

{% code lineNumbers="true" %}

```bash
Unable to find image 'containous/whoami:latest' locally
latest: Pulling from containous/whoami
29015087d73b: Pull complete 
0109a00d13bc: Pull complete 
d3caffff64d8: Pull complete 
Digest: sha256:7d6a3c8f91470a23ef380320609ee6e69ac68d20bc804f3a1c6065fb56cfa34e
Status: Downloaded newer image for containous/whoami:latest
Starting up on port 80
```

{% endcode %}

Here's a breakdown, line by line, of what happened:

* Line 1: Docker checked the local cache for the image, and informs us that it couldn't find the image.
* Line 2: Since Docker couldn't find the image locally, it goes to Dockerhub and pulls (downloads) the image.
* Lines 3-5: Docker images are made in layers, so each line corresponds to one layer pulled by Docker.
* Line 6: This shows a checksum of the download. Checksums are a security feature that allows you to check whether downloaded files have been tampered with.&#x20;
* Line 7: This is a status report that tells us that the download is complete.
* Line 8: This is a log from the "whoami" application itself, telling us that it has started, and it is running on port 80.

A lot happened there. The important parts are that Docker downloaded the image we requested, and ran it. It is possible to download and run the image in separate steps, but Docker typically isn't used that way.&#x20;

Once the image is downloaded, it is saved on the computer, so that it doesn't need to be re-downloaded every time we run the application. The command above will work regardless of whether the image has already been downloaded or not.

## Checking a Container is Up

In the last line of the output above, Docker says something is running on port 80? Let's test that out. In a new terminal tab/window, run

```bash
curl http://localhost:80
```

The output I received was:

```
Hostname: a61ec392609e
IP: 127.0.0.1
IP: 172.17.0.2
RemoteAddr: 172.17.0.1:57142
GET / HTTP/1.1
Host: localhost
User-Agent: curl/7.79.1
Accept: */*
```

If you received similar output, congratulations! That is a successful response from whoami, and you successfully got a response from your first Docker container [🎉](https://emojipedia.org/party-popper/)

The `Hostname` is the ID of the container that we created. The other information mostly reflects back the HTTP headers that were sent by curl.

I suggest you also try visiting `http://localhost:80` in a browser, and you will get back even more information (since the browser sends more headers).

That's pretty cool. We launched an application with just one command, and without writing any code.

## Checking Running Containers with Docker

We can also check whether a container is running with the Docker cli. To do this, use

```
docker ps
```

You can think of `docker ps` as like the `ls` command, in that it lists the running containers.

The output I received was

```
CONTAINER ID   IMAGE               COMMAND     CREATED          STATUS          PORTS                NAMES
a61ec392609e   containous/whoami   "/whoami"   16 seconds ago   Up 15 seconds   0.0.0.0:80->80/tcp   pensive_dubinsky
```

Notice the container ID matches the Hostname presented to us by Whoami. The command also gives some basic information about the running container (e.g. the port mapping, how long the container has been running).

## Stopping a Container

Ending a container's lifecycle is just as important as starting it. Without stopping our containers, we would eventually have huge numbers of containers using up our resources.

There are two ways to stop Docker containers. Since we ran `whoami` interactively, we can stop the container simply by entering `Ctrl+c` (cancel) in our terminal.&#x20;

<figure><img src="https://119211556-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FUlo0oxkOkVbZ5QNv6A1Z%2Fuploads%2FjvOKelEu2MTES0vuHTO4%2FScreenshot%202023-04-04%20at%2007.33.30.png?alt=media&amp;token=9da6b4b9-4ada-4643-89cf-5a0e2893f64c" alt=""><figcaption></figcaption></figure>

A good way of checking that the container has stopped, is by running `docker ps`. The output no longer shows our `whoami` container.&#x20;

```
docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
```

You can also check that the container has stopped by visiting `http://localhost:80` again.

Although the container is stopped, that does not mean it has been fully deleted. A `-a` option (short for "all") can be added to the `docker ps` command to ask Docker to show all containers. So, to see our stopped container, use&#x20;

```
docker ps -a
```

which shows an output of

{% code lineNumbers="true" %}

```
CONTAINER ID   IMAGE                            COMMAND                  CREATED          STATUS                          PORTS     NAMES
a61ec392609e   containous/whoami                "/whoami"                2 minutes ago   Exited (2) 1 minute ago                 pensive_dubinsky
```

{% endcode %}

## Removing a Container

In most cases, stopping a container is enough, but to understand all the steps, we'll demonstrate removing a container too.&#x20;

Copy the CONTAINER ID from the previous step. Then to remove the container, we run

```
docker rm <CONTAINER_ID>
```

When it is successful, `docker rm` returns the ID of the removed container. If you ever want to remove more than one container at once, you can simply add many container IDs, separated by spaces.

Running `docker ps -a` again shows that the container has been removed! Great.

{% code lineNumbers="true" %}

```
docker ps -a
CONTAINER ID   IMAGE                            COMMAND                  CREATED          STATUS                         PORTS     NAMES
```

{% endcode %}

## Summary

Although the application we ran, whoami, was very simple, we introduced some key concepts that are part of any application's lifecycle, namely:

* Running a container
* Checking it is up
* Stopping a container
* Removing a container

These are the most important concepts to understand when using Docker. If you managed to follow these steps, you are about 80% of the way to becoming a fully fledged Docker user! Awesome.


# Docker Compose

There are two main ways in which people run Docker. The first way uses the `docker` command, which we covered in the previous section. In this section, we'll look at the second way, in which a configuration file is used to define the settings for our Docker container.

In this step of the guide, we will cover:

1. [What are docker-compose files?](#what-are-docker-compose-files)
2. [Creating a docker-compose file](#creating-a-docker-compose-file)
3. [Running docker-compose](#running-docker-compose)
4. [Stopping docker-compose](#stopping-docker-compose)

## What are docker-compose files?

Why would we use configuration files when we can just use commands? Some Docker commands can get pretty long. Plus, if we want to run 7+ containers as part of one website, it can be a lot of work entering 7 `docker run` or `docker rm` commands every time you want to start/stop our websites.&#x20;

docker-compose files are usually called `docker-compose.yml`. They are nothing more than text files, and they use a specific notation called [yaml](https://en.wikipedia.org/wiki/YAML), which is like JSON, but more readable. `docker-compose` is also the name of the command we'll use to run Docker this way.

In this step of the guide, we won't cover everything you can do with docker-compose files (that would be a lot), but we will cover some basics, and show you how to use them to run containers.&#x20;

## Creating a docker-compose file

In this step, we'll set up a simple docker-compose file, that tells Docker how we want to run whoami.

Make a new directory, and in that directory, create a new file called `docker-compose.yml`. Using a text editor, enter the following contents into `docker-compose.yml`:

```yaml
version: '3'

services:
  whoami:
    image: containous/whoami
    ports:
      - 80:80
```

Let's go over how this file works:

* The line `version: '3'` tells Docker which version of docker-compose syntax to expect
* `services` is the yaml section in which we list the applications we want to run
* `whoami` is the name we have given to the service we want to run
* &#x20;`image: containous/whoami` tells Docker which image to use for the container
* The lines `ports:` and `- 80:80` tell Docker that we want port 80 on the outside of the container, to be mapped to port 80 on the inside of the container.

Notice that the syntax is similar to what we used in the `docker run` command in the Whoami section. That is of course intentional, and shows how Docker and docker-compose are closely related.

## &#x20;Running docker-compose

Running docker-compose is simple, since we already did the hard work in creating the configuration file. Docker assumes that a docker-compose file is called `docker-compose.yml`, so all we need to do, is run&#x20;

```bash
docker-compose up
```

This gave the output

<pre class="language-bash"><code class="lang-bash"> ⠿ Container play-whoami-1  Created                                                                                                                                            0.1s
Attaching to play-whoami-1
<strong>play-whoami-1  | Starting up on port 80
</strong></code></pre>

The important line above is `play-whoami-1  | Starting up on port 80`. This tells us that the line `Starting up on port 80` was logged from within a container called `play-whoami-1.`

Once again, let's use `curl http://localhost:80` in a new terminal to check the container is running. This gives a similar output to when we ran whoami with `docker`.

```
Hostname: 268742d8d212
IP: 127.0.0.1
IP: 172.20.0.2
RemoteAddr: 172.20.0.1:60638
GET / HTTP/1.1
Host: localhost
User-Agent: curl/7.79.1
Accept: */*
```

Running `docker ps` confirms the Hostname output by whoami, and the name of the container (play-whoami-1) that we saw from the output of `docker-compose up` (scroll across to see the names).

```bash
CONTAINER ID   IMAGE               COMMAND     CREATED              STATUS              PORTS                NAMES
268742d8d212   containous/whoami   "/whoami"   About a minute ago   Up About a minute   0.0.0.0:80->80/tcp   play-whoami-1
```

## Stopping docker-compose

Stopping docker-compose is similar to stopping a container started with `docker`. We can press Ctrl+c to exit.

We can confirm that the container has stopped by running `docker ps -a`

```bash
docker ps -a
CONTAINER ID   IMAGE               COMMAND     CREATED         STATUS                      PORTS     NAMES
268742d8d212   containous/whoami   "/whoami"   5 minutes ago   Exited (2) 16 seconds ago             play-whoami-1
```

Removing containers that were launched with `docker-compose`, is done easily with the command

```bash
docker-compose rm
```

## Summary

In this step of the guide, we showed how `docker-compose` can be used to run, stop and remove applications. We saw how similar using `docker-compose` is to using `docker` commands, but also how running applications can be simpler this way, since the complexity is hidden in the `docker-compose.yml` file.

This makes up the last 20% of what I consider to be the requirements for a capable Docker user. There may be a few remaining concepts that this guide has not covered yet, but there is nothing major. The advantage of learning to use docker-compose, is that you can easily use other people's configuration files to launch nodes, websites and so on, without needing to know how everything was configured internally.&#x20;


# Installing Docker on a Server

This section explains how to install Docker and docker-compose on a server.

The guide starts from the assumption that you have set up a server, and you are connected to the server through ssh.

Root privileges are needed to install Docker, so before executing the commands below, make sure you are logged in as root, using

```bash
sudo su
```

## Installing Docker

Docker provide an official script to install `docker` that works on most systems. The official script can be run with

```bash
curl -fsSL https://get.docker.com | bash
```

Once the command has finished and if it looks successful, you can check whether the Docker was installed correctly with

```bash
docker --version
```

which gave me the output of

```bash
Docker version 23.0.1, build a5ee5b1
```

## Installing docker-compose

The easiest way to install docker-compose is with

```bash
curl -L https://github.com/docker/compose/releases/latest/download/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose && chmod +x /usr/local/bin/docker-compose
```

If it looks like the command ran successfully, you can check the version with

```bash
docker-compose --version
```

which should give an output similar to

```bash
Docker Compose version v2.15.1
```

Awesome.

## Summary

If the outputs of `docker --version` and `docker-compose --version` looked similar to the example output above (don't worry about exact version numbers), then your Docker installation should be set up correctly and ready to go.


# Downloading the Configuration Files

In the "The Basics" section, we showed how [docker-compose](/the-basics/docker-compose) can be used to run a whoami container. We'll be using a similar approach will to run the Coti node. This section describes the files we'll be using to define our Docker containers, and gives a command to download them on to your server.

## Summary of the Configuration Files

Here is a summary of the files that will be downloaded in this step, and what each file does:

* [`docker-compose.yml`](https://github.com/tomjwells/coti-node/blob/master/docker-compose.yml)
  * This file tells Docker to run two containers, one of which is the Coti node, and the other is a web server called [Traefik](https://traefik.io/traefik/).&#x20;
  * The Coti node container runs the fullnode application.&#x20;
  * Traefik performs a few roles, including issuing/renewing SSL certificates, redirecting requests received on port `80` to port `443`, and forwarding requests received on ports `443` and `7070` to the Coti node container.&#x20;
* [`traefik_conf.yml`](https://github.com/tomjwells/coti-node/blob/master/traefik_conf.yml)
  * This is a configuration file that is specific to the Traefik web server, and contains some additional settings required to generate SSL certificates that get an A+ rating with [SSL Labs](https://www.ssllabs.com/ssltest/).

Feel free to look through these files, although it's not necessary to edit or understand them to follow the guide and get your node installed.

## Copying the Configuration Files

The command below creates a new directory (called `coti-node`), and downloads the two configuration files into the new directory.

```
mkdir coti-node &&\
 cd coti-node &&\
 curl -sLJO https://raw.githubusercontent.com/tomjwells/coti-node/master/docker-compose.yml &&\
 curl -sLJO https://raw.githubusercontent.com/tomjwells/coti-node/master/traefik_conf.yml
```

You can use `ls` to check that the files were downloaded successfully. This should show two new files in the `coti-node` directory: `docker-compose.yml` and `traefik_conf.yml`.

## Summary

If the command above was successful, you now have the configuration files you need to run your node. In the next step, we'll create one last file called `.env`, which allows you to specify the unique information (like private key, seed key and server name) required to set up your node.


# Creating the .env file

`.env` are a way to make certain values accessible to an application running in a container. We'll use the `.env` file to configure the node with the information that is specific to your node (like private key, seed key, and server name).

{% hint style="info" %}
If you haven't created your private key and seed information yet, please see the step-by-step instructions on [GeordieR's guide](https://cotidocs.geordier.co.uk/wallet-and-kyc/generating-your-seed).
{% endhint %}

## Creating the .env file

From within the `coti-node` directory, create a new file called `.env`. To do this in `vim`, for example, one could run

```bash
vim .env
```

After creating the `.env` file, copy the following contents into the file, replacing everything in the angle brackets (<>), including the angle brackets themselves, with the information for your node.

<pre class="language-bash" data-title=".env" data-line-numbers><code class="lang-bash"><strong>ACTION="&#x3C;mainnet or testnet>"
</strong>SERVERNAME="&#x3C;Your desired mainnet or testnet URL>"
PKEY="&#x3C;Your private key>"
SEED="&#x3C;Your seed key>"
EMAIL="&#x3C;Your email address>"
</code></pre>

### Example .env file

Here is an example `.env` file for a fictional testnet node called "my-coti-node.xyz", with a private key of 1234567890, and a seed key of ABCDEFGHIJ.

{% code title=".env (example)" lineNumbers="true" %}

```bash
ACTION="testnet"
SERVERNAME="my-coti-node.xyz"
PKEY="1234567890"
SEED="ABCDEFGHIJ"
EMAIL="info@my-coti-node.xyz"
```

{% endcode %}

## Optional Variables

An optional, but useful environment variable, is `VERSION`. This controls which version of the coti-node software that Docker will run.&#x20;

If you want to run the latest version (which is generally suitable for testnet node operators), then you don't need to specify the `VERSION` environment variable.

On the other hand, if you want to run a particular version of the Coti node, this can be done by adding the following line to your `.env` file

```bash
VERSION="X.Y.Z"
```

where `X.Y.Z` is the release tag of the version you wish to run. A list of the available versions can be found [here](https://hub.docker.com/r/atomnode/coti-node/tags), which correspond to the [official releases](https://github.com/coti-io/coti-node/releases) made available by Coti.

## Summary

At this point, you have done all of the hard work needed to set up your node. The next step shows how to launch the node with Docker.


# Launching Your Node

If you have followed the steps in the guide up to this point, you are now ready to launch your node.

## Launching the Node

First, check you are working from the `coti-node` directory, and that you are logged in as root (`sudo su`). From there, the node can be launched with

```
docker-compose up
```

The video below shows an example of the output when running the Coti node with Docker. This may be useful to watch, so you know what to expect.

{% embed url="<https://youtu.be/TIid1FFYchw>" %}

{% hint style="success" %}
Remember: If you ever want to stop the container quickly and regain access to the terminal, you can do so easily by hitting Ctrl+c.
{% endhint %}

Once your logs reach the "`COTI NODE IS UP`" point, your node is running. Keep an eye on the logs for 5 minutes or so, and make sure the behaviour looks stable.&#x20;

If there are any errors, the clues will be in the logs.

Once you are happy that the behaviour look stable, you can safely close the terminal window, which exits the terminal, and leaves the container running.&#x20;

## Congratulations 🎉

Once a node is up, it usually won't require much maintenance. If you followed the [Docker Compose steps](/the-basics/docker-compose) from the "The Basics" section, you'll know how to start, stop and remove containers with `docker-compose`.  More commands and instructions for particular tasks are shown in the [Commands Reference](/docker-reference/commands-reference) section.&#x20;

Coti release new versions of the node software every so often, and it is important to stay up to date. The next step explains how to upgrade the node version using Docker.


# Upgrading Your Node

When Coti release new versions of their software, it is important to keep your node up to date, especially if your node is on the testnet, so that the new software can be tested before being rolled out to mainnet.

Fortunately with Docker, upgrading is simple.

## Upgrading to the Latest Version

If you didn't choose a version in your `.env` file, the Coti node can be upgraded with

```bash
docker-compose up -d
```

This tells Docker to re-launch your node. In the process of re-launching, Docker check Dockerhub to make sure it has the latest version, and it downloads a newer version if one is available. The `-d` flag tells Docker to run the container in "detached mode", which means that the terminal will be freed from the container once it is launched.

## Upgrading (or Downgrading) to a Specific Version

If you chose a version in your `.env` file using the `VERSION` environment variable, you should edit the version number in your `.env` file before relaunching the node.

After changing the version number in the `.env` file, upgrading/downgrading can be done with the same command:

```bash
docker-compose up -d
```

## Summary

If you have followed the guide this far, you now know everything you need to run your node with Docker! Make sure to pass the favour on by helping others set up their nodes, and stay active within the community. Thanks for reading.

A list of useful `docker` and `docker-compose` commands is kept at the end of this guide, that you can turn to if you ever need to perform tasks that are not covered earlier in the guide.&#x20;


# Commands Reference

## Stopping Containers

When the terminal is not attached to a container, it cannot be stopped with `Ctrl+c`. In this case the commands below can be used to stop a container.

Stop a container launched with `docker`:&#x20;

```
docker stop <CONTAINER_ID>
```

Stop a container/containers launched with `docker-compose`:

```
docker-compose down
```

## Logs

Follow the node logs:

```
docker-compose logs coti-node --follow
```

Output the node logs to a file:

```
docker-compose logs coti-node > coti-node.log
```

Copy the node logs to your local computer (run this from your local computer):

```bash
scp my-user@my-coti-node.xyz:~/coti-node/coti-node.log .
```

Follow the logs of the `node-monitor`:

```bash
docker-compose logs node-monitor --follow
```


