No Result
View All Result
CloudReports
  • Home
  • Linux
  • Web development
  • Javascript
  • SQL
  • Ant Design tutorial
  • QR Code Scanner
  • Home
  • Linux
  • Web development
  • Javascript
  • SQL
  • Ant Design tutorial
  • QR Code Scanner
No Result
View All Result
CloudReports
No Result
View All Result
Home Linux

How to create a self-signed SSL certificate for Apache on Ubuntu 16.04

npn by npn
July 18, 2021
in Linux, Web development
Reading Time: 16 mins read
0
How to create a self-signed SSL certificate for Apache on Ubuntu 16.04
0
SHARES
1k
VIEWS
Share on FacebookShare on Twitter

Contents

  • 1 Introduction
    • 1.1 READ ALSO
    • 1.2 Ubuntu 22.04 versus 20.04 comparison
    • 1.3 Linux’s last command
    • 1.4 Preconditions
      • 1.4.1 Step 1 – Downloading the Go API Sample
      • 1.4.2 Step 2 – Build an Ubuntu Base Image
      • 1.4.3 Step 3 – Create a language-specific base image
      • 1.4.4 Step 4 – Build Basic Alpine Images
      • 1.4.5 Step 5 – Exclude build tools with a multistep build
  • 2 Conclusion
5/5 - (11 votes)

Introduction

In a production environment, Docker makes it easy to build, deploy, and run applications inside containers. Containers allow developers to bundle applications and all of their essential needs and dependencies into a single package that you can turn into a Docker image and replicate. Docker images are generated from Dockerfiles. The Dockerfile is a file in which you define the image, the base operating system it will have, and the commands to run.

READ ALSO

Ubuntu 22.04 versus 20.04 comparison

Ubuntu 22.04 versus 20.04 comparison

April 26, 2022
37.7k
Linux’s last command

Linux’s last command

April 26, 2022
635

Large Docker images can increase the time it takes to create and send images between clusters and cloud providers. If, for example, you have a gigabyte-sized image to apply every time one of your developers triggers a build, the throughput you create on your network builds up during the CI / CD process, makes your application slow and ultimately costs you resources. . For this reason, Docker images suitable for production should contain only the bare essentials.

There are several ways to reduce the size of Docker images in order to optimize production. First of all, these images usually don’t need any developer tools to run their apps, so it doesn’t need to add them at all. Using a multi-stage build process, you can use intermediate images to compile and generate the code, install dependencies, and integrate everything into the smallest size possible, then copy the final version of your app to an empty image without generation tools. Additionally, you can use an image with a tiny base, such as Alpine Linux. Alpine is a Linux distribution suitable for production because it only has the bare essentials for your application to function.

In this tutorial, you’ll optimize Docker images in a few simple steps, making them smaller, faster, and better suited for production. You’ll build images for a sample Go API in several different Docker containers, starting with Ubuntu and language-specific images, and then moving to Alpine. Distribution. You’ll also use multistage versions to optimize your images for production. The end goal of this tutorial is to show the difference in size between using default Ubuntu images and optimized counterparts, as well as showing the benefit of multi-stage builds. After reading this tutorial, you will be able to apply these techniques to your own CI / CD projects and pipelines.

Preconditions

Before you begin, you will need:

  • An Ubuntu 18.04 server with a non-root user account with privileges + sudo +. Follow our tutorial https://www.digitalocean.com/community/tutorials/initial-server-setup-with-ubuntu-18-04 for initial server setup with Ubuntu 18.04]. Although this tutorial has been tested on Ubuntu 18.04, you can follow most of the steps in any Linux distribution.
  • Docker installed on your server. Follow steps 1 and 2 of How to Install and Use Docker on Ubuntu 18.04 for installation instructions.

Step 1 – Downloading the Go API Sample

Before optimizing your Docker image, you must first download the sample API from which you will build your Docker images. Using a simple Go API will walk you through all the key steps in building and running an app in a Docker container. This tutorial uses Go because it is a compiled language such as C ++ or Java, but unlike them has a very small footprint.

On your server, start by cloning the example Go API:

git clone https://github.com/do-community/mux-go-api.git

Once the project is cloned, you will have a named directory + mux-go-api w on your server. Move into this directory with + cd +:

cd mux-go-api

This will be the base directory for your project. You will build your Docker images from this directory. Inside you’ll find the source code for an API written with Go in the file + api.go +. While this API is minimal and has only a few endpoints, it will be fine to simulate a production-ready API for the purposes of this tutorial.

