# Backend Access & Database Operations ## Access Backend Container ```bash # Find which node runs the backend ssh dockeradmin@ docker service ps maplefile_backend --filter "desired-state=running" # Note the NODE column # SSH to that worker ssh dockeradmin@ # Get container ID export BACKEND_CONTAINER=$(docker ps --filter "name=maplefile.*backend" -q | head -1) # Open shell docker exec -it $BACKEND_CONTAINER sh # Or run single command docker exec $BACKEND_CONTAINER ./maplefile-backend --help ``` ## View Logs ```bash # Follow logs docker logs -f $BACKEND_CONTAINER # Last 100 lines docker logs --tail 100 $BACKEND_CONTAINER # Search for errors docker logs $BACKEND_CONTAINER 2>&1 | grep -i error ``` ## Database Operations ### Run Migrations (Safe) ```bash docker exec $BACKEND_CONTAINER ./maplefile-backend migrate up ``` Auto-runs on backend startup when `DATABASE_AUTO_MIGRATE=true` (default in stack file). ### Rollback Last Migration (Destructive) ```bash docker exec $BACKEND_CONTAINER ./maplefile-backend migrate down ``` Only rolls back 1 migration. Run multiple times for multiple rollbacks. ### Reset Database (Full Wipe) ```bash # 1. SSH to any Cassandra node (any of the 3 nodes works) ssh dockeradmin@ # 2. Find the Cassandra container ID export CASSANDRA_CONTAINER=$(docker ps --filter "name=cassandra" -q | head -1) # 3. Drop keyspace (DELETES ALL DATA - propagates to all 3 nodes) docker exec -it $CASSANDRA_CONTAINER cqlsh -e "DROP KEYSPACE IF EXISTS maplefile;" # 4. Wait for schema to propagate across cluster sleep 5 # 5. Recreate keyspace (propagates to all 3 nodes) docker exec -it $CASSANDRA_CONTAINER cqlsh -e " CREATE KEYSPACE IF NOT EXISTS maplefile WITH replication = { 'class': 'SimpleStrategy', 'replication_factor': 3 };" # 6. Wait for schema agreement across cluster sleep 5 # 7. Verify keyspace exists docker exec -it $CASSANDRA_CONTAINER cqlsh -e "DESCRIBE KEYSPACE maplefile;" # 8. Restart backend to run migrations # You must pull the new image on the worker node first # Find which worker runs the service: ssh dockeradmin@ docker service ps maplefile_backend # Note the worker node name # Pull image on the worker: ssh dockeradmin@ docker pull registry.digitalocean.com/ssp/maplefile-backend:prod exit # Force restart on manager: ssh dockeradmin@ docker service update --force maplefile_backend # Verify new version is running: docker service logs maplefile_backend --tail 50 # Look for: 📝 Git Commit: ``` ## Troubleshooting ### Container Not Found ```bash # Check service status docker service ps maplefile_backend # List all backend containers docker ps | grep backend ``` ### Wrong Container (MaplePress vs MapleFile) ```bash # Verify you have MapleFile (not MaplePress) docker ps | grep $BACKEND_CONTAINER # Should show "maplefile-backend" in image name ``` ### Migration Fails ```bash # Check environment (from worker node) docker exec $BACKEND_CONTAINER env | grep DATABASE # Check Cassandra connectivity docker exec $BACKEND_CONTAINER nc -zv cassandra-1 9042 ``` ## Configuration Environment variables are in `~/stacks/maplefile-stack.yml` on manager node, not `.env` files. To change config: 1. Edit `~/stacks/maplefile-stack.yml` 2. Pull new image on worker: `ssh dockeradmin@ && docker pull registry.digitalocean.com/ssp/maplefile-backend:prod && exit` 3. Force restart on manager: `docker service update --force maplefile_backend` **Important**: Worker nodes cache images locally. You MUST pull the new image on the worker node before restarting the service. The `--resolve-image always` and `--with-registry-auth` flags do NOT reliably force worker nodes to pull new images. --- **Last Updated**: November 2025