From 5f66209f333a41a71184c635c924f39853c51c64 Mon Sep 17 00:00:00 2001 From: Richard Attermeyer Date: Mon, 11 Dec 2023 21:54:25 +0000 Subject: [PATCH] WIP --- build.gradle.kts | 5 +- ...demo.ci.java-common-conventions.gradle.kts | 4 +- infrastructure/README.adoc | 21 +- infrastructure/compose.yaml | 278 ++++++++++++++++++ ...ker-compose.yml => docker-compose.yml.bak} | 15 +- .../0010_create_multiple_databases.sh | 48 +++ infrastructure/sonarqube/Dockerfile | 6 + infrastructure/verdaccio/config.yaml | 16 + utilities/build.gradle.kts | 40 ++- 9 files changed, 411 insertions(+), 22 deletions(-) create mode 100644 infrastructure/compose.yaml rename infrastructure/{docker-compose.yml => docker-compose.yml.bak} (92%) create mode 100644 infrastructure/postgresql/initdb.d/0010_create_multiple_databases.sh create mode 100644 infrastructure/sonarqube/Dockerfile create mode 100644 infrastructure/verdaccio/config.yaml diff --git a/build.gradle.kts b/build.gradle.kts index cdea450..2eaf633 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,4 +1,7 @@ -plugins { id("com.diffplug.spotless") version "6.22.0" } +plugins { + id("com.diffplug.spotless") version "6.22.0" + id("maven-publish") +} repositories { mavenCentral() } diff --git a/buildSrc/src/main/kotlin/com.opitzconsulting.demo.ci.java-common-conventions.gradle.kts b/buildSrc/src/main/kotlin/com.opitzconsulting.demo.ci.java-common-conventions.gradle.kts index 2d63674..b251d86 100644 --- a/buildSrc/src/main/kotlin/com.opitzconsulting.demo.ci.java-common-conventions.gradle.kts +++ b/buildSrc/src/main/kotlin/com.opitzconsulting.demo.ci.java-common-conventions.gradle.kts @@ -10,7 +10,9 @@ plugins { repositories { // Use Maven Central for resolving dependencies. - mavenCentral() + maven { + url = uri("https://mvn.demo.rattermeyer.de/releases") + } } dependencies { diff --git a/infrastructure/README.adoc b/infrastructure/README.adoc index e398ec7..60ae2ab 100644 --- a/infrastructure/README.adoc +++ b/infrastructure/README.adoc @@ -9,10 +9,15 @@ Lets say it is `192.168.1.151` then the URLs for accessing the services are: |=== |Service | URL | User / Pwd -| git | https://git.demo.rattermeyer.de.nip.io[] | -| woodpecker | https://ci.demo.rattermeyer.de.nip.io[] | -| Traefik Dashboard | http://traefik.demorattermeyer.de.nip.io[] | -| +| Traefik Dashboard | http://traefik.demorattermeyer.de[] | +| git | https://git.demo.rattermeyer.de[] | +| woodpecker | https://ci.demo.rattermeyer.de[] | +| mvn ui | https://mvn-ui.demo.rattermeyer.de[] | +| mvn (repo) | http://mvn.rattermeyer.de[] | +| Mail | https://mail.demo.rattermeyer.de[] | +| Docker Registry | https://container.demo.rattermeyer.de[] | +| Docker Registry UI | https://container-ui.demo.rattermeyer.de[] | +| NPM Registry / proxy | https://npm.demo.rattermeyer.de[] | |=== First start forgejo using: @@ -25,13 +30,13 @@ E.g., fjadmin / admin123 / fjadmin@rattermeyer.de Setup > Applications > oauth2 apps -woodpecker / https://ci.demo.rattermeyer.de.nip.io/authorize +woodpecker / https://ci.demo.rattermeyer.de/authorize note client-id and client-secret and enter this in .env for. Now you can start everything using `docker compose up -d`. -== Chaning IP +== Changing IP If the IP address of your computer changes, you have to update some configuration. @@ -43,7 +48,7 @@ If the IP address of your computer changes, you have to update some configuratio == Check access to woodpecker -Access https://ci.demo.rattermeyer.de.nip.io and try to login. +Access https://ci.demo.rattermeyer.de and try to login. == Create and push a repository @@ -56,7 +61,7 @@ You need to disable ssl verification for this remote in your local git directory Then add the repository -git remote add origin https://git.demo.rattermeyer.de.nip.io:8543/fjadmin/ci-demo-2.git +git remote add origin https://git.demo.rattermeyer.de:8543/fjadmin/ci-demo-2.git and push it diff --git a/infrastructure/compose.yaml b/infrastructure/compose.yaml new file mode 100644 index 0000000..016b2a5 --- /dev/null +++ b/infrastructure/compose.yaml @@ -0,0 +1,278 @@ +--- +version: "3.7" + +networks: + woodpecker: + forgejo: + sonarqube: + proxy: + driver: bridge + + +volumes: + forgejo: + postgres: + woodpecker: + traefik_config: + traefik_certs: + traefik_logs: + traefik_acme: + registry: + artifacts_data: + verdaccio_data: + verdaccio_config: + verdaccio_plugins: + sonarqube_data: + sonarqube_logs: + +services: + traefik: + image: traefik:v2.10.5 + container_name: traefik + restart: always + # using network mode host allows traefik access to all "docker networks" + # otherwise traefik needs to be part of any network defined + network_mode: host + command: + - "--certificatesresolvers.letsencrypt.acme.caServer=https://acme-staging-v02.api.letsencrypt.org/directory" + - "--certificatesresolvers.letsencrypt.acme.email=richard.attermeyer@gmail.com" + volumes: + - "/var/run/docker.sock:/var/run/docker.sock:ro" + - "./traefik/traefik.yml:/etc/traefik/traefik.yml:ro" + - "traefik_certs:/etc/certs" + - "traefik_logs:/var/log/traefik" + - "traefik_acme:/etc/acme" + labels: + - "traefik.enable=true" + - "traefik.http.routers.dashboard.rule=Host(`${TRAEFIK_HOST}`)" + - "traefik.http.routers.dashboard.tls=true" + - "traefik.http.routers.dashboard.tls.certresolver=letsencrypt" + - "traefik.http.routers.dashboard.entrypoints=https" + - "traefik.http.routers.dashboard.service=api@internal" + - "traefik.http.services.dashboard.loadbalancer.server.port=8080" + - "traefik.http.middlewares.local-ipwhitelist.ipwhitelist.sourcerange=${TRAEIFK_LOCALIP_WHITELIST}" + + smtp: + image: "maildev/maildev:2.1.0" + networks: + - proxy + ports: + - "1025:1025" + labels: + - "traefik.enable=true" + - "traefik.http.routers.mail.rule=Host(`${MAIL_HOST}`)" + - "traefik.http.routers.mail.tls=true" + - "traefik.http.routers.mail.entrypoints=https" + - "traefik.http.services.mail.loadbalancer.server.port=1080" + + forgejo: + image: codeberg.org/forgejo/forgejo:1.20 + container_name: forgejo + environment: + - USER_UID=1000 + - USER_GID=1000 + - FORGEJO__database__DB_TYPE=postgres + - FORGEJO__database__HOST=db:5432 + - FORGEJO__database__NAME=forgejo + - FORGEJO__database__USER=forgejo_admin + - FORGEJO__database__PASSWD=forgejo_admin + - FORGEJO__database__SCHEMA=forgejo + - FORGEJO__server__ROOT_URL=${FORGEJO_URL} + - FORGEJO__webhook__SKIP_TLS_VERIFY=true + - FORGEJO__webhook__ALLOWED_HOST_LIST=external,* + - FORGEJO__webhook__DELIVER_TIMEOUT=20 + - FORGEJO__mailer__SMTP_ADDR=smtp + - FORGEJO__mailer__SMTP_PORT=1025 + - FORGEJO__mailer__SMTP_ENABLED=true + - FORGEJO__server__LFS_START_SERVER=true + - FORGEJO__CRON__ENABLED=true + - FORGEJO__service__DISABLE_REGISTRATION=true + restart: always + ports: + - "3000:3000" + networks: + - forgejo + - proxy + volumes: + - forgejo:/data + - /etc/timezone:/etc/timezone:ro + - /etc/localtime:/etc/localtime:ro + depends_on: + - db + labels: + - "traefik.enable=true" + - "traefik.http.routers.forgejo.rule=Host(`${FORGEJO_HOST}`)" + - "traefik.http.routers.forgejo.entrypoints=https" + - "traefik.http.routers.forgejo.tls=true" + - "traefik.http.routers.forgejo.tls.certresolver=letsencrypt" + - "traefik.http.services.forgejo.loadbalancer.server.port=3000" + - "traefik.tcp.routers.forgejo-ssh.rule=HostSNI(`*`)" + - "traefik.tcp.routers.forgejo-ssh.entrypoints=ssh" + - "traefik.tcp.routers.forgejo-ssh.service=gitea-ssh-svc" + - "traefik.tcp.services.forgejo-ssh-svc.loadbalancer.server.port=22" + + db: + image: postgres:16 + restart: always + environment: + - POSTGRES_PASSWORD=changeme + - POSTGRESQL_POSTGRES_PASSWORD=changeme + - PGPASSWORD=changeme + - POSTGRESQL_PASSWORD=changeme + - POSTGRESQL_MULTIPLE_DATABASES=forgejo,sonarqube + networks: + - forgejo + - sonarqube + volumes: + - postgres:/var/lib/postgresql/data + - "./postgresql/initdb.d:/docker-entrypoint-initdb.d:Z" + + woodpecker-server: + image: woodpeckerci/woodpecker-server:v1.0.5 + container_name: woodpecker-server + restart: unless-stopped + cpus: 0.5 + mem_limit: 512m + networks: + - woodpecker + - proxy + environment: + - "WOODPECKER_OPEN=true" + - "WOODPECKER_HOST=${WOODPECKER_URL}" + - "WOODPECKER_AGENT_SECRET=${WOODPECKER_AGENT_SECRET}" + - "WOODPECKER_ADMIN=${WOODPECKER_ADMIN}" + - "WOODPECKER_GITEA=true" + - "WOODPECKER_GITEA_URL=${WOODPECKER_FORGEJO_URL}" + - "WOODPECKER_GITEA_CLIENT=${WOODPECKER_FORGEJO_CLIENT}" + - "WOODPECKER_GITEA_SECRET=${WOODPECKER_FORGEJO_SECRET}" + - "WOODPECKER_GITEA_SKIP_VERIFY=true" + - "WOODPECKER_LIMIT_MEM=2147483648" + - "WOODPECKER_LIMIT_MEM_SWAP=2147483648" + volumes: + - "woodpecker:/var/lib/woodpecker" + labels: + - "traefik.enable=true" + - "traefik.http.routers.woodpecker.rule=Host(`${WOODPECKER_HOST}`)" + - "traefik.http.routers.woodpecker.tls=true" + - "traefik.http.routers.woodpecker.tls.certresolver=letsencrypt" + - "traefik.http.routers.woodpecker.entrypoints=https" + - "traefik.http.services.woodpecker.loadbalancer.server.port=8000" + + woodpecker-agent: + container_name: woodpecker-agent + image: woodpeckerci/woodpecker-agent:v1.0.5 + restart: unless-stopped + cpus: 0.5 + mem_limit: 512m + depends_on: + - woodpecker-server + networks: + - woodpecker + environment: + - "WOODPECKER_SERVER=woodpecker-server:9000" + - "WOODPECKER_AGENT_SECRET=${WOODPECKER_AGENT_SECRET}" + - "WOODPECKER_MAX_WORKFLOWS=2" + volumes: + - "/var/run/docker.sock:/var/run/docker.sock" + + registry: + image: registry:2 + container_name: registry + networks: + - proxy + environment: + - REGISTRY_STORAGE_DELETE_ENABLED=true + volumes: + - registry:/var/lib/registry + labels: + - "traefik.enable=true" + - "traefik.http.routers.registry.rule=Host(`${REGISTRY_HOST}`)" + - "traefik.http.routers.registry.tls=true" + - "traefik.http.routers.registry.middlewares=local-ipwhitelist" + - "traefik.http.routers.registry.entrypoints=https" + - "traefik.http.services.registry.loadbalancer.server.port=5000" + ui: + image: joxit/docker-registry-ui:latest + environment: + - DELETE_IMAGES=true + - REGISTRY_TITLE=My Private Docker Registry + - NGINX_PROXY_PASS_URL=http://registry:5000 + - SINGLE_REGISTRY=true + depends_on: ['registry'] + networks: + - proxy + labels: + - "traefik.enable=true" + - "traefik.http.routers.regui.rule=Host(`${REGISTRY_UI_HOST}`)" + - "traefik.http.routers.regui.tls=true" + - "traefik.http.routers.regui.tls.certresolver=letsencrypt" + - "traefik.http.routers.regui.entrypoints=https" + - "traefik.http.services.regui.loadbalancer.passhostheader=true" + mvn-registry: + image: ghcr.io/dzikoysk/reposilite:3.5.0 + container_name: reposilite + deploy: + resources: + limits: + memory: ${REPOSILITE_MEMORY} + networks: + - proxy + volumes: + - artifacts_data:/app/data + stdin_open: true + environment: + - JAVA_OPTS=-Xmx${REPOSILITE_MEMORY} ${REPOSILITE_JAVA_COMPOSE_OPTS} + - REPOSILITE_OPTS=--port ${REPOSILITE_PORT} ${REPOSILITE_COMPOSE_OPTS} + tty: true + labels: + - "traefik.enable=true" + - "traefik.http.routers.mvn.rule=Host(`${REPOSILITE_HOST}`)" + - "traefik.http.routers.mvn.tls=true" + - "traefik.http.routers.mvn.tls.certresolver=letsencrypt" + - "traefik.http.routers.mvn.entrypoints=https" + + verdaccio: + image: verdaccio/verdaccio:5 + container_name: verdaccio + volumes: + - verdaccio_data:/verdaccio/storage + - verdaccio_config:/verdaccio/conf + - verdaccio_plugins:/verdaccio/plugins + ports: + - "4873:4873" + networks: + - proxy + labels: + - "traefik.enable=true" + - "traefik.http.routers.npm.rule=Host(`${VERDACCIO_HOST}`)" + - "traefik.http.routers.npm.entrypoints=http" + - "traefik.http.services.npm.loadbalancer.server.port=4873" + + sonarqube: + image: demo/sonarqube:9.9-custom + build: + context: ./sonarqube + volumes: + - 'sonarqube_data:/opt/sonarqube/data' + - 'sonarqube_logs:/opt/sonarqube/logs' + depends_on: + - db + networks: + - sonarqube + environment: + # ALLOW_EMPTY_PASSWORD is recommended only for development. + - ALLOW_EMPTY_PASSWORD=yes + - SONAR_JDBC_URL=jdbc:postgresql://db:5432/sonarqube + - SONAR_JDBC_USERNAME=sonarqube_admin + - SONAR_JDBC_PASSWORD=sonarqube_admin + labels: + - "traefik.enable=true" + - "traefik.http.routers.sonarqube.rule=Host(`${SONARQUBE_HOST}`)" + - "traefik.http.routers.sonarqube.tls=true" + - "traefik.http.routers.sonarqube.tls.certresolver=letsencrypt" + - "traefik.http.routers.sonarqube.entrypoints=https" + # + # watchtower: + # image: containrrr/watchtower:latest + # volumes: + # - /var/run/docker.sock:/var/run/docker.sock diff --git a/infrastructure/docker-compose.yml b/infrastructure/docker-compose.yml.bak similarity index 92% rename from infrastructure/docker-compose.yml rename to infrastructure/docker-compose.yml.bak index 712c227..5373dee 100644 --- a/infrastructure/docker-compose.yml +++ b/infrastructure/docker-compose.yml.bak @@ -47,7 +47,7 @@ services: - "traefik.http.routers.dashboard.entrypoints=https" - "traefik.http.routers.dashboard.service=api@internal" - "traefik.http.services.dashboard.loadbalancer.server.port=8080" - - "traefik.http.middlewares.local-ipwhitelist.ipwhitelist.sourcerange=127.0.0.1/32, 192.168.0.0/16, 172.16.0.0/12, ::1" + - "traefik.http.middlewares.local-ipwhitelist.ipwhitelist.sourcerange=${TRAEIFK_LOCALIP_WHITELIST}" smtp: image: "maildev/maildev:2.1.0" @@ -180,6 +180,7 @@ services: - "traefik.enable=true" - "traefik.http.routers.registry.rule=Host(`${REGISTRY_HOST}`)" - "traefik.http.routers.registry.tls=true" + - "traefik.http.routers.registry.middlewares=local-ipwhitelist" - "traefik.http.routers.registry.entrypoints=https" - "traefik.http.services.registry.loadbalancer.server.port=5000" ui: @@ -218,15 +219,9 @@ services: labels: - "traefik.enable=true" - "traefik.http.routers.mvn.rule=Host(`${REPOSILITE_HOST}`)" - - "traefik.http.routers.mvn.entrypoints=http" - - "traefik.http.routers.mvn.service=mvn" - - "traefik.http.routers.mvn.middlewares=local-ipwhitelist" - - "traefik.http.services.mvn.loadbalancer.server.port=${REPOSILITE_PORT}" - - "traefik.http.routers.mvnui.rule=Host(`${REPOSILITE_UI_HOST}`)" - - "traefik.http.routers.mvnui.entrypoints=https" - - "traefik.http.routers.mvnui.tls=true" - - "traefik.http.routers.mvnui.service=mvn" - - "traefik.http.services.mvnui.loadbalancer.server.port=${REPOSILITE_PORT}" + - "traefik.http.routers.mvn.tls=true" + - "traefik.http.routers.mvn.tls.certresolver=letsencrypt" + - "traefik.http.routers.mvn.entrypoints=https" verdaccio: image: verdaccio/verdaccio:5 diff --git a/infrastructure/postgresql/initdb.d/0010_create_multiple_databases.sh b/infrastructure/postgresql/initdb.d/0010_create_multiple_databases.sh new file mode 100644 index 0000000..15ff795 --- /dev/null +++ b/infrastructure/postgresql/initdb.d/0010_create_multiple_databases.sh @@ -0,0 +1,48 @@ +#!/bin/bash + +set -e +set -u + +function create_user_and_database() { + local database=$1 + echo " Creating user and database '$database'" + psql -v ON_ERROR_STOP=1 --username postgres <("basic") + } + } + } + publications { + create("maven") { + groupId = "com.example" + artifactId = "utils-library" + version = "1.0.0" + from(components["java"]) + } + } +} + + +dependencies { + implementation("org.springframework.boot:spring-boot-starter") + api(project(":list")) }