x-db-credentials: &db-credentials
  POSTGRES_USER: &db-user ${POSTGRES_USER}
  POSTGRES_PASSWORD: &db-password ${POSTGRES_PASSWORD}
  POSTGRES_DB: &db-name ${POSTGRES_DB}

services:   
  code-server:
    build:
      context: .
      dockerfile: Dockerfile.code-server
    container_name: code-server-changemaker
    environment:
      - DOCKER_USER=${USER_NAME:-coder}
      - DEFAULT_WORKSPACE=/home/coder/mkdocs/
    user: "${USER_ID:-1000}:${GROUP_ID:-1000}"
    volumes:
      - ./configs/code-server/.config:/home/coder/.config
      - ./configs/code-server/.local:/home/coder/.local
      - ./mkdocs:/home/coder/mkdocs/
    ports:
      - "${CODE_SERVER_PORT:-8888}:8080"
    restart: unless-stopped
    networks:
      - changemaker-lite

  listmonk-app:
    image: listmonk/listmonk:latest
    container_name: listmonk_app
    restart: unless-stopped
    ports:
      - "${LISTMONK_PORT:-9000}:9000"
    networks:
      - changemaker-lite
    hostname: ${LISTMONK_HOSTNAME}
    depends_on:
      - listmonk-db
    command: [sh, -c, "./listmonk --install --idempotent --yes --config '' && ./listmonk --upgrade --yes --config '' && ./listmonk --config ''"]
    environment:
      LISTMONK_app__address: 0.0.0.0:9000
      LISTMONK_db__user: *db-user
      LISTMONK_db__password: *db-password
      LISTMONK_db__database: *db-name
      LISTMONK_db__host: listmonk-db
      LISTMONK_db__port: 5432
      LISTMONK_db__ssl_mode: disable
      LISTMONK_db__max_open: 25
      LISTMONK_db__max_idle: 25
      LISTMONK_db__max_lifetime: 300s
      TZ: Etc/UTC
      LISTMONK_ADMIN_USER: ${LISTMONK_ADMIN_USER:-}
      LISTMONK_ADMIN_PASSWORD: ${LISTMONK_ADMIN_PASSWORD:-}
    volumes:
      - ./assets/uploads:/listmonk/uploads:rw

  listmonk-db:
    image: postgres:17-alpine
    container_name: listmonk_db
    restart: unless-stopped
    ports:
      - "127.0.0.1:${LISTMONK_DB_PORT:-5432}:5432"
    networks:
      - changemaker-lite
    environment:
      <<: *db-credentials
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER}"]
      interval: 10s
      timeout: 5s
      retries: 6
    volumes:
      - type: volume
        source: listmonk-data
        target: /var/lib/postgresql/data

  mkdocs:
    image: squidfunk/mkdocs-material
    container_name: mkdocs-changemaker
    volumes:
      - ./mkdocs:/docs:rw
      - ./assets/images:/docs/assets/images:rw
    user: "${USER_ID:-1000}:${GROUP_ID:-1000}"
    ports:
      - "${MKDOCS_PORT:-4000}:8000"
    environment:
      - SITE_URL=${BASE_DOMAIN:-https://changeme.org}
    command: serve --dev-addr=0.0.0.0:8000 --watch-theme --livereload
    networks:
      - changemaker-lite
    restart: unless-stopped

  mkdocs-site-server:
    image: lscr.io/linuxserver/nginx:latest
    container_name: mkdocs-site-server-changemaker
    environment:
      - PUID=${USER_ID:-1000}  # Uses USER_ID from your .env file, defaults to 1000
      - PGID=${GROUP_ID:-1000} # Uses GROUP_ID from your .env file, defaults to 1000
      - TZ=Etc/UTC
    volumes:
      - ./mkdocs/site:/config/www  # Mounts your static site to Nginx's web root
    ports:
      - "${MKDOCS_SITE_SERVER_PORT:-4001}:80"  # Exposes Nginx's port 80 to host port 4001
    restart: unless-stopped
    networks:
      - changemaker-lite

  n8n:
    image: docker.n8n.io/n8nio/n8n
    container_name: n8n-changemaker
    restart: unless-stopped
    ports:
      - "${N8N_PORT:-5678}:5678"
    environment:
      - N8N_HOST=${N8N_HOST:-n8n.${DOMAIN}}
      - N8N_PORT=5678
      - N8N_PROTOCOL=https
      - NODE_ENV=production
      - WEBHOOK_URL=https://${N8N_HOST:-n8n.${DOMAIN}}/
      - GENERIC_TIMEZONE=${GENERIC_TIMEZONE:-UTC}
      - N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY:-changeMe}
      - N8N_USER_MANAGEMENT_DISABLED=false
      - N8N_DEFAULT_USER_EMAIL=${N8N_USER_EMAIL:-admin@example.com}
      - N8N_DEFAULT_USER_PASSWORD=${N8N_USER_PASSWORD:-changeMe}
    volumes:
      - n8n_data:/home/node/.n8n
      - ./local-files:/files
    networks:
      - changemaker-lite

  nocodb: 
    depends_on: 
      root_db: 
        condition: service_healthy
    environment: 
      NC_DB: "pg://root_db:5432?u=postgres&p=password&d=root_db"
    image: "nocodb/nocodb:latest"
    ports: 
      - "${NOCODB_PORT:-8090}:8080"
    restart: always
    volumes: 
      - "nc_data:/usr/app/data"
    networks:
      - changemaker-lite
  root_db: 
    environment: 
      POSTGRES_DB: root_db
      POSTGRES_PASSWORD: password
      POSTGRES_USER: postgres
    healthcheck: 
      interval: 10s
      retries: 10
      test: "pg_isready -U \"$$POSTGRES_USER\" -d \"$$POSTGRES_DB\""
      timeout: 2s
    image: postgres:16.6
    restart: always
    volumes: 
      - "db_data:/var/lib/postgresql/data"
    networks:
      - changemaker-lite

  # Homepage App
  homepage-changemaker:
    image: ghcr.io/gethomepage/homepage:latest
    container_name: homepage-changemaker
    ports:
      - "${HOMEPAGE_PORT:-3010}:3000"
    volumes:
      - ./configs/homepage:/app/config
      - ./assets/icons:/app/public/icons
      - ./assets/images:/app/public/images
      - /var/run/docker.sock:/var/run/docker.sock
    environment:
      - PUID=${USER_ID:-1000}
      - PGID=${DOCKER_GROUP_ID:-984}
      - TZ=Etc/UTC
      - HOMEPAGE_ALLOWED_HOSTS=*
      - HOMEPAGE_VAR_BASE_URL=${HOMEPAGE_VAR_BASE_URL:-http://localhost}
    restart: unless-stopped
    networks:
      - changemaker-lite

  # Gitea - Git service
  gitea-app:
    image: gitea/gitea:1.23.7
    container_name: gitea_changemaker
    environment:
      - USER_UID=${USER_ID:-1000}
      - USER_GID=${GROUP_ID:-1000}
      - GITEA__database__DB_TYPE=${GITEA_DB_TYPE:-mysql}
      - GITEA__database__HOST=${GITEA_DB_HOST:-gitea-db:3306}
      - GITEA__database__NAME=${GITEA_DB_NAME:-gitea}
      - GITEA__database__USER=${GITEA_DB_USER:-gitea}
      - GITEA__database__PASSWD=${GITEA_DB_PASSWD}
      - GITEA__server__ROOT_URL=${GITEA_ROOT_URL}
      - GITEA__server__HTTP_PORT=3000
      - GITEA__server__PROTOCOL=http
      - GITEA__server__DOMAIN=${GITEA_DOMAIN}
      - GITEA__server__ENABLE_GZIP=true
      - GITEA__server__PROXY_PROTOCOL=true
      - GITEA__server__PROXY_PROXY_PROTOCOL_TLS=true
      - GITEA__server__PROXY_ALLOW_SUBNET=0.0.0.0/0
    restart: unless-stopped
    networks:
      - changemaker-lite
    volumes:
      - gitea_data:/data
      - /etc/timezone:/etc/timezone:ro
      - /etc/localtime:/etc/localtime:ro
    ports:
      - "${GITEA_WEB_PORT:-3030}:3000"
      - "${GITEA_SSH_PORT:-2222}:22"
    depends_on:
      - gitea-db

  gitea-db:
    image: mysql:8
    container_name: gitea_mysql_changemaker
    restart: unless-stopped
    environment:
      - MYSQL_ROOT_PASSWORD=${GITEA_DB_ROOT_PASSWORD}
      - MYSQL_USER=${GITEA_DB_USER:-gitea}
      - MYSQL_PASSWORD=${GITEA_DB_PASSWD}
      - MYSQL_DATABASE=${GITEA_DB_NAME:-gitea}
    networks:
      - changemaker-lite
    volumes:
      - mysql_data:/var/lib/mysql
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "${GITEA_DB_USER:-gitea}", "-p${GITEA_DB_PASSWD}"]
      interval: 10s
      timeout: 5s
      retries: 5

  # Client Website Server
  client-website-server:
    image: lscr.io/linuxserver/nginx:latest
    container_name: client-website-server-changemaker
    environment:
      - PUID=${USER_ID:-1000}
      - PGID=${GROUP_ID:-1000}
      - TZ=Etc/UTC
    volumes:
      - ./site:/config/www
      - ./configs/nginx/client-website/default.conf:/config/nginx/site-confs/default.conf
    ports:
      - "${CLIENT_WEBSITE_PORT:-8080}:80"
    restart: unless-stopped
    networks:
      - changemaker-lite

networks:
  changemaker-lite:
    driver: bridge

volumes:
  listmonk-data:
  n8n_data:
  nc_data:
  db_data:
  gitea_data:
  mysql_data: