Refactored.
This commit is contained in:
parent
f4a49ad4b9
commit
9dad75464b
37 changed files with 667 additions and 247 deletions
|
|
@ -123,9 +123,9 @@ task dev:status
|
|||
|
||||
```
|
||||
NAMES STATUS PORTS
|
||||
maple-cassandra-1-dev Up 2 minutes (healthy) 0.0.0.0:9042->9042/tcp
|
||||
maple-redis-dev Up 2 minutes (healthy) 0.0.0.0:6379->6379/tcp
|
||||
maple-wordpress-dev Up 2 minutes (healthy) 0.0.0.0:8081->80/tcp
|
||||
mapleopentech-cassandra-1-dev Up 2 minutes (healthy) 0.0.0.0:9042->9042/tcp
|
||||
mapleopentech-redis-dev Up 2 minutes (healthy) 0.0.0.0:6379->6379/tcp
|
||||
mapleopentech-wordpress-dev Up 2 minutes (healthy) 0.0.0.0:8081->80/tcp
|
||||
...
|
||||
```
|
||||
|
||||
|
|
@ -264,7 +264,7 @@ task redis
|
|||
|
||||
**View debug logs:**
|
||||
```bash
|
||||
docker exec -it maple-wordpress-dev tail -f /var/www/html/wp-content/debug.log
|
||||
docker exec -it mapleopentech-wordpress-dev tail -f /var/www/html/wp-content/debug.log
|
||||
```
|
||||
|
||||
### Working with SeaweedFS (S3 Storage)
|
||||
|
|
@ -298,12 +298,12 @@ S3_SECRET_KEY=any
|
|||
|
||||
All data is stored in Docker volumes and survives restarts:
|
||||
|
||||
- `maple-cassandra-1-dev`, `maple-cassandra-2-dev`, `maple-cassandra-3-dev`
|
||||
- `maple-redis-dev`
|
||||
- `maple-meilisearch-dev`
|
||||
- `maple-seaweedfs-dev`
|
||||
- `maple-mariadb-dev`
|
||||
- `maple-wordpress-dev`
|
||||
- `mapleopentech-cassandra-1-dev`, `mapleopentech-cassandra-2-dev`, `mapleopentech-cassandra-3-dev`
|
||||
- `mapleopentech-redis-dev`
|
||||
- `mapleopentech-meilisearch-dev`
|
||||
- `mapleopentech-seaweedfs-dev`
|
||||
- `mapleopentech-mariadb-dev`
|
||||
- `mapleopentech-wordpress-dev`
|
||||
|
||||
**To completely reset (deletes all data):**
|
||||
```bash
|
||||
|
|
@ -336,7 +336,7 @@ WITH replication = {'class': 'SimpleStrategy', 'replication_factor': 3};
|
|||
2. Configure your project's `docker-compose.dev.yml`:
|
||||
```yaml
|
||||
networks:
|
||||
maple-dev:
|
||||
mapleopentech-dev:
|
||||
external: true
|
||||
|
||||
services:
|
||||
|
|
@ -349,7 +349,7 @@ services:
|
|||
- REDIS_HOST=redis
|
||||
- REDIS_DB=2 # Use next available: 0=maplepress, 1=maplefile
|
||||
networks:
|
||||
- maple-dev
|
||||
- mapleopentech-dev
|
||||
```
|
||||
|
||||
3. Restart infrastructure:
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
version: '3'
|
||||
version: "3"
|
||||
|
||||
# Variables for Docker Compose command detection
|
||||
vars:
|
||||
|
|
@ -24,7 +24,7 @@ tasks:
|
|||
- echo "✅ Infrastructure ready!"
|
||||
- echo ""
|
||||
- echo "📊 Running Services:"
|
||||
- docker ps --filter "name=maple-"
|
||||
- docker ps --filter "name=mapleopentech-"
|
||||
|
||||
dev:wait:
|
||||
desc: Wait for all services to be healthy
|
||||
|
|
@ -33,7 +33,7 @@ tasks:
|
|||
- |
|
||||
echo "Waiting for Cassandra Node 1..."
|
||||
for i in {1..30}; do
|
||||
if docker exec maple-cassandra-1-dev cqlsh -e "describe cluster" >/dev/null 2>&1; then
|
||||
if docker exec mapleopentech-cassandra-1-dev cqlsh -e "describe cluster" >/dev/null 2>&1; then
|
||||
echo "✅ Cassandra Node 1 is ready"
|
||||
break
|
||||
fi
|
||||
|
|
@ -43,7 +43,7 @@ tasks:
|
|||
- |
|
||||
echo "Waiting for Cassandra Node 2..."
|
||||
for i in {1..30}; do
|
||||
if docker exec maple-cassandra-2-dev cqlsh -e "describe cluster" >/dev/null 2>&1; then
|
||||
if docker exec mapleopentech-cassandra-2-dev cqlsh -e "describe cluster" >/dev/null 2>&1; then
|
||||
echo "✅ Cassandra Node 2 is ready"
|
||||
break
|
||||
fi
|
||||
|
|
@ -53,7 +53,7 @@ tasks:
|
|||
- |
|
||||
echo "Waiting for Cassandra Node 3..."
|
||||
for i in {1..30}; do
|
||||
if docker exec maple-cassandra-3-dev cqlsh -e "describe cluster" >/dev/null 2>&1; then
|
||||
if docker exec mapleopentech-cassandra-3-dev cqlsh -e "describe cluster" >/dev/null 2>&1; then
|
||||
echo "✅ Cassandra Node 3 is ready"
|
||||
break
|
||||
fi
|
||||
|
|
@ -63,7 +63,7 @@ tasks:
|
|||
- |
|
||||
echo "Waiting for Redis..."
|
||||
for i in {1..10}; do
|
||||
if docker exec maple-redis-dev redis-cli ping >/dev/null 2>&1; then
|
||||
if docker exec mapleopentech-redis-dev redis-cli ping >/dev/null 2>&1; then
|
||||
echo "✅ Redis is ready"
|
||||
break
|
||||
fi
|
||||
|
|
@ -72,7 +72,7 @@ tasks:
|
|||
- |
|
||||
echo "Waiting for SeaweedFS..."
|
||||
for i in {1..10}; do
|
||||
if docker exec maple-seaweedfs-dev /usr/bin/wget -q --spider http://127.0.0.1:9333/cluster/status 2>/dev/null; then
|
||||
if docker exec mapleopentech-seaweedfs-dev /usr/bin/wget -q --spider http://127.0.0.1:9333/cluster/status 2>/dev/null; then
|
||||
echo "✅ SeaweedFS is ready"
|
||||
break
|
||||
fi
|
||||
|
|
@ -84,7 +84,7 @@ tasks:
|
|||
cmds:
|
||||
- |
|
||||
echo "📦 Initializing Cassandra keyspaces..."
|
||||
docker exec -i maple-cassandra-1-dev cqlsh < cassandra/init-scripts/01-create-keyspaces.cql
|
||||
docker exec -i mapleopentech-cassandra-1-dev cqlsh < cassandra/init-scripts/01-create-keyspaces.cql
|
||||
echo "✅ Keyspaces initialized with replication_factor=3"
|
||||
|
||||
dev:status:
|
||||
|
|
@ -92,7 +92,7 @@ tasks:
|
|||
cmds:
|
||||
- |
|
||||
echo "📊 Infrastructure Status:"
|
||||
docker ps --filter "name=maple-" --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
|
||||
docker ps --filter "name=mapleopentech-" --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
|
||||
|
||||
dev:stop:
|
||||
desc: Stop all infrastructure services (keeps data)
|
||||
|
|
@ -130,39 +130,39 @@ tasks:
|
|||
exit 1
|
||||
fi
|
||||
echo "🗑️ Dropping keyspace: $KEYSPACE"
|
||||
docker exec maple-cassandra-1-dev cqlsh -e "DROP KEYSPACE IF EXISTS $KEYSPACE;"
|
||||
docker exec mapleopentech-cassandra-1-dev cqlsh -e "DROP KEYSPACE IF EXISTS $KEYSPACE;"
|
||||
echo "📦 Recreating keyspace: $KEYSPACE"
|
||||
docker exec maple-cassandra-1-dev cqlsh -e "CREATE KEYSPACE IF NOT EXISTS $KEYSPACE WITH REPLICATION = {'class': 'SimpleStrategy', 'replication_factor': 3} AND DURABLE_WRITES = true;"
|
||||
docker exec mapleopentech-cassandra-1-dev cqlsh -e "CREATE KEYSPACE IF NOT EXISTS $KEYSPACE WITH REPLICATION = {'class': 'SimpleStrategy', 'replication_factor': 3} AND DURABLE_WRITES = true;"
|
||||
echo "✅ Keyspace $KEYSPACE cleaned and recreated"
|
||||
|
||||
# Cassandra-specific tasks
|
||||
cql:
|
||||
desc: Open Cassandra CQL shell (connects to node 1)
|
||||
cmds:
|
||||
- docker exec -it maple-cassandra-1-dev cqlsh
|
||||
- docker exec -it mapleopentech-cassandra-1-dev cqlsh
|
||||
|
||||
cql:keyspaces:
|
||||
desc: List all keyspaces
|
||||
cmds:
|
||||
- docker exec maple-cassandra-1-dev cqlsh -e "DESCRIBE KEYSPACES;"
|
||||
- docker exec mapleopentech-cassandra-1-dev cqlsh -e "DESCRIBE KEYSPACES;"
|
||||
|
||||
cql:tables:
|
||||
desc: List tables in a keyspace (usage task cql:tables -- maplepress)
|
||||
cmds:
|
||||
- docker exec maple-cassandra-1-dev cqlsh -e "USE {{.CLI_ARGS}}; DESCRIBE TABLES;"
|
||||
- docker exec mapleopentech-cassandra-1-dev cqlsh -e "USE {{.CLI_ARGS}}; DESCRIBE TABLES;"
|
||||
|
||||
cql:status:
|
||||
desc: Show Cassandra cluster status
|
||||
cmds:
|
||||
- docker exec maple-cassandra-1-dev nodetool status
|
||||
- docker exec mapleopentech-cassandra-1-dev nodetool status
|
||||
|
||||
# Redis-specific tasks
|
||||
redis:
|
||||
desc: Open Redis CLI
|
||||
cmds:
|
||||
- docker exec -it maple-redis-dev redis-cli
|
||||
- docker exec -it mapleopentech-redis-dev redis-cli
|
||||
|
||||
redis:info:
|
||||
desc: Show Redis info
|
||||
cmds:
|
||||
- docker exec maple-redis-dev redis-cli INFO
|
||||
- docker exec mapleopentech-redis-dev redis-cli INFO
|
||||
|
|
|
|||
|
|
@ -453,13 +453,13 @@ docker node inspect mapleopentech-swarm-worker-10-prod --format '{{.Spec.Labels}
|
|||
**Important:** Workers must access Cassandra and Redis.
|
||||
|
||||
```bash
|
||||
# Add worker-10 to maple-private-prod network
|
||||
# Add worker-10 to mapleopentech-private-prod network
|
||||
# This is done automatically when services start on the worker
|
||||
# But verify connectivity:
|
||||
|
||||
# On worker-10, test Redis connectivity
|
||||
ssh root@<worker-10-ip>
|
||||
docker run --rm --network maple-private-prod redis:7.0-alpine redis-cli -h redis ping
|
||||
docker run --rm --network mapleopentech-private-prod redis:7.0-alpine redis-cli -h redis ping
|
||||
|
||||
# Should output: PONG
|
||||
```
|
||||
|
|
|
|||
|
|
@ -153,8 +153,8 @@ DNS: [Your DNS provider]
|
|||
SSL: Let's Encrypt (automatic via Caddy)
|
||||
|
||||
Networks:
|
||||
- maple-private-prod: Databases and internal services
|
||||
- maple-public-prod: Public-facing services (Caddy + backends)
|
||||
- mapleopentech-private-prod: Databases and internal services
|
||||
- mapleopentech-public-prod: Public-facing services (Caddy + backends)
|
||||
|
||||
Databases:
|
||||
- Cassandra: 3-node cluster, RF=3, QUORUM consistency
|
||||
|
|
|
|||
|
|
@ -27,8 +27,8 @@ This document defines the **multi-application architecture** for Maple Open Tech
|
|||
│ - Meilisearch (worker 5) │
|
||||
│ │
|
||||
│ Networks: │
|
||||
│ - maple-private-prod (databases, cache, search) │
|
||||
│ - maple-public-prod (reverse proxies + backends) │
|
||||
│ - mapleopentech-private-prod (databases, cache, search) │
|
||||
│ - mapleopentech-public-prod (reverse proxies + backends) │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
|
|
@ -40,7 +40,7 @@ This document defines the **multi-application architecture** for Maple Open Tech
|
|||
│ Service: maplepress_backend │
|
||||
│ Hostname: maplepress-backend │
|
||||
│ Port: 8000 │
|
||||
│ Networks: maple-private-prod + maple-public-prod │
|
||||
│ Networks: mapleopentech-private-prod + mapleopentech-public-prod │
|
||||
│ Connects to: Cassandra, Redis, Meilisearch, Spaces │
|
||||
│ │
|
||||
│ Service: maplepress_backend-caddy │
|
||||
|
|
@ -66,7 +66,7 @@ This document defines the **multi-application architecture** for Maple Open Tech
|
|||
│ Service: maplefile_backend │
|
||||
│ Hostname: maplefile-backend │
|
||||
│ Port: 8000 │
|
||||
│ Networks: maple-private-prod + maple-public-prod │
|
||||
│ Networks: mapleopentech-private-prod + mapleopentech-public-prod │
|
||||
│ Connects to: Cassandra, Redis, Meilisearch, Spaces │
|
||||
│ │
|
||||
│ Service: maplefile_backend-caddy │
|
||||
|
|
@ -92,7 +92,7 @@ This document defines the **multi-application architecture** for Maple Open Tech
|
|||
│ Service: mapleopentech_backend │
|
||||
│ Hostname: mapleopentech-backend │
|
||||
│ Port: 8000 │
|
||||
│ Networks: maple-private-prod + maple-public-prod │
|
||||
│ Networks: mapleopentech-private-prod + mapleopentech-public-prod │
|
||||
│ Connects to: Cassandra, Redis, Meilisearch, Spaces │
|
||||
│ │
|
||||
│ Service: mapleopentech_backend-caddy │
|
||||
|
|
@ -256,7 +256,7 @@ docker config ls
|
|||
|
||||
## Network Topology
|
||||
|
||||
### maple-private-prod (Shared by ALL Apps)
|
||||
### mapleopentech-private-prod (Shared by ALL Apps)
|
||||
|
||||
**Purpose**: Private backend services - databases, cache, search
|
||||
|
||||
|
|
@ -268,7 +268,7 @@ docker config ls
|
|||
|
||||
**Security**: No ingress ports, no internet access, internal-only
|
||||
|
||||
### maple-public-prod (Per-App Reverse Proxies + Backends)
|
||||
### mapleopentech-public-prod (Per-App Reverse Proxies + Backends)
|
||||
|
||||
**Purpose**: Internet-facing services - reverse proxies and backends
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ We use a **multi-network architecture** following industry best practices for se
|
|||
│ Docker Swarm Cluster │
|
||||
│ │
|
||||
│ ┌────────────────────────────────────────────────────────────┐ │
|
||||
│ │ maple-private-prod (Overlay Network) │ │
|
||||
│ │ mapleopentech-private-prod (Overlay Network) │ │
|
||||
│ │ No Internet Access | Internal Services Only │ │
|
||||
│ │ SHARED by ALL applications │ │
|
||||
│ ├────────────────────────────────────────────────────────────┤ │
|
||||
|
|
@ -31,7 +31,7 @@ We use a **multi-network architecture** following industry best practices for se
|
|||
│ └────────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌────────────────────────────────────────────────────────────┐ │
|
||||
│ │ maple-public-prod (Overlay Network) │ │
|
||||
│ │ mapleopentech-public-prod (Overlay Network) │ │
|
||||
│ │ Internet-Facing | Public Services │ │
|
||||
│ ├────────────────────────────────────────────────────────────┤ │
|
||||
│ │ Reverse Proxies (Caddy - ports 80/443): │ │
|
||||
|
|
@ -48,14 +48,14 @@ We use a **multi-network architecture** following industry best practices for se
|
|||
│ └────────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ Note: Application backends join BOTH networks: │
|
||||
│ - Receive requests from Caddy on maple-public-prod │
|
||||
│ - Access databases/cache on maple-private-prod │
|
||||
│ - Receive requests from Caddy on mapleopentech-public-prod │
|
||||
│ - Access databases/cache on mapleopentech-private-prod │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## Networks Explained
|
||||
|
||||
### 1. `maple-private-prod` (Current)
|
||||
### 1. `mapleopentech-private-prod` (Current)
|
||||
|
||||
**Purpose**: Backend services that should NEVER be exposed to the internet.
|
||||
|
||||
|
|
@ -86,7 +86,7 @@ cassandra-2:9042
|
|||
cassandra-3:9042
|
||||
```
|
||||
|
||||
### 2. `maple-public-prod` (Current - In Use)
|
||||
### 2. `mapleopentech-public-prod` (Current - In Use)
|
||||
|
||||
**Purpose**: Internet-facing services that handle external traffic.
|
||||
|
||||
|
|
@ -110,9 +110,9 @@ cassandra-3:9042
|
|||
|
||||
**Routing Flow:**
|
||||
```
|
||||
Internet → Caddy Reverse Proxy (maple-public-prod)
|
||||
→ Application Backend (maple-public-prod + maple-private-prod)
|
||||
→ Databases/Cache (maple-private-prod only)
|
||||
Internet → Caddy Reverse Proxy (mapleopentech-public-prod)
|
||||
→ Application Backend (mapleopentech-public-prod + mapleopentech-private-prod)
|
||||
→ Databases/Cache (mapleopentech-private-prod only)
|
||||
|
||||
Example (MaplePress):
|
||||
https://getmaplepress.ca → maplepress-backend-caddy
|
||||
|
|
@ -157,19 +157,19 @@ Both networks are created and in use:
|
|||
docker network create \
|
||||
--driver overlay \
|
||||
--attachable \
|
||||
maple-private-prod
|
||||
mapleopentech-private-prod
|
||||
|
||||
# Create public network (done in 06_caddy.md - used by reverse proxies)
|
||||
docker network create \
|
||||
--driver overlay \
|
||||
--attachable \
|
||||
maple-public-prod
|
||||
mapleopentech-public-prod
|
||||
|
||||
# Verify both exist
|
||||
docker network ls | grep maple
|
||||
# Should show:
|
||||
# maple-private-prod
|
||||
# maple-public-prod
|
||||
# mapleopentech-private-prod
|
||||
# mapleopentech-public-prod
|
||||
```
|
||||
|
||||
### Multi-App Pattern
|
||||
|
|
@ -183,7 +183,7 @@ docker network ls | grep maple
|
|||
|
||||
### Go Backend Connecting to Services
|
||||
|
||||
**On `maple-private-prod` network:**
|
||||
**On `mapleopentech-private-prod` network:**
|
||||
|
||||
```go
|
||||
// Redis connection
|
||||
|
|
@ -206,16 +206,16 @@ services:
|
|||
backend:
|
||||
image: your-backend:latest
|
||||
networks:
|
||||
- maple-private-prod # Access to databases
|
||||
- maple-public-prod # Receive HTTP requests (when deployed)
|
||||
- mapleopentech-private-prod # Access to databases
|
||||
- mapleopentech-public-prod # Receive HTTP requests (when deployed)
|
||||
environment:
|
||||
- REDIS_HOST=redis
|
||||
- CASSANDRA_HOSTS=cassandra-1,cassandra-2,cassandra-3
|
||||
|
||||
networks:
|
||||
maple-private-prod:
|
||||
mapleopentech-private-prod:
|
||||
external: true
|
||||
maple-public-prod:
|
||||
mapleopentech-public-prod:
|
||||
external: true
|
||||
```
|
||||
|
||||
|
|
@ -256,7 +256,7 @@ docker service inspect your_service --format '{{.Spec.TaskTemplate.Networks}}'
|
|||
### Test Connectivity Between Networks
|
||||
|
||||
```bash
|
||||
# From a container on maple-private-prod
|
||||
# From a container on mapleopentech-private-prod
|
||||
docker exec -it <container> ping redis
|
||||
docker exec -it <container> nc -zv cassandra-1 9042
|
||||
|
||||
|
|
@ -266,19 +266,19 @@ docker exec -it <container> nc -zv cassandra-1 9042
|
|||
### View All Services on a Network
|
||||
|
||||
```bash
|
||||
docker network inspect maple-private-prod --format '{{range .Containers}}{{.Name}} {{end}}'
|
||||
docker network inspect mapleopentech-private-prod --format '{{range .Containers}}{{.Name}} {{end}}'
|
||||
```
|
||||
|
||||
## Migration Path
|
||||
|
||||
### Current Status
|
||||
- ✅ `maple-private-prod` created
|
||||
- ✅ Cassandra on `maple-private-prod`
|
||||
- ✅ Redis on `maple-private-prod`
|
||||
- ✅ `mapleopentech-private-prod` created
|
||||
- ✅ Cassandra on `mapleopentech-private-prod`
|
||||
- ✅ Redis on `mapleopentech-private-prod`
|
||||
- ⏳ Backend deployment (next)
|
||||
- ⏳ Public network + NGINX (future)
|
||||
|
||||
### When to Create `maple-public-prod`
|
||||
### When to Create `mapleopentech-public-prod`
|
||||
|
||||
Create the public network when you're ready to:
|
||||
1. Deploy NGINX reverse proxy
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ Cassandra Cluster (NEW):
|
|||
### Cassandra Configuration
|
||||
|
||||
- **Version**: Cassandra 5.0.4
|
||||
- **Cluster Name**: maple-private-prod-cluster
|
||||
- **Cluster Name**: mapleopentech-private-prod-cluster
|
||||
- **Replication Factor**: 3 (each data stored on all 3 nodes)
|
||||
- **Data Center**: datacenter1
|
||||
- **Heap Size**: 512MB (reduced for 2GB RAM constraint)
|
||||
|
|
@ -358,7 +358,7 @@ Copy and paste the following:
|
|||
version: '3.8'
|
||||
|
||||
networks:
|
||||
maple-private-prod:
|
||||
mapleopentech-private-prod:
|
||||
external: true
|
||||
|
||||
volumes:
|
||||
|
|
@ -371,9 +371,9 @@ services:
|
|||
image: cassandra:5.0.4
|
||||
hostname: cassandra-1
|
||||
networks:
|
||||
- maple-private-prod
|
||||
- mapleopentech-private-prod
|
||||
environment:
|
||||
- CASSANDRA_CLUSTER_NAME=maple-private-prod-cluster
|
||||
- CASSANDRA_CLUSTER_NAME=mapleopentech-private-prod-cluster
|
||||
- CASSANDRA_DC=datacenter1
|
||||
- CASSANDRA_ENDPOINT_SNITCH=GossipingPropertyFileSnitch
|
||||
- CASSANDRA_SEEDS=cassandra-1,cassandra-2,cassandra-3
|
||||
|
|
@ -401,9 +401,9 @@ services:
|
|||
image: cassandra:5.0.4
|
||||
hostname: cassandra-2
|
||||
networks:
|
||||
- maple-private-prod
|
||||
- mapleopentech-private-prod
|
||||
environment:
|
||||
- CASSANDRA_CLUSTER_NAME=maple-private-prod-cluster
|
||||
- CASSANDRA_CLUSTER_NAME=mapleopentech-private-prod-cluster
|
||||
- CASSANDRA_DC=datacenter1
|
||||
- CASSANDRA_ENDPOINT_SNITCH=GossipingPropertyFileSnitch
|
||||
- CASSANDRA_SEEDS=cassandra-1,cassandra-2,cassandra-3
|
||||
|
|
@ -431,9 +431,9 @@ services:
|
|||
image: cassandra:5.0.4
|
||||
hostname: cassandra-3
|
||||
networks:
|
||||
- maple-private-prod
|
||||
- mapleopentech-private-prod
|
||||
environment:
|
||||
- CASSANDRA_CLUSTER_NAME=maple-private-prod-cluster
|
||||
- CASSANDRA_CLUSTER_NAME=mapleopentech-private-prod-cluster
|
||||
- CASSANDRA_DC=datacenter1
|
||||
- CASSANDRA_ENDPOINT_SNITCH=GossipingPropertyFileSnitch
|
||||
- CASSANDRA_SEEDS=cassandra-1,cassandra-2,cassandra-3
|
||||
|
|
@ -460,19 +460,19 @@ services:
|
|||
|
||||
### Step 4: Create Shared Overlay Network
|
||||
|
||||
Before deploying any services, create the shared `maple-private-prod` network that all services will use:
|
||||
Before deploying any services, create the shared `mapleopentech-private-prod` network that all services will use:
|
||||
|
||||
```bash
|
||||
# Create the maple-private-prod overlay network
|
||||
# Create the mapleopentech-private-prod overlay network
|
||||
docker network create \
|
||||
--driver overlay \
|
||||
--attachable \
|
||||
maple-private-prod
|
||||
mapleopentech-private-prod
|
||||
|
||||
# Verify it was created
|
||||
docker network ls | grep maple-private-prod
|
||||
docker network ls | grep mapleopentech-private-prod
|
||||
# Should show:
|
||||
# abc123... maple-private-prod overlay swarm
|
||||
# abc123... mapleopentech-private-prod overlay swarm
|
||||
```
|
||||
|
||||
**What is this network for?**
|
||||
|
|
@ -847,7 +847,7 @@ docker exec -it $CONTAINER_ID cqlsh -e "SELECT * FROM test.users;"
|
|||
|
||||
```bash
|
||||
# On your local machine, add:
|
||||
CASSANDRA_CLUSTER_NAME=maple-private-prod-cluster
|
||||
CASSANDRA_CLUSTER_NAME=mapleopentech-private-prod-cluster
|
||||
CASSANDRA_DC=datacenter1
|
||||
CASSANDRA_REPLICATION_FACTOR=3
|
||||
|
||||
|
|
@ -1132,7 +1132,7 @@ docker exec -it $(docker ps -q --filter "name=cassandra") nodetool status
|
|||
```yaml
|
||||
# In your application stack file:
|
||||
networks:
|
||||
maple-private-prod:
|
||||
mapleopentech-private-prod:
|
||||
external: true
|
||||
```
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
**What You'll Build**:
|
||||
- Single Redis instance on existing worker-1
|
||||
- Password-protected with Docker secrets
|
||||
- Private network communication only (maple-private-prod overlay)
|
||||
- Private network communication only (mapleopentech-private-prod overlay)
|
||||
- Persistent data with AOF + RDB
|
||||
- Ready for Go application connections
|
||||
|
||||
|
|
@ -37,23 +37,23 @@ Docker Swarm Cluster:
|
|||
│
|
||||
├── mapleopentech-swarm-worker-1-prod (10.116.0.3)
|
||||
│ └── Redis (single instance)
|
||||
│ ├── Network: maple-private-prod (overlay, shared)
|
||||
│ ├── Network: mapleopentech-private-prod (overlay, shared)
|
||||
│ ├── Port: 6379 (private only)
|
||||
│ ├── Auth: Password (Docker secret)
|
||||
│ └── Data: Persistent volume
|
||||
│
|
||||
└── mapleopentech-swarm-worker-2,3,4-prod
|
||||
└── Cassandra Cluster (3 nodes)
|
||||
└── Same network: maple-private-prod
|
||||
└── Same network: mapleopentech-private-prod
|
||||
|
||||
Shared Network (maple-private-prod):
|
||||
Shared Network (mapleopentech-private-prod):
|
||||
├── All services can communicate
|
||||
├── Service discovery by name (redis, cassandra-1, etc.)
|
||||
└── No public internet access
|
||||
|
||||
Future Application:
|
||||
└── mapleopentech-swarm-worker-X-prod
|
||||
└── Go Backend → Connects to redis:6379 and cassandra:9042 on maple-private-prod
|
||||
└── Go Backend → Connects to redis:6379 and cassandra:9042 on mapleopentech-private-prod
|
||||
```
|
||||
|
||||
### Redis Configuration
|
||||
|
|
@ -164,7 +164,7 @@ Copy and paste the following:
|
|||
version: '3.8'
|
||||
|
||||
networks:
|
||||
maple-private-prod:
|
||||
mapleopentech-private-prod:
|
||||
external: true
|
||||
|
||||
volumes:
|
||||
|
|
@ -179,7 +179,7 @@ services:
|
|||
image: redis:7-alpine
|
||||
hostname: redis
|
||||
networks:
|
||||
- maple-private-prod
|
||||
- mapleopentech-private-prod
|
||||
volumes:
|
||||
- redis-data:/data
|
||||
secrets:
|
||||
|
|
@ -240,16 +240,16 @@ Save and exit (`:wq` in vi).
|
|||
|
||||
### Step 2: Verify Shared Overlay Network
|
||||
|
||||
**Check if the maple-private-prod network exists:**
|
||||
**Check if the mapleopentech-private-prod network exists:**
|
||||
|
||||
```bash
|
||||
docker network ls | grep maple-private-prod
|
||||
docker network ls | grep mapleopentech-private-prod
|
||||
```
|
||||
|
||||
**You should see:**
|
||||
|
||||
```
|
||||
abc123... maple-private-prod overlay swarm
|
||||
abc123... mapleopentech-private-prod overlay swarm
|
||||
```
|
||||
|
||||
**If you completed 02_cassandra.md** (Step 4), the network already exists and you're good to go!
|
||||
|
|
@ -257,14 +257,14 @@ abc123... maple-private-prod overlay swarm
|
|||
**If the network doesn't exist**, create it now:
|
||||
|
||||
```bash
|
||||
# Create the shared maple-private-prod network
|
||||
# Create the shared mapleopentech-private-prod network
|
||||
docker network create \
|
||||
--driver overlay \
|
||||
--attachable \
|
||||
maple-private-prod
|
||||
mapleopentech-private-prod
|
||||
|
||||
# Verify it was created
|
||||
docker network ls | grep maple-private-prod
|
||||
docker network ls | grep mapleopentech-private-prod
|
||||
```
|
||||
|
||||
**What is this network?**
|
||||
|
|
@ -436,22 +436,22 @@ docker stack deploy -c redis-stack.yml redis
|
|||
|
||||
### Problem: Network Not Found During Deployment
|
||||
|
||||
**Symptom**: `network "maple-private-prod" is declared as external, but could not be found`
|
||||
**Symptom**: `network "mapleopentech-private-prod" is declared as external, but could not be found`
|
||||
|
||||
**Solution:**
|
||||
|
||||
Create the shared `maple-private-prod` network first:
|
||||
Create the shared `mapleopentech-private-prod` network first:
|
||||
|
||||
```bash
|
||||
# Create the network
|
||||
docker network create \
|
||||
--driver overlay \
|
||||
--attachable \
|
||||
maple-private-prod
|
||||
mapleopentech-private-prod
|
||||
|
||||
# Verify it exists
|
||||
docker network ls | grep maple-private-prod
|
||||
# Should show: maple-private-prod overlay swarm
|
||||
docker network ls | grep mapleopentech-private-prod
|
||||
# Should show: mapleopentech-private-prod overlay swarm
|
||||
|
||||
# Then deploy Redis
|
||||
docker stack deploy -c redis-stack.yml redis
|
||||
|
|
@ -487,10 +487,10 @@ docker stack deploy -c redis-stack.yml redis
|
|||
# Must show: map[redis:true]
|
||||
```
|
||||
|
||||
4. **Verify maple-private-prod network exists:**
|
||||
4. **Verify mapleopentech-private-prod network exists:**
|
||||
```bash
|
||||
docker network ls | grep maple-private-prod
|
||||
# Should show: maple-private-prod overlay swarm
|
||||
docker network ls | grep mapleopentech-private-prod
|
||||
# Should show: mapleopentech-private-prod overlay swarm
|
||||
```
|
||||
|
||||
### Problem: Can't Connect (Authentication Failed)
|
||||
|
|
@ -548,9 +548,9 @@ docker stack deploy -c redis-stack.yml redis
|
|||
|
||||
1. **Verify both services on same network:**
|
||||
```bash
|
||||
# Check your app is on maple-private-prod network
|
||||
# Check your app is on mapleopentech-private-prod network
|
||||
docker service inspect your_app --format '{{.Spec.TaskTemplate.Networks}}'
|
||||
# Should show maple-private-prod
|
||||
# Should show mapleopentech-private-prod
|
||||
```
|
||||
|
||||
2. **Test DNS resolution:**
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -41,7 +41,7 @@ Internet (HTTPS) → Caddy (worker-6) → Backend (worker-6) → Cassandra/Redis
|
|||
- **Image**: Ubuntu 24.04 LTS x64
|
||||
- **Size**: Basic shared CPU, 2 GB / 2 vCPU ($18/mo)
|
||||
- **Hostname**: `mapleopentech-swarm-worker-6-prod`
|
||||
- **VPC Network**: Select same VPC as your swarm (maple-vpc-prod)
|
||||
- **VPC Network**: Select same VPC as your swarm (mapleopentech-vpc-prod)
|
||||
- **SSH Keys**: Add your SSH key
|
||||
4. Click **Create Droplet**
|
||||
5. Wait 1-2 minutes for droplet to provision
|
||||
|
|
@ -349,8 +349,8 @@ dig www.getmaplepress.ca +short
|
|||
|
||||
We need two overlay networks for our services:
|
||||
|
||||
1. **maple-private-prod** - Backend connects to databases (already exists from guides 02-04)
|
||||
2. **maple-public-prod** - NGINX and Backend communicate (new)
|
||||
1. **mapleopentech-private-prod** - Backend connects to databases (already exists from guides 02-04)
|
||||
2. **mapleopentech-public-prod** - NGINX and Backend communicate (new)
|
||||
|
||||
**On manager:**
|
||||
|
||||
|
|
@ -358,11 +358,11 @@ We need two overlay networks for our services:
|
|||
ssh dockeradmin@<manager-public-ip>
|
||||
|
||||
# Check private network exists
|
||||
docker network ls | grep maple-private-prod
|
||||
# Should show: maple-private-prod (created in previous guides)
|
||||
docker network ls | grep mapleopentech-private-prod
|
||||
# Should show: mapleopentech-private-prod (created in previous guides)
|
||||
|
||||
# Create public network
|
||||
docker network create --driver overlay --attachable maple-public-prod
|
||||
docker network create --driver overlay --attachable mapleopentech-public-prod
|
||||
|
||||
# Verify both exist
|
||||
docker network ls | grep maple
|
||||
|
|
@ -371,8 +371,8 @@ docker network ls | grep maple
|
|||
**Expected output:**
|
||||
|
||||
```
|
||||
abc123... maple-private-prod overlay swarm
|
||||
def456... maple-public-prod overlay swarm
|
||||
abc123... mapleopentech-private-prod overlay swarm
|
||||
def456... mapleopentech-public-prod overlay swarm
|
||||
```
|
||||
|
||||
**Why two networks?**
|
||||
|
|
@ -380,7 +380,7 @@ def456... maple-public-prod overlay swarm
|
|||
- **Public**: NGINX forwards requests to Backend (internet-facing)
|
||||
- Backend joins BOTH networks to receive requests and access databases
|
||||
|
||||
**✅ Checkpoint:** Both `maple-private-prod` and `maple-public-prod` networks exist
|
||||
**✅ Checkpoint:** Both `mapleopentech-private-prod` and `mapleopentech-public-prod` networks exist
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -601,9 +601,9 @@ vi maplepress-stack.yml
|
|||
version: '3.8'
|
||||
|
||||
networks:
|
||||
maple-private-prod:
|
||||
mapleopentech-private-prod:
|
||||
external: true
|
||||
maple-public-prod:
|
||||
mapleopentech-public-prod:
|
||||
external: true
|
||||
|
||||
secrets:
|
||||
|
|
@ -625,8 +625,8 @@ services:
|
|||
image: registry.digitalocean.com/ssp/maplepress_backend:prod
|
||||
hostname: maplepress-backend
|
||||
networks:
|
||||
- maple-public-prod # Receives requests from Caddy
|
||||
- maple-private-prod # Accesses databases
|
||||
- mapleopentech-public-prod # Receives requests from Caddy
|
||||
- mapleopentech-private-prod # Accesses databases
|
||||
secrets:
|
||||
- maplepress_jwt_secret
|
||||
- maplepress_ip_encryption_key
|
||||
|
|
@ -871,7 +871,7 @@ docker service logs maplepress_backend --tail 100
|
|||
# 1. Can't reach databases
|
||||
# - Verify Cassandra running: docker service ls | grep cassandra
|
||||
# - Verify Redis running: docker service ls | grep redis
|
||||
# - Check backend is on maple-private-prod network
|
||||
# - Check backend is on mapleopentech-private-prod network
|
||||
|
||||
# 2. Secrets missing
|
||||
docker secret ls
|
||||
|
|
@ -1047,9 +1047,9 @@ docker service logs -f maplepress_backend
|
|||
docker service ls
|
||||
# Should show: cassandra_cassandra-1, cassandra_cassandra-2, cassandra_cassandra-3, redis_redis, meilisearch_meilisearch
|
||||
|
||||
# 2. Verify backend is on maple-private-prod network
|
||||
# 2. Verify backend is on mapleopentech-private-prod network
|
||||
docker service inspect maplepress_backend --format '{{range .Spec.TaskTemplate.Networks}}{{.Target}} {{end}}'
|
||||
# Should include maple-private-prod
|
||||
# Should include mapleopentech-private-prod
|
||||
|
||||
# 3. Test DNS resolution from backend container
|
||||
ssh dockeradmin@<worker-6-public-ip>
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
**Time to Complete**: 20-30 minutes
|
||||
**Prerequisites**:
|
||||
- ✅ Completed guide **05_backend.md** (Backend deployed and running)
|
||||
- ✅ Backend service accessible on `maple-public-prod` network
|
||||
- ✅ Backend service accessible on `mapleopentech-public-prod` network
|
||||
- ✅ Domain name pointing to worker-6 public IP
|
||||
- ✅ Email address for Let's Encrypt SSL certificate notifications
|
||||
|
||||
|
|
@ -59,7 +59,7 @@ Backend (worker-6)
|
|||
Databases (Cassandra, Redis, Meilisearch on other workers)
|
||||
```
|
||||
|
||||
**Key concept:** Caddy and Backend are both on worker-6, connected via the `maple-public-prod` Docker overlay network. Caddy can reach Backend by the hostname `backend` - Docker's built-in DNS resolves this to the backend container's IP automatically.
|
||||
**Key concept:** Caddy and Backend are both on worker-6, connected via the `mapleopentech-public-prod` Docker overlay network. Caddy can reach Backend by the hostname `backend` - Docker's built-in DNS resolves this to the backend container's IP automatically.
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -328,9 +328,9 @@ vi maplepress-stack.yml
|
|||
version: '3.8'
|
||||
|
||||
networks:
|
||||
maple-private-prod:
|
||||
mapleopentech-private-prod:
|
||||
external: true
|
||||
maple-public-prod:
|
||||
mapleopentech-public-prod:
|
||||
external: true
|
||||
|
||||
volumes:
|
||||
|
|
@ -362,8 +362,8 @@ services:
|
|||
image: registry.digitalocean.com/ssp/maplepress_backend:prod
|
||||
hostname: maplepress-backend
|
||||
networks:
|
||||
- maple-public-prod
|
||||
- maple-private-prod
|
||||
- mapleopentech-public-prod
|
||||
- mapleopentech-private-prod
|
||||
secrets:
|
||||
- maplepress_jwt_secret
|
||||
- maplepress_ip_encryption_key
|
||||
|
|
@ -431,7 +431,7 @@ services:
|
|||
image: caddy:2-alpine
|
||||
hostname: caddy
|
||||
networks:
|
||||
- maple-public-prod
|
||||
- mapleopentech-public-prod
|
||||
ports:
|
||||
# Port 80 - HTTP (for Let's Encrypt challenges and HTTP→HTTPS redirect)
|
||||
# Using mode: host to bind directly to worker-6's network interface
|
||||
|
|
@ -488,7 +488,7 @@ Save: `Esc`, then `:wq`, then `Enter`
|
|||
|
||||
**Understanding the stack file:**
|
||||
|
||||
- **`maple-public-prod` network**: Shared network with backend
|
||||
- **`mapleopentech-public-prod` network**: Shared network with backend
|
||||
- Both Caddy and Backend are connected here
|
||||
- Allows Caddy to reach Backend by hostname
|
||||
- `external: true` means we created this network earlier (in 05_backend.md)
|
||||
|
|
@ -542,9 +542,9 @@ Before deploying, let's make sure everything is ready:
|
|||
docker service ls | grep backend
|
||||
# Should show: maplepress_backend 1/1 registry.digitalocean.com/ssp/maplepress_backend:prod
|
||||
|
||||
# 2. Check maple-public-prod network exists
|
||||
docker network ls | grep maple-public-prod
|
||||
# Should show: maple-public-prod overlay swarm
|
||||
# 2. Check mapleopentech-public-prod network exists
|
||||
docker network ls | grep mapleopentech-public-prod
|
||||
# Should show: mapleopentech-public-prod overlay swarm
|
||||
|
||||
# 3. Verify worker-6 has backend label
|
||||
docker node inspect mapleopentech-swarm-worker-6-prod --format '{{.Spec.Labels}}'
|
||||
|
|
@ -734,8 +734,8 @@ All should show `1/1` in REPLICAS column.
|
|||
docker network ls | grep maple
|
||||
|
||||
# Should show:
|
||||
# abc123... maple-private-prod overlay swarm
|
||||
# def456... maple-public-prod overlay swarm
|
||||
# abc123... mapleopentech-private-prod overlay swarm
|
||||
# def456... mapleopentech-public-prod overlay swarm
|
||||
```
|
||||
|
||||
### 5.3 Verify Service Connectivity
|
||||
|
|
@ -978,8 +978,8 @@ docker service logs maplepress_backend-caddy --tail 100
|
|||
# - Stop conflicting service
|
||||
|
||||
# 3. Network not found
|
||||
docker network ls | grep maple-public-prod
|
||||
# If missing, create it: docker network create --driver overlay --attachable maple-public-prod
|
||||
docker network ls | grep mapleopentech-public-prod
|
||||
# If missing, create it: docker network create --driver overlay --attachable mapleopentech-public-prod
|
||||
```
|
||||
|
||||
### Problem: Deployment Fails with "only updates to Labels are allowed"
|
||||
|
|
@ -1245,7 +1245,7 @@ docker service ls | grep backend
|
|||
# 2. Are both on same network?
|
||||
docker service inspect maplepress_backend --format '{{range .Spec.TaskTemplate.Networks}}{{.Target}} {{end}}'
|
||||
docker service inspect maplepress_backend-caddy --format '{{range .Spec.TaskTemplate.Networks}}{{.Target}} {{end}}'
|
||||
# Both should include: maple-public-prod
|
||||
# Both should include: mapleopentech-public-prod
|
||||
|
||||
# 3. Test from Caddy container
|
||||
ssh dockeradmin@<worker-6-public-ip>
|
||||
|
|
@ -1478,7 +1478,7 @@ Internet (HTTPS)
|
|||
Caddy (worker-6) - Automatic SSL, reverse proxy
|
||||
↓
|
||||
Backend (worker-6) - Your Go application
|
||||
↓ maple-private-prod network
|
||||
↓ mapleopentech-private-prod network
|
||||
Cassandra (workers 1-3) - Database cluster
|
||||
Redis (worker-4) - Cache
|
||||
Meilisearch (worker-5) - Search engine
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ Internet (HTTPS)
|
|||
- **Image**: Ubuntu 24.04 LTS x64
|
||||
- **Size**: Basic shared CPU, 1 GB / 1 vCPU ($6/mo) - Frontend is lightweight
|
||||
- **Hostname**: `mapleopentech-swarm-worker-7-prod`
|
||||
- **VPC Network**: Select same VPC as your swarm (maple-vpc-prod)
|
||||
- **VPC Network**: Select same VPC as your swarm (mapleopentech-vpc-prod)
|
||||
- **SSH Keys**: Add your SSH key
|
||||
4. Click **Create Droplet**
|
||||
5. Wait 1-2 minutes for droplet to provision
|
||||
|
|
|
|||
|
|
@ -364,8 +364,8 @@ dig www.maplefile.ca +short
|
|||
|
||||
We need two overlay networks for our services:
|
||||
|
||||
1. **maple-private-prod** - Backend connects to databases (already exists from guides 02-04)
|
||||
2. **maple-public-prod** - Caddy and Backend communicate (already exists from guide 06)
|
||||
1. **mapleopentech-private-prod** - Backend connects to databases (already exists from guides 02-04)
|
||||
2. **mapleopentech-public-prod** - Caddy and Backend communicate (already exists from guide 06)
|
||||
|
||||
**On manager:**
|
||||
|
||||
|
|
@ -376,15 +376,15 @@ ssh dockeradmin@143.110.210.162
|
|||
docker network ls | grep maple
|
||||
|
||||
# Should show:
|
||||
# maple-private-prod overlay swarm
|
||||
# maple-public-prod overlay swarm
|
||||
# mapleopentech-private-prod overlay swarm
|
||||
# mapleopentech-public-prod overlay swarm
|
||||
```
|
||||
|
||||
**If maple-public-prod doesn't exist, create it:**
|
||||
**If mapleopentech-public-prod doesn't exist, create it:**
|
||||
|
||||
```bash
|
||||
# Create public network
|
||||
docker network create --driver overlay --attachable maple-public-prod
|
||||
docker network create --driver overlay --attachable mapleopentech-public-prod
|
||||
|
||||
# Verify both exist
|
||||
docker network ls | grep maple
|
||||
|
|
@ -395,7 +395,7 @@ docker network ls | grep maple
|
|||
- **Public**: Caddy forwards requests to Backend (internet-facing)
|
||||
- Backend joins BOTH networks to receive requests and access databases
|
||||
|
||||
**✅ Checkpoint:** Both `maple-private-prod` and `maple-public-prod` networks exist
|
||||
**✅ Checkpoint:** Both `mapleopentech-private-prod` and `mapleopentech-public-prod` networks exist
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -623,9 +623,9 @@ vi ~/stacks/maplefile-stack.yml
|
|||
version: '3.8'
|
||||
|
||||
networks:
|
||||
maple-private-prod:
|
||||
mapleopentech-private-prod:
|
||||
external: true
|
||||
maple-public-prod:
|
||||
mapleopentech-public-prod:
|
||||
external: true
|
||||
|
||||
secrets:
|
||||
|
|
@ -645,8 +645,8 @@ services:
|
|||
image: registry.digitalocean.com/ssp/maplefile-backend:prod
|
||||
hostname: maplefile-backend
|
||||
networks:
|
||||
- maple-public-prod # Receives requests from Caddy
|
||||
- maple-private-prod # Accesses databases
|
||||
- mapleopentech-public-prod # Receives requests from Caddy
|
||||
- mapleopentech-private-prod # Accesses databases
|
||||
secrets:
|
||||
- maplefile_jwt_secret
|
||||
- redis_password
|
||||
|
|
@ -935,7 +935,7 @@ docker service logs maplefile_backend --tail 100
|
|||
# 1. Can't reach databases
|
||||
# - Verify Cassandra running: docker service ls | grep cassandra
|
||||
# - Verify Redis running: docker service ls | grep redis
|
||||
# - Check backend is on maple-private-prod network
|
||||
# - Check backend is on mapleopentech-private-prod network
|
||||
|
||||
# 2. Secrets missing
|
||||
docker secret ls
|
||||
|
|
@ -1027,9 +1027,9 @@ docker stack deploy -c ~/stacks/maplefile-stack.yml maplefile
|
|||
docker service ls | grep cassandra
|
||||
# Should show: cassandra_cassandra-1, cassandra_cassandra-2, cassandra_cassandra-3
|
||||
|
||||
# 2. Verify backend is on maple-private-prod network
|
||||
# 2. Verify backend is on mapleopentech-private-prod network
|
||||
docker service inspect maplefile_backend --format '{{range .Spec.TaskTemplate.Networks}}{{.Target}} {{end}}'
|
||||
# Should include maple-private-prod
|
||||
# Should include mapleopentech-private-prod
|
||||
|
||||
# 3. Test DNS resolution from backend container
|
||||
ssh dockeradmin@143.110.212.253
|
||||
|
|
@ -1189,14 +1189,14 @@ cd ~/stacks
|
|||
|
||||
## Network Architecture Notes
|
||||
|
||||
**Private Network (maple-private-prod):**
|
||||
**Private Network (mapleopentech-private-prod):**
|
||||
- Cassandra cluster (3 nodes) - Shared by ALL apps
|
||||
- Redis - Shared by ALL apps (different DB numbers per app)
|
||||
- Both MaplePress and MapleFile use same infrastructure
|
||||
- MaplePress uses Cassandra keyspace: `maplepress`, Redis DB: 0
|
||||
- MapleFile uses Cassandra keyspace: `maplefile`, Redis DB: 1
|
||||
|
||||
**Public Network (maple-public-prod):**
|
||||
**Public Network (mapleopentech-public-prod):**
|
||||
- Each app gets its own Caddy instance
|
||||
- maplefile-backend-caddy (to be deployed in Part 2)
|
||||
- maplepress-backend-caddy (already deployed)
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
**Time to Complete**: 20-30 minutes
|
||||
**Prerequisites**:
|
||||
- ✅ Completed guide **09_maplefile_backend.md** (Backend deployed and running)
|
||||
- ✅ Backend service accessible on `maple-public-prod` network
|
||||
- ✅ Backend service accessible on `mapleopentech-public-prod` network
|
||||
- ✅ Domain name `maplefile.ca` pointing to worker-8 public IP
|
||||
- ✅ Email address for Let's Encrypt SSL certificate notifications
|
||||
|
||||
|
|
@ -59,7 +59,7 @@ Backend (worker-8)
|
|||
Databases (Cassandra, Redis on other workers)
|
||||
```
|
||||
|
||||
**Key concept:** Caddy and Backend are both on worker-8, connected via the `maple-public-prod` Docker overlay network. Caddy can reach Backend by the hostname `maplefile-backend` - Docker's built-in DNS resolves this to the backend container's IP automatically.
|
||||
**Key concept:** Caddy and Backend are both on worker-8, connected via the `mapleopentech-public-prod` Docker overlay network. Caddy can reach Backend by the hostname `maplefile-backend` - Docker's built-in DNS resolves this to the backend container's IP automatically.
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -345,7 +345,7 @@ configs:
|
|||
image: caddy:2.9.1-alpine
|
||||
hostname: maplefile-caddy
|
||||
networks:
|
||||
- maple-public-prod
|
||||
- mapleopentech-public-prod
|
||||
ports:
|
||||
# Port 80 - HTTP (for Let's Encrypt challenges and HTTP→HTTPS redirect)
|
||||
# Using mode: host to bind directly to worker-8's network interface
|
||||
|
|
@ -402,7 +402,7 @@ Save: `Esc`, then `:wq`, then `Enter`
|
|||
|
||||
**Understanding the stack file:**
|
||||
|
||||
- **`maple-public-prod` network**: Shared network with backend
|
||||
- **`mapleopentech-public-prod` network**: Shared network with backend
|
||||
- Both Caddy and Backend are connected here
|
||||
- Allows Caddy to reach Backend by hostname
|
||||
- `external: true` means we created this network earlier (in 09_maplefile_backend.md)
|
||||
|
|
@ -431,7 +431,7 @@ Save: `Esc`, then `:wq`, then `Enter`
|
|||
|
||||
- **Placement constraint**:
|
||||
- `node.labels.maplefile-backend == true` - Same as backend (worker-8)
|
||||
- Caddy and Backend MUST be on the same node to share `maple-public-prod` network
|
||||
- Caddy and Backend MUST be on the same node to share `mapleopentech-public-prod` network
|
||||
- Docker overlay networks work best when services are colocated
|
||||
|
||||
### 3.2 Deploy Updated Stack
|
||||
|
|
@ -679,12 +679,12 @@ docker service logs maplefile_backend-caddy --tail 50
|
|||
# Should show: Running
|
||||
```
|
||||
|
||||
2. **Backend not on maple-public-prod network**
|
||||
2. **Backend not on mapleopentech-public-prod network**
|
||||
```bash
|
||||
# Check backend networks
|
||||
docker service inspect maplefile_backend --format '{{json .Spec.TaskTemplate.Networks}}'
|
||||
|
||||
# Should include maple-public-prod
|
||||
# Should include mapleopentech-public-prod
|
||||
```
|
||||
|
||||
3. **Wrong hostname in Caddyfile**
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ Choose this approach if you want better isolation and independent scaling.
|
|||
- **Image**: Ubuntu 24.04 LTS x64
|
||||
- **Size**: Basic shared CPU, 1 GB / 1 vCPU ($6/mo) - Frontend is lightweight
|
||||
- **Hostname**: `mapleopentech-swarm-worker-9-prod`
|
||||
- **VPC Network**: Select same VPC as your swarm (maple-vpc-prod)
|
||||
- **VPC Network**: Select same VPC as your swarm (mapleopentech-vpc-prod)
|
||||
- **SSH Keys**: Add your SSH key
|
||||
- **Tags**: Add tags like `production`, `maplefile`, `frontend`
|
||||
4. Click **Create Droplet**
|
||||
|
|
|
|||
|
|
@ -27,9 +27,9 @@ Internet (HTTPS)
|
|||
├─ getmaplepress.ca → Backend API (worker-6)
|
||||
└─ getmaplepress.com → Frontend (worker-7)
|
||||
↓
|
||||
Backend Services (maple-public-prod + maple-private-prod)
|
||||
Backend Services (mapleopentech-public-prod + mapleopentech-private-prod)
|
||||
↓
|
||||
Databases (maple-private-prod only)
|
||||
Databases (mapleopentech-private-prod only)
|
||||
├─ Cassandra: 3-node cluster (workers 2,3,4) - RF=3, QUORUM
|
||||
├─ Redis: Single instance (worker-1/manager)
|
||||
└─ Meilisearch: Single instance (worker-5)
|
||||
|
|
@ -51,7 +51,7 @@ Internet (HTTPS)
|
|||
- Command-line tools verification
|
||||
|
||||
**[00-network-architecture.md](00-network-architecture.md)** - Network design
|
||||
- Network segmentation strategy (`maple-private-prod` vs `maple-public-prod`)
|
||||
- Network segmentation strategy (`mapleopentech-private-prod` vs `mapleopentech-public-prod`)
|
||||
- Security principles (defense in depth)
|
||||
- Service communication patterns
|
||||
- Firewall rules overview
|
||||
|
|
@ -360,13 +360,13 @@ setup/
|
|||
|
||||
### Network Architecture
|
||||
|
||||
**`maple-private-prod` (overlay network):**
|
||||
**`mapleopentech-private-prod` (overlay network):**
|
||||
- All databases (Cassandra, Redis, Meilisearch)
|
||||
- Backend services (access to databases)
|
||||
- **No internet access** (security)
|
||||
- Internal-only communication
|
||||
|
||||
**`maple-public-prod` (overlay network):**
|
||||
**`mapleopentech-public-prod` (overlay network):**
|
||||
- Caddy reverse proxies
|
||||
- Backend services (receive HTTP requests)
|
||||
- Ports 80/443 exposed to internet
|
||||
|
|
@ -447,7 +447,7 @@ docker logs <container-id>
|
|||
docker service inspect maplepress_backend
|
||||
|
||||
# Check network
|
||||
docker network inspect maple-private-prod
|
||||
docker network inspect mapleopentech-private-prod
|
||||
|
||||
# List configs
|
||||
docker config ls
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
version: '3.8'
|
||||
version: "3.8"
|
||||
|
||||
networks:
|
||||
maple-private-prod:
|
||||
mapleopentech-private-prod:
|
||||
external: true
|
||||
maple-public-prod:
|
||||
mapleopentech-public-prod:
|
||||
external: true
|
||||
|
||||
secrets:
|
||||
|
|
@ -24,8 +24,8 @@ services:
|
|||
image: registry.digitalocean.com/ssp/maplepress_backend:latest
|
||||
hostname: backend
|
||||
networks:
|
||||
- maple-public-prod # Receive requests from NGINX
|
||||
- maple-private-prod # Access databases
|
||||
- mapleopentech-public-prod # Receive requests from NGINX
|
||||
- mapleopentech-private-prod # Access databases
|
||||
secrets:
|
||||
- maplepress_jwt_secret
|
||||
- redis_password
|
||||
|
|
@ -93,18 +93,27 @@ services:
|
|||
resources:
|
||||
limits:
|
||||
memory: 1G
|
||||
cpus: '1.0'
|
||||
cpus: "1.0"
|
||||
reservations:
|
||||
memory: 512M
|
||||
cpus: '0.5'
|
||||
cpus: "0.5"
|
||||
update_config:
|
||||
parallelism: 1
|
||||
delay: 10s
|
||||
failure_action: rollback
|
||||
order: start-first # Zero-downtime: start new before stopping old
|
||||
order: start-first # Zero-downtime: start new before stopping old
|
||||
|
||||
healthcheck:
|
||||
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "--header=X-Tenant-ID: healthcheck", "http://localhost:8000/health"]
|
||||
test:
|
||||
[
|
||||
"CMD",
|
||||
"wget",
|
||||
"--no-verbose",
|
||||
"--tries=1",
|
||||
"--spider",
|
||||
"--header=X-Tenant-ID: healthcheck",
|
||||
"http://localhost:8000/health",
|
||||
]
|
||||
interval: 30s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
version: '3.8'
|
||||
version: "3.8"
|
||||
|
||||
networks:
|
||||
maple-private-prod:
|
||||
mapleopentech-private-prod:
|
||||
external: true
|
||||
|
||||
volumes:
|
||||
|
|
@ -14,9 +14,9 @@ services:
|
|||
image: cassandra:5.0.4
|
||||
hostname: cassandra-1
|
||||
networks:
|
||||
- maple-private-prod
|
||||
- mapleopentech-private-prod
|
||||
environment:
|
||||
- CASSANDRA_CLUSTER_NAME=maple-prod-cluster
|
||||
- CASSANDRA_CLUSTER_NAME=mapleopentech-prod-cluster
|
||||
- CASSANDRA_DC=datacenter1
|
||||
- CASSANDRA_ENDPOINT_SNITCH=GossipingPropertyFileSnitch
|
||||
- CASSANDRA_SEEDS=cassandra-1,cassandra-2,cassandra-3
|
||||
|
|
@ -44,9 +44,9 @@ services:
|
|||
image: cassandra:5.0.4
|
||||
hostname: cassandra-2
|
||||
networks:
|
||||
- maple-private-prod
|
||||
- mapleopentech-private-prod
|
||||
environment:
|
||||
- CASSANDRA_CLUSTER_NAME=maple-prod-cluster
|
||||
- CASSANDRA_CLUSTER_NAME=mapleopentech-prod-cluster
|
||||
- CASSANDRA_DC=datacenter1
|
||||
- CASSANDRA_ENDPOINT_SNITCH=GossipingPropertyFileSnitch
|
||||
- CASSANDRA_SEEDS=cassandra-1,cassandra-2,cassandra-3
|
||||
|
|
@ -74,9 +74,9 @@ services:
|
|||
image: cassandra:5.0.4
|
||||
hostname: cassandra-3
|
||||
networks:
|
||||
- maple-private-prod
|
||||
- mapleopentech-private-prod
|
||||
environment:
|
||||
- CASSANDRA_CLUSTER_NAME=maple-prod-cluster
|
||||
- CASSANDRA_CLUSTER_NAME=mapleopentech-prod-cluster
|
||||
- CASSANDRA_DC=datacenter1
|
||||
- CASSANDRA_ENDPOINT_SNITCH=GossipingPropertyFileSnitch
|
||||
- CASSANDRA_SEEDS=cassandra-1,cassandra-2,cassandra-3
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
version: '3.8'
|
||||
version: "3.8"
|
||||
|
||||
networks:
|
||||
maple-private-prod:
|
||||
mapleopentech-private-prod:
|
||||
external: true
|
||||
|
||||
volumes:
|
||||
|
|
@ -16,7 +16,7 @@ services:
|
|||
image: getmeili/meilisearch:v1.5
|
||||
hostname: meilisearch
|
||||
networks:
|
||||
- maple-private-prod
|
||||
- mapleopentech-private-prod
|
||||
volumes:
|
||||
- meilisearch-data:/meili_data
|
||||
secrets:
|
||||
|
|
@ -49,7 +49,15 @@ services:
|
|||
reservations:
|
||||
memory: 768M
|
||||
healthcheck:
|
||||
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:7700/health"]
|
||||
test:
|
||||
[
|
||||
"CMD",
|
||||
"wget",
|
||||
"--no-verbose",
|
||||
"--tries=1",
|
||||
"--spider",
|
||||
"http://localhost:7700/health",
|
||||
]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
version: '3.8'
|
||||
version: "3.8"
|
||||
|
||||
networks:
|
||||
maple-public-prod:
|
||||
mapleopentech-public-prod:
|
||||
external: true
|
||||
|
||||
volumes:
|
||||
|
|
@ -13,14 +13,14 @@ services:
|
|||
image: nginx:alpine
|
||||
hostname: nginx
|
||||
networks:
|
||||
- maple-public-prod
|
||||
- mapleopentech-public-prod
|
||||
ports:
|
||||
- "80:80"
|
||||
- "443:443"
|
||||
volumes:
|
||||
- nginx-ssl-certs:/etc/letsencrypt
|
||||
- nginx-ssl-www:/var/www/certbot
|
||||
- /var/run/docker.sock:/tmp/docker.sock:ro # For nginx-proxy
|
||||
- /var/run/docker.sock:/tmp/docker.sock:ro # For nginx-proxy
|
||||
configs:
|
||||
- source: nginx_config
|
||||
target: /etc/nginx/nginx.conf
|
||||
|
|
@ -30,7 +30,7 @@ services:
|
|||
replicas: 1
|
||||
placement:
|
||||
constraints:
|
||||
- node.labels.backend == true # Same node as backend
|
||||
- node.labels.backend == true # Same node as backend
|
||||
restart_policy:
|
||||
condition: on-failure
|
||||
delay: 5s
|
||||
|
|
@ -38,12 +38,20 @@ services:
|
|||
resources:
|
||||
limits:
|
||||
memory: 256M
|
||||
cpus: '0.5'
|
||||
cpus: "0.5"
|
||||
reservations:
|
||||
memory: 128M
|
||||
cpus: '0.25'
|
||||
cpus: "0.25"
|
||||
healthcheck:
|
||||
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:80/health"]
|
||||
test:
|
||||
[
|
||||
"CMD",
|
||||
"wget",
|
||||
"--no-verbose",
|
||||
"--tries=1",
|
||||
"--spider",
|
||||
"http://localhost:80/health",
|
||||
]
|
||||
interval: 30s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
version: '3.8'
|
||||
version: "3.8"
|
||||
|
||||
networks:
|
||||
maple-private-prod:
|
||||
mapleopentech-private-prod:
|
||||
external: true
|
||||
|
||||
volumes:
|
||||
|
|
@ -16,7 +16,7 @@ services:
|
|||
image: redis:7-alpine
|
||||
hostname: redis
|
||||
networks:
|
||||
- maple-private-prod
|
||||
- mapleopentech-private-prod
|
||||
volumes:
|
||||
- redis-data:/data
|
||||
secrets:
|
||||
|
|
@ -66,7 +66,13 @@ services:
|
|||
reservations:
|
||||
memory: 512M
|
||||
healthcheck:
|
||||
test: ["CMD", "sh", "-c", "redis-cli -a $$(cat /run/secrets/redis_password) ping | grep PONG"]
|
||||
test:
|
||||
[
|
||||
"CMD",
|
||||
"sh",
|
||||
"-c",
|
||||
"redis-cli -a $$(cat /run/secrets/redis_password) ping | grep PONG",
|
||||
]
|
||||
interval: 10s
|
||||
timeout: 3s
|
||||
retries: 3
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ bind 0.0.0.0
|
|||
port 6379
|
||||
|
||||
# Protected mode disabled (we rely on Docker network isolation)
|
||||
# Only containers on maple-prod overlay network can access
|
||||
# Only containers on mapleopentech-prod overlay network can access
|
||||
protected-mode no
|
||||
|
||||
# ==============================================================================
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ tasks:
|
|||
silent: true
|
||||
cmds:
|
||||
- |
|
||||
if ! docker network inspect maple-dev >/dev/null 2>&1; then
|
||||
if ! docker network inspect mapleopentech-dev >/dev/null 2>&1; then
|
||||
echo "❌ Infrastructure not running!"
|
||||
echo ""
|
||||
echo "Start it with:"
|
||||
|
|
@ -58,7 +58,7 @@ tasks:
|
|||
echo ""
|
||||
exit 1
|
||||
fi
|
||||
if ! docker ps | grep -q maple-cassandra-1-dev; then
|
||||
if ! docker ps | grep -q mapleopentech-cassandra-1-dev; then
|
||||
echo "❌ Cassandra not running!"
|
||||
echo ""
|
||||
echo "Start it with:"
|
||||
|
|
@ -89,7 +89,7 @@ tasks:
|
|||
deps: [build]
|
||||
cmds:
|
||||
- echo "⚠️ Dropping keyspace 'maplefile'..."
|
||||
- docker exec maple-cassandra-1-dev cqlsh -e "DROP KEYSPACE IF EXISTS maplefile;"
|
||||
- docker exec mapleopentech-cassandra-1-dev cqlsh -e "DROP KEYSPACE IF EXISTS maplefile;"
|
||||
- echo "✅ Keyspace dropped"
|
||||
- echo "🔄 Running migrations to recreate schema..."
|
||||
- ./maplefile-backend migrate up
|
||||
|
|
@ -169,11 +169,11 @@ tasks:
|
|||
cmds:
|
||||
- echo "Building version {{.GIT_COMMIT}} at {{.BUILD_TIME}}"
|
||||
- docker build -f Dockerfile --rm
|
||||
--build-arg GIT_COMMIT={{.GIT_COMMIT_FULL}}
|
||||
--build-arg BUILD_TIME={{.BUILD_TIME}}
|
||||
-t registry.digitalocean.com/ssp/maplefile-backend:prod
|
||||
-t registry.digitalocean.com/ssp/maplefile-backend:{{.GIT_COMMIT}}
|
||||
--platform linux/amd64 .
|
||||
--build-arg GIT_COMMIT={{.GIT_COMMIT_FULL}}
|
||||
--build-arg BUILD_TIME={{.BUILD_TIME}}
|
||||
-t registry.digitalocean.com/ssp/maplefile-backend:prod
|
||||
-t registry.digitalocean.com/ssp/maplefile-backend:{{.GIT_COMMIT}}
|
||||
--platform linux/amd64 .
|
||||
- docker push registry.digitalocean.com/ssp/maplefile-backend:prod
|
||||
- docker push registry.digitalocean.com/ssp/maplefile-backend:{{.GIT_COMMIT}}
|
||||
- echo "Deployed version {{.GIT_COMMIT}} - use this to verify on production"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# Use external network from infrastructure
|
||||
networks:
|
||||
maple-dev:
|
||||
mapleopentech-dev:
|
||||
external: true
|
||||
|
||||
services:
|
||||
|
|
@ -110,10 +110,11 @@ services:
|
|||
volumes:
|
||||
- ./:/go/src/codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend
|
||||
networks:
|
||||
- maple-dev
|
||||
- mapleopentech-dev
|
||||
restart: unless-stopped
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:${SERVER_PORT:-8000}/health"]
|
||||
test:
|
||||
["CMD", "curl", "-f", "http://localhost:${SERVER_PORT:-8000}/health"]
|
||||
interval: 30s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
|
|
|
|||
|
|
@ -2,4 +2,70 @@ module codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend
|
|||
|
||||
go 1.25.4
|
||||
|
||||
require go.uber.org/mock v0.6.0 // indirect
|
||||
require (
|
||||
codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend v0.0.0-20251202195307-f4a49ad4b9d0
|
||||
github.com/awnumar/memguard v0.23.0
|
||||
github.com/aws/aws-sdk-go-v2 v1.40.1
|
||||
github.com/aws/aws-sdk-go-v2/config v1.32.3
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.19.3
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.93.0
|
||||
github.com/aws/smithy-go v1.24.0
|
||||
github.com/bsm/redislock v0.9.4
|
||||
github.com/gocql/gocql v1.7.0
|
||||
github.com/golang-jwt/jwt/v5 v5.3.0
|
||||
github.com/golang-migrate/migrate/v4 v4.19.1
|
||||
github.com/google/wire v0.7.0
|
||||
github.com/mailgun/mailgun-go/v4 v4.23.0
|
||||
github.com/oschwald/geoip2-golang v1.13.0
|
||||
github.com/redis/go-redis/v9 v9.17.2
|
||||
github.com/robfig/cron/v3 v3.0.1
|
||||
github.com/spf13/cobra v1.10.1
|
||||
github.com/stretchr/testify v1.10.0
|
||||
github.com/tyler-smith/go-bip39 v1.1.0
|
||||
go.uber.org/mock v0.6.0
|
||||
go.uber.org/zap v1.27.1
|
||||
golang.org/x/crypto v0.45.0
|
||||
golang.org/x/vuln v1.1.4
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/awnumar/memcall v0.4.0 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.4 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.15 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.15 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.15 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.15 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.4 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.6 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.15 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.15 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/signin v1.0.3 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.30.6 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.11 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.41.3 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
||||
github.com/go-chi/chi/v5 v5.2.1 // indirect
|
||||
github.com/golang/snappy v0.0.4 // indirect
|
||||
github.com/google/subcommands v1.2.0 // indirect
|
||||
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/mailgun/errors v0.4.0 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/oschwald/maxminddb-golang v1.13.0 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||
github.com/spf13/pflag v1.0.9 // indirect
|
||||
go.uber.org/multierr v1.10.0 // indirect
|
||||
golang.org/x/mod v0.29.0 // indirect
|
||||
golang.org/x/sync v0.18.0 // indirect
|
||||
golang.org/x/sys v0.38.0 // indirect
|
||||
golang.org/x/telemetry v0.0.0-20251008203120-078029d740a8 // indirect
|
||||
golang.org/x/tools v0.38.0 // indirect
|
||||
golang.org/x/tools/go/packages/packagestest v0.1.1-deprecated // indirect
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,2 +1,217 @@
|
|||
codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend v0.0.0-20251202195307-f4a49ad4b9d0 h1:B6BOeHvghv8GdsYE9WjrmY9dXGmBGlOvt5w204dL24Y=
|
||||
codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend v0.0.0-20251202195307-f4a49ad4b9d0/go.mod h1:2FLpwTrS59a2D/CzoMBfC9SGHFhlMfX+8jXKW+Mpc2I=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
|
||||
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
|
||||
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
|
||||
github.com/awnumar/memcall v0.4.0 h1:B7hgZYdfH6Ot1Goaz8jGne/7i8xD4taZie/PNSFZ29g=
|
||||
github.com/awnumar/memcall v0.4.0/go.mod h1:8xOx1YbfyuCg3Fy6TO8DK0kZUua3V42/goA5Ru47E8w=
|
||||
github.com/awnumar/memguard v0.23.0 h1:sJ3a1/SWlcuKIQ7MV+R9p0Pvo9CWsMbGZvcZQtmc68A=
|
||||
github.com/awnumar/memguard v0.23.0/go.mod h1:olVofBrsPdITtJ2HgxQKrEYEMyIBAIciVG4wNnZhW9M=
|
||||
github.com/aws/aws-sdk-go-v2 v1.40.1 h1:difXb4maDZkRH0x//Qkwcfpdg1XQVXEAEs2DdXldFFc=
|
||||
github.com/aws/aws-sdk-go-v2 v1.40.1/go.mod h1:MayyLB8y+buD9hZqkCW3kX1AKq07Y5pXxtgB+rRFhz0=
|
||||
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.4 h1:489krEF9xIGkOaaX3CE/Be2uWjiXrkCH6gUX+bZA/BU=
|
||||
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.4/go.mod h1:IOAPF6oT9KCsceNTvvYMNHy0+kMF8akOjeDvPENWxp4=
|
||||
github.com/aws/aws-sdk-go-v2/config v1.32.3 h1:cpz7H2uMNTDa0h/5CYL5dLUEzPSLo2g0NkbxTRJtSSU=
|
||||
github.com/aws/aws-sdk-go-v2/config v1.32.3/go.mod h1:srtPKaJJe3McW6T/+GMBZyIPc+SeqJsNPJsd4mOYZ6s=
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.19.3 h1:01Ym72hK43hjwDeJUfi1l2oYLXBAOR8gNSZNmXmvuas=
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.19.3/go.mod h1:55nWF/Sr9Zvls0bGnWkRxUdhzKqj9uRNlPvgV1vgxKc=
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.15 h1:utxLraaifrSBkeyII9mIbVwXXWrZdlPO7FIKmyLCEcY=
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.15/go.mod h1:hW6zjYUDQwfz3icf4g2O41PHi77u10oAzJ84iSzR/lo=
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.15 h1:Y5YXgygXwDI5P4RkteB5yF7v35neH7LfJKBG+hzIons=
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.15/go.mod h1:K+/1EpG42dFSY7CBj+Fruzm8PsCGWTXJ3jdeJ659oGQ=
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.15 h1:AvltKnW9ewxX2hFmQS0FyJH93aSvJVUEFvXfU+HWtSE=
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.15/go.mod h1:3I4oCdZdmgrREhU74qS1dK9yZ62yumob+58AbFR4cQA=
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4 h1:WKuaxf++XKWlHWu9ECbMlha8WOEGm0OUEZqm4K/Gcfk=
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4/go.mod h1:ZWy7j6v1vWGmPReu0iSGvRiise4YI5SkR3OHKTZ6Wuc=
|
||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.15 h1:NLYTEyZmVZo0Qh183sC8nC+ydJXOOeIL/qI/sS3PdLY=
|
||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.15/go.mod h1:Z803iB3B0bc8oJV8zH2PERLRfQUJ2n2BXISpsA4+O1M=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.4 h1:0ryTNEdJbzUCEWkVXEXoqlXV72J5keC1GvILMOuD00E=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.4/go.mod h1:HQ4qwNZh32C3CBeO6iJLQlgtMzqeG17ziAA/3KDJFow=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.6 h1:P1MU/SuhadGvg2jtviDXPEejU3jBNhoeeAlRadHzvHI=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.6/go.mod h1:5KYaMG6wmVKMFBSfWoyG/zH8pWwzQFnKgpoSRlXHKdQ=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.15 h1:3/u/4yZOffg5jdNk1sDpOQ4Y+R6Xbh+GzpDrSZjuy3U=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.15/go.mod h1:4Zkjq0FKjE78NKjabuM4tRXKFzUJWXgP0ItEZK8l7JU=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.15 h1:wsSQ4SVz5YE1crz0Ap7VBZrV4nNqZt4CIBBT8mnwoNc=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.15/go.mod h1:I7sditnFGtYMIqPRU1QoHZAUrXkGp4SczmlLwrNPlD0=
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.93.0 h1:IrbE3B8O9pm3lsg96AXIN5MXX4pECEuExh/A0Du3AuI=
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.93.0/go.mod h1:/sJLzHtiiZvs6C1RbxS/anSAFwZD6oC6M/kotQzOiLw=
|
||||
github.com/aws/aws-sdk-go-v2/service/signin v1.0.3 h1:d/6xOGIllc/XW1lzG9a4AUBMmpLA9PXcQnVPTuHHcik=
|
||||
github.com/aws/aws-sdk-go-v2/service/signin v1.0.3/go.mod h1:fQ7E7Qj9GiW8y0ClD7cUJk3Bz5Iw8wZkWDHsTe8vDKs=
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.30.6 h1:8sTTiw+9yuNXcfWeqKF2x01GqCF49CpP4Z9nKrrk/ts=
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.30.6/go.mod h1:8WYg+Y40Sn3X2hioaaWAAIngndR8n1XFdRPPX+7QBaM=
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.11 h1:E+KqWoVsSrj1tJ6I/fjDIu5xoS2Zacuu1zT+H7KtiIk=
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.11/go.mod h1:qyWHz+4lvkXcr3+PoGlGHEI+3DLLiU6/GdrFfMaAhB0=
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.41.3 h1:tzMkjh0yTChUqJDgGkcDdxvZDSrJ/WB6R6ymI5ehqJI=
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.41.3/go.mod h1:T270C0R5sZNLbWUe8ueiAF42XSZxxPocTaGSgs5c/60=
|
||||
github.com/aws/smithy-go v1.24.0 h1:LpilSUItNPFr1eY85RYgTIg5eIEPtvFbskaFcmmIUnk=
|
||||
github.com/aws/smithy-go v1.24.0/go.mod h1:LEj2LM3rBRQJxPZTB4KuzZkaZYnZPnvgIhb4pu07mx0=
|
||||
github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932 h1:mXoPYz/Ul5HYEDvkta6I8/rnYM5gSdSV2tJ6XbZuEtY=
|
||||
github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932/go.mod h1:NOuUCSz6Q9T7+igc/hlvDOUdtWKryOrtFyIVABv/p7k=
|
||||
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY=
|
||||
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4=
|
||||
github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs=
|
||||
github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c=
|
||||
github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA=
|
||||
github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0=
|
||||
github.com/bsm/redislock v0.9.4 h1:X/Wse1DPpiQgHbVYRE9zv6m070UcKoOGekgvpNhiSvw=
|
||||
github.com/bsm/redislock v0.9.4/go.mod h1:Epf7AJLiSFwLCiZcfi6pWFO/8eAYrYpQXFxEDPoDeAk=
|
||||
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
||||
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/containerd/errdefs v1.0.0 h1:tg5yIfIlQIrxYtu9ajqY42W3lpS19XqdxRQeEwYG8PI=
|
||||
github.com/containerd/errdefs v1.0.0/go.mod h1:+YBYIdtsnF4Iw6nWZhJcqGSg/dwvV7tyJ/kCkyJ2k+M=
|
||||
github.com/containerd/errdefs/pkg v0.3.0 h1:9IKJ06FvyNlexW690DXuQNx2KA2cUJXx151Xdx3ZPPE=
|
||||
github.com/containerd/errdefs/pkg v0.3.0/go.mod h1:NJw6s9HwNuRhnjJhM7pylWwMyAkmCQvQ4GpJHEqRLVk=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
|
||||
github.com/dhui/dktest v0.4.6 h1:+DPKyScKSEp3VLtbMDHcUq6V5Lm5zfZZVb0Sk7Ahom4=
|
||||
github.com/dhui/dktest v0.4.6/go.mod h1:JHTSYDtKkvFNFHJKqCzVzqXecyv+tKt8EzceOmQOgbU=
|
||||
github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk=
|
||||
github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
|
||||
github.com/docker/docker v28.3.3+incompatible h1:Dypm25kh4rmk49v1eiVbsAtpAsYURjYkaKubwuBdxEI=
|
||||
github.com/docker/docker v28.3.3+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c=
|
||||
github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc=
|
||||
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
|
||||
github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
|
||||
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
||||
github.com/go-chi/chi/v5 v5.2.1 h1:KOIHODQj58PmL80G2Eak4WdvUzjSJSm0vG72crDCqb8=
|
||||
github.com/go-chi/chi/v5 v5.2.1/go.mod h1:L2yAIGWB3H+phAw1NxKwWM+7eUH/lU8pOMm5hHcoops=
|
||||
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
|
||||
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||
github.com/gocql/gocql v1.7.0 h1:O+7U7/1gSN7QTEAaMEsJc1Oq2QHXvCWoF3DFK9HDHus=
|
||||
github.com/gocql/gocql v1.7.0/go.mod h1:vnlvXyFZeLBF0Wy+RS8hrOdbn0UWsWtdg07XJnFxZ+4=
|
||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||
github.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo=
|
||||
github.com/golang-jwt/jwt/v5 v5.3.0/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE=
|
||||
github.com/golang-migrate/migrate/v4 v4.19.1 h1:OCyb44lFuQfYXYLx1SCxPZQGU7mcaZ7gH9yH4jSFbBA=
|
||||
github.com/golang-migrate/migrate/v4 v4.19.1/go.mod h1:CTcgfjxhaUtsLipnLoQRWCrjYXycRz/g5+RWDuYgPrE=
|
||||
github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
|
||||
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/google/go-cmdtest v0.4.1-0.20220921163831-55ab3332a786 h1:rcv+Ippz6RAtvaGgKxc+8FQIpxHgsF+HBzPyYL2cyVU=
|
||||
github.com/google/go-cmdtest v0.4.1-0.20220921163831-55ab3332a786/go.mod h1:apVn/GCasLZUVpAJ6oWAuyP7Ne7CEsQbTnc0plM3m+o=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/renameio v0.1.0 h1:GOZbcHa3HfsPKPlmyPyN2KEohoMXOhdMbHrvbpl2QaA=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/google/subcommands v1.2.0 h1:vWQspBTo2nEqTUFita5/KeEWlUL8kQObDFbub/EN9oE=
|
||||
github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk=
|
||||
github.com/google/wire v0.7.0 h1:JxUKI6+CVBgCO2WToKy/nQk0sS+amI9z9EjVmdaocj4=
|
||||
github.com/google/wire v0.7.0/go.mod h1:n6YbUQD9cPKTnHXEBN2DXlOp/mVADhVErcMFb0v3J18=
|
||||
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed h1:5upAirOpQc1Q53c0bnx2ufif5kANL7bfZWcc6VJWJd8=
|
||||
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4=
|
||||
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
|
||||
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/mailgun/errors v0.4.0 h1:6LFBvod6VIW83CMIOT9sYNp28TCX0NejFPP4dSX++i8=
|
||||
github.com/mailgun/errors v0.4.0/go.mod h1:xGBaaKdEdQT0/FhwvoXv4oBaqqmVZz9P1XEnvD/onc0=
|
||||
github.com/mailgun/mailgun-go/v4 v4.23.0 h1:jPEMJzzin2s7lvehcfv/0UkyBu18GvcURPr2+xtZRbk=
|
||||
github.com/mailgun/mailgun-go/v4 v4.23.0/go.mod h1:imTtizoFtpfZqPqGP8vltVBB6q9yWcv6llBhfFeElZU=
|
||||
github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0=
|
||||
github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo=
|
||||
github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0=
|
||||
github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
|
||||
github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
|
||||
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
|
||||
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
||||
github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug=
|
||||
github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM=
|
||||
github.com/oschwald/geoip2-golang v1.13.0 h1:Q44/Ldc703pasJeP5V9+aFSZFmBN7DKHbNsSFzQATJI=
|
||||
github.com/oschwald/geoip2-golang v1.13.0/go.mod h1:P9zG+54KPEFOliZ29i7SeYZ/GM6tfEL+rgSn03hYuUo=
|
||||
github.com/oschwald/maxminddb-golang v1.13.0 h1:R8xBorY71s84yO06NgTmQvqvTvlS/bnYZrrWX1MElnU=
|
||||
github.com/oschwald/maxminddb-golang v1.13.0/go.mod h1:BU0z8BfFVhi1LQaonTwwGQlsHUEu9pWNdMfmq4ztm0o=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/redis/go-redis/v9 v9.17.2 h1:P2EGsA4qVIM3Pp+aPocCJ7DguDHhqrXNhVcEp4ViluI=
|
||||
github.com/redis/go-redis/v9 v9.17.2/go.mod h1:u410H11HMLoB+TP67dz8rL9s6QW2j76l0//kSOd3370=
|
||||
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
|
||||
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
||||
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
github.com/spf13/cobra v1.10.1 h1:lJeBwCfmrnXthfAupyUTzJ/J4Nc1RsHC/mSRU2dll/s=
|
||||
github.com/spf13/cobra v1.10.1/go.mod h1:7SmJGaTHFVBY0jW4NXGluQoLvhqFQM+6XSKD+P4XaB0=
|
||||
github.com/spf13/pflag v1.0.9 h1:9exaQaMOCwffKiiiYk6/BndUBv+iRViNW+4lEMi0PvY=
|
||||
github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8=
|
||||
github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U=
|
||||
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
|
||||
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 h1:F7Jx+6hwnZ41NSFTO5q4LYDtJRXBf2PD0rNBkeB/lus=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0/go.mod h1:UHB22Z8QsdRDrnAtX4PntOl36ajSxcdUMt1sF7Y6E7Q=
|
||||
go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ=
|
||||
go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I=
|
||||
go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE=
|
||||
go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E=
|
||||
go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4=
|
||||
go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0=
|
||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
||||
go.uber.org/mock v0.6.0 h1:hyF9dfmbgIX5EfOdasqLsWD6xqpNZlXblLB/Dbnwv3Y=
|
||||
go.uber.org/mock v0.6.0/go.mod h1:KiVJ4BqZJaMj4svdfmHM0AUx4NJYO8ZNpPnZn1Z+BBU=
|
||||
go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ=
|
||||
go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
||||
go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc=
|
||||
go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q=
|
||||
golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4=
|
||||
golang.org/x/mod v0.29.0 h1:HV8lRxZC4l2cr3Zq1LvtOsi/ThTgWnUk/y64QSs8GwA=
|
||||
golang.org/x/mod v0.29.0/go.mod h1:NyhrlYXJ2H4eJiRy/WDBO6HMqZQ6q9nk4JzS3NuCK+w=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I=
|
||||
golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
|
||||
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
golang.org/x/telemetry v0.0.0-20251008203120-078029d740a8 h1:LvzTn0GQhWuvKH/kVRS3R3bVAsdQWI7hvfLHGgh9+lU=
|
||||
golang.org/x/telemetry v0.0.0-20251008203120-078029d740a8/go.mod h1:Pi4ztBfryZoJEkyFTI5/Ocsu2jXyDr6iSdgJiYE/uwE=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/tools v0.38.0 h1:Hx2Xv8hISq8Lm16jvBZ2VQf+RLmbd7wVUsALibYI/IQ=
|
||||
golang.org/x/tools v0.38.0/go.mod h1:yEsQ/d/YK8cjh0L6rZlY8tgtlKiBNTL14pGDJPJpYQs=
|
||||
golang.org/x/tools/go/expect v0.1.0-deprecated h1:jY2C5HGYR5lqex3gEniOQL0r7Dq5+VGVgY1nudX5lXY=
|
||||
golang.org/x/tools/go/expect v0.1.0-deprecated/go.mod h1:eihoPOH+FgIqa3FpoTwguz/bVUSGBlGQU67vpBeOrBY=
|
||||
golang.org/x/tools/go/packages/packagestest v0.1.1-deprecated h1:1h2MnaIAIXISqTFKdENegdpAgUXz6NrPEsbIeWaBRvM=
|
||||
golang.org/x/tools/go/packages/packagestest v0.1.1-deprecated/go.mod h1:RVAQXBGNv1ib0J382/DPCRS/BPnsGebyM1Gj5VSDpG8=
|
||||
golang.org/x/vuln v1.1.4 h1:Ju8QsuyhX3Hk8ma3CesTbO8vfJD9EvUBgHvkxHBzj0I=
|
||||
golang.org/x/vuln v1.1.4/go.mod h1:F+45wmU18ym/ca5PLTPLsSzr2KppzswxPP603ldA67s=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
|
||||
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
|
|
|||
|
|
@ -106,7 +106,7 @@ LOGGER_FORMAT=console
|
|||
# For running OUTSIDE Docker:
|
||||
# Change to: MEILISEARCH_HOST=http://localhost:7700
|
||||
MEILISEARCH_HOST=http://meilisearch:7700
|
||||
MEILISEARCH_API_KEY=maple-dev-master-key-change-in-production
|
||||
MEILISEARCH_API_KEY=mapleopentech-dev-master-key-change-in-production
|
||||
MEILISEARCH_INDEX_PREFIX=site_
|
||||
|
||||
# ============================================================================
|
||||
|
|
|
|||
|
|
@ -319,7 +319,7 @@ JWT tokens expire after 60 minutes. Re-run the [registration step](#testing-the-
|
|||
|
||||
**Verify:**
|
||||
```bash
|
||||
docker exec maple-wordpress-dev curl http://maplepress-backend-dev:8000/health
|
||||
docker exec mapleopentech-wordpress-dev curl http://maplepress-backend-dev:8000/health
|
||||
```
|
||||
|
||||
## 🛠️ Technology Stack
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ tasks:
|
|||
silent: true
|
||||
cmds:
|
||||
- |
|
||||
if ! docker network inspect maple-dev >/dev/null 2>&1; then
|
||||
if ! docker network inspect mapleopentech-dev >/dev/null 2>&1; then
|
||||
echo "❌ Infrastructure not running!"
|
||||
echo ""
|
||||
echo "Start it with:"
|
||||
|
|
@ -58,7 +58,7 @@ tasks:
|
|||
echo ""
|
||||
exit 1
|
||||
fi
|
||||
if ! docker ps | grep -q maple-cassandra-1-dev; then
|
||||
if ! docker ps | grep -q mapleopentech-cassandra-1-dev; then
|
||||
echo "❌ Cassandra not running!"
|
||||
echo ""
|
||||
echo "Start it with:"
|
||||
|
|
@ -89,7 +89,7 @@ tasks:
|
|||
deps: [build]
|
||||
cmds:
|
||||
- echo "⚠️ Dropping keyspace 'maplepress'..."
|
||||
- docker exec maple-cassandra-1-dev cqlsh -e "DROP KEYSPACE IF EXISTS maplepress;"
|
||||
- docker exec mapleopentech-cassandra-1-dev cqlsh -e "DROP KEYSPACE IF EXISTS maplepress;"
|
||||
- echo "✅ Keyspace dropped"
|
||||
- echo "🔄 Running migrations to recreate schema..."
|
||||
- ./maplepress-backend migrate up
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# Use external network from infrastructure
|
||||
networks:
|
||||
maple-dev:
|
||||
mapleopentech-dev:
|
||||
external: true
|
||||
|
||||
services:
|
||||
|
|
@ -41,7 +41,7 @@ services:
|
|||
|
||||
# Meilisearch Configuration (if needed)
|
||||
MEILISEARCH_HOST: ${MEILISEARCH_HOST:-http://meilisearch:7700}
|
||||
MEILISEARCH_API_KEY: ${MEILISEARCH_API_KEY:-maple-dev-master-key-change-in-production}
|
||||
MEILISEARCH_API_KEY: ${MEILISEARCH_API_KEY:-mapleopentech-dev-master-key-change-in-production}
|
||||
|
||||
# S3 Configuration (SeaweedFS - S3-compatible storage)
|
||||
AWS_ACCESS_KEY: ${AWS_ACCESS_KEY:-any}
|
||||
|
|
@ -63,10 +63,18 @@ services:
|
|||
volumes:
|
||||
- ./:/go/src/codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend
|
||||
networks:
|
||||
- maple-dev
|
||||
- mapleopentech-dev
|
||||
restart: unless-stopped
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "-H", "X-Tenant-ID: healthcheck", "http://localhost:${SERVER_PORT:-8000}/health"]
|
||||
test:
|
||||
[
|
||||
"CMD",
|
||||
"curl",
|
||||
"-f",
|
||||
"-H",
|
||||
"X-Tenant-ID: healthcheck",
|
||||
"http://localhost:${SERVER_PORT:-8000}/health",
|
||||
]
|
||||
interval: 30s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
|
|
|
|||
|
|
@ -2596,7 +2596,7 @@ CMD ["/app/app-backend", "daemon"]
|
|||
```yaml
|
||||
# Use external network from shared infrastructure
|
||||
networks:
|
||||
maple-dev:
|
||||
mapleopentech-dev:
|
||||
external: true
|
||||
|
||||
services:
|
||||
|
|
@ -2640,7 +2640,7 @@ services:
|
|||
volumes:
|
||||
- ./:/go/src/codeberg.org/mapleopentech/monorepo/cloud/your-backend-name
|
||||
networks:
|
||||
- maple-dev
|
||||
- mapleopentech-dev
|
||||
restart: unless-stopped
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:${SERVER_PORT:-8000}/health"]
|
||||
|
|
|
|||
|
|
@ -212,7 +212,7 @@ curl -X POST http://localhost:8000/api/v1/login \
|
|||
|
||||
**Verify from WordPress container**:
|
||||
```bash
|
||||
docker exec maple-wordpress-dev curl http://maplepress-backend-dev:8000/health
|
||||
docker exec mapleopentech-wordpress-dev curl http://maplepress-backend-dev:8000/health
|
||||
# Should return: {"status":"healthy"}
|
||||
```
|
||||
|
||||
|
|
@ -322,8 +322,8 @@ task build # Build binary (only for manual operations)
|
|||
task migrate:up # Manual migration (only if needed)
|
||||
|
||||
# View infrastructure logs
|
||||
docker logs maple-cassandra-1-dev # Cassandra logs
|
||||
docker logs maple-redis-dev # Redis logs
|
||||
docker logs mapleopentech-cassandra-1-dev # Cassandra logs
|
||||
docker logs mapleopentech-redis-dev # Redis logs
|
||||
```
|
||||
|
||||
---
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue