Skip to content

Deployment Guide

Overview

This guide covers the deployment options for the Gustaffo Reservations Application, including container-based deployment with Docker, cloud deployment on AWS, and traditional server deployment.

Prerequisites

Before deploying the application, ensure you have:

  • Java 17 or later installed on the target environment
  • PostgreSQL 13.x or later database server
  • SMTP server for email notifications
  • Sufficient memory (minimum 2GB RAM recommended)
  • Network access to external services (IBE system, payment gateways)

Deployment Options

Docker Deployment

The application includes Dockerfiles for containerized deployment.

Building the Docker Image

1
2
3
4
5
# Build the application
./gradlew clean build

# Build the Docker image
docker build -t gustaffo/reservations:latest .

Running with Docker Compose

Create a docker-compose.yml file:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
version: '3'

services:
  app:
    image: gustaffo/reservations:latest
    ports:
      - "8080:8080"
    environment:
      - SPRING_PROFILES_ACTIVE=prod
      - SPRING_DATASOURCE_URL=jdbc:postgresql://db:5432/gustaffo_reservations
      - SPRING_DATASOURCE_USERNAME=postgres
      - SPRING_DATASOURCE_PASSWORD=postgres
      - JAVA_OPTS=-Xmx1g -Xms512m
    depends_on:
      - db
    restart: always

  db:
    image: postgres:13
    ports:
      - "5432:5432"
    environment:
      - POSTGRES_DB=gustaffo_reservations
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=postgres
    volumes:
      - postgres_data:/var/lib/postgresql/data

volumes:
  postgres_data:

Start the application:

1
docker-compose up -d

AWS Deployment

The application can be deployed to AWS using Elastic Beanstalk, ECS, or EC2 instances.

Elastic Beanstalk Deployment

  1. Package the application as a JAR file:

    1
    ./gradlew bootJar
    
  2. Create a Procfile in the project root:

    1
    web: java -Dserver.port=$PORT $JAVA_OPTS -jar build/libs/reservations-3.1.1.jar
    
  3. Deploy to Elastic Beanstalk:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    # Install EB CLI if not already installed
    pip install awsebcli
    
    # Initialize EB project
    eb init
    
    # Create EB environment
    eb create reservations-prod
    
    # Deploy the application
    eb deploy
    

ECS Deployment

The project includes a task-definition.json file for AWS ECS deployment:

  1. Create an ECR repository for the application:

    1
    aws ecr create-repository --repository-name gustaffo/reservations
    
  2. Build and push the Docker image:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    # Build the Docker image
    docker build -t gustaffo/reservations:latest .
    
    # Tag the image for ECR
    docker tag gustaffo/reservations:latest [AWS_ACCOUNT_ID].dkr.ecr.[REGION].amazonaws.com/gustaffo/reservations:latest
    
    # Login to ECR
    aws ecr get-login-password | docker login --username AWS --password-stdin [AWS_ACCOUNT_ID].dkr.ecr.[REGION].amazonaws.com
    
    # Push the image to ECR
    docker push [AWS_ACCOUNT_ID].dkr.ecr.[REGION].amazonaws.com/gustaffo/reservations:latest
    
  3. Register the task definition:

    1
    aws ecs register-task-definition --cli-input-json file://task-definition.json
    
  4. Create or update the ECS service:

    1
    aws ecs create-service --cluster [CLUSTER_NAME] --service-name gustaffo-reservations --task-definition gustaffo-reservations:1 --desired-count 2 --launch-type FARGATE --network-configuration "awsvpcConfiguration={subnets=[SUBNET_ID_1,SUBNET_ID_2],securityGroups=[SECURITY_GROUP_ID],assignPublicIp=ENABLED}" --load-balancers "targetGroupArn=[TARGET_GROUP_ARN],containerName=gustaffo-reservations,containerPort=8080"
    

Traditional Server Deployment

1. Building the Application

1
./gradlew clean bootJar

This will create a self-contained JAR file in the build/libs directory.

2. Configuring the Environment

