Skip to content

Commit 89a5266

Browse files
committed
Providing a fully working Docker build and documentation how to run everything using Docker. This fixes #25
1 parent 6a027a6 commit 89a5266

File tree

3 files changed

+168
-1
lines changed

3 files changed

+168
-1
lines changed

.dockerignore

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# exclude underlying OS specific node modules
2+
frontend/node*
3+
4+
# also leave out pre-build output folders
5+
frontend/target
6+
backend/target

Dockerfile

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Docker multi-stage build
2+
3+
# 1. Building the App with Maven
4+
FROM maven:3-jdk-11
5+
6+
ADD . /springbootvuejs
7+
WORKDIR /springbootvuejs
8+
9+
# Just echo so we can see, if everything is there :)
10+
RUN ls -l
11+
12+
# Run Maven build
13+
RUN mvn clean install
14+
15+
16+
# Just using the build artifact and then removing the build-container
17+
FROM openjdk:11-jdk
18+
19+
MAINTAINER Jonas Hecht
20+
21+
VOLUME /tmp
22+
23+
# Add Spring Boot app.jar to Container
24+
COPY --from=0 "/springbootvuejs/backend/target/backend-0.0.1-SNAPSHOT.jar" app.jar
25+
26+
ENV JAVA_OPTS=""
27+
28+
# Fire up our Spring Boot app by default
29+
ENTRYPOINT [ "sh", "-c", "java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar /app.jar" ]

README.md

