Gin practice nine deploying Golang applications to Docker

Source: Internet
Author: User
Tags docker ps docker run
This is a creation in Article, where the information may have evolved or changed.

Deploying Golang apps to Docker

Project Address: Https://github.com/EDDYCJY/go ... (Get in the car, support a wave)
Original address: Https://segmentfault.com/a/11 ...

Note:

    • You need to install docker and match the image source before you start.
    • This section of the source code on the f-20180324-docker branch
    • Start the project catalog from this section go-gin-example as a benchmark (please adapt yourself to your local project)

Introduced

Here's a brief introduction to Docker, which suggests deep learning

Docker is an open-source, lightweight container technology that allows developers to package their applications and apply the context of their run to a portable image and then publish them to any Docker-enabled system. With container technology, Docker provides an isolated operating environment for applications with virtually no performance overhead

    • Simplified configuration
    • Code Pipeline Management
    • Improve development efficiency
    • Isolated Applications
    • Fast, continuous deployment

We will then formally begin the docker process and preparation of the project, with each headline as a step outline

Golang

First, the preparation of Dockerfile

go-gin-exampleCreate a Dockerfile file in the project root directory, write content

FROM golang:latestWORKDIR $GOPATH/src/github.com/EDDYCJY/go-gin-exampleCOPY . $GOPATH/src/github.com/EDDYCJY/go-gin-exampleRUN go build .EXPOSE 8000ENTRYPOINT ["./go-gin-example"]

Role

golang:latestMirror as the underlying image, set the working directory to $GOPATH/src/go-gin-example , and copy the contents of the current context directory into the $GOPATH/src/go-gin-example

After the go build compilation is complete, set the container launcher to the ./go-gin-example executable file that we compiled

Note go-gin-example that docker compiling in the container does not compile on the host site.

Description

The Dockerfile file is a configuration file for defining the Docker image generation process, the file content is an instruction, each instruction is constructed one layer, so the content of each instruction is to describe how the layer should be constructed; These directives apply to the underlying image and eventually create a new image

You can think of to quickly create a custom Docker image

1. From

Specify the underlying image (required instruction, and must be the first instruction)

2, Workdir

Format is WORKDIR < working directory path >

You WORKDIR can use directives to specify the working directory (or the current directory), and the current directory for each layer is changed to the specified directory, and if the directory does not exist, it WORKDIR will help you set up the directory

3. COPY

Format:

COPY <源路径>... <目标路径>COPY ["<源路径1>",... "<目标路径>"]

COPYDirectives will be copied from the build context directory < source path > files/directories into a new layer of mirrors within the < destination path > location

4. RUN

Used to execute command-line commands

Format: RUN < command >

5, EXPOSE

Format EXPOSE < port 1> [< port 2> ...]

EXPOSEThe directive is to declare the runtime container to provide the service port, which is just a declaration that will not be applied to this port at runtime because the service is opened

There are two benefits to writing such a declaration in Dockerfile

    • Helps image users understand the daemon port of the mirroring service to facilitate configuration mapping
    • When the runtime uses random port mappings, that is docker run -P , when the port is automatically mapped randomly EXPOSE

6, EntryPoint

ENTRYPOINTIn the same format as the RUN instruction format, it is divided into two formats

    • execFormat:
<ENTRYPOINT> "<CMD>"
    • shellFormat:
ENTRYPOINT [ "curl", "-s", "http://ip.cn" ]

ENTRYPOINTInstruction is the specified container launcher and parameters

Second, build the image

go-gin-exampleThe project root directory is executed under thedocker build -t gin-blog-docker .

The command function is to create/build the image, -t specify the name gin-blog-docker , and . build the content as the current context directory

$ docker build -t gin-blog-docker .Sending build context to Docker daemon 96.39 MBStep 1/6 : FROM golang:latest ---> d632bbfe5767Step 2/6 : WORKDIR $GOPATH/src/github.com/EDDYCJY/go-gin-example ---> 56294f978c5dRemoving intermediate container e112997b995dStep 3/6 : COPY . $GOPATH/src/github.com/EDDYCJY/go-gin-example ---> 3b60960120cfRemoving intermediate container 63e310b3f60cStep 4/6 : RUN go build . ---> Running in 52648a431450 ---> 7bfbeb301feaRemoving intermediate container 52648a431450Step 5/6 : EXPOSE 8000 ---> Running in 98f5b387d1bb ---> b65bd4076c65Removing intermediate container 98f5b387d1bbStep 6/6 : ENTRYPOINT ./go-gin-example ---> Running in c4f6cdeb667b ---> d8a109c7697cRemoving intermediate container c4f6cdeb667bSuccessfully built d8a109c7697c

