# run "docker-compose -p derejame up -d" to run with stack name

#version: '3.9'
#docker-compose -p derejame up -d
#docker-compose -p derejame down --volumes --rmi all
#docker-compose -f docker-compose.yml -p derejame up -d
#docker-compose -f docker-compose.yml -p derejame up -d --build --no-cache
#docker-compose -f docker-compose.yml -p derejame down --volumes
#docker-compose -f docker-compose.yml -p derejame down --volumes --rmi all 
# Stop and remove everything
#docker-compose -p derejame down --volumes --rmi all
# Build fresh images with no cache
#docker-compose -f docker-compose.yml -p derejame build --no-cache
# Start the services
#docker-compose -f docker-compose.yml -p derejame up -d
#sudo rm -rf /var/lib/docker/volumes/derejame_web_content/_data/backend/forms/vendor/baluart/yii2-tom-select
# to remove non persitent data and volumes for the webcontent
version: '3.9'

services:
  # Shared volume for web content
  webdata:
#    image: alpine
    image: php:8.2-fpm-alpine
    container_name: derejame_webdata
    volumes:
      - web_content:/var/www/html
      - ./:/source # Uncomment it for development only persists files and folders
#      - ./:/var/www/html # Uncomment it for development only persists files and folders      
    networks:
      derejanet:
        ipv4_address: 192.168.160.55
#    command: sh -c "cp -a /source/. /var/www/html && chown -R www-data:www-data /var/www/html && tail -f /dev/null"
# To manually add user group to the command below add the following line at the top of the command
#     addgroup -S www-data && adduser -S www-data -G www-data &&
    command: >
      sh -c "
        apk add inotify-tools rsync &&
        rsync -a /source/ /var/www/html/ &&
        chown -R www-data:www-data /var/www/html &&
        while inotifywait -r -e modify,create,delete /source; do
          rsync -a /source/ /var/www/html/ &&
          chown -R www-data:www-data /var/www/html;
        done &&
        tail -f /dev/null
      "    
#    command: sh -c "cp -a /source/. /var/www/html && chown -R www-data:www-data /var/www/html && tail -f /dev/null"        
#    command: tail -f /dev/null  # This will keep the container running
    #command: ["chown", "-R", "www-data:www-data", "/var/www/html"]

  php:
    #image: mikeintosh/derejame:latest
    build:
      context: .
      dockerfile: Dockerfile
      target: base
    container_name: derejame_system
    volumes:
      - web_content:/var/www/html
      #- ./docker-entrypoint.sh:/usr/local/bin/docker-entrypoint.sh  # Uncomment it for development only persists files and folders    
    expose:
      - "9009"
    depends_on:
      - db
      - webdata
    networks:
      derejanet:
        ipv4_address: 192.168.160.10

#    entrypoint: ["sh", "/usr/local/bin/docker-entrypoint.sh"]
#    command: ["php-fpm"]        
   
  nginx:
    build:
      context: .
      dockerfile: Dockerfile
      target: nginx_extended
    container_name: derejame_nginx
    ports:
      - "8880:80"
      - "8443:443"  # Change it from 8443 to standard 443
    volumes:
      - web_content:/var/www/html
      - /etc/letsencrypt:/etc/letsencrypt:ro  # Add this line to mount SSL certs
      - ./config/nginx.conf:/etc/nginx/conf.d/default.conf
    depends_on:
      - php
      - webdata
      - metabase  # Ensure metabase is available
    networks:
      derejanet:
        ipv4_address: 192.168.160.20

  metabase:
    image: metabase/metabase:latest
    container_name: derjame_metabase
    ports:
      - "4000:3000"
    environment:
      MB_DB_FILE: /dev/random/merqdereja.db
      MB_DB_TYPE: postgres
      MB_DB_DBNAME: merqderejadb
      MB_DB_PORT: 5432
      MB_DB_USER: merqderejadb
      MB_DB_PASS: merqderejadb
      MB_DB_HOST: postgres
      MB_ADMIN_EMAIL: dev@merqconsultancy.org
      MB_ADMIN_FIRST_NAME: MERQ
      MB_ADMIN_PASSWORD: merqderejadev0
      MB_SITE_URL: "https://viz.mne.dereja.com"
      MB_APPLICATION_NAME: "Dereja M&E Analytics"
      MB_EMBEDDING_SECRET_KEY: "9693b4787b92d195bd1352bea4dc71b5bfff0da137ee549388cb2d6524f432a0" # Change this to a secure random string if you have to but fix the embedding secret key in the metabase settings
      MB_ENABLE_EMBEDDING: "true"
