How can I position an icon over an image?

To overlay two elements, one approach is to make a parent position: relative, and then the overlay position: absolute.

In this case, this example should work, where the download icon can be any element, such as a bootstrap button.

.img-download {
  position: relative;
}

.img-download > a {
  position: absolute;
  background: white;
  bottom: 0;
  left: 0;
}
<!-- font awesome CSS -->
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.1/css/all.css" integrity="sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr" crossorigin="anonymous">

<div class="img-download">
  <!-- image of dog -->
  <img src="https://loremflickr.com/320/240/dog" width="320" height="240" alt="dog">
  
  <!-- download icon -->
  <a href="https://loremflickr.com/320/240/dog" download="dog.jpg"><i class="fas fa-download"></i> Download</a>
</div>

Let me add a variant, when you need to position the icon on right corner of unknown-width img, it doesn't work with previous response. Should introduce a wrapper as below:

.wrapper { display: flex; justify-content: center;}    
.content { position: relative; width: max-content}
.content img { display: block; }
.content .fa-download { position: absolute; bottom:10px; right:10px; }
<link href="https://use.fontawesome.com/releases/v5.7.1/css/all.css" rel="stylesheet"/>

<div class="wrapper">
   <div class="content">
     <img src="https://placekitten.com/300/300">
     <a href="dog.png" download="new-filename"><i class="fas fa-download"></i></a>
   </div>
</div>

You need a relative container around your image and then you set your icon to be position: absolute.

.container { position: relative; }
.container img { display: block; }
.container .fa-download { position: absolute; bottom:0; left:0; }
<link href="https://use.fontawesome.com/releases/v5.7.1/css/all.css" rel="stylesheet"/>

<div class="container">
   <img src="https://placekitten.com/300/300">
   <a href="dog.png" download="new-filename"><i class="fas fa-download"></i></a>
</div>

The reason why you need you img to be display: block is because, by default, img's are display: inline and your img will have a space between the bottom of it and the bottom of the container - so your download icon will appear slightly below your img. Setting it to display: block stops this.