Now that you’ve downloaded the sample Go API, you’re ready to build an Ubuntu Docker base image, against which you can compare the most recent optimized Docker images.

Step 2 – Build an Ubuntu Base Image

For your first Docker image, it will be helpful to see what it looks like when you start with an Ubuntu base image. This will condition your sample API in an environment similar to the software you are already running on your Ubuntu server. In the image, you will install the various packages and modules required to run your application. You will find, however, that this process creates a rather heavy Ubuntu image which will affect the build time and code readability of your Docker file.

Start by writing a Docker file that tells Docker to build an Ubuntu image, install Go, and run the sample API. Make sure to create the Docker file in the directory of the cloned repository. If you cloned to the home directory, it should be “+ $HOME/mux-go-api“.

Create a new file named + Dockerfile.ubuntu. Open it in + nano +or in your favorite text editor:

nano ~/mux-go-api/Dockerfile.ubuntu

In this Docker file, you define an Ubuntu image and install Golang. Next, you will install the necessary dependencies and build the binary. Add the following content to + ​​Dockerfile.ubuntu:

~/mux-go-api/Dockerfile.ubuntu

FROM ubuntu:18.04

RUN apt-get update -y \
 && apt-get install -y git gcc make golang-

ENV GOROOT /usr/lib/go-
ENV PATH $GOROOT/bin:$PATH
ENV GOPATH /root/go
ENV APIPATH /root/go/src/api

WORKDIR $APIPATH
COPY . .

RUN \
 go get -d -v \
 && go install -v \
 && go build

EXPOSE 3000
CMD ["./api"]

Starting at the top, the command + FROM +specifies the base operating system for the image. Then, the command + RUN +installs the Go language when creating the image. + ENV +sets specific environment variables that the Go compiler needs to function properly. + WORKDIR +specifies the directory we want to copy the code to, and the command + COPY +takes the code from the directory where it is located + Dockerfile.ubuntu +and copies it to the image. The last command + RUNinstalls the dependencies necessary for the source code to compile and run the API.

Save and exit the file. You can now run the command + build +to create a Docker image from the Docker file you just created:

docker build -f Dockerfile.ubuntu -t ubuntu .

The command + build +builds an image from a Docker file. The flag + -f +indicates that you want to build from the file + Dockerfile.ubuntu +, while + -t +means tag, which means that you are tagging it with the name + ubuntu +. The last point represents the current context where is located + Dockerfile.ubuntu +.

It will take a while, so feel free to take a break. Once the build is complete, you will have an Ubuntu image ready to run your API. But the final image size might not be ideal; anything over a few hundred MB for this API would be considered too large an image.

Run the following command to list all Docker images and find your Ubuntu image size:

docker images

The output displays the image you just created:

OutputREPOSITORY  TAG     IMAGE ID        CREATED         SIZE
ubuntu      latest  61b2096f6871    33 seconds ago
. . .

As shown in the output, this image has a size of * 636MB * for a basic Golang API, a number that may vary slightly from machine to machine. On several versions, this large size will significantly affect deployment times and network throughput.

In this section, you’ve built an Ubuntu image with all the necessary Go tools and dependencies to run the API cloned in step 1. In the next section, you’ll use a predefined, language-specific Docker image for simplicity. your Docker file and streamline the build process.

Step 3 – Create a language-specific base image

Preset images are ordinary base images that users have edited to include tools specific to the situation. Users can then upload these images to the Docker Hub image repository, allowing other users to use the shared image instead of having to write their own Dockerfiles. This is a common process in a production situation. You can find various pre-built images on Docker Hub for almost any use case. In this step, you’ll build your sample API using a Go-specific image that has the compiler and dependencies already installed.

With predefined base images already containing the tools you need to build and run your application, you can significantly reduce build time. Since you are starting with a base that has all the necessary tools preinstalled on it, you can skip adding them to your Docker file, making it look a lot cleaner and ultimately reduce compilation time.

Go ahead and create another Docker file and name it + Dockerfile.golang +. Open it in your text editor:

nano ~/mux-go-api/Dockerfile.golang

This file will be much more concise than the previous one as it has all of the Go-specific dependencies, tools, and compilers preinstalled.

Now add the following lines:

~/mux-go-api/Dockerfile.golang

FROM golang:

WORKDIR /go/src/api
COPY . .

RUN \
   go get -d -v \
   && go install -v \
   && go build

EXPOSE 3000
CMD ["./api"]

Starting at the top, you will find that the instruction + FROM +is now + golang: +. This means that Docker will grab a pre-built Go image from Docker Hub that has all the necessary Go tools already installed.

Now again build the Docker image with:

docker build -f Dockerfile.golang -t golang .

Check the final image size with the following command:

docker images

This will give a result similar to this:

OutputREPOSITORY  TAG     IMAGE ID        CREATED         SIZE
golang      latest  eaee5f524da2    40 seconds ago
. . .

While the Docker file itself is more efficient and the build time is shorter, the overall image size has actually increased. The preset Golang image is around 744MB *, which is quite a bit.

This is the preferred way to create Docker images. It gives you a base image that the community has approved as a standard to use for the specified language, in this case, Go. However, to prepare an image for production, you need to remove unnecessary elements from the application by running.

Remember, using these large images is okay when you are unsure of your needs. Feel free to use them both as disposable containers and as a base for creating other images. For development or testing purposes, when you don’t need to consider sending images over the network, you can use large images perfectly. But if you want to optimize deployments, you need to do your best to make your images as small as possible.

Now that you’ve tested a language-specific image, you can move on to the next step, which is to use the Alpine Linux lightweight distribution as the base image to lighten your Docker image.

Step 4 – Build Basic Alpine Images

One of the easiest steps to optimize your Docker images is to use smaller base images. Alpine is a lightweight Linux distribution designed for security and resource efficiency. The Alpine Docker image uses musl libc and BusyBox to keep it compact, requiring no more than 8MB in a container to run. . The small size is due to the fact that the binary packages have been upgraded and split, giving you more control over what you install, helping to keep the environment as small and efficient as possible.

The process of creating an Alpine image is similar to creating the Ubuntu image in step 2. First, create a new file named + Dockerfile.alpine +:

nano ~/mux-go-api/Dockerfile.alpine

Now add this snippet:

~/mux-go-api/Dockerfile.alpine

FROM alpine:

RUN apk add --no-cache \
   ca-certificates \
   git \
   gcc \
   musl-dev \
   openssl \
   go

ENV GOPATH /go
ENV PATH $GOPATH/bin:/usr/local/go/bin:$PATH
ENV APIPATH $GOPATH/src/api
RUN mkdir -p "$GOPATH/src" "$GOPATH/bin" "$APIPATH" && chmod -R 777 "$GOPATH"

WORKDIR $APIPATH
COPY . .

RUN \
   go get -d -v \
   && go install -v \
   && go build

EXPOSE 3000
CMD ["./api"]

Here you add the command + apk add +to use Alpine’s package manager to install Go and all the libraries it needs. As with the Ubuntu image, you also need to set the environment variables.

Go ahead and build the image:

docker build -f Dockerfile.alpine -t alpine .

Again, check the size of the image:

docker images

You will receive output similar to this:

OutputREPOSITORY  TAG     IMAGE ID        CREATED         SIZE
alpine      latest  ee35a601158d    30 seconds ago
. . .

The size has come down to around * 426MB *.

The small size of the Alpine base image reduced the size of the final image, but you can do a few more operations to reduce it further.

Then try to use a pre-built Alpine image for Go. This will shorten the Dockerfile and also reduce the size of the final image. Since the pre-built Alpine image for Go is built with Go compiled from the source, its footprint is significantly reduced.

Start by creating a new file called ++:

nano ~/mux-go-api/Dockerfile.golang-alpine

Add the following content to the file:

~/mux-go-api/Dockerfile.golang-alpine

FROM golang:

RUN apk add --no-cache --update git

WORKDIR /go/src/api
COPY . .

RUN go get -d -v \
 && go install -v \
 && go build

EXPOSE 3000
CMD ["./api"]