# On Virtualmin Apache server, you need to create a proxy for the metabase service
# Note to remember create  sudo virtualmin create-proxy --domain viz.mne.dereja.com --path / --url http://127.0.0.1:4000/
# sudo cat /etc/apache2/sites-enabled/viz.mne.dereja.com.conf
# sudo virtualmin list-proxies --domain viz.mne.dereja.com
# Verify the proxy is working by running the following command
#curl http://127.0.0.1:4000/api/health
    depends_on:
      - postgres
    networks:
      derejanet:
        ipv4_address: 192.168.160.30

  postgres:
    image: postgres:latest
    container_name: derejame_postgres
    environment:
      POSTGRES_DB: merqderejadb
      POSTGRES_USER: merqderejadb
      POSTGRES_PASSWORD: merqderejadb
    volumes:
      - postgres_data:/var/lib/postgresql/data
      - ./src/merqderejadb:/docker-entrypoint-initdb.d/merqderejadb
    networks:
      derejanet:
        ipv4_address: 192.168.160.40

  db:
    image: mariadb:latest
    container_name: derejame_mariadb
    restart: always
    environment:
      MYSQL_ROOT_HOST: localhost # will be accessible only from the host machine using 127.0.0.1
      # MYSQL_ROOT_HOST: '%' # Uncomment this line to allow remote root access
      MYSQL_DATABASE: me_dereja
      MYSQL_ROOT_PASSWORD: merqderejadmin
      MYSQL_USER: me_dereja
      MYSQL_PASSWORD: me_dereja
    volumes:
      - mysql_data:/var/lib/mysql
      - ./mysql-init:/docker-entrypoint-initdb.d
    ports:
      - "3306:3306" # Expose MySQL/MariaDB on port 3306 to the host and make sure it is not already in use
    networks:
      #- derejanet
      derejanet:
        ipv4_address: 192.168.160.50

  phpmyadmin:
    image: phpmyadmin:latest
    restart: always
    ports:
      - "3307:80"
    environment:
      PMA_ARBITRARY: 1
      PMA_HOSTS: db
      PMA_USER: me_dereja
      PMA_PASSWORD: me_dereja
      UPLOAD_LIMIT: 300M
    networks:
      derejanet:
        ipv4_address: 192.168.160.60

  pgadmin:
    image: dpage/pgadmin4:latest
    ports:
      - "5454:80"
    environment:
      PGADMIN_DEFAULT_EMAIL: dev@merqconsultancy.org
      PGADMIN_DEFAULT_PASSWORD: merqderejadev
    volumes:
      - pgadmin_data:/var/lib/pgadmin
    depends_on:
      - postgres
    networks:
      derejanet:
        ipv4_address: 192.168.160.70

# Add Portainer and setup service to docker-compose for container management
  portainer:
    image: portainer/portainer-ce:latest
    container_name: derejame_portainer
    restart: unless-stopped
    ports:
      - "9099:9000"
    volumes:
      - portainer_data:/data
      - /var/run/docker.sock:/var/run/docker.sock
    environment:
      - DOCKER_HOST=tcp://docker-proxy:2375
    networks:
      derejanet:
        ipv4_address: 192.168.160.110

  portainer-setup:
    image: curlimages/curl:latest
    container_name: portainer-setup
    user: root
    depends_on:
      - portainer
    networks:
      derejanet:
        ipv4_address: 192.168.160.120
    command: |
      sh -c '
      apk add --no-cache jq
      until curl -s http://portainer:9000/api/status >/dev/null; do sleep 2; done

      # Create admin user
      curl -X POST http://portainer:9000/api/users/admin/init \
        -H "Content-Type: application/json" \
        -d "{\"username\":\"admin\",\"password\":\"derejaportainers\"}"

      TOKEN=$$(curl -s -X POST http://portainer:9000/api/auth \
        -H "Content-Type: application/json" \
        -d "{\"username\":\"admin\",\"password\":\"derejaportainers\"}" \
        | jq -r ".jwt")

      # Create a new user with restricted access
      curl -X POST http://portainer:9000/api/users \
        -H "Content-Type: application/json" \
        -H "Authorization: Bearer $$TOKEN" \
        -d "{\"username\":\"dereja_user\",\"password\":\"derejapassword\",\"role\":2}"

      # Apply resource filtering to restrict access to derejame stack only
      curl -X PUT http://portainer:9000/api/settings \
        -H "Content-Type: application/json" \
        -H "Authorization: Bearer $$TOKEN" \
        -d "{\"resourceFilters\":[{\"type\":\"label\",\"label\":\"com.docker.compose.project=derejame\"}]}"

      # Assign 'derejame_user' access to derejame stack only
      STACK_ID=$$(curl -s -X GET http://portainer:9000/api/stacks \
        -H "Authorization: Bearer $$TOKEN" | jq -r '.[] | select(.Name=="derejame") | .Id')

      curl -X PUT http://portainer:9000/api/stacks/$$STACK_ID/access \
        -H "Content-Type: application/json" \
        -H "Authorization: Bearer $$TOKEN" \
        -d "[{\"UserId\":2,\"Role\":1}]"
      '

  mongo:
    image: mongo:latest
    restart: always
    environment:
      MONGO_INITDB_ROOT_USERNAME: merqderejadev
      MONGO_INITDB_ROOT_PASSWORD: merqderejadev
    volumes:
      - mongo_data:/data/db
    networks:
      derejanet:
        ipv4_address: 192.168.160.80

  mongo-express:
    image: mongo-express:latest
    restart: always
    ports:
      - "8018:8081"
    environment:
      ME_CONFIG_MONGODB_ADMINUSERNAME: merqderejadev
      ME_CONFIG_MONGODB_ADMINPASSWORD: merqderejadev
      ME_CONFIG_MONGODB_URL: mongodb://merqderejadev:merqderejadev@mongo:27017/
      ME_CONFIG_BASICAUTH_USERNAME: merqderejauser
      ME_CONFIG_BASICAUTH_PASSWORD: merqderejauser
    depends_on:
      - mongo
    networks:
      derejanet:
        ipv4_address: 192.168.160.90

  chat:
