<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Beksultan Mamatkadyr uulu</title>
    <description>The latest articles on DEV Community by Beksultan Mamatkadyr uulu (@beksultandev).</description>
    <link>https://dev.to/beksultandev</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F858521%2F78317d27-9fb5-4bc3-a12d-c56678c4f731.jpg</url>
      <title>DEV Community: Beksultan Mamatkadyr uulu</title>
      <link>https://dev.to/beksultandev</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/beksultandev"/>
    <language>en</language>
    <item>
      <title>How to Add HTTPS Support to Your Spring Boot App?</title>
      <dc:creator>Beksultan Mamatkadyr uulu</dc:creator>
      <pubDate>Mon, 20 Nov 2023 16:21:12 +0000</pubDate>
      <link>https://dev.to/beksultandev/how-to-add-https-support-to-your-spring-boot-app-2h53</link>
      <guid>https://dev.to/beksultandev/how-to-add-https-support-to-your-spring-boot-app-2h53</guid>
      <description>&lt;h3&gt;
  
  
  Introduction
&lt;/h3&gt;

&lt;p&gt;In this post, we will walk through how to configure HTTPS in a Spring Boot application using self-signed certificates to encrypt connections and add transport layer security.&lt;/p&gt;

&lt;h3&gt;
  
  
  What You'll Need
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Docker&lt;/li&gt;
&lt;li&gt;Domain Name&lt;/li&gt;
&lt;li&gt;AWS EC2 Instance&lt;/li&gt;
&lt;li&gt;Java&lt;/li&gt;
&lt;li&gt;Spring Boot&lt;/li&gt;
&lt;li&gt;Code Editor&lt;/li&gt;
&lt;li&gt;Terminal Access&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What You Should Know
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Basic Docker commands like run, build, etc.&lt;/li&gt;
&lt;li&gt;How to create an A record in DNS.&lt;/li&gt;
&lt;li&gt;Spring Boot basics - creating a project, running with Gradle/Maven etc.&lt;/li&gt;
&lt;li&gt;Basic Linux commands like cd, ls, vim etc to navigate the terminal.&lt;/li&gt;
&lt;li&gt;How to launch an EC2 instance on AWS and connect via SSH.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Generate Certificates
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Why do we need certificates?&lt;/strong&gt;&lt;br&gt;
Certificates allow secure HTTPS connections. They contain public keys that encrypt data sent between a server and clients. This protects the data from spying. Certificates also validate that you are connected to the right server.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What we need to generate certificates?&lt;/strong&gt;&lt;br&gt;
To generate certificates, you need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A Docker installed server like an AWS EC2 instance&lt;/li&gt;
&lt;li&gt;The server's IP address connected to a domain name using DNS&lt;/li&gt;
&lt;li&gt;An 'A record' added to DNS to map the domain to the server's IP&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;How to generate certificates?&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Connect to server using ssh.&lt;/li&gt;
&lt;li&gt;Create a Docker volume called certs &lt;code&gt;docker volume create certs&lt;/code&gt;. We need volume to store certificates.&lt;/li&gt;
&lt;li&gt;Run this command below to get certificate and store it to volume certs.
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker run -d \
--name certbot \
-v certs:/etc/letsencrypt \
-v certs-data:/var/lib/letsencrypt \
-p 80:80 \
-p 443:443 \
certbot/certbot \
certonly --standalone --preferred-challenges http --email youremail@gmail.com -d yourdomain.com --agree-tos
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;blockquote&gt;
&lt;p&gt;Replace &lt;strong&gt;&lt;a href="mailto:youremail@gmail.com"&gt;youremail@gmail.com&lt;/a&gt;&lt;/strong&gt; and &lt;strong&gt;yourdomain.com&lt;/strong&gt; with your real email and domain before running certbot!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The Docker container will exit after generating the certificate. Check the container logs to see where the certificate files were saved.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jxRLtqgu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/241kolulg85mkwnx206m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jxRLtqgu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/241kolulg85mkwnx206m.png" alt="Image description" width="800" height="343"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Perfect we generated certificates and stored to docker volume certs and when we run our Spring Boot App it'll take certificates from volume.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;
  
  
  Configure Spring Boot for HTTPS
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Create a Spring Boot App&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Generate Spring Boot app using this link &lt;a href="https://start.spring.io/#!type=gradle-project&amp;amp;language=java&amp;amp;platformVersion=3.1.5&amp;amp;packaging=jar&amp;amp;jvmVersion=17&amp;amp;groupId=dev.beksultan&amp;amp;artifactId=spring-boot-https&amp;amp;name=spring-boot-https&amp;amp;description=Add%20HTTPS%20Support%20to%20Your%20Spring%20Boot%20App&amp;amp;packageName=https&amp;amp;dependencies=web"&gt;start.spring.io&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Add simple @GetMapping to check is our app working.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@SpringBootApplication
@RestController
public class SpringBootHttpsApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringBootHttpsApplication.class, args);
    }

    @GetMapping("/hello")
    public String hello() {
        return "Hello World! 🚀";
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Now go to application.properties and configure ssl.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;server.ssl.enabled=true
server.ssl.certificate=${FULLCHAINPEM}
server.ssl.certificate-private-key=${PRIVKEYPEM}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;If you're using .yml then use this configuration.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;server:
  ssl:
    enabled: true
    certificate: ${FULLCHAINPEM}
    certificate-private-key: ${PRIVKEYPEM}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Containerizing Spring Boot App&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To containerize your Spring Boot app, you need to create a Dockerfile. The Dockerfile tells Docker how to package your app. &lt;br&gt;
I used Gradle as package manager and my Dockerfile looks like below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FROM openjdk:20 as build
WORKDIR /app
COPY . ./
RUN microdnf install findutils
RUN ./gradlew build -x test

FROM openjdk:20-jdk-slim
WORKDIR /app
COPY --from=build /app/build/libs/spring-boot-https-0.0.1.jar .
CMD ["java", "-jar", "spring-boot-https-0.0.1.jar"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Build Docker Image and Push to &lt;a href="//hub.docker.com"&gt;Dockerhub&lt;/a&gt;&lt;/strong&gt;&lt;br&gt;
To build Docker Image, you need to execute this command&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker build -t spring-boot-https:1 .
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;When building Docker images on macOS to run on Linux, there can be platform compatibility issues. The image needs to target linux/amd64 to work properly on Ubuntu.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To build a compatible image, use the Docker buildx command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker buildx build --platform linux/amd64 -t spring-boot-https:1 .
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After building docker image push your image to your dockerhub using these commands&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker tag spring-boot-https:1 &amp;lt;Dockerhub Username&amp;gt;/spring-boot-https:1

docker push &amp;lt;Dockerhub Username&amp;gt;/spring-boot-https:1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;We used Dockerhub for Demo. You can use other registry like AWS ECR etc.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;After pushing image to Dockerhub we could use it on any server.&lt;/p&gt;

&lt;h3&gt;
  
  
  Run Spring Boot App on Server
&lt;/h3&gt;

&lt;p&gt;To run the Dockerized Spring Boot app, we can use Docker Compose. This defines how to run the container with a yaml config file.&lt;/p&gt;

&lt;p&gt;compose.yml&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;services:
  spring-boot-https:
    container_name: spring-boot-https
    image: beksultancs/spring-boot-https:1
    restart: unless-stopped
    ports:
      - "443:443"
    volumes:
      - certs:/certs
    environment:
      - SERVER_PORT=443
      - FULLCHAINPEM=/certs/live/hi.beksultan.dev/fullchain.pem
      - PRIVKEYPEM=/certs/live/hi.beksultan.dev/privkey.pem
volumes:
  certs:
    external: true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we need transfer compose.yml to server or we can create this file in server. If you wanted to create compose.yml locally and transfer to server you can use scp command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;scp -I &amp;lt;PrivateKey&amp;gt; compose.yml &amp;lt;Username&amp;gt;:&amp;lt;Host&amp;gt;:~/ 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or you can create file on server using &lt;strong&gt;vim&lt;/strong&gt; or &lt;strong&gt;nano&lt;/strong&gt; and copy paste it.&lt;/p&gt;

&lt;p&gt;Final step we should run our compose.yml using command&lt;br&gt;
&lt;code&gt;docker compose -f compose.yml up -d&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;That's all! Our app should run on our domain with https &lt;strong&gt;&lt;a href="https://yourdomain/hello"&gt;https://yourdomain/hello&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ygXTsXVf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/75x955memy02r1n4hx9b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ygXTsXVf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/75x955memy02r1n4hx9b.png" alt="Image description" width="732" height="388"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If you don't want to use docker compose, then u just need to execute this command on server&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker run -d \
  --name spring-boot-https \
  -p 443:443 \
  -v certs:/certs \
  -e SERVER_PORT=443 \ 
  -e FULLCHAINPEM=/certs/live/hi.beksultan.dev/fullchain.pem \
  -e PRIVKEYPEM=/certs/live/hi.beksultan.dev/privkey.pem \
  beksultancs/spring-boot-https:1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that's it! We have configured a Spring Boot application to use HTTPS with a self-signed certificate. The steps we covered were:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Generating a self-signed certificate using Certbot&lt;/li&gt;
&lt;li&gt;Adding the certificate files to a Docker volume&lt;/li&gt;
&lt;li&gt;Configuring the Spring Boot application properties for SSL&lt;/li&gt;
&lt;li&gt;Containerizing the app with a Dockerfile&lt;/li&gt;
&lt;li&gt;Running the Docker image on a server using docker-compose&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With these steps, your Spring Boot app can now serve content over HTTPS securely. The self-signed certificate allows encrypting connections without needing a certificate from a CA.&lt;/p&gt;

&lt;p&gt;I hope this tutorial was helpful! Let me know in the comments if you have any other questions on configuring Spring Boot for HTTPS. I'm planning to write a follow up post on how to add HTTPS to a React app with Nginx as a reverse proxy. So stay tuned!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/beksultancode/spring-boot-https.git"&gt;Github&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