The only differences between + Dockerfile.golang-alpine +and + + Dockerfile.alpine +are the order + FROM +and the first order + RUN +. Now the command + FROM +specifies an image + golang +with the tag ++, and + RUN +only has a Git install command. You need Git for the command to + go get`work in the second au bas de` + RUN + + Dockerfile.golang-alpine` command.

Build the image with the following command:

docker build -f Dockerfile.golang-alpine -t golang-alpine .

Get your list of images:

docker images

You will receive the following output:

OutputREPOSITORY      TAG     IMAGE ID        CREATED         SIZE
golang-alpine   latest  97103a8b912b    49 seconds ago

Now the image size is reduced to approximately * 288MB *.

Although you have managed to reduce the size considerably, there is one more thing you need to do to get the image ready for production. This is called a multi-stage construction. By using multistage versions, you can use one image to build the application, while using another, lighter image to package the compiled application for production, a process you will perform in the next step.

Step 5 – Exclude build tools with a multistep build

Ideally, the images you run in production should not have a build tool or redundant dependencies for running the production application. You can remove them from the final Docker image using multi-step builds. It works by building the binary, or in other words, the compiled Go app, in an intermediate container, and then copying it to an empty container that doesn’t have any unnecessary dependencies.

Start by creating another file called ++:

nano ~/mux-go-api/Dockerfile.multistage

What you will add here will be familiar to you. Start by adding the exact same code as with + Dockerfile.golang-alpine +. But this time also add a second image to which you will copy the binary from the first image.

~/mux-go-api/Dockerfile.multistage

ADVERTISEMENT
FROM golang:1.10-alpine3.8

RUN apk add --no-cache --update git

WORKDIR /go/src/api
COPY . .

RUN go get -d -v \
 && go install -v \
 && go build

##

FROM alpine:3.8
COPY  /go/bin/api /go/bin/
EXPOSE 3000
CMD ["/go/bin/api"]

Save and close the file. Here you have two commands + FROM +. The first is identical to + ​​Dockerfile.golang-alpine +, except for the presence of an + AS à plusieurs étages +in the command + FROM +. This will give it the name + multiétage +, which you will then reference at the bottom of the file + Dockerfile.multistage +. In the second command + FROM, you will use an `alpine ‘image de base et + + COPY +on the Go app compiled from the image + multiétage. This process will further reduce the size of the final image, thus preparing it for production.

Run the build with the following command:

docker build -f Dockerfile.multistage -t prod .

Check the image size now, after using a multi-step build.

docker images

You will find two new images instead of just one:

OutputREPOSITORY      TAG     IMAGE ID        CREATED         SIZE
prod            latest  82fc005abc40    38 seconds ago
<none>          <none>  d7855c8f8280    38 seconds ago
. . .

The image + <none> +is the image + plusieurs étages +built with the command + FROM golang: 1.10-alpine3.8 +. It is only an intermediary used to build and compile the Go application, while the image + prod +in this context is the final image which only contains the compiled Go application.

Starting at 744MB *, you have now reduced the image size to approximately * 11.3MB *. Keeping track of an image as small as this and sending it over the network to your production servers will be much easier than with an image larger than 700MB and will save you significant resources in the long run. term.

Conclusion

In this tutorial, you optimized Docker images for production by using different base Docker images and an intermediate image to compile and generate the code. That way, you’ve packaged your sample API in the smallest size possible. You can use these techniques to improve the speed of building and deploying your Docker applications and any CI / CD pipelines you may have.

ShareTweetShare
Previous Post

Keeping cash at home, a phenomenon that is growing in France

Next Post

How does Nodejs solve the problem of high concurrency?

npn

npn

Related Posts

Ubuntu 22.04 versus 20.04 comparison
Linux

Ubuntu 22.04 versus 20.04 comparison

April 26, 2022
37.7k
Linux’s last command
Linux

Linux’s last command

April 26, 2022
635
What is the location of the MySQL databases?
Linux

What is the location of the MySQL databases?

April 24, 2022
598
How to find the Linux file creation date?
Linux

How to find the Linux file creation date?

April 24, 2022
770
Top 10 Best WordPress SEO themes of 2022
Web development

Top 10 Best WordPress SEO themes of 2022

March 16, 2022
492
Gmail – Gmail Sign Up – Gmail Login
Web development

Gmail – Gmail Sign Up – Gmail Login

August 30, 2021
7.1k
Next Post
How does Nodejs solve the problem of high concurrency?

How does Nodejs solve the problem of high concurrency?

Discussion about this post

No Result
View All Result

Categories

  • Android (1)
  • Ant Design tutorial (7)
  • App/Game (2)
  • Javascript (16)
  • Layout and Routing (2)
  • Linux (9)
  • PC & LAPTOP (6)
  • PERSONAL FINANCES (1)
  • React (13)
  • SQL (2)
  • TECHNOLOGY & DIGITAL (7)
  • The Basics (5)
  • Web development (37)

Search

No Result
View All Result

Categories

  • Android (1)
  • Ant Design tutorial (7)
  • App/Game (2)
  • Javascript (16)
  • Layout and Routing (2)
  • Linux (9)
  • PC & LAPTOP (6)
  • PERSONAL FINANCES (1)
  • React (13)
  • SQL (2)
  • TECHNOLOGY & DIGITAL (7)
  • The Basics (5)
  • Web development (37)
No Result
View All Result
  • Home
  • Linux
  • Web development
  • Javascript
  • SQL
  • Ant Design tutorial
  • QR Code Scanner