Deploying Gin (Go web framework) application with Docker
Tags: go, docker
Published: 2020-05-05 14:22:12

The importance of Docker cannot be over emphasized as it helps accelerate developer on-boarding and also ensures environment consistency.

Deploying gin application with Docker might be tricky. This article has two sections. These include:

1. Hooking volume to Gin source code in docker

2. Building a docker image for Gin application using Dockerfile

**N.B** : You must have golang set up on your machine.

#### Hooking volume to Gin source code in docker
[Volumes](https://docs.docker.com/storage/volumes/) are the preferred mechanism for persisting data generated by and used by Docker containers. 

Volumes are often a better choice than persisting data in a container's writable layer, because a volume does not increase the size of the containers using it, and the volume's contents exist outside the lifecycle of a given container. Thus, a volume can be shared between multiple containers

We will be working with this sample [repository](https://github.com/zeedt/go-docker-dev.to). Clone this repository to your $GOPATH on your local machine.

To dockerize Go application, you need golang docker image to achieve this. You can pull the golang image from docker hub using the command below:

```
docker pull golang
```  

Navigate to your $GOPATH where you cloned the repository. Then run this command:

```
docker run -d -p 3005:3004 -v $(pwd):/go/src -w "/go/src/go-docker-dev.to" golang go run go-docker-dev.to/src/app
```

The above command creates and starts a container from golang image. 

**-v $(pwd):/go/src** mounts the files/directories on your current working directory to **/go/src** which is the $GOPATH in the container.

**go run go-docker-dev.to/src/app** runs the go application.

**-p 3005:3004** binds the exposed port 3004 to docker host on port 3005

**-w "/go/src/go-docker-dev.to"** specifies the working directory in the container

You can use docker ps -a to check the status of the created container. It should be up.

![image] (https://res.cloudinary.com/zeed/image/upload/v1588538850/Screen_Shot_2020-05-03_at_9.42.53_PM.png)

Once the container status has been confirmed to be up, launch http://localhost:3005 on your browser. 

![image](https://res.cloudinary.com/zeed/image/upload/v1588539341/Screen_Shot_2020-05-03_at_9.53.54_PM.png)

### Building a docker image for Gin application using Dockerfile
In this section, we will create a custom docker image which will use the golang docker image from docker hub as the base image. To create this, create a Dockerfile in the project directory. 

It is advisable to copy all the necessary go dependencies that are used in the project to a sub-directory in the project directory. This is to save time that will be used to install the dependencies when creating the image.

For the purpose of this article, we will be copying the dependencies required for this project from $GOPATH/src to a sub directory (dependencies) in the project directory.

See the sample Dockerfile below:

```
FROM golang:alpine

MAINTAINER Maintainer

ENV GIN_MODE=release
ENV PORT=3004

WORKDIR /go/src/go-docker-dev.to

COPY src /go/src/go-docker-dev.to/src
COPY templates /go/src/go-docker-dev.to/templates

# Run the two commands below to install git and dependencies for the project. 
# RUN apk update && apk add --no-cache git
# RUN go get ./...

COPY dependencies /go/src #if you don't want to pull dependencies from git 

RUN go build go-docker-dev.to/src/app

EXPOSE $PORT

ENTRYPOINT ["./app"]

```

**FROM golang:alpine** indicates the base image to use which is golang

 
**MAINTAINER Maintainer** specifies the maintainer of the application. It could be name, username or email address.

**ENV GIN_MODE=release** sets the GIN_MODE environment variable

**ENV PORT=3004** sets the port environment variable

**WORKDIR /go/src/go-docker-dev.to** sets the container working directory

**COPY src /go/src/go-docker-dev.to/src** copies the src directory from the host to the image

**COPY templates /go/src/go-docker-dev.to/templates** copies the templates directory from the host to the image

**RUN apk update && apk add --no-cache git** This installs git in the environment as git is required to pull go dependencies

**RUN go get ./...** This recursively pulls the go dependencies required.

**COPY dependencies /go/src** copies the dependencies required to the $GOPATH of the image

**RUN go build go-docker-dev.to/src/app** This builds the application.

**EXPOSE $PORT** This expose the container port to the host machine

**ENTRYPOINT ["./app"]** This defines the entry point to the application when the container is started. It executes the go application.

From the project directory, execute the command below:

```
docker build -t go-docker-dev.to-gin  .
```

You will see the log of the build as shown below

![image](https://res.cloudinary.com/zeed/image/upload/v1588688089/Screen_Shot_2020-05-05_at_3.12.34_PM.png)

Once the image has been successfully created, you can initiate a container  to run the application using the command below:

```
docker run -d -p 3006:3004 go-docker-dev.to-gin
```
You can then launch localhost:3006 on your browser to confirm it is up and running.

![image](https://res.cloudinary.com/zeed/image/upload/v1588542588/Screen_Shot_2020-05-03_at_10.49.27_PM.png)