AWS ECR OR Docker Hub
Tags: docker, webdev, tutorial, node
Published: 2021-02-28 18:23:52

 Hey Dev's

How are the tutorials been coming along? I believe by now you can handle a whole project by yourself. In my previous tutorial, we discussed Docker, Node, and Vue [https://dev.to/kevin_odongo35/docker-node-and-vue-5e74](https://dev.to/kevin_odongo35/docker-node-and-vue-5e74).

In today's tutorial, we want to go further and discuss the production approach. In production, you wouldn't want to use the Mongo DB container or Redis container. Things will begin to change while going to production. My previous article will get you up and running during Development.

For production, the approach will change. Below was the stack we were working with:

1. Vue for front end
2. Node and Express for backend
3. Socker.io
4. Turn server
5. WebRTC
6. Redis for catching
7. MongoDB as your database
8. Turn server

In production, we can use MongoDB Atlas [https://www.mongodb.com/cloud/atlas](https://www.mongodb.com/cloud/atlas) and AWS ElastiCache (Redis or Memcached) [https://aws.amazon.com/elasticache/](https://aws.amazon.com/elasticache/). In essence, we just have to change the environment file which holds the URLs for Redis and MongoDB. Rebuild the image and push it to the Docker hub or AWS ECR.

Practical learning is always the best. The first step is to learn how to push your image to Docker Hub and AWS ECR. 

#### Brief description about Docker Hub and AWS ECR

*Amazon Elastic Container Registry (ECR) is a fully managed container registry that makes it easy to store, manage, share, and deploy your container images and artifacts anywhere.*

*Docker Hub is a service provided by Docker for finding and sharing container images with your team. It is the world’s largest repository of container images with an array of content sources including container community developers, open-source projects, and independent software vendors (ISV) building and distributing their code in containers.*

#### Pricing

With Amazon Elastic Container Registry, there are no upfront fees or commitments. You pay only for the amount of data you store in your public or private repositories and data transferred to the Internet. As part of the AWS Free Tier, new Amazon ECR customers get 500 MB-month of storage for one year for your private repositories. As a new or existing customer, Amazon ECR offers you 50 GB-month of always-free storage for your public repositories. Read more about ECR pricing [https://aws.amazon.com/ecr/pricing/](https://aws.amazon.com/ecr/pricing/).

Docker Hub charges between 0 USD to 7 USD. For public images generally, it is free for all subscriptions. Read more about Docker Hub pricing [https://aws.amazon.com/ecr/pricing/](https://aws.amazon.com/ecr/pricing/).

*For production you wouldn't want your images to be public*

Example
- Let us create a default Vue project:
 
```
vue create docker_tutorial_app
```
- Once your project is created run the following command

```
yarn run serve
// go to https://localhost:8080
```
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hdgfm9n47nq26qc9ckg4.png)

- Now that our application is running let us create the following files

```
// in the root of the vue folder create a Dockerfile
touch Dockerfile // assuming you have Linux on your computer.
touch Dockerfile.dev
touch Docker-compose.yml 
touch .dockerignore
```

We are going to have two Dockerfiles one for development and the other for production.

In Dockerfile.dev paste the following:

```javascript
# install node
FROM node:lts-alpine

# make the 'app' folder the current working directory
WORKDIR /app

# copy both 'package.json' and 'package-lock.json' (if available)
COPY package*.json ./

# install project dependencies
RUN yarn install

# copy project files and folders to the current working directory (i.e. 'app' folder)
COPY . .

# serve application in development
CMD [ "yarn", "serve" ]
```

In Dockerfile paste the following:

```javascript
# install node
FROM node:lts-alpine as build-stage

# make the 'app' folder the current working directory
WORKDIR /app

# copy both 'package.json' and 'package-lock.json' (if available)
COPY package*.json ./

# install project dependencies
RUN yarn install

# copy project files and folders to the current working directory (i.e. 'app' folder)
COPY . .

# build app for production with minification
RUN yarn run build

# production stage
# install nginx
FROM nginx:stable-alpine as production-stage

# copy dist directory that contains all of our files
COPY --from=build-stage /app/dist /usr/share/nginx/html

# expose port 80
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

```

In Docker-compose.yml paste the following:
#### NOTE
In the Docker-compose.yml file below we are only building our development dockerfile.

```javascript
version: "3.8"
services: 
  vue_docker_tutorial:
    container_name: vue_docker_tutorial
    build: 
      context: .
      dockerfile: Dockerfile.dev
    ports: 
      - 8080:8080
    volumes:
      - ./:/app
      - /app/node_modules
```

In your .dockerignore file copy all the contents in .gitignore

```
.DS_Store
node_modules
/dist

/tests/e2e/videos/
/tests/e2e/screenshots/


# local env files
.env.local
.env.*.local

# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*

# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
```

Here is our application structure.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k8uqs6zwinvf75b67nqn.png)

During development, all you have to do is run the following command.

```
Docker-compose up 
```

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6lnsisen5wqtanjzjhp5.png)

Your application will be up and running. There are several ways of running your test. I prefer the approach below in running your tests.

Once the application is running open a new terminal and run the following command to run all your tests.

```
docker exec -it vue_docker_tutorial yarn test:unit // unit test
docker exec -it vue_docker_tutorial yarn test:e2e // cypress test
```

To shut down all containers, use the following command.

```
Docker-compose down
```

When done with the development stage build your image for production. You can do this using the Docker-compose by changing the Dockerfile.dev to Dockerfile or running the command below.

```
Docker build -t vue_docker_tutorial .
Docker run -p 80:80 vue_docker_tutorial
// Your application will be running on port https:localhost:80
```

Now that we have an image of our application next step is to push it to Docker Hub or AWS ECR.

# Docker Hub
To push our image to Docker Hub log in [https://hub.docker.com/](https://hub.docker.com/)

- Run the following command

```
docker login
```

- Create a new repository:
*For this tutorial I created one called vue_docker_tutorial*

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2rme3l7fh5vgnxsuetsn.png)

Remember when we created our image we named it vue_docker_tutorial therefore we will need to rename it to kevinodongo/vue_docker_tutorial:tagname. 

**To push an image to Docker Hub, you must first name your local image using your Docker Hub username and the repository name that you created through Docker Hub on the web.**

To rename an image run the following command

```
docker tag vue_docker_tutorial kevinodongo/vue_docker_tutorial:version_1
```
Once we have renamed we can push our image to Docker Hub

```
docker push kevinodongo/vue_docker_tutorial:version_1
```

That is all we have to do to push your image to the Docker Hub. To test your image go to Docker playground [https://www.docker.com/play-with-docker](https://www.docker.com/play-with-docker)

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nbc99o14og00b6kn6yj8.png)

- Go to the lab environment
- Click Login
- Add Instance
- Run the following command

```
// replace with the image you just pushed
// your image should be successfully pulled.
docker pull kevinodongo/vue_docker_tutorial:version_1 
```
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ul6def3ljwyvf0679rci.png)


