|
| 1 | +# Docker Deployment (Production-like Local Stack) |
| 2 | + |
| 3 | +This setup runs a production-like environment locally using Docker Compose with: |
| 4 | +- **Keycloak** as the OIDC identity provider |
| 5 | +- **Next.js app** in production mode with Keycloak authentication |
| 6 | + |
| 7 | +This simulates how the application would run in production with a real identity provider. |
| 8 | + |
| 9 | +## Prerequisites |
| 10 | + |
| 11 | +- Docker and Docker Compose installed |
| 12 | +- Ports 3002 and 8080 available |
| 13 | + |
| 14 | +## Quick Start |
| 15 | + |
| 16 | +1. **Start the stack**: |
| 17 | + ```bash |
| 18 | + docker compose up --build |
| 19 | + ``` |
| 20 | + |
| 21 | +2. **Wait for services to be ready**: |
| 22 | + - Keycloak: http://localhost:8080 (takes ~30 seconds) |
| 23 | + - App: http://localhost:3002 |
| 24 | + |
| 25 | +3. **Log in to the app**: |
| 26 | + - Click "Sign In with OIDC" |
| 27 | + - Username: `test` |
| 28 | + - Password: `test` |
| 29 | + |
| 30 | +## Architecture |
| 31 | + |
| 32 | +``` |
| 33 | +┌─────────────┐ ┌──────────────┐ |
| 34 | +│ │ │ │ |
| 35 | +│ Browser │────────▶│ Next.js │ |
| 36 | +│ │ │ (port 3002)│ |
| 37 | +└─────────────┘ └───────┬──────┘ |
| 38 | + │ |
| 39 | + │ OIDC Auth |
| 40 | + ▼ |
| 41 | + ┌──────────────┐ |
| 42 | + │ │ |
| 43 | + │ Keycloak │ |
| 44 | + │ (port 8080)│ |
| 45 | + └──────────────┘ |
| 46 | +``` |
| 47 | + |
| 48 | +## Configuration |
| 49 | + |
| 50 | +All configuration is done via environment variables in `docker-compose.yml`: |
| 51 | + |
| 52 | +### Keycloak Service |
| 53 | +- **Admin Console**: http://localhost:8080/admin |
| 54 | + - Username: `admin` |
| 55 | + - Password: `admin` |
| 56 | +- **Realm**: `toolhive` |
| 57 | +- **Pre-configured client**: `toolhive-cloud-ui` |
| 58 | + |
| 59 | +### Next.js App Service |
| 60 | +Environment variables: |
| 61 | +- `BETTER_AUTH_SECRET`: Auth session encryption key |
| 62 | +- `BETTER_AUTH_URL`: Public URL of the app |
| 63 | +- `TRUSTED_ORIGINS`: Allowed CORS origins |
| 64 | +- `OIDC_ISSUER_URL`: Keycloak realm URL (internal container URL) |
| 65 | +- `OIDC_CLIENT_ID`: OAuth client identifier |
| 66 | +- `OIDC_CLIENT_SECRET`: OAuth client secret |
| 67 | + |
| 68 | +## Test User |
| 69 | + |
| 70 | +A test user is pre-created in Keycloak: |
| 71 | +- **Username**: `test` |
| 72 | + |
| 73 | +- **Password**: `test` |
| 74 | +- **Name**: Test User |
| 75 | + |
| 76 | +## Keycloak Admin Access |
| 77 | + |
| 78 | +Access the Keycloak admin console to manage users, clients, and settings: |
| 79 | + |
| 80 | +1. Open http://localhost:8080/admin |
| 81 | +2. Log in with admin credentials (admin/admin) |
| 82 | +3. Select the `toolhive` realm |
| 83 | + |
| 84 | +## Customization |
| 85 | + |
| 86 | +### Adding More Users |
| 87 | + |
| 88 | +1. Access Keycloak admin console |
| 89 | +2. Go to Users → Add User |
| 90 | +3. Fill in user details |
| 91 | +4. Go to Credentials tab and set a password |
| 92 | + |
| 93 | +### Modifying Client Settings |
| 94 | + |
| 95 | +1. Access Keycloak admin console |
| 96 | +2. Go to Clients → `toolhive-cloud-ui` |
| 97 | +3. Modify settings as needed |
| 98 | +4. Remember to update redirect URIs if changing ports |
| 99 | + |
| 100 | +### Changing Environment Variables |
| 101 | + |
| 102 | +Edit `docker-compose.yml` and restart: |
| 103 | +```bash |
| 104 | +docker compose down |
| 105 | +docker compose up --build |
| 106 | +``` |
| 107 | + |
| 108 | +## Stopping the Stack |
| 109 | + |
| 110 | +```bash |
| 111 | +# Stop services |
| 112 | +docker compose down |
| 113 | + |
| 114 | +# Stop and remove volumes (resets Keycloak data) |
| 115 | +docker compose down -v |
| 116 | +``` |
| 117 | + |
| 118 | +## Troubleshooting |
| 119 | + |
| 120 | +### Keycloak not starting |
| 121 | +- Wait 30-60 seconds for Keycloak to initialize |
| 122 | +- Check logs: `docker compose logs keycloak` |
| 123 | + |
| 124 | +### App can't connect to Keycloak |
| 125 | +- Ensure both containers are on the same network |
| 126 | +- Check `OIDC_ISSUER_URL` uses container name: `http://keycloak:8080` |
| 127 | + |
| 128 | +### Authentication redirects to wrong URL |
| 129 | +- Browser uses `http://localhost:3002` |
| 130 | +- Container uses `http://keycloak:8080` (internal) |
| 131 | +- Ensure redirect URIs in Keycloak match `http://localhost:3002/api/auth/oauth2/callback/oidc` |
| 132 | + |
| 133 | +## Production Deployment |
| 134 | + |
| 135 | +For actual production deployment: |
| 136 | + |
| 137 | +1. **Use a proper database** for Keycloak (PostgreSQL, MySQL) |
| 138 | +2. **Enable HTTPS** with proper certificates |
| 139 | +3. **Use strong secrets** - generate with `openssl rand -base64 32` |
| 140 | +4. **Configure proper hostname** in Keycloak settings |
| 141 | +5. **Remove dev mode** from Keycloak command |
| 142 | +6. **Set up persistent volumes** for Keycloak data |
| 143 | +7. **Configure proper CORS** origins |
| 144 | +8. **Use Kubernetes/cloud services** instead of Docker Compose |
| 145 | + |
| 146 | +## Differences from Development Mode |
| 147 | + |
| 148 | +| Aspect | Development (`pnpm dev`) | Production-like (Docker) | |
| 149 | +|--------|-------------------------|--------------------------| |
| 150 | +| Identity Provider | Test OIDC provider | Keycloak | |
| 151 | +| Authentication | Auto-login | Real login form | |
| 152 | +| User Management | Hardcoded test user | Keycloak admin UI | |
| 153 | +| Configuration | `.env.local` file | Environment variables | |
| 154 | +| Build | Development mode | Production build | |
| 155 | +| Performance | Slow (dev mode) | Fast (optimized) | |
| 156 | + |
| 157 | +## Network Details |
| 158 | + |
| 159 | +The Docker Compose setup creates an internal bridge network (`toolhive`): |
| 160 | +- App and Keycloak communicate via container names |
| 161 | +- External access via published ports (3000, 8080) |
| 162 | +- Browser connects to `localhost`, app connects to `keycloak` hostname |
0 commit comments