Elixir / Phoenix — Uploading images to AWS S3 (With ARC)

Hello, and thanks for checking in. In this post, I’d like to discuss how to upload images to an S3 bucket. We will continue working on the application we wrote earlier - Imageer. If you haven’t worked your way through it, I recommend doing so first. Elixir / Phoenix — Uploading images locally (With ARC)

Last time, we successfully managed to upload images to a local folder, and display the images in our images index template. Uploading to S3 with ARC requires us to install a couple of more packages:

# mix.exs
applications: [:phoenix, :phoenix_pubsub, :phoenix_html, :cowboy, :logger, :gettext,:phoenix_ecto, :postgrex, :arc_ecto, :ex_aws, :httpoison, :poison]]
defp deps do
[{:phoenix, “~> 1.2.1”},
{:phoenix_pubsub, “~> 1.0”},
{:phoenix_ecto, “~> 3.0”},
{:postgrex, “>= 0.0.0”},
{:phoenix_html, “~> 2.6”},
{:phoenix_live_reload, “~> 1.0”, only: :dev},
{:gettext, “~> 0.11”},
{:cowboy, “~> 1.0”},
{:arc, “~> 0.5.2”},
{:arc_ecto, “~> 0.4.4”},
{:ex_aws, “~> 0.5.0”}, #new package
{:poison, “~> 2.0”}, #new package
{:httpoison, “~> 0.9.0”}] #new package

We also added the new packages to our applications, so that they get run when we start our server.

Let’s install the new packages:

~/imageer$ mix deps.get
Running dependency resolution
Dependency resolution completed

We’ll restart our application, and everything should be up and running.

Now, we are going to configure ARC and ex_aws to work properly with S3. First create a new s3 bucket, and add the configurations to our dev.exs file (since we’re working on a dev environment)

config :arc,
bucket: “nameofyourbucket”,
virtual_host: true
config :ex_aws,
access_key_id: “accesskey”,
secret_access_key: “secretkey”,
region: “eu-central-1”,
host: “s3.eu-central-1.amazonaws.com”,
s3: [
scheme: “https://”,
host: “s3.eu-central-1.amazonaws.com”,
region: “eu-central-1”

If you are using the standard US bucket, you don’t need to set virtual_host, region, host or s3 configs. These are for using buckets other than the standard one. We also need to restart our server after the configurations.

Now, if we try and upload an image, it gets uploaded, however the image isn’t visible for us. If we look in our source code (HTML) we have:

<h4><a href=”/images/new”>Upload new image</a></h4> 
<img src=”https://yourbucket.s3.amazonaws.com/uploads/cat1.jpeg?v=63641413100"><br>
<img src=”https://yourbucket.s3.amazonaws.com/uploads/cat2.jpeg?v=63641413105"><br>
<img src=”https://yourbucket.s3.amazonaws.com/uploads/cat1.jpeg?v=63643235268"><br>

So the image path is properly set. However, if we click on any of the links, we’ll get a “Access Denied” error from AWS. We need to add a simple policy to our S3 bucket. We can do so by clicking on our newly created bucket in the AWS console, click Properties, Permissions and “Add bucket policy”. Copy and paste the following into it:

“Version”: “2012–10–17”,
“Id”: “Policy1380877762691”,
“Statement”: [
“Sid”: “Stmt1380877761162”,
“Effect”: “Allow”,
“Principal”: {
“AWS”: “*”
“Action”: “s3:GetObject”,
“Resource”: “arn:aws:s3:::yourbucketname/*”

This will allow a http get request to our bucket, so that our app can retrieve the images we just uploaded. If we try and refresh our website again, we’ll get cats!

The image between the cat pictures are from a previously uploaded image to our local folder, and is not available in our S3 bucket. let’s try and upload that image to our S3 (you can find it in the local upload folder):

Sweet! Our image upload to S3 works.

That’s it for now.
Until next time!
Stephan Bakkelund Valois

One clap, two clap, three clap, forty?

By clapping more or less, you can signal to us which stories really stand out.