# AWS ECR

- Log into your AWS account if you don't have one create one here [https://portal.aws.amazon.com/billing/signup](https://portal.aws.amazon.com/billing/signup)

- Search for ECR product and click get started.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/icqixwjaod9cdtd5qrb0.png)

- Select public and add an alias for your repo. Other sections are optional you can create your repo.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/70cme629ivrn2g39jw2q.png)

- Click push commands. This will display how you need to push your image to AWS ECR. 
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/syum9e076op9kbuoabyn.png)

- Retrieve an authentication token and authenticate your Docker client to your registry.

```
aws ecr-public get-login-password --region us-east-1 | docker login --username AWS --password-stdin public.ecr.aws/<pQ45969> 
```

- Tag the image we had created previously

```
docker tag vue_docker_tutorial:latest public.ecr.aws/y0d6c0o4/vue_docker_tutorial:latest
```

- Run the following command to push this image to your newly created AWS repository:

```
docker push public.ecr.aws/y0d6c0o4/vue_docker_tutorial:latest
```

That is all we have to do to push the image to AWS ECR.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4i2slka12kwysqkseatb.png)


# CONCLUSION

In the first tutorial, we learned how to simplify learning Docker using two files. Just understand the following files Docker-compose.yml and Dockerfile. The rest of the commands will fall in place as you go along. In the real world, we can not master all commands but once we know what we want we can always reference Docker documentation.

Today we have gone a step further in knowing how to upload our images to Docker Hub and AWS ECR. We have also learned how to structure our Dockerfiles and Docker-compose. I have used a Vue project but the logic is the same with any project.

Assume you have applications with vue_frontend and node_backend. You will have a Dockerfile in vue_frontend directory and another in node_backend directory. But a single Docker-compose.yml file in the root of the directory. You will launch both vue_frontend and node_backend using the Docker-compose file.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7royr94qwldro08posg8.png)

At this stage assume all your images have been uploaded to Docker Hub or AWS ECR. Our next move will be deploying our application. Once the application is deployed we will need to manage all the containers deployed. How do we go about this?

This is where Kubernetes/AWS EKS and AWS ECS come along. They will assist us in managing our containers. In our next tutorial, we will deconstruct Kubernetes, AWS EKS, and AWS ECS.

What about AWS Fargate?

**AWS Fargate is a serverless compute engine for containers that work with both Amazon Elastic Container Service (ECS) and Amazon Elastic Kubernetes Service (EKS). Fargate makes it easy for you to focus on building your applications**

*The server-less world of Container!!!!*

Have a good week ahead of you and see you in the next tutorial.

Thank you.