Create a application-prod.yml file with production configuration:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
spring:
  datasource:
    url: jdbc:postgresql://[DB_HOST]:5432/gustaffo_reservations
    username: [DB_USERNAME]
    password: [DB_PASSWORD]
  jpa:
    hibernate:
      ddl-auto: validate

server:
  port: 8080
  compression:
    enabled: true

3. Running the Application

1
java -jar -Dspring.profiles.active=prod build/libs/reservations-3.1.1.jar

4. Setting Up as a Service

Create a systemd service file /etc/systemd/system/gustaffo-reservations.service:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
[Unit]
Description=Gustaffo Reservations Application
After=syslog.target network.target

[Service]
User=appuser
Group=appuser
WorkingDirectory=/opt/gustaffo/reservations
ExecStart=/usr/bin/java -Xmx1g -Xms512m -jar reservations-3.1.1.jar --spring.profiles.active=prod
SuccessExitStatus=143
TimeoutStopSec=10
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target

Enable and start the service:

1
2
systemctl enable gustaffo-reservations.service
systemctl start gustaffo-reservations.service

Database Migration

The application uses Flyway for database migrations. Migrations are automatically applied when the application starts. For manual migration:

1
./gradlew flywayMigrate -Dflyway.url=jdbc:postgresql://[DB_HOST]:5432/gustaffo_reservations -Dflyway.user=[DB_USERNAME] -Dflyway.password=[DB_PASSWORD]

Load Balancing and Scaling

The application can be horizontally scaled by running multiple instances behind a load balancer:

Session Management

When running multiple instances, use one of the following approaches for session management:

  1. Sticky Sessions: Configure the load balancer to use sticky sessions
  2. Redis Session Storage: Configure Spring Session to use Redis for session storage
1
2
3
4
5
6
spring:
  session:
    store-type: redis
    redis:
      host: [REDIS_HOST]
      port: 6379

Cache Synchronization

When running multiple instances, use a distributed cache like Redis for Hibernate second-level cache:

1
2
3
4
5
6
7
spring:
  jpa:
    properties:
      hibernate:
        cache:
          use_second_level_cache: true
          region.factory_class: org.hibernate.cache.redis.hibernate5.SingletonRedisRegionFactory

SSL Configuration

It's recommended to terminate SSL at the load balancer. If you need to configure SSL directly in the application:

1
2
3
4
5
6
7
server:
  port: 8443
  ssl:
    key-store: classpath:keystore.p12
    key-store-password: [KEYSTORE_PASSWORD]
    key-store-type: PKCS12
    key-alias: gustaffo

Environment Variables

Important environment variables for configuration:

Variable Description Default
SPRING_PROFILES_ACTIVE Active Spring profile prod
SPRING_DATASOURCE_URL JDBC URL for database jdbc:postgresql://localhost:5432/gustaffo_reservations
SPRING_DATASOURCE_USERNAME Database username postgres
SPRING_DATASOURCE_PASSWORD Database password -
SERVER_PORT Port to run the application on 8080
JAVA_OPTS JVM options -Xmx1g -Xms512m

Health Checks

The application provides health endpoints through Spring Actuator:

  • /actuator/health: Overall application health
  • /actuator/health/liveness: Liveness check
  • /actuator/health/readiness: Readiness check

Configure your load balancer or container orchestration platform to use these endpoints for health monitoring.

Deployment Checklist

  • Database connection is configured and tested
  • Application properties are configured for production
  • SSL certificates are installed (if applicable)
  • Email server configuration is tested
  • External service endpoints are accessible
  • Health check endpoints are configured
  • Logging is configured and tested
  • Monitoring is set up
  • Backup procedure is established
  • Deployment rollback plan is ready

Troubleshooting

Common Issues

Database Connection Failures

1
Could not create connection to database server

Solution: Verify database credentials and network connectivity.

Out of Memory Errors

1
java.lang.OutOfMemoryError: Java heap space

Solution: Increase the heap size using JVM options (e.g., -Xmx2g).

Application Startup Failures

1
Could not create bean: Unable to create requested service [org.hibernate.cache.spi.RegionFactory]

Solution: Ensure all required dependencies are available and properly configured.

Back to top