#    image: derejame_chatbot
    container_name: derejame_chatbot
    build:
      context: .
      dockerfile: Dockerfile
      target: ai_chatbot
    ports:
      - "8502:8502"
    volumes:
      - ./ai/chat:/ai/chat
    environment:
      - PYTHONUNBUFFERED=1
    healthcheck:
      test: ["CMD", "curl", "--fail", "http://localhost:8502/_stcore/health"]      
      #test: ["CMD", "curl", "--fail", "https://localhost:8502/_stcore/health"]      
#      test: ["CMD", "wget", "--spider", "https://localhost:8502/_stcore/health"]
      interval: 30s  # Check health every 30 seconds
      retries: 3  # Retry up to 3 times before marking as unhealthy
      start_period: 10s  # Wait 10 seconds before starting health checks
      timeout: 5s  # Health check timeout of 5 seconds    
    networks:
      derejanet:
        ipv4_address: 192.168.160.100

  mkdocs:
    image: squidfunk/mkdocs-material:latest
    container_name: dereja_docs
    ports:
      - "8558:8558"  # Expose MkDocs server on port 8000
    volumes:
      - ./docs/userguide/:/docs  # Mount the current docs directory to /docs inside the container
    restart: unless-stopped  # Ensures the container restarts unless manually stopped
    command: serve -a 0.0.0.0:8558  # Start the MkDocs development server on all interfaces

    environment:
      - MKDOCS_CONFIG=mkdocs.yml  # Specify the configuration file

    healthcheck:
      #test: ["CMD", "curl", "-f", "http://0.0.0.0:8558"]  # Health check for the service
      test: ["CMD", "nc", "-z", "0.0.0.0", "8558"]  # Health check for the service
      interval: 30s  # Check health every 30 seconds
      retries: 3  # Retry up to 3 times before marking as unhealthy
      start_period: 10s  # Wait 10 seconds before starting health checks
      timeout: 5s  # Health check timeout of 5 seconds

    networks:
      derejanet:
        ipv4_address: 192.168.160.130

  # OpenAPI Generator Service
  openapigen:
    build:
      context: .
      dockerfile: Dockerfile
      target: openapi_gen
    container_name: derejame_openapigen
    restart: unless-stopped
    volumes:
      - ./api/gen:/app
    ports:
      - "5000:5000"
    environment:
      - DB_HOST=db
      - DB_PORT=${DB_PORT:-3306}
      - DB_USER=${DB_USER:-me_dereja}
      - DB_PASSWORD=${DB_PASSWORD:-me_dereja}
      - DB_NAME=${DB_NAME:-me_dereja}
      - FLASK_HOST=0.0.0.0
      - FLASK_PORT=5000
      - FLASK_DEBUG=${FLASK_DEBUG:-False}
    depends_on:
      - db
    networks:
      derejanet:
        ipv4_address: 192.168.160.140
    healthcheck:
      test: ["CMD", "nc", "-z", "0.0.0.0", "5000"]  # Health check for the openapigen service    
      #test: ["CMD", "curl", "-f", "http://localhost:5000"]
      interval: 30s
      timeout: 10s
      retries: 3

  # Swagger Editor Service
  derejame_swagger_editor:
    image: docker.swagger.io/swaggerapi/swagger-editor:latest
    container_name: derejame_swagger_editor
    environment:
      - URL=https://mne.dereja.com/api/gen/derejamne_dynamic.yaml
    ports:
      - "8080:8080"
    networks:
      derejanet:
        ipv4_address: 192.168.160.150
    restart: unless-stopped

  # Swagger UI Service
  derejame_swagger_ui:
    image: swaggerapi/swagger-ui
    container_name: derejame_swagger_ui
    environment:
      - SWAGGER_JSON_URL=https://mne.dereja.com/api/gen/output/openapi.json
    ports:
      - "5055:8080"
    networks:
      derejanet:
        ipv4_address: 192.168.160.160
    restart: unless-stopped      
      
networks:
  derejanet:
    driver: bridge
    ipam:
      config:
        - subnet: 192.168.160.0/24

volumes:
  web_content:
  postgres_data:
  mysql_data:
  pgadmin_data:
  portainer_data:
  mongo_data: