├── .gitignore
├── LICENSE
├── README.md
├── app
├── .gitignore
├── Dockerfile
├── LICENSE
├── pom.xml
└── src
│ └── main
│ ├── java
│ └── com
│ │ └── hellokoding
│ │ └── account
│ │ ├── WebApplication.java
│ │ ├── model
│ │ ├── MailProperties.java
│ │ ├── User.java
│ │ ├── VerificationForm.java
│ │ └── VerificationToken.java
│ │ ├── repository
│ │ ├── UserRepository.java
│ │ └── VerificationTokenRepository.java
│ │ ├── service
│ │ ├── SendingMailService.java
│ │ └── VerificationTokenService.java
│ │ └── web
│ │ └── AccountController.java
│ └── resources
│ ├── application.properties
│ ├── static
│ ├── css
│ │ └── main.css
│ └── js
│ │ └── main.js
│ └── templates
│ ├── email-verification.ftl
│ └── verification-form.ftl
├── docker-compose.yaml
└── nginx
└── conf.d
└── app.conf
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea
2 | target
3 | *.iml
4 | out
5 | .DS_Store
6 | data
7 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 Hello Koding
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # [Email Verification Example with Spring Boot, MySQL, Docker Compose, Amazon SES](https://hellokoding.com/email-verification-example-with-spring-boot-mysql-docker-compose/)
2 |
3 | ## What you'll need
4 | - Docker CE
5 | - Amazon SES account
6 | - SMTP Credentials of your Amazon SES account
7 | - Verified From email and To email on SES console
8 |
9 | ## Stack
10 | - Docker
11 | - Spring Boot
12 | - Java Mail API
13 | - Spring Data JPA
14 | - MySQL
15 | - NGINX
16 | - Maven
17 |
18 | ## Run
19 | - Run command `docker-compose up`
20 | - Access to http://localhost/
21 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | .idea
2 | target
3 | *.iml
4 | out
5 | .DS_Store
6 |
--------------------------------------------------------------------------------
/app/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM maven:3.5-jdk-8
2 |
--------------------------------------------------------------------------------
/app/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 Hello Koding
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/app/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 4.0.0
4 | com.hellokoding
5 | email-verification-springboot-mysql-dockercompose
6 | email-verification-springboot-mysql-dockercompose
7 |
8 | org.springframework.boot
9 | spring-boot-starter-parent
10 | 1.5.9.RELEASE
11 |
12 |
13 |
14 | 1.8
15 |
16 |
17 |
18 |
19 | org.springframework.boot
20 | spring-boot-starter-freemarker
21 |
22 |
23 | org.springframework.boot
24 | spring-boot-starter-data-jpa
25 |
26 |
27 | mysql
28 | mysql-connector-java
29 |
30 |
31 | org.hibernate
32 | hibernate-java8
33 |
34 |
35 | com.sun.mail
36 | javax.mail
37 | 1.6.0
38 |
39 |
40 |
41 |
42 |
43 | org.springframework.boot
44 | spring-boot-maven-plugin
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/app/src/main/java/com/hellokoding/account/WebApplication.java:
--------------------------------------------------------------------------------
1 | package com.hellokoding.account;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 |
6 | @SpringBootApplication
7 | public class WebApplication {
8 | public static void main(String[] args) throws Exception {
9 | SpringApplication.run(WebApplication.class, args);
10 | }
11 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/hellokoding/account/model/MailProperties.java:
--------------------------------------------------------------------------------
1 | package com.hellokoding.account.model;
2 |
3 | import org.springframework.boot.context.properties.ConfigurationProperties;
4 | import org.springframework.stereotype.Component;
5 |
6 | @Component
7 | @ConfigurationProperties(prefix = "mail")
8 | public class MailProperties {
9 | public static class SMTP {
10 | String host;
11 | String port;
12 | String username;
13 | String password;
14 |
15 | public String getHost() {
16 | return host;
17 | }
18 |
19 | public void setHost(String host) {
20 | this.host = host;
21 | }
22 |
23 | public String getPort() {
24 | return port;
25 | }
26 |
27 | public void setPort(String port) {
28 | this.port = port;
29 | }
30 |
31 | public String getUsername() {
32 | return username;
33 | }
34 |
35 | public void setUsername(String username) {
36 | this.username = username;
37 | }
38 |
39 | public String getPassword() {
40 | return password;
41 | }
42 |
43 | public void setPassword(String password) {
44 | this.password = password;
45 | }
46 | }
47 |
48 | private SMTP smtp;
49 | private String from;
50 | private String fromName;
51 | private String verificationapi;
52 |
53 | public SMTP getSmtp() {
54 | return smtp;
55 | }
56 |
57 | public void setSmtp(SMTP smtp) {
58 | this.smtp = smtp;
59 | }
60 |
61 | public String getFrom() {
62 | return from;
63 | }
64 |
65 | public void setFrom(String from) {
66 | this.from = from;
67 | }
68 |
69 | public String getFromName() {
70 | return fromName;
71 | }
72 |
73 | public void setFromName(String fromName) {
74 | this.fromName = fromName;
75 | }
76 |
77 | public String getVerificationapi() {
78 | return verificationapi;
79 | }
80 |
81 | public void setVerificationapi(String verificationapi) {
82 | this.verificationapi = verificationapi;
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/app/src/main/java/com/hellokoding/account/model/User.java:
--------------------------------------------------------------------------------
1 | package com.hellokoding.account.model;
2 |
3 | import javax.persistence.*;
4 |
5 | @Entity
6 | public class User {
7 | private Long id;
8 | private String email;
9 | private Boolean isActive;
10 | private VerificationToken verificationToken;
11 |
12 | @Id
13 | @GeneratedValue(strategy = GenerationType.AUTO)
14 | public Long getId() {
15 | return id;
16 | }
17 |
18 | public void setId(Long id) {
19 | this.id = id;
20 | }
21 |
22 | public String getEmail() {
23 | return email;
24 | }
25 |
26 | public void setEmail(String email) {
27 | this.email = email;
28 | }
29 |
30 | public Boolean getIsActive() {
31 | return isActive;
32 | }
33 |
34 | public void setIsActive(Boolean isActive) {
35 | this.isActive = isActive;
36 | }
37 |
38 | @OneToOne(mappedBy = "user", cascade = CascadeType.ALL)
39 | public VerificationToken getVerificationToken() {
40 | return verificationToken;
41 | }
42 |
43 | public void setVerificationToken(VerificationToken verificationToken) {
44 | this.verificationToken = verificationToken;
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/app/src/main/java/com/hellokoding/account/model/VerificationForm.java:
--------------------------------------------------------------------------------
1 | package com.hellokoding.account.model;
2 |
3 | import org.hibernate.validator.constraints.Email;
4 | import org.hibernate.validator.constraints.NotEmpty;
5 |
6 | public class VerificationForm {
7 | @NotEmpty
8 | @Email
9 | private String email;
10 |
11 | public String getEmail() {
12 | return email;
13 | }
14 |
15 | public void setEmail(String email) {
16 | this.email = email;
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/app/src/main/java/com/hellokoding/account/model/VerificationToken.java:
--------------------------------------------------------------------------------
1 | package com.hellokoding.account.model;
2 |
3 | import javax.persistence.*;
4 | import java.time.LocalDateTime;
5 | import java.util.UUID;
6 |
7 | @Entity
8 | public class VerificationToken {
9 | public static final String STATUS_PENDING = "PENDING";
10 | public static final String STATUS_VERIFIED = "VERIFIED";
11 |
12 | private Long id;
13 | private String token;
14 | private String status;
15 | private LocalDateTime expiredDateTime;
16 | private LocalDateTime issuedDateTime;
17 | private LocalDateTime confirmedDateTime;
18 | private User user;
19 |
20 | public VerificationToken(){
21 | this.token = UUID.randomUUID().toString();
22 | this.issuedDateTime = LocalDateTime.now();
23 | this.expiredDateTime = this.issuedDateTime.plusDays(1);
24 | this.status = STATUS_PENDING;
25 | }
26 |
27 | @Id
28 | @GeneratedValue(strategy = GenerationType.AUTO)
29 | public Long getId() {
30 | return id;
31 | }
32 |
33 | public void setId(Long id) {
34 | this.id = id;
35 | }
36 |
37 | public String getToken() {
38 | return token;
39 | }
40 |
41 | public void setToken(String token) {
42 | this.token = token;
43 | }
44 |
45 | public String getStatus() {
46 | return status;
47 | }
48 |
49 | public void setStatus(String status) {
50 | this.status = status;
51 | }
52 |
53 | public LocalDateTime getExpiredDateTime() {
54 | return expiredDateTime;
55 | }
56 |
57 | public void setExpiredDateTime(LocalDateTime expiredDateTime) {
58 | this.expiredDateTime = expiredDateTime;
59 | }
60 |
61 | public LocalDateTime getIssuedDateTime() {
62 | return issuedDateTime;
63 | }
64 |
65 | public void setIssuedDateTime(LocalDateTime issuedDateTime) {
66 | this.issuedDateTime = issuedDateTime;
67 | }
68 |
69 | public LocalDateTime getConfirmedDateTime() {
70 | return confirmedDateTime;
71 | }
72 |
73 | public void setConfirmedDateTime(LocalDateTime confirmedDateTime) {
74 | this.confirmedDateTime = confirmedDateTime;
75 | }
76 |
77 | @OneToOne(cascade = CascadeType.ALL)
78 | @JoinColumn(name = "user_id")
79 | public User getUser() {
80 | return user;
81 | }
82 |
83 | public void setUser(User user) {
84 | this.user = user;
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/app/src/main/java/com/hellokoding/account/repository/UserRepository.java:
--------------------------------------------------------------------------------
1 | package com.hellokoding.account.repository;
2 |
3 | import com.hellokoding.account.model.User;
4 | import org.springframework.data.jpa.repository.JpaRepository;
5 |
6 | import java.util.List;
7 |
8 | public interface UserRepository extends JpaRepository {
9 | List findByEmail(String email);
10 | }
11 |
--------------------------------------------------------------------------------
/app/src/main/java/com/hellokoding/account/repository/VerificationTokenRepository.java:
--------------------------------------------------------------------------------
1 | package com.hellokoding.account.repository;
2 |
3 | import com.hellokoding.account.model.VerificationToken;
4 | import org.springframework.data.jpa.repository.JpaRepository;
5 |
6 | import java.util.List;
7 |
8 | public interface VerificationTokenRepository extends JpaRepository {
9 | List findByUserEmail(String email);
10 | List findByToken(String token);
11 | }
12 |
--------------------------------------------------------------------------------
/app/src/main/java/com/hellokoding/account/service/SendingMailService.java:
--------------------------------------------------------------------------------
1 | package com.hellokoding.account.service;
2 |
3 | import com.hellokoding.account.model.MailProperties;
4 | import freemarker.template.Configuration;
5 | import freemarker.template.Template;
6 | import org.springframework.beans.factory.annotation.Autowired;
7 | import org.springframework.stereotype.Service;
8 | import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;
9 |
10 | import javax.mail.Message;
11 | import javax.mail.Session;
12 | import javax.mail.Transport;
13 | import javax.mail.internet.InternetAddress;
14 | import javax.mail.internet.MimeMessage;
15 | import java.util.HashMap;
16 | import java.util.Map;
17 | import java.util.Properties;
18 | import java.util.logging.Level;
19 | import java.util.logging.Logger;
20 |
21 | @Service
22 | public class SendingMailService {
23 | private final MailProperties mailProperties;
24 | private final Configuration templates;
25 |
26 | @Autowired
27 | SendingMailService(MailProperties mailProperties, Configuration templates){
28 | this.mailProperties = mailProperties;
29 | this.templates = templates;
30 | }
31 |
32 | public boolean sendVerificationMail(String toEmail, String verificationCode) {
33 | String subject = "Please verify your email";
34 | String body = "";
35 | try {
36 | Template t = templates.getTemplate("email-verification.ftl");
37 | Map map = new HashMap<>();
38 | map.put("VERIFICATION_URL", mailProperties.getVerificationapi() + verificationCode);
39 | body = FreeMarkerTemplateUtils.processTemplateIntoString(t, map);
40 | } catch (Exception ex) {
41 | Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, ex.getMessage(), ex);
42 | }
43 | return sendMail(toEmail, subject, body);
44 | }
45 |
46 | private boolean sendMail(String toEmail, String subject, String body) {
47 | try {
48 | Properties props = System.getProperties();
49 | props.put("mail.transport.protocol", "smtp");
50 | props.put("mail.smtp.port", mailProperties.getSmtp().getPort());
51 | props.put("mail.smtp.starttls.enable", "true");
52 | props.put("mail.smtp.auth", "true");
53 |
54 | Session session = Session.getDefaultInstance(props);
55 | session.setDebug(true);
56 |
57 | MimeMessage msg = new MimeMessage(session);
58 | msg.setFrom(new InternetAddress(mailProperties.getFrom(), mailProperties.getFromName()));
59 | msg.setRecipient(Message.RecipientType.TO, new InternetAddress(toEmail));
60 | msg.setSubject(subject);
61 | msg.setContent(body, "text/html");
62 |
63 | Transport transport = session.getTransport();
64 | transport.connect(mailProperties.getSmtp().getHost(), mailProperties.getSmtp().getUsername(), mailProperties.getSmtp().getPassword());
65 | transport.sendMessage(msg, msg.getAllRecipients());
66 | return true;
67 | } catch (Exception ex) {
68 | Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, ex.getMessage(), ex);
69 | }
70 |
71 | return false;
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/app/src/main/java/com/hellokoding/account/service/VerificationTokenService.java:
--------------------------------------------------------------------------------
1 | package com.hellokoding.account.service;
2 |
3 | import com.hellokoding.account.model.User;
4 | import com.hellokoding.account.model.VerificationToken;
5 | import com.hellokoding.account.repository.UserRepository;
6 | import com.hellokoding.account.repository.VerificationTokenRepository;
7 | import org.springframework.beans.factory.annotation.Autowired;
8 | import org.springframework.http.ResponseEntity;
9 | import org.springframework.stereotype.Service;
10 |
11 | import java.time.LocalDateTime;
12 | import java.util.List;
13 |
14 | @Service
15 | public class VerificationTokenService {
16 | private UserRepository userRepository;
17 | private VerificationTokenRepository verificationTokenRepository;
18 | private SendingMailService sendingMailService;
19 |
20 | @Autowired
21 | public VerificationTokenService(UserRepository userRepository, VerificationTokenRepository verificationTokenRepository, SendingMailService sendingMailService){
22 | this.userRepository = userRepository;
23 | this.verificationTokenRepository = verificationTokenRepository;
24 | this.sendingMailService = sendingMailService;
25 | }
26 |
27 | public void createVerification(String email){
28 | List users = userRepository.findByEmail(email);
29 | User user;
30 | if (users.isEmpty()) {
31 | user = new User();
32 | user.setEmail(email);
33 | userRepository.save(user);
34 | } else {
35 | user = users.get(0);
36 | }
37 |
38 | List verificationTokens = verificationTokenRepository.findByUserEmail(email);
39 | VerificationToken verificationToken;
40 | if (verificationTokens.isEmpty()) {
41 | verificationToken = new VerificationToken();
42 | verificationToken.setUser(user);
43 | verificationTokenRepository.save(verificationToken);
44 | } else {
45 | verificationToken = verificationTokens.get(0);
46 | }
47 |
48 | sendingMailService.sendVerificationMail(email, verificationToken.getToken());
49 | }
50 |
51 | public ResponseEntity verifyEmail(String token){
52 | List verificationTokens = verificationTokenRepository.findByToken(token);
53 | if (verificationTokens.isEmpty()) {
54 | return ResponseEntity.badRequest().body("Invalid token.");
55 | }
56 |
57 | VerificationToken verificationToken = verificationTokens.get(0);
58 | if (verificationToken.getExpiredDateTime().isBefore(LocalDateTime.now())) {
59 | return ResponseEntity.unprocessableEntity().body("Expired token.");
60 | }
61 |
62 | verificationToken.setConfirmedDateTime(LocalDateTime.now());
63 | verificationToken.setStatus(VerificationToken.STATUS_VERIFIED);
64 | verificationToken.getUser().setIsActive(true);
65 | verificationTokenRepository.save(verificationToken);
66 |
67 | return ResponseEntity.ok("You have successfully verified your email address.");
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/app/src/main/java/com/hellokoding/account/web/AccountController.java:
--------------------------------------------------------------------------------
1 | package com.hellokoding.account.web;
2 |
3 | import com.hellokoding.account.model.VerificationForm;
4 | import com.hellokoding.account.service.VerificationTokenService;
5 | import org.springframework.beans.factory.annotation.Autowired;
6 | import org.springframework.stereotype.Controller;
7 | import org.springframework.ui.Model;
8 | import org.springframework.validation.BindingResult;
9 | import org.springframework.web.bind.annotation.GetMapping;
10 | import org.springframework.web.bind.annotation.PostMapping;
11 | import org.springframework.web.bind.annotation.ResponseBody;
12 |
13 | import javax.validation.Valid;
14 |
15 | @Controller
16 | public class AccountController {
17 | @Autowired
18 | VerificationTokenService verificationTokenService;
19 |
20 | @GetMapping("/")
21 | public String index() {
22 | return "redirect:/email-verification";
23 | }
24 |
25 | @GetMapping("/email-verification")
26 | public String formGet(Model model) {
27 | model.addAttribute("verificationForm", new VerificationForm());
28 | return "verification-form";
29 | }
30 |
31 | @PostMapping("/email-verification")
32 | public String formPost(@Valid VerificationForm verificationForm, BindingResult bindingResult, Model model) {
33 | if (!bindingResult.hasErrors()) {
34 | model.addAttribute("noErrors", true);
35 | }
36 | model.addAttribute("verificationForm", verificationForm);
37 |
38 | verificationTokenService.createVerification(verificationForm.getEmail());
39 | return "verification-form";
40 | }
41 |
42 | @GetMapping("/verify-email")
43 | @ResponseBody
44 | public String verifyEmail(String code) {
45 | return verificationTokenService.verifyEmail(code).getBody();
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/app/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | spring.freemarker.template-loader-path: classpath:/templates
2 | spring.freemarker.suffix: .ftl
3 |
4 | spring.datasource.url=jdbc:mysql://mysql:3306/account?useSSL=false
5 | spring.datasource.username=root
6 | spring.datasource.password=hellokoding
7 | spring.datasource.driver-class-name=com.mysql.jdbc.Driver
8 |
9 | spring.jpa.hibernate.ddl-auto=create
10 | spring.jpa.database-platform=org.hibernate.dialect.MySQLDialect
11 | spring.jpa.generate-ddl=true
12 | spring.jpa.show-sql=true
13 |
14 | mail.smtp.host={YOUR_SES_SMTP_HOST}
15 | mail.smtp.port={YOUR_SES_SMTP_PORT}
16 | mail.smtp.username={YOUR_SES_SMTP_USERNAME}
17 | mail.smtp.password={YOUR_SES_SMTP_PASSWORD}
18 | mail.from={YOUR_FROM_EMAIL}
19 | mail.from-name={YOUR_FROM_NAME}
20 |
21 | mail.verificationapi=http://localhost/verify-email?code=
--------------------------------------------------------------------------------
/app/src/main/resources/static/css/main.css:
--------------------------------------------------------------------------------
1 | .hello-title{
2 | color: darkgreen;
3 | }
--------------------------------------------------------------------------------
/app/src/main/resources/static/js/main.js:
--------------------------------------------------------------------------------
1 | (function(){
2 | console.log("Hello World!");
3 | })();
--------------------------------------------------------------------------------
/app/src/main/resources/templates/email-verification.ftl:
--------------------------------------------------------------------------------
1 | Hi Giau,
2 |
3 | Thanks for using Hello Koding! Please confirm your email address by clicking on the link below.
4 |
5 | ${VERIFICATION_URL}
6 |
7 | If you did not sign up for a Hello Koding account please disregard this email.
8 |
9 | The Hello Koding team,
--------------------------------------------------------------------------------
/app/src/main/resources/templates/verification-form.ftl:
--------------------------------------------------------------------------------
1 | <#import "/spring.ftl" as spring />
2 |
3 |
4 |
5 |
6 |
7 | Activate account with Spring Boot, MongoDB, NGINX, Docker Compose
8 |
9 |
10 | Verify your email
11 |
12 | <@spring.bind "verificationForm"/>
13 | <#if verificationForm?? && noErrors??>
14 | Sent a confirmation link to your inbox ${verificationForm.email}
15 | <#else>
16 |
23 | #if>
24 |
25 |
--------------------------------------------------------------------------------
/docker-compose.yaml:
--------------------------------------------------------------------------------
1 | version: '3'
2 | services:
3 | nginx:
4 | container_name: some-nginx
5 | image: nginx:1.13
6 | restart: always
7 | ports:
8 | - 80:80
9 | - 443:443
10 | volumes:
11 | - ./nginx/conf.d:/etc/nginx/conf.d
12 | depends_on:
13 | - app
14 |
15 | mysql:
16 | container_name: some-mysql
17 | image: mysql/mysql-server:5.7
18 | environment:
19 | MYSQL_ROOT_PASSWORD: hellokoding
20 | MYSQL_ROOT_HOST: '%'
21 | MYSQL_DATABASE: account
22 | ports:
23 | - "3306:3306"
24 | restart: always
25 |
26 | app:
27 | restart: always
28 | build: ./app
29 | working_dir: /app
30 | volumes:
31 | - ./app:/app
32 | - ~/.m2:/root/.m2
33 | expose:
34 | - "8080"
35 | command: mvn clean spring-boot:run
36 | depends_on:
37 | - mysql
38 |
--------------------------------------------------------------------------------
/nginx/conf.d/app.conf:
--------------------------------------------------------------------------------
1 | server {
2 | listen 80;
3 | charset utf-8;
4 | access_log off;
5 |
6 | location / {
7 | proxy_pass http://app:8080;
8 | proxy_set_header Host $host:$server_port;
9 | proxy_set_header X-Forwarded-Host $server_name;
10 | proxy_set_header X-Real-IP $remote_addr;
11 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
12 | }
13 |
14 | location /static {
15 | access_log off;
16 | expires 30d;
17 |
18 | alias /app/static;
19 | }
20 | }
21 |
--------------------------------------------------------------------------------