Přeskočit obsah

Pokročilé nastavení

Časové pásmo

Aby fungovala komunikace přes ActiveMQ, je nutné mít správně nastavený čas na serveru a všech klientech. Je také vhodné mít u všech kontejnerů v souboru docker-compose.yml nastavené správné časové pásmo.

---
    environment:
      TZ: Europe/Prague
---

Tip

Pokud PMC neběží v dockeru, ale jako java proces na serveru, časové pásmo se nastavuje příkazem timedatectl. Viz příklad níže:

sudo timedatectl set-timezone Europe/Prague

Logování

Defaultně docker používá JSON File logging driver, který není úplně vhodný ke zpětnému dohledávání událostí. Pro tyto účely je lepší použít Journald logging driver. Můžeme ho zkombinovat s utilitami jako rsyslog a logrotate. Příklad konfigurace níže. (nejedná se o kompletní soubor docker-compose.yml, ale pouze o příklad konfigurace jedné služby)

  pmc-be:
    image: docker.greencenter.site/pmc-backend:v2.0.3.001
    restart: always
    volumes:
      - './crt:/usr/local/share/ca-certificates/extra:ro'
      - './pmc/application-local.properties:/opt/pmc/application-local.properties'
      - './pmc/.m2:/root/.m2/repository'
      - './scep/secret:/secret/:ro'
      - './scep/depot:/opt/pmc/scep/depot'
    ports:
      - 127.0.0.1:${PMC_API_PORT}:${PMC_API_PORT}
    logging:
      driver: 'journald' # (1)!
      options:
        tag: 'pmc' # (2)!
    environment:
      PMC_BE_ENVIRONMENT: ${PMC_BE_ENVIRONMENT}
      PMC_FLAGS: "--spring.profiles.active=${PMC_BE_ENVIRONMENT} -Duser.country=CZ -Duser.language=cs"
    depends_on:
     - keycloak
     - pmc_db
     - activemq
    extra_hosts:
     - "pmc.test.local:host-gateway"

  1. Definice logovacího driveru. V tomto případě 'journald'.
  2. Konfigurace tagu, se kterým má služba logovat.

Toto nastavení způsobí, že služba už nebude logovat do dockeru, ale do systémového journalu. Zprávy mohou být posílány do odděleného souboru přes rsyslog, viz konfigurace níže.

/etc/rsyslog.d/21-pmc.conf
:programname, isequal, "pmc" /var/log/pmc.log

Rotaci logů můžeme nastavit přes utilitu logrotate

/etc/logrotate.d/pmc
/var/log/pmc.log {
        weekly
        rotate 40
        delaycompress
        compress
        notifempty
        missingok
        su root syslog
        copytruncate
}

Konfigurační soubor PMC BE

Příklad konfigurace PMC. Konkrétní konfigurace samozřejmě záleží na prostředí. U důležitých parametrů jsou doplněny poznámky.

# (1)!
# server port
server.port=8012

# this options rules connection (true) to parking, in the false option is only BE running without parking connections
pmc.dataloader = true
pmc.gmtp = true

# (2)!
pmc.sip.synchronization = true

pmc.sip.implementation = eu.scrumware.pmc.service.sip.SipService
pmc.uri.check = false
pmc.pos.cert = true


# user and password for basic auth.
# this option is not used
basic.user=webapi
basic.password=xxxxxxxxx

# (3)!
# user and password for cert installer
pmc.scep.user=scepapi
pmc.scep.password=xxxxxxxxx

# (4)!
# user and password for auth. mobile application
pmc.mobile.user = mobileapi
pmc.mobile.password=xxxxxxxxx

# (5)!
# user and password for back end auth. to keycloak
mobile.keycloak.username=pmc_backend
mobile.keycloak.password=xxxxxxxxx

# (6)!
# DB postgreSQL configuration 
spring.datasource.platform=postgres
spring.datasource.driver-class-name=org.postgresql.Driver
#spring.datasource.jdbcUrl=jdbc:postgresql://localhost:5432/pmc
spring.datasource.jdbcUrl=jdbc:postgresql://127.0.0.1:5432/pmc
sslmode=require
spring.datasource.username=pmc
spring.datasource.password=xxxxxxxxx
spring.datasource.idle-timeout=180000
spring.datasource.connection-timeout=30000
spring.datasource.minimum-idle=20
spring.datasource.maximum-pool-size=20
spring.datasource.pool-name=PmcPool
spring.datasource.max-lifetime=1800000
spring.datasource.connection-test-query=SELECT 1

# (7)!
# DB postgreSQL configuration for Asterisk
asterisk.datasource.platform=postgres
asterisk.datasource.driver-class-name=org.postgresql.Driver
asterisk.datasource.jdbcUrl=jdbc:postgresql://100.64.0.1:5432/asterisk
asterisk.datasource.username=asterisk
asterisk.datasource.password=xxxxxxxxx
asterisk.datasource.idle-timeout=180000
asterisk.datasource.connection-timeout=30000 
asterisk.datasource.minimum-idle=5
asterisk.datasource.maximum-pool-size=5
asterisk.datasource.poolName=AsteriskPool
asterisk.datasource.max-lifetime=1800000
asterisk.datasource.connectionTestQuery=SELECT 1
asterisk.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true

# (8)!
# show SQL and parameters
# spring.jpa.show-sql=true
# logging.level.org.hibernate.SQL=DEBUG
# logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE

# SQL batch
spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true
spring.jpa.properties.hibernate.jdbc.batch_size=50
spring.jpa.properties.hibernate.order_inserts=true

# (9)!
#flyway
spring.flyway.baseline-on-migrate=true
flyway.url=jdbc:postgresql://127.0.0.1:5432/pmc
flyway.user=pmc
flyway.password=xxxxxxxxx

# (10)!
# logging setting
logging.level.root=WARN
logging.level.eu.scrumware.pmc=INFO
logging.level.eu.scrumware.pmc.gmtp.service=DEBUG
logging.level.eu.scrumware.pmc.service.mqsdk=DEBUG
logging.level.cz.green=INFO
logging.level.cz.gree=INFO
logging.level.org.springframework=INFO
logging.level.com.zaxxer.hikari.HikariConfig=DEBUG
logging.level.com.zaxxer.hikari=DEBUG
logging.level.org.keycloak=TRACE
logging.level.org.springframework.web.servlet.mvc.method.annotation=INFO
logging.pattern.console=%d{yyyy-MM-dd HH:mm:ss} - %logger{36} - %msg%n
logging.pattern.file=%d{yyyy-MM-dd HH:mm:ss} - %logger{36} - %msg%n
logging.file.name=pmc.log
logging.file.max-size=100MB

spring.main.allow-bean-definition-overriding=true