+133-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
[![Build Status](https://travis-ci.org/jonashackt/spring-boot-vuejs.svg?branch=master)](https://travis-ci.org/jonashackt/spring-boot-vuejs)
44
[![Coverage Status](https://coveralls.io/repos/github/jonashackt/spring-boot-vuejs/badge.svg?branch=master)](https://coveralls.io/github/jonashackt/spring-boot-vuejs?branch=master)
55
[![License](http://img.shields.io/:license-mit-blue.svg)](https://github.com/jonashackt/spring-boot-vuejs/blob/master/LICENSE)
6-
[![versionspringboot](https://img.shields.io/badge/springboot-2.1.1_RELEASE-brightgreen.svg)](https://github.com/spring-projects/spring-boot)
6+
[![versionspringboot](https://img.shields.io/badge/springboot-2.1.2_RELEASE-brightgreen.svg)](https://github.com/spring-projects/spring-boot)
77
[![versionnodejs](https://img.shields.io/badge/nodejs-v11.5.0-brightgreen.svg)](https://nodejs.org/en/)
88
[![versionvuejs](https://img.shields.io/badge/vue.js-2.5.21-brightgreen.svg)](https://vuejs.org/)
99
[![versionvuecli](https://img.shields.io/badge/vue_CLI-3.2.1-brightgreen.svg)](https://cli.vuejs.org/)
@@ -52,6 +52,7 @@ This project is used as example in a variety of articles & as eBook:
5252
* [Shift from templates to plugin-based architecture in Vue Cli 3](#shift-from-templates-to-plugin-based-architecture-in-vue-cli-3)
5353
* [OMG! My package.json is so small - Vue CLI 3 Plugins](#omg-my-packagejson-is-so-small---vue-cli-3-plugins)
5454
* [The vue.config.js file](#the-vueconfigjs-file)
55+
* [Build and run with Docker](#build-and-run-with-docker)
5556

5657

5758

@@ -1063,6 +1064,137 @@ npm update
10631064
```
10641065

10651066

1067+
## Build and run with Docker
1068+
1069+
In the issue [jonashackt/spring-boot-vuejs/issues/25](https://github.com/jonashackt/spring-boot-vuejs/issues/25) the question on how to build and run our spring-boot-vuejs app with Docker.
1070+
1071+
As already stated in the issue there are multiple ways of doing this. One I want to outline here is a more in-depth variant, where you'll know exacltly what's going on behind the scenes.
1072+
1073+
First we'll make use of [Docker's multi-stage build feature](https://docs.docker.com/develop/develop-images/multistage-build/) - in __the first stage__ we'll build our Spring Boot Vue.js app using our established Maven build process. Let's have a look into our [Dockerfile](Dockerfile):
1074+
1075+
```dockerfile
1076+
# Docker multi-stage build
1077+
1078+
# 1. Building the App with Maven
1079+
FROM maven:3-jdk-11
1080+
1081+
ADD . /springbootvuejs
1082+
WORKDIR /springbootvuejs
1083+
1084+
# Just echo so we can see, if everything is there :)
1085+
RUN ls -l
1086+
1087+
# Run Maven build
1088+
RUN mvn clean install
1089+
```
1090+
1091+
A crucial part here is to add all necessary files into our Docker build context - but leaving out the underlying OS specific node libraries! As not leaving them out would lead [to errors like](https://stackoverflow.com/questions/37986800/node-sass-could-not-find-a-binding-for-your-current-environment?page=1&tab=active#tab-top):
1092+
1093+
```
1094+
Node Sass could not find a binding for your current environment: Linux 64-bit with Node.js 11.x
1095+
```
1096+
1097+
Therefore we create a [.dockerignore](.dockerignore) file and leave out the directories `frontend/node_modules` & `frontend/node` completely using the `frontend/node*` configuration:
1098+
1099+
```
1100+
# exclude underlying OS specific node modules
1101+
frontend/node*
1102+
1103+
# also leave out pre-build output folders
1104+
frontend/target
1105+
backend/target
1106+
```
1107+
1108+
We also ignore the pre-build output directories.
1109+
1110+
In __the second stage__ of our [Dockerfile](Dockerfile) we use the build output of the first stage and prepare everything to run our Spring Boot powered Vue.js app later:
1111+
1112+
```dockerfile
1113+
# Just using the build artifact and then removing the build-container
1114+
FROM openjdk:11-jdk
1115+
1116+
MAINTAINER Jonas Hecht
1117+
1118+
VOLUME /tmp
1119+
1120+
# Add Spring Boot app.jar to Container
1121+
COPY --from=0 "/springbootvuejs/backend/target/backend-0.0.1-SNAPSHOT.jar" app.jar
1122+
1123+
ENV JAVA_OPTS=""
1124+
1125+
# Fire up our Spring Boot app by default
1126+
ENTRYPOINT [ "sh", "-c", "java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar /app.jar" ]
1127+
```
1128+
1129+
Now we should everything prepared to run our Docker build:
1130+
1131+
```
1132+
docker build . --tag spring-boot-vuejs:latest
1133+
```
1134+
1135+
This build can take a while, since all Maven and NPM dependencies need to be downloaded for the build.
1136+
1137+
When the build is finished, simply start a Docker container based on the newly build image and prepare the correct port to be bound to the Docker host for easier access later:
1138+
1139+
```
1140+
docker run -d -p 8088:8088 --name myspringvuejs spring-boot-vuejs
1141+
```
1142+
1143+
Have a look into your running Docker containers with `docker ps` and you should see the new container:
1144+
1145+
```
1146+
$ docker ps
1147+
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1148+
745e854d7781 spring-boot-vuejs "sh -c 'java $JAVA_O…" 12 seconds ago Up 11 seconds 0.0.0.0:8088->8088/tcp myspringvuejs
1149+
```
1150+
1151+
If you want to see the typical Spring Boot startup logs, just use `docker logs 745e854d7781 --follow`:
1152+
1153+
```
1154+
$ docker logs 745e854d7781 --follow
1155+
1156+
. ____ _ __ _ _
1157+
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
1158+
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
1159+
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
1160+
' |____| .__|_| |_|_| |_\__, | / / / /
1161+
=========|_|==============|___/=/_/_/_/
1162+
:: Spring Boot :: (v2.1.2.RELEASE)
1163+
1164+
2019-01-29 09:42:07.621 INFO 8 --- [ main] d.j.s.SpringBootVuejsApplication : Starting SpringBootVuejsApplication v0.0.1-SNAPSHOT on 745e854d7781 with PID 8 (/app.jar started by root in /)
1165+
2019-01-29 09:42:07.627 INFO 8 --- [ main] d.j.s.SpringBootVuejsApplication : No active profile set, falling back to default profiles: default
1166+
2019-01-29 09:42:09.001 INFO 8 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data repositories in DEFAULT mode.
1167+
2019-01-29 09:42:09.103 INFO 8 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 90ms. Found 1 repository interfaces.
1168+
2019-01-29 09:42:09.899 INFO 8 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration' of type [org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration$$EnhancerBySpringCGLIB$$bb072d94] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
1169+
2019-01-29 09:42:10.715 INFO 8 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8088 (http)
1170+
2019-01-29 09:42:10.765 INFO 8 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
1171+
2019-01-29 09:42:10.765 INFO 8 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.14]
1172+
2019-01-29 09:42:10.783 INFO 8 --- [ main] o.a.catalina.core.AprLifecycleListener : The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: [/usr/java/packages/lib:/usr/lib/x86_64-linux-gnu/jni:/lib/x86_64-linux-gnu:/usr/lib/x86_64-linux-gnu:/usr/lib/jni:/lib:/usr/lib]
1173+
2019-01-29 09:42:10.920 INFO 8 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
1174+
2019-01-29 09:42:10.921 INFO 8 --- [ main] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 3209 ms
1175+
2019-01-29 09:42:11.822 INFO 8 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting...
1176+
2019-01-29 09:42:12.177 INFO 8 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed.
1177+
2019-01-29 09:42:12.350 INFO 8 --- [ main] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [
1178+
name: default
1179+
...]
1180+
2019-01-29 09:42:12.520 INFO 8 --- [ main] org.hibernate.Version : HHH000412: Hibernate Core {5.3.7.Final}
1181+
2019-01-29 09:42:12.522 INFO 8 --- [ main] org.hibernate.cfg.Environment : HHH000206: hibernate.properties not found
1182+
2019-01-29 09:42:12.984 INFO 8 --- [ main] o.hibernate.annotations.common.Version : HCANN000001: Hibernate Commons Annotations {5.0.4.Final}
1183+
2019-01-29 09:42:13.894 INFO 8 --- [ main] org.hibernate.dialect.Dialect : HHH000400: Using dialect: org.hibernate.dialect.H2Dialect
1184+
2019-01-29 09:42:15.644 INFO 8 --- [ main] o.h.t.schema.internal.SchemaCreatorImpl : HHH000476: Executing import script 'org.hibernate.tool.schema.internal.exec.ScriptSourceInputNonExistentImpl@64524dd'
1185+
2019-01-29 09:42:15.649 INFO 8 --- [ main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
1186+
2019-01-29 09:42:16.810 INFO 8 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'
1187+
2019-01-29 09:42:16.903 WARN 8 --- [ main] aWebConfiguration$JpaWebMvcConfiguration : spring.jpa.open-in-view is enabled by default. Therefore, database queries may be performed during view rendering. Explicitly configure spring.jpa.open-in-view to disable this warning
1188+
2019-01-29 09:42:17.116 INFO 8 --- [ main] o.s.b.a.w.s.WelcomePageHandlerMapping : Adding welcome page: class path resource [public/index.html]
1189+
2019-01-29 09:42:17.604 INFO 8 --- [ main] o.s.b.a.e.web.EndpointLinksResolver : Exposing 2 endpoint(s) beneath base path '/actuator'
1190+
2019-01-29 09:42:17.740 INFO 8 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8088 (http) with context path ''
1191+
2019-01-29 09:42:17.745 INFO 8 --- [ main] d.j.s.SpringBootVuejsApplication : Started SpringBootVuejsApplication in 10.823 seconds (JVM running for 11.485)
1192+
```
1193+
1194+
Now access your Dockerized Spring Boot powererd Vue.js app inside your Browser at [http://localhost:8088](http://localhost:8088).
1195+
1196+
If you have played enough with your Dockerized app, don't forget to stop (`docker stop 745e854d7781`) and remove (`docker rm 745e854d7781`) it in the end.
1197+
10661198

10671199
# Links
10681200

0 commit comments

Comments
 (0)