Getting started with Spring Boot and Docker
Tags: java, docker, webdev
Published: 2021-05-20 11:48:32

[Docker](https://docs.docker.com) is a container engine that makes it possible to bundle, ship, and distribute applications across distributed servers.
<!--more-->
### Prerequisites
1. Have [Java Development Kit 11](https://www.oracle.com/java/technologies/javase-jdk15-downloads.html/) or newer installed on your computer.
2. Make sure [Docker](https://docs.docker.com/docker-for-windows/install/) is installed on your computer.

To get started with Docker, visit [Getting started with Docker](/engineering-education/getting-started-with-docker/).

### Project setup
We will bundle and containerize the application that we created [here](/engineering-education/spring-boot-crud-api/). The application allowed us to perform CRUD functionalities on the Todo items via a REST API.

To check if `JDK` is installed and configured correctly on your computer, execute the command below.

```bash
$ java --version
java 15.0.2 2021-01-19
```

Execute the command below to create a working directory for the project.
```bash
$ mkdir todo
$ cd todo
```

In the directory created above, execute the command below to clone the project to your computer.

```bash
$ git clone https://github.com/paulodhiambo/springbootcrud.git
```

Execute the command below to move into the project folder.
```bash
$ cd springbootcrud
```

Run the application to verify if the project is correctly set up and the application runs without errors.
```bash
$ gradle build
```

The project structure is shown below.
```bash
└── springbootcrud         # < project root package
    ├── src
    │   ├── main
    │   ├── test
    ├── build.gradle
    ├── gradlew
    ├── Dockerfile # Dockerfile where we write all the container build instructions
    └── gradlew.bat    
    └── settings.gradle
```

### Creating a Dockerfile
A Dockerfile is a plain text file that contains instructions from which a Docker image is built. A Dockerfile contains the commands below.
- **FROM**: directive sets the image on which the container will be based on.
- **RUN**: executes commands in the container. 
- **COPY**: creates a copy of files from the file system in the container.
- **CMD**: sets the executable commands within the container.

Create a `Dockerfile` in the project's root folder.

Add the code snippets below to the `Dockerfile` created above.

```Docker
FROM openjdk:8-jdk-alpine
RUN addgroup -S springdocker && adduser -S springdocker -G springdocker
USER springdocker:springdocker
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
```

- `FROM openjdk:8-jdk-alpine` sets the base image from which the Docker container will be created.
- `RUN addgroup -S springdocker && adduser -S springdocker -G springdocker` add a user profile to the container.
- `USER springdocker:springdocker` sets the user in the container making it possible to execute commands in the container as an administrator.
- `ARG JAR_FILE=target/*.jar` sets the path to `jar` generated by `gradle build` command to `ARG_FILE` variable.
- `COPY  ${JAR_FILE} app.jar` copies the `jar` file created after running `gradle build` command to the `app.jar` file inside the docker container.
- `ENTRYPOINT ["java","-jar","/app.jar"]` indicates that the container has an executable file.

### Building the Docker image
To build a Docker image from the Dockerfile we have created above, execute the command below.

```bash
$ docker build --build-arg JAR_FILE=build/libs/\*.jar -t spring-boot-docker:latest .
```

- `--build-arg JAR_FILE=build/libs/\*.jar` sets the path to the `jar` file generated by running `gradle build` command.
- `-t` sets the tag for the image.
- `.` indicates that the `Dockerfile` is in the current directory.

Execute the command below to list all the Docker images available on your computer.
```bash
$ docker image ls
REPOSITORY    TAG            IMAGE ID       CREATED         SIZE
spring-boot-docker               latest              b7a1056c3eb2   31 minutes ago   143MB
springio/gs-spring-boot-docker   latest              b7a1056c3eb2   31 minutes ago   143MB
<none>                           <none>              4f8c8633df3e   2 days ago       105MB
latest                           latest              6c802830c996   4 weeks ago      414MB
```

From the list above, we see the `spring-boot-docker` image that we have created.

### Creating and running the Docker Container
Execute the command below to create a Docker container from the Docker image we have created above.

```bash
$ docker run --name spring-boot-docker -d -p 8080:8080 spring-boot-docker:latest
```

- `--name` flag sets the Docker container name.
- `-d` flag makes the image run in the background.
- `-p 8080:8080` maps port 8080 in the Docker container to port 8080 in localhost.
- `spring-boot-docker:latest` specifies the image from which the Docker container is built.

Execute the command below to list all the running Docker containers.
```bash
$ docker container ps
CONTAINER ID   IMAGE                   COMMAND                  CREATED       STATUS       PORTS                        NAMES
792fce534e3a   spring-boot-docker   "java -jar /app.jar"   31 minutes ago   Up 31 minutes   0.0.0.0:8080->8080/tcp   spring-boot-docker
```

1. Visit `localhost` on port 8080 to confirm if the `spring-boot-crud` application is running in the container.

![Docker Hub image](https://raw.githubusercontent.com/section-engineering-education/engineering-education/ff641cbb3e5d23703a46deb85fccd1c9360376dd/articles/spring-docker/docker_get.png)

### Pushing the Docker image to Docker Hub

![Docker Hub image](https://raw.githubusercontent.com/section-engineering-education/engineering-education/ff641cbb3e5d23703a46deb85fccd1c9360376dd/articles/spring-docker/docker_create.png)

Docker Hub is an online repository of Docker container images. Docker hub stores Docker containers and also makes it easier to share Docker images with other developers.

Create a Docker Hub account [here](https://hub.docker.com/) if you don't have one.

After creating an account, log in to Docker Hub, create a repository with the name `spring-boot-crud` and the description `Spring Boot Docker Image`.

Execute the command below to push the Docker image to the repository that we have created in the Docker Hub.

```bash
$ docker login
$ docker tag spring-boot-docker:latest <username>/spring-boot-docker:latest
$ docker push <username>/spring-boot-docker:latest
```

- The `docker login` command authenticates you into your Docker Hub account on the command line, making it possible to push Docker images to Docker Hub.
- `docker tag spring-boot-docker: latest <username>/spring-boot-docker: latest` this command modifies the tag of our local Docker image to include the Docker Hub username.
- `docker push <username>/spring-boot-docker: latest` pushes the image to Docker Hub repository we created earlier.

**Note:** Replace `<username>` with your actual Docker Hub username.

The source code to the application is in [this](https://github.com/paulodhiambo/springbootcrud/tree/spring-docker) GitHub repository.

### Conclusion
Docker is a great tool for building and packaging applications with the required dependencies to run them both locally and in production. [Docker playground](https://labs.play-with-docker.com/) is a browser-based environment that you can use to test various Docker commands without installing Docker locally on your computer.

Happy coding!