# (11)!
# keycloak connection and settings
keycloak.enable-basic-auth=false
keycloak.auth-server-url=https://kc.parkcloud.cz/auth/
keycloak.realm=sw-pmc
keycloak.ssl-required=none
keycloak.allow-any-hostname=true
#keycloak.cors-allowed-methods=GET
keycloak.cors=true
keycloak.resource=pmc-front
keycloak.public-client=true
keycloak.bearer-only=true
keycloak.principal-attribute=preferred_username
keycloak.security-constraints[0].authRoles[0]=offline_access
keycloak.security-constraints[0].securityCollections[0].patterns[0]=/api/*
realm-public-key=sc
try-this.auth-server-url-short=kc.parkcloud.cz

# number of displayed rows in section event
pmc.countRows=50
pmc.last.hour=24

# default duration task value in minutes
task.duration.defaultValue = 480

# parking time out connection in ms
pmc.sleepingTime=60000

# time for refresh cards group
pmc.sip.cardGroupTimeOut=600000

# time out web sockets streams
spring.mvc.async.request-timeout=45000
pmc.sse.timeout=45000

# default enum time out in ms
pmc.enum.timeout=10000

# maximum photo age
pmc.photo.timeout=20

# fire base configuration
firebase.send.url=https://fcm.googleapis.com/fcm/send
firebase.host.url=fcm.googleapis.com
firebase.webAPIkey=xxxxxxxxx

pmc.fullText.count = 20

pmc.qm.server = true

# (12)!
pmc.qm.queue.0 = pos.q000
pmc.qm.queue.prefix = pos.q
pmc.qm.queue.blob = blob.file
pmc.qm.queue.blob.apmId = 55
pmc.qm.url = ssl://localhost:61617?verifyHostName=false
pmc.qm.username = pos_broker
pmc.qm.password = xxxxxxxxx
pmc.qm.targetFilePath = /opt/pmc/tmp
pmc.qm.targetDummyFile = /opt/pmc/tmp/dummy.txt
pmc.qm.tempDir = /opt/pmc/tmp

# (13)!
pmc.qm.ftp.url = 93.185.103.49
pmc.qm.ftp.port = 21
pmc.qm.ftp.user = pmc_ftp
pmc.qm.ftp.password = xxxxxxxxx

# (14)!
# MQ SDK setting
pmc.mqsdk.server = true
pmc.mqsdk.url = ssl://localhost:61617?verifyHostName=false
pmc.mqsdk.username = pos_broker
pmc.mqsdk.password = xxxxxxxxx
pmc.mqsdk.queueName = mqsdk
pmc.mqsdk.timeout = 10000
pmc.mqsdk.lastSyncronizeTimeout = 10000
pmc.mqsdk.expirationTime = 120000

# max upload size file
spring.servlet.multipart.max-file-size = 300MB
spring.servlet.multipart.max-request-size = 300MB

# (15)!
# pos cert registration and control
# (17)!
pmc.cert.scep.dir = ./cert/cert
# (18)!
pmc.cert.scep.bin = /var/lib/pmc/scepclient-linux-amd64
# (19)!
pmc.cert.scep.param = bin, -private-key, client.key, -challenge, xxxxxxxxx, -cn, "posName", -organization, "Scrumware", -ou, "Scrumware", -country, "CZ", -server-url, http://127.0.0.1:8099/scep
# (20)!
pmc.cert.openssl.dir = /var/lib/pmc/scep/depot/crl
# (21)!
pmc.cert.openssl.bin = openssl
# (22)!
pmc.cert.openssl.param = bin, pkcs12, -export, -out, cert.p12, -in, ./client.pem, -inkey, ./client.key, -password, pass:
# (23)!
pmc.cert.openssl.param2 = bin, ca, -config, /var/lib/pmc/scep/openssl.cnf, -passin, file:/var/lib/pmc/scep/capas, -revoke, /var/lib/pmc/scep/depot/
# (24)!
pmc.cert.openssl.param3 = bin, ca, -config, /var/lib/pmc/scep/openssl.cnf, -gencrl, -out, ./revocation.crl, -keyfile, /var/lib/pmc/scep/depot/ca.key, -passin, file:/var/lib/pmc/scep/capas

pmc.dataloader.payment.timeout = 60

# (16)!
# Actuator
management.endpoints.web.discovery.enabled=true
management.endpoints.web.base-path=/manage

management.endpoints.enabled-by-default=false
management.endpoint.auditevents.enabled=true
management.endpoint.beans.enabled=true
management.endpoint.configprops.enabled=true
management.endpoint.env.enabled=true
management.endpoint.flyway.enabled=true
management.endpoint.health.enabled=true
management.endpoint.health.show-details=always
management.endpoint.info.enabled=true
management.endpoint.loggers.enabled=true
management.endpoint.metrics.enabled=true
management.endpoint.scheduledtasks.enabled=true
management.endpoint.threaddump.enabled=true
management.endpoint.mappings.enabled=true

management.endpoints.web.exposure.include=*

pmc.mq.heaertbeat = true
pmc.extapi.keyname = x-api-key


easypark.server-url=https://gated-staging.easyparksystem.net/gated/

easypark.auth-server-url=https://sso-staging.easyparksystem.net/api/

easypark.username=GREENC_STAG
easypark.password=xxxxxxxxx
pmc.mqsdk.expirationTime = 120000
spring.jpa.properties.hibernate.cache.use_second_level_cache=true
spring.jpa.properties.hibernate.cache.use_query_cache=true
spring.jpa.properties.hibernate.cache.region.factory_class=org.hibernate.cache.jcache.JCacheRegionFactory
spring.jpa.properties.hibernate.javax.cache.provider=org.ehcache.jsr107.EhcacheCachingProvider
spring.jpa.properties.javax.persistence.sharedCache.mode=ENABLE_SELECTIVE
  1. Port, na kterém běží api
  2. Synchronizace s databází asterisu - Pokud se sip nepoužívá, mělo by být vypnuto
  3. Uživatelské jméno a heslo pro vydávání certifikátů pomocí scep
  4. Uživatelské jméno a heslo pro mobilní aplikaci
  5. Uživatelské jméno a heslo pro uživatele keycloaku, který může spravovat ostatní uživatele
  6. Připojení k databázi PMC
  7. Připojení k SIP databáti
  8. Logování SQL příkazů - odkomentovat pro debug účely
  9. Připojení k PMC databázi pro flyway
  10. Nastavení logování
  11. Nastavení keycloaku
  12. Konfigurace ActiveMQ
  13. Konfigurace FTP pro přenos videí na APM
  14. Konfigurace ActiveMQ
  15. Nastavení scep
  16. Nastavení aktuatoru
  17. Cesta k certifikátům vytvořeným přes SCEP
  18. Cesta k binárnímu souboru SCEP klienta
  19. Parametry spuštění SCEP klienta. Challenge musí odpovídat nastavení scep serveru.
  20. Cesta k CRL
  21. Binární soubor openssl - ve většině případů není třeba měnit
  22. Parametry openssl pro export certifikátu do formátu p12
  23. Parametry openssl pro zneplatnění certifikátu
  24. Parametry openssl pro vytvoření CRL

docker-compose.yml

Níže je příklad souboru docker-compose.yml - konkrétní konfigurace závisí na prostředí (časové pásmo atp.), ale toto může sloužit jako šablona. Důležité parametry jsou popsány v poznámkách.

version: '3.1'

services:

# (1)!
# PMC
  # (2)!
  pmc-db:
    image: postgres:14.12-alpine3.20
    container_name: pmc-db
    restart: always
    volumes:
      - './postgres-data:/var/lib/postgresql/data'
    ports:
      - 127.0.0.1:5435:5432
    environment:
      # (17)!
      TZ: Europe/Prague

      POSTGRES_DB: ${PMC_DB_NAME}
      POSTGRES_USER: ${PMC_DB_USER}
      POSTGRES_PASSWORD: ${PMC_DB_PASSWORD}
    # (18)!
    logging:
      driver: 'journald'
      options:
        tag: 'pmc-db'

  # (3)!
  pmc-be:
    image: docker.greencenter.site/pmc-backend:v2.0.3.032
    restart: always
    container_name: pmc-be
    volumes:
      - './crt:/usr/local/share/ca-certificates/extra:ro'
      - './pmc/application-local.properties:/opt/pmc/application-local.properties'
      - './pmc/.m2:/root/.m2/repository'
      - './scep/secret:/secret/:ro'
      - './scep/depot:/opt/pmc/scep/depot'
    ports:
      # (13)!
      - 127.0.0.1:${PMC_API_PORT}:${PMC_API_PORT}
    environment:
      TZ: Europe/Prague
      POSTGRES_DB: ${PMC_DB_NAME}
      PMC_BE_ENVIRONMENT: ${PMC_BE_ENVIRONMENT}
      PMC_FLAGS: "--spring.config.location=./ --spring.profiles.active=${PMC_BE_ENVIRONMENT} -Duser.country=CZ -Duser.language=cs docker "
    depends_on:
     - keycloak
     - pmc-db
     - activemq
    extra_hosts:
     - "pmc.green.internal:host-gateway"
    logging:
      driver: 'journald'
      options:
        tag: 'pmc-be'

  # (4)!
  pmc-fe:
    image: docker.greencenter.site/pmc-fe:v2.0.3.030
    container_name: pmc-fe
    restart: always
    environment:
      TZ: Europe/Prague
    volumes:
     - './pmc-fe/httpd.conf:/etc/apache2/apache2.conf'
     - './pmc-fe/.env:/build/.env'
     - './pmc-fe/node_modules:/build/node_modules'
    ports:
      # (16)!
      - 127.0.0.1:8089:80
    logging:
      driver: 'journald'
      options:
        tag: 'pmc-fe'

  # (5)!
  scep:
    image: docker.greencenter.site/pmc-scep:1.0
    container_name: scep
    restart: always
    environment:
      TZ: Europe/Prague
    volumes:
     - './scep/secret:/opt/scep/secret:ro'
     - './scep/depot:/opt/scep/depot'
    ports:
     # (14)!
     - 127.0.0.1:8098:8099
    logging:
      driver: 'journald'
      options:
        tag: 'pmc-scep'

# (6)!
# ActiveMQ
  activemq:
    image: apache/activemq-classic:5.18.3
    container_name: activemq
    restart: always
    environment:
      TZ: Europe/Prague
    volumes:
     - './activemq/conf:/opt/apache-activemq/conf'
    ports:
     # (15)!
     - 61618:61616
    logging:
     driver: 'journald'
     options:
       tag: 'activemq'

# (7)!
# Keycloak
  keycloak:
    image: quay.io/keycloak/keycloak:23.0.4
    container_name: keycloak
    restart: always
    volumes:
      - './keycloak_themes:/opt/keycloak/themes'
      - './kc-crt/cert.pem:/keycloak.pem:ro'
      - './kc-crt/key.pem:/keycloak.key:ro'
    environment:
      KC_LOG_LEVEL: INFO
      KC_HOSTNAME_ADMIN_URL: ${KEYCLOAK_FRONTEND_URL}
      DB_VENDOR: POSTGRES
      DB_ADDR: keycloak-db
      # (19)!
      KC_HOSTNAME_URL: ${KEYCLOAK_FRONTEND_URL}
      KC_DB: postgres
      KC_DB_URL: 'jdbc:postgresql://keycloak-db:5432/keycloak'
      KC_DB_USERNAME: keycloak
      KC_FEATURES: docker
      DB_DATABASE: keycloak
      DB_SCHEMA: public
      KC_HTTPS_PORT: ${KEYCLOAK_HTTPS_PORT}
      KC_DB_PASSWORD: ${KEYCLOAK_DB_PASSWORD}
      KEYCLOAK_ADMIN: ${KEYCLOAK_ADMIN_USER}
      KEYCLOAK_ADMIN_PASSWORD: ${KEYCLOAK_ADMIN_PASSWORD}
      KC_PROXY_HEADERS: xforwarded
      KC_PROXY: "passthrough"
      KC_HTTPS_CERTIFICATE_FILE: /keycloak.pem
      KC_HTTPS_CERTIFICATE_KEY_FILE: /keycloak.key
      KC_HOSTNAME_STRICT_BACKCHANNEL: "true"
      TZ: Europe/Prague
    ports:
      # (12)!
      - 127.0.0.1:${KEYCLOAK_HTTPS_PORT}:${KEYCLOAK_HTTPS_PORT}
      - 127.0.0.1:8084:8084
    command: " --spi-login-protocol-openid-connect-legacy-logout-redirect-uri=true  --spi-login-protocol-openid-connect-suppress-logout-confirmation-screen=true start -Dkeycloak.hostname.provider=fixed -Dkeycloak.hostname.fixed.hostname=${KEYCLOAK_HOSTNAME} -Dkeycloak.hostname.fixed.httpsPort=443 -Dkeycloak.hostname.fixed.frontendUrl=${KEYCLOAK_FRONTEND_URL}/auth -Dkeycloak.hostname.fixed.forceBackendUrlToFrontendUrl=true "
    depends_on:
      - keycloak-db
    logging:
      driver: 'journald'
      options:
        tag: 'keycloak'

  # (8)!
  keycloak-db:
    image: postgres:14.12-alpine3.20
    container_name: keycloak-db
    restart: always
    volumes:
      - './keycloak-data:/var/lib/postgresql/data'
    environment:
      TZ: Europe/Prague
      POSTGRES_DB: keycloak
      POSTGRES_USER: keycloak
      POSTGRES_PASSWORD: ${KEYCLOAK_DB_PASSWORD}
    logging:
      driver: 'journald'
      options:
        tag: 'keycloak-db'

# (9)!
# Data Pumps
  # (10)!
  etl-pmc:
    image: docker.greencenter.site/etlpostgres:1.0.4
    container_name: etl-pmc
    restart: always
    volumes:
      - './etl-pmc/application-docker-pmc.properties:/opt/etl/application-docker-pmc.properties'
      - './crt:/usr/local/share/ca-certificates/extra:ro'
    extra_hosts:
     - "pmc.green.internal:host-gateway"
    environment:
      TZ: Europe/Prague
      ETL_FLAGS: "--spring.profiles.active=docker-pmc -Duser.country=CZ -Duser.language=cs"
    logging:
      driver: 'journald'
      options:
        tag: 'etl-pmc'

  # (11)!
  etl-kc:
    image: docker.greencenter.site/etlpostgres:1.0.4
    container_name: etl-kc
    restart: always
    restart: always
    volumes:
      - './etl-kc/application-docker-pmc.properties:/opt/etl/application-docker-pmc.properties'
      - './crt:/usr/local/share/ca-certificates/extra:ro'
    extra_hosts:
     - "pmc.green.internal:host-gateway"
    environment:
      TZ: Europe/Prague
      ETL_FLAGS: "--spring.profiles.active=docker-pmc -Duser.country=CZ -Duser.language=cs"
    logging:
      driver: 'journald'
      options:
        tag: 'etl-kc'
  1. Část konfigurace, kde se nastavují kontejnery související s aplikací PMC
  2. Databáze PMC
  3. PMC - backend
  4. PMC - frontend
  5. SCEP - služba na vydávání certifikátů pro POS
  6. Konfigurace služby ActiveMQ
  7. Část konfigurace, kde se nastavují kontejnery související s aplikací Keycloak
  8. Databáze aplikace keycloak
  9. Část konfigurace, kde se nastavují kontejnery související s ETL
  10. Datová pumpa PMC
  11. Datová pumpa Keycloak
  12. Https port keycloaku - tento port je definován v souboru .env a musí odpovídat nastavení reverse-proxy.
  13. API port PMC - tento port je devinován v souboru .env a musí odpovídat nastavení reverse-proxy. Zároveň musí sedět s nastavením server.port v properties backendu
  14. Port pro SCEP - musí odpovídat nastavení reverse-proxy.
  15. Na tomto portu bude dostupné AciveMQ. (Na všech síťových rozhraních!)
  16. Na tomto portu bude dostupné pmc-fe. Musí odpovídat nastavení reverse-proxy
  17. Nastavení časového pásma - toto je doporučeno nastavit u všech kontejnerů
  18. Viz logování
  19. URL keycloaku - definováno v souboru .env a musí přesně odpovídat doméně, na které je keycloak dostupný. Příklad: https://kc.parkcloud.cz