# yaml-language-server: $schema=https://schema.zeabur.app/template.json
apiVersion: zeabur.com/v1
kind: Template
metadata:
    name: Kotlin Spring Boot Starter
spec:
    description: This repository serves as a starter template for building applications with Kotlin and Spring Boot. It provides a basic structure and setup, including database migration with Flyway, Docker configuration, and a sample API for managing user data.
    icon: https://upload.wikimedia.org/wikipedia/commons/7/74/Kotlin_Icon.png
    tags:
        - API
        - Starter
        - Database
    readme: "# Kotlin Spring Boot Starter\n\nThis repository serves as a starter template for building applications with Kotlin and Spring Boot. It provides a basic structure and setup, including database migration with Flyway, Docker configuration, and a sample API for managing user data.\n## Features\n\n- **Kotlin and Spring Boot**: Leverage the powerful combination of Kotlin and Spring Boot for building robust and maintainable applications.\n- **Flyway**: Integrated database migration management to handle schema changes effortlessly.\n- **PostgreSQL**: Pre-configured PostgreSQL database for development and production environments.\n- **Docker**: Docker and Docker Compose configurations for containerized development and deployment.\n- **Gradle**: Gradle build system for dependency management and build automation.\n- **Sample** API: Includes a sample API for user management with basic CRUD operations.\n- **Testing**: Configured for testing with JUnit 5 and MockMvc.\n\n## Getting Started\n\n### Prerequisites\n\n- [JDK 17](https://jdk.java.net/)\n- [Gradle](https://gradle.org/)\n- [Docker](https://www.docker.com/)\n\n### Running the Application\n\n1. **Clone the repository**:\n   ```sh\n   git clone https://github.com/UranusLin/kotlin-springboot-starter.git\n   cd kotlin-springboot-starter\n   ```\n\n2. **Build the application**:\n   ```sh\n   make build\n   ```\n   \n3. **Run the application**:\n   ```sh\n   make run\n   ```\n\n4. **Run with Docker**:\n   ```sh\n   make docker-up\n   ```\n\n5. **ktlintCheck**:\n   ```sh\n   make llint\n   ```\n\n6. **ktlintFormat**:\n   ```sh\n   make format\n   ```\n\n7. **Run Tests**:\n   ```sh\n   make test\n   ```\n   \n### Project Structure\n```css\nkotlin-springboot-starter/\n├── build.gradle.kts\n├── Makefile\n├── src/\n│   ├── main/\n│   │   ├── kotlin/\n│   │   │   └── com/\n│   │   │       └── starter/\n│   │   │           ├── controller/\n│   │   │           │   └── UserController.kt\n│   │   │           ├── service/\n│   │   │           │   └── UserService.kt\n│   │   │           ├── repository/\n│   │   │           │   └── UserRepository.kt\n│   │   │           ├── model/\n│   │   │           │   └── User.kt\n│   │   │           ├── dto/\n│   │   │           │   └── UserDto.kt\n│   │   │           ├── config/\n│   │   │           │   └── SecurityConfig.kt\n│   │   │           └── KotlinSpringbootStarterApplication.kt\n│   │   ├── resources/\n│   │   │   ├── db/\n│   │   │   │   └── migration/\n│   │   │   │       └── V1__Initial_schema.sql\n│   │   │   ├── static/\n│   │   │   ├── templates/\n│   │   │   ├── application.yml\n│   │   │   └── application-dev.yml\n│   │   │── docker/\n│   │   │   └── Dockerfile\n│   │   │   └── docker-compose.yml\n│   └── test/\n│       ├── kotlin/\n│       │   └── com/\n│       │       └── starter/\n│       │           └── UserControllerTest.kt\n│       └── resources/\n│           └── application-test.yml\n└── README.md\n```\n\n### Configuration\n#### application.yml\n```yaml\nspring:\n  datasource:\n    url: jdbc:postgresql://db:5432/gym_management\n    username: your_db_username\n    password: your_db_password\n    driver-class-name: org.postgresql.Driver\n  jpa:\n    hibernate:\n      ddl-auto: none\n    show-sql: true\n  flyway:\n    enabled: true\n    locations: classpath:db/migration\n    baseline-on-migrate: true\n```\n\n### Docker Compose\n#### docker-compose.yml\n```yaml\nversion: '3.8'\n\nservices:\n  app:\n    image: kotlin-springboot-starter\n    build:\n      context: .\n      dockerfile: Dockerfile\n    ports:\n      - \"8080:8080\"\n    depends_on:\n      - db\n    environment:\n      SPRING_DATASOURCE_URL: jdbc:postgresql://db:5432/springboot-starter\n      SPRING_DATASOURCE_USERNAME: your_db_username\n      SPRING_DATASOURCE_PASSWORD: your_db_password\n      SPRING_FLYWAY_ENABLED: true\n      SPRING_FLYWAY_LOCATIONS: classpath:db/migration\n      SPRING_FLYWAY_BASELINE_ON_MIGRATE: true\n\n  db:\n    image: postgres:13\n    environment:\n      POSTGRES_DB: springboot-starter\n      POSTGRES_USER: your_db_username\n      POSTGRES_PASSWORD: your_db_password\n    ports:\n      - \"5432:5432\"\n    volumes:\n      - pgdata:/var/lib/postgresql/data\n\nvolumes:\n  pgdata:\n```\n\n### Database Migration\nThis project uses Flyway for database migrations. Migration scripts are located in `src/main/resources/db/migration`.\n\n#### Applying Migrations\nTo apply migrations, run:\n```sh\nmake migrate\n```\n\n#### Swagger\nSwagger UI is available at `http://localhost:8080/swagger-ui/index.html#/`\n![](./docs/imgs/Swagger_page.png)\n\n\n### Contributing\nContributions are welcome! Please feel free to submit a PR or open an issue.\n\n### License\nThis project is licensed under the MIT License.\n\n### TODO\n- [x] Add Swagger\n- [ ] Add JWT\n- [ ] Add Logging\n- [ ] Add environment variables\n- [ ] Add Exception Handling\n- [ ] Add Integration Tests\n- [ ] Add CI/CD Pipeline\n- [ ] Add more features\n\n"
    services:
        - name: PostgreSQL
          icon: https://raw.githubusercontent.com/zeabur/service-icons/main/marketplace/postgresql.svg
          template: PREBUILT
          spec:
            id: postgresql
            source:
                image: postgres:16
                command:
                    - docker-entrypoint.sh
                    - -c
                    - config_file=/etc/postgresql/postgresql.conf
            ports:
                - id: database
                  port: 5432
                  type: TCP
            volumes:
                - id: data
                  dir: /var/lib/postgresql/data
            instructions:
                - title: Connection String
                  content: postgresql://${POSTGRES_USERNAME}:${POSTGRES_PASSWORD}@${PORT_FORWARDED_HOSTNAME}:${DATABASE_PORT_FORWARDED_PORT}/${POSTGRES_DATABASE}
                - title: PostgreSQL Connect Command
                  content: psql "postgresql://${POSTGRES_USERNAME}:${POSTGRES_PASSWORD}@${PORT_FORWARDED_HOSTNAME}:${DATABASE_PORT_FORWARDED_PORT}/${POSTGRES_DATABASE}"
                - title: PostgreSQL username
                  content: ${POSTGRES_USERNAME}
                - title: PostgresSQL password
                  content: ${POSTGRES_PASSWORD}
                - title: PostgresSQL database
                  content: ${POSTGRES_DATABASE}
                - title: PostgreSQL host
                  content: ${PORT_FORWARDED_HOSTNAME}
                - title: PostgreSQL port
                  content: ${DATABASE_PORT_FORWARDED_PORT}
            env:
                PGDATA:
                    default: /var/lib/postgresql/data/pgdata
                POSTGRES_CONNECTION_STRING:
                    default: postgresql://${POSTGRES_USERNAME}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DATABASE}
                    expose: true
                POSTGRES_DATABASE:
                    default: ${POSTGRES_DB}
                    expose: true
                POSTGRES_DB:
                    default: zeabur
                POSTGRES_HOST:
                    default: ${CONTAINER_HOSTNAME}
                    expose: true
                POSTGRES_PASSWORD:
                    default: ${PASSWORD}
                    expose: true
                POSTGRES_PORT:
                    default: ${DATABASE_PORT}
                    expose: true
                POSTGRES_URI:
                    default: ${POSTGRES_CONNECTION_STRING}
                    expose: true
                POSTGRES_USER:
                    default: root
                POSTGRES_USERNAME:
                    default: ${POSTGRES_USER}
                    expose: true
            configs:
                - path: /etc/postgresql/postgresql.conf
                  template: |
                    # https://github.com/postgres/postgres/blob/master/src/backend/utils/misc/postgresql.conf.sample
                    listen_addresses = '*'
                    max_connections = 100
                    shared_buffers = 128MB
                    dynamic_shared_memory_type = posix
                    max_wal_size = 1GB
                    min_wal_size = 80MB
                    log_timezone = 'Etc/UTC'
                    datestyle = 'iso, mdy'
                    timezone = 'Etc/UTC'
                    lc_messages = 'en_US.utf8'
                    lc_monetary = 'en_US.utf8'
                    lc_numeric = 'en_US.utf8'
                    lc_time = 'en_US.utf8'
                    default_text_search_config = 'pg_catalog.english'
                  permission: null
                  envsubst: null
