diff --git a/.env.dist b/.env.dist new file mode 100644 index 0000000..82c0222 --- /dev/null +++ b/.env.dist @@ -0,0 +1,5 @@ +MYSQL_ROOT_PASSWORD= +MYSQL_DATABASE= +MYSQL_USER= +MYSQL_PASSWORD= +JWT_SECRET= \ No newline at end of file diff --git a/api/Dockerfile b/api/Dockerfile new file mode 100644 index 0000000..e63e870 --- /dev/null +++ b/api/Dockerfile @@ -0,0 +1,14 @@ +FROM openjdk:13-alpine + +ENV APPLICATION_USER ktor +RUN adduser -D -g '' $APPLICATION_USER + +RUN mkdir /app +RUN chown -R $APPLICATION_USER /app + +USER $APPLICATION_USER + +COPY ./target/api-0.0.1-jar-with-dependencies.jar /app/notes-api.jar +WORKDIR /app + +CMD ["java", "-server", "-XX:+UnlockExperimentalVMOptions", "-XX:InitialRAMFraction=2", "-XX:MinRAMFraction=2", "-XX:MaxRAMFraction=2", "-XX:+UseG1GC", "-XX:MaxGCPauseMillis=100", "-XX:+UseStringDeduplication", "-jar", "notes-api.jar"] \ No newline at end of file diff --git a/api/pom.xml b/api/pom.xml index e3e0a43..098b0a5 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -24,7 +24,7 @@ UTF-8 true 12 - io.ktor.server.netty.EngineMain + be.vandewalleh.NotesApplicationKt 13 ${java.version} ${java.version} @@ -150,11 +150,6 @@ HikariCP 3.4.2 - - com.sksamuel.hoplite - hoplite-core - ${hoplite_version} - com.sksamuel.hoplite hoplite-yaml diff --git a/api/resources/application.yaml b/api/resources/application.yaml index 388f21a..a3d011b 100644 --- a/api/resources/application.yaml +++ b/api/resources/application.yaml @@ -1,18 +1,18 @@ env: staging database: - host: 127.0.0.1 + host: ${MYSQL_HOST} port: 3306 - name: Notes - username: test - password: test + name: ${MYSQL_DATABASE} + username: ${MYSQL_USER} + password: ${MYSQL_PASSWORD} server: host: 0.0.0.0 port: 8081 jwt: - secret: ${random.string(25)} + secret: ${JWT_SECRET} auth: validity: 1 unit: HOURS diff --git a/api/src/NotesApplication.kt b/api/src/NotesApplication.kt index 65a3f58..ae7e54d 100644 --- a/api/src/NotesApplication.kt +++ b/api/src/NotesApplication.kt @@ -19,6 +19,7 @@ import org.kodein.di.generic.singleton import org.slf4j.Logger import org.slf4j.LoggerFactory import javax.sql.DataSource +import kotlin.system.exitProcess val kodein = Kodein { import(serviceModule) diff --git a/deploy.sh b/deploy.sh new file mode 100755 index 0000000..1af31cf --- /dev/null +++ b/deploy.sh @@ -0,0 +1,26 @@ +#!/bin/bash + +check_installed() { + if ! [ -x "$(command -v $1)" ]; then + echo "Error: $1 is not installed." >&2 + exit 1 + fi +} + +check_installed docker-compose +check_installed yarn +check_installed mvn + +docker-compose down + +# Generate Nuxt.js static website +pushd frontend || exit 1 +yarn run generate +popd || exit 1 + +# Generate fat jar +pushd api || exit 1 +mvn clean package +popd || exit 1 + +docker-compose up -d --build diff --git a/docker-compose.yml b/docker-compose.yml index 0f8a33a..0064d57 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,18 +1,59 @@ -version: '3' +version: '2.2' services: + nginx: + image: nginx:latest + container_name: notes-nginx + environment: + - PUID=1000 + - PGID=1000 + - TZ=Europe/Brussels + volumes: + - ./frontend/dist:/usr/share/nginx/html + - ./nginx/nginx.conf:/etc/nginx/nginx.conf + - ./nginx/server.conf:/etc/nginx/server.conf + ports: + - 80:80 + - 443:443 + depends_on: + - api + + db: image: mariadb container_name: notes-mariadb + env_file: + - .env environment: - PUID=1000 - PGID=1000 - - MYSQL_ROOT_PASSWORD=test - TZ=Europe/Brussels - - MYSQL_DATABASE=Notes - - MYSQL_USER=test - - MYSQL_PASSWORD=test ports: + # This is only for testing - 3306:3306 + volumes: + - notes-db-volume:/var/lib/mysql + healthcheck: + test: ["CMD", "mysqladmin" ,"ping", "-h", "localhost"] + timeout: 10s + retries: 10 + + api: + build: ./api + container_name: notes-api + ports: + # This is only for testing + - 8081:8081 + env_file: + - .env + environment: + - TZ=Europe/Brussels + - MYSQL_HOST=db + depends_on: + db: + condition: service_healthy + +volumes: + notes-db-volume: \ No newline at end of file diff --git a/frontend/plugins/axios.js b/frontend/plugins/axios.js index c8c4384..661a171 100644 --- a/frontend/plugins/axios.js +++ b/frontend/plugins/axios.js @@ -3,5 +3,5 @@ export default function ({ $axios }) { console.log('Making request to ' + config.url) }) - $axios.setBaseURL('http://localhost:8081') + $axios.setBaseURL(process.env.API_URL) } diff --git a/nginx/nginx.conf b/nginx/nginx.conf new file mode 100644 index 0000000..22e53f6 --- /dev/null +++ b/nginx/nginx.conf @@ -0,0 +1,33 @@ + +user nginx; +worker_processes 1; + +error_log /var/log/nginx/error.log warn; +pid /var/run/nginx.pid; + + +events { + worker_connections 1024; +} + + +http { + include /etc/nginx/mime.types; + default_type application/octet-stream; + + log_format main '$remote_addr - $remote_user [$time_local] "$request" ' + '$status $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for"'; + + access_log /var/log/nginx/access.log main; + + sendfile on; + #tcp_nopush on; + + keepalive_timeout 65; + + #gzip on; + + include /etc/nginx/server.conf; +} + diff --git a/nginx/server.conf b/nginx/server.conf new file mode 100644 index 0000000..c5a171f --- /dev/null +++ b/nginx/server.conf @@ -0,0 +1,28 @@ +server { + listen 80; + server_name localhost; + + #charset koi8-r; + #access_log /var/log/nginx/host.access.log main; + + location / { + root /usr/share/nginx/html; + index index.html index.htm; + } + + #error_page 404 /404.html; + + # redirect server error pages to the static page /50x.html + # + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } + + location /api/ { + rewrite ^/api/(.*) /$1 break; + proxy_pass http://api:8081/; + } + +} +