Third, verify the image

View all mirrors to determine gin-blog-docker if the image you just built is present

$ docker imagesREPOSITORY              TAG                 IMAGE ID            CREATED              SIZEgin-blog-docker         latest              d8a109c7697c        About a minute ago   946 MBdocker.io/golang        latest              d632bbfe5767        8 days ago           779 MB...

Iv. Creating and running a new container

Execute commanddocker run -p 8000:8000 gin-blog-docker

$ docker run -p 8000:8000 gin-blog-dockerdial tcp 127.0.0.1:3306: connect: connection refused[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production. - using env:    export GIN_MODE=release - using code:    gin.SetMode(gin.ReleaseMode)...Actual pid is 1

You think you're done with the operation?

You think too much, take a closer look at the console output an error dial tcp 127.0.0.1:3306: connect: connection refused

Let's try to find out what Mysql the problem is, and then the second we'll solve the problem.

Mysql

One, pull the mirror

DockerDownload the image from the public repository Dockerhub MySQL (domestic recommendation with a mirror)

$ docker pull mysql

Second, create and run a new container

Run Mysql the container and set the container ID to return after successful execution

$ docker run --name mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=rootroot -d mysql8c86ac986da4922492934b6fe074254c9165b8ee3e184d29865921b0fef29e64

Connect to Mysql

The initialization Mysql should

Golang + Mysql

First, remove the image

Because there is a problem with the original image, we need to delete it, here are a few ways

    • Remove the original problematic image and rebuild a new image
    • Rebuilding a different name , tag new image

Delete the original problematic image, which -f is forced to delete and its associated state

If you do not -f , you need to perform a docker ps -a check on the associated container to rm remove the dependencies

$ docker rmi -f gin-blog-dockerUntagged: gin-blog-docker:latestDeleted: sha256:d8a109c7697c3c2d9b4de7dbb49669d10106902122817b6467a031706bc52ab4Deleted: sha256:b65bd4076c65a3c24029ca4def3b3f37001ff7c9eca09e2590c4d29e1e23dce5Deleted: sha256:7bfbeb301fea9d8912a4b7c43e4bb8b69bdc57f0b416b372bfb6510e476a7deeDeleted: sha256:3b60960120cf619181c1762cdc1b8ce318b8c815e056659809252dd321bcb642Deleted: sha256:56294f978c5dfcfa4afa8ad033fd76b755b7ecb5237c6829550741a4d2ce10bc

Second, modify the configuration file

Change the project's configuration file conf/app.ini to

#debug or releaseRUN_MODE = debug[app]PAGE_SIZE = 10JWT_SECRET = 233[server]HTTP_PORT = 8000READ_TIMEOUT = 60WRITE_TIMEOUT = 60[database]TYPE = mysqlUSER = rootPASSWORD = rootrootHOST = mysql:3306NAME = blogTABLE_PREFIX = blog_

Iii. Rebuilding the image

Repeat the previous steps and go back to gin-blog the project root directory to executedocker build -t gin-blog-docker .

Iv. Creating and running a new container

Association

Q: We need to Golang correlate containers and Mysql containers, so what do we need to do?

A: Increase the command --link mysql:mysql to allow the Golang container to interconnect with the container, Mysql through --link , can be directly within the container using its associated container alias access , not through IP, but --link only to resolve the association between single-machine containers, in the case of distributed multi-machine, Need to connect in another way

Run

Execute commanddocker run --link mysql:mysql -p 8000:8000 gin-blog-docker

$ docker run --link mysql:mysql -p 8000:8000 gin-blog-docker[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production. - using env:    export GIN_MODE=release - using code:    gin.SetMode(gin.ReleaseMode)...Actual pid is 1

Results

Check the startup output, interface test, data in the database, all normal; our Golang containers and Mysql containers are successfully connected and running, and we're done:)

Review

Thinking

Although the application has been able to run up

But if there is a Golang Docker certain understanding, I hope you can think of at least 2 questions

    • Why do you gin-blog-docker occupy so much space? (available for docker ps -as | grep gin-blog-docker Viewing)
    • MysqlContainers are used directly, where are the data stored?

Create an ultra-small golang image

Q: The first question, why is this mirror size so large?

A: The FROM golang:latest official image is drawn, golang including the compilation and operating environment of Golang, plus a bunch of gcc, build tools, quite complete

This is problematic, we can not compile the site in the Golang container, we do not use those things at all, we only need an environment that can run the executable file

Building Scratch Mirrors

Scratch mirror, simple, compact, basic is an empty image

I. Modification of Dockerfile

FROM scratchWORKDIR $GOPATH/src/github.com/EDDYCJY/go-gin-exampleCOPY . $GOPATH/src/github.com/EDDYCJY/go-gin-exampleEXPOSE 8000CMD ["./go-gin-example"]

Second, compile the executable file

CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o go-gin-example .

The executable generated by the compilation relies on some libraries and is dynamically linked. In this case, because the scratch mirror is used, it is an empty image, so we need to make a static link to the generated executable that depends on the library

Third, build the image

$ docker build -t gin-blog-docker-scratch .Sending build context to Docker daemon 133.1 MBStep 1/5 : FROM scratch ---> Step 2/5 : WORKDIR $GOPATH/src/github.com/EDDYCJY/go-gin-example ---> Using cache ---> ee07e166a638Step 3/5 : COPY . $GOPATH/src/github.com/EDDYCJY/go-gin-example ---> 1489a0693d51Removing intermediate container e3e9efc0fe4dStep 4/5 : EXPOSE 8000 ---> Running in b5630de5544a ---> 6993e9f8c944Removing intermediate container b5630de5544aStep 5/5 : CMD ./go-gin-example ---> Running in eebc0d8628ae ---> 5310bebeb86aRemoving intermediate container eebc0d8628aeSuccessfully built 5310bebeb86a

Note that if your Golang application does not rely on any of the configuration files, it is possible to copy the executable file directly, and no other need to care

There are several solutions available here

    • Dependency File Unified Management Mount
    • Go-bindata, please.

...

So if you solve the problem of file dependencies , you don't need to put the directory COPY in.

Four, the operation

$ docker run --link mysql:mysql -p 8000:8000 gin-blog-docker-scratch[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production. - using env:    export GIN_MODE=release - using code:    gin.SetMode(gin.ReleaseMode)[GIN-debug] GET    /auth                     --> github.com/EDDYCJY/go-gin-example/routers/api.GetAuth (3 handlers)...

Run successfully, the program also receives requests normally

And then we'll look at the size, execute the docker ps -as command.

$ docker ps -asCONTAINER ID        IMAGE                     COMMAND                  ...         SIZE9ebdba5a8445        gin-blog-docker-scratch   "./go-gin-example"       ...     0 B (virtual 132 MB)427ee79e6857        gin-blog-docker           "./go-gin-example"       ...     0 B (virtual 946 MB)

From the result, take the size Scratch of a mirrored-based container to complete the goal

MySQL Mount data volume

Without any interference, the database is empty each time a container is started Mysql . In addition, after the deletion of the container, the data is lost (there are all kinds of unexpected cases), very bad!

Data volumes

A data volume is designed to persist data, its lifecycle is independent of the container, Docker does not automatically delete the data volume after the container is deleted, and there is no mechanism for garbage collection to handle data volumes that do not have any container references. If you need to remove the data volume while removing the container. You can use this command when you delete a container. docker rm -v

A data volume is a special directory that can be used by one or more containers, bypassing UFS and providing many useful features:

    • Data volumes can be shared and reused between containers
    • Changes to the data volume will take effect immediately
    • Updates to the data volume do not affect mirroring
    • The data volume is always present by default, even if the container is deleted
Note: The use of the data volume, similar to Linux under the directory or file mount, the image is designated as a mount point in the directory of the files will be hidden, can be displayed to see the mounted data volumes.

How to Mount

First, create a directory to hold the data volume; sample directory /data/docker-mysql , notice that --name mysql the container with the original name needs to be deleteddocker rm

$ docker run --name mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=rootroot -v /data/docker-mysql:/var/lib/mysql -d mysql54611dbcd62eca33fb320f3f624c7941f15697d998f40b24ee535a1acf93ae72

Create success, check the directory /data/docker-mysql , there are a lot of database files

Verify

Then you verify that the goal is to create some test tables and data, then delete the current container, re-create the container, and the database data will still exist (of course the data volume is pointing to the same)

I've verified it, what about you?

Reference

Sample code for this series

    • Go-gin-example

Books

    • docker--from getting started to practicing
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.