File size: 4,587 Bytes
669e1fe
 
 
5de0538
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
669e1fe
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4317049
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
59d0f3b
a539e91
1307cd4
044c02e
 
 
 
 
 
59d0f3b
 
 
 
 
 
 
 
044c02e
 
59d0f3b
 
 
 
 
 
 
044c02e
 
 
 
 
 
286e89e
044c02e
a7eec1a
044c02e
 
 
b359c29
044c02e
 
 
59d0f3b
 
 
 
 
044c02e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9675789
044c02e
 
 
 
 
 
669e1fe
 
4317049
044c02e
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
version: '3.8'

services:
  # app:
  #   build: .
  #   ports:
  #     - "5003:5003"
  #   volumes:
  #     - ./storage:/app/storage
  #     - ./instance:/app/instance
  #   environment:
  #     PYTHONUNBUFFERED: 1
  #     POSTGRES_USER: attstoreuser
  #     POSTGRES_PASSWORD: attstorepass
  #     POSTGRES_DB: attstoredb
  #     DATABASE_URL: postgresql://attstoreuser:attstorepass@postgres:5432/attstoredb
  #     STORAGE_TYPE: CLOUD_STORAGE
  #     MINIO_ENDPOINT: http://minio:9000
  #     MINIO_ACCESS_KEY: minioadmin
  #     MINIO_SECRET_KEY: minioadmin
  #     MINIO_BUCKET: attstorebucket
  #     MINIO_SECURE: 'false'
  #   depends_on:
  #     postgres:
  #       condition: service_healthy
  #     minio:
  #       condition: service_healthy

  postgres:
    image: postgres:15
    restart: always
    ports:
      - "5432:5432"
    environment:
      POSTGRES_USER: attstoreuser
      POSTGRES_PASSWORD: attstorepass
      POSTGRES_DB: attstoredb
    volumes:
      - pgdata:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -q -U $${POSTGRES_USER:-attstoreuser} -d $${POSTGRES_DB:-attstoredb} -h 127.0.0.1 -p 5432"]
      interval: 5s
      timeout: 5s
      retries: 5
  minio:
    image: minio/minio:latest
    command: server /data --console-address ":9001"
    ports:
      - "9000:9000"
      - "9001:9001"
    environment:
      MINIO_ROOT_USER: minioadmin
      MINIO_ROOT_PASSWORD: minioadmin
    volumes:
      - minio-data:/data
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/ready"]
      interval: 5s
      timeout: 5s
      retries: 5
  attstore:
    image: ghcr.io/scribe-security/attstore:latest
    platform: linux/amd64
    # Expose only to the internal network; Traefik will publish externally
    expose:
      - "5003"
    networks:
      - default
      - lbnet
    volumes:
      - ./storage:/app/storage
      - ./instance:/app/instance
    environment:
      PYTHONUNBUFFERED: 1
      POSTGRES_USER: attstoreuser
      POSTGRES_PASSWORD: attstorepass
      POSTGRES_DB: attstoredb
      # Route DB connections through PgBouncer for pooling
      DATABASE_URL: postgresql://attstoreuser:attstorepass@pgbouncer:6432/attstoredb
      STORAGE_TYPE: CLOUD_STORAGE
      CLOUD_STORAGE_PROVIDER: MINIO
      MINIO_ENDPOINT: http://minio:9000
      MINIO_ACCESS_KEY: minioadmin
      MINIO_SECRET_KEY: minioadmin
      MINIO_BUCKET: attstorebucket
      MINIO_SECURE: 'false'
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.attstore.rule=PathPrefix(`/`)"
      - "traefik.http.routers.attstore.entrypoints=web"
      - "traefik.http.services.attstore.loadbalancer.server.port=5003"
      - "traefik.http.services.attstore.loadbalancer.server.scheme=http"
      - "traefik.http.services.attstore.loadbalancer.sticky.cookie.name=attstore-sticky-cookie"
      - "traefik.docker.network=lbnet"
      - "traefik.http.services.attstore.loadbalancer.healthcheck.path=/healthz"
      - "traefik.http.services.attstore.loadbalancer.healthcheck.interval=5s"
      - "traefik.http.services.attstore.loadbalancer.healthcheck.timeout=2s"
    healthcheck:
      test: ["CMD-SHELL", "python - <<'PY'\nimport sys,urllib.request\ntry:\n    with urllib.request.urlopen('http://localhost:5003/healthz', timeout=2) as r:\n        sys.exit(0 if r.status == 200 else 1)\nexcept Exception:\n    sys.exit(1)\nPY\n"]
      interval: 5s
      timeout: 3s
      retries: 20
    depends_on:
      postgres:
        condition: service_healthy
      minio:
        condition: service_healthy
      pgbouncer:
        condition: service_started

  # Reverse proxy / load balancer that exposes :5003 externally
  traefik:
    image: traefik:v2.10
    command:
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.web.address=:5003"
      - "--log.level=INFO"
    ports:
      - "5003:5003"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock:ro"
    networks:
      - lbnet

  # Connection pooler for Postgres
  pgbouncer:
    image: edoburu/pgbouncer:latest
    expose:
      - "6432"
    environment:
      DB_HOST: postgres
      DB_PORT: 5432
      DB_USER: attstoreuser
      DB_PASSWORD: attstorepass
      DB_NAME: attstoredb
      POOL_MODE: transaction
      MAX_CLIENT_CONN: 600
      DEFAULT_POOL_SIZE: 20
      AUTH_TYPE: plain
      LISTEN_ADDR: 0.0.0.0
      LISTEN_PORT: 6432
    depends_on:
      postgres:
        condition: service_healthy

volumes:
  pgdata:
  minio-data:

networks:
  lbnet:
    name: lbnet