Files
roa2web-service-auto/DOKPLOY_DEPLOYMENT.md
Marius Mutu 9008876b16 chore: Remove obsolete microservices directories and update all references
- Delete data-entry-app/ (1.6GB), reports-app/ (447MB), .auto-build-data/
- Saved ~1.4GB disk space (64% reduction: 2.2GB → 845MB)

Updated references across 38 files:
- .claude/rules/ paths: backend/modules/, src/modules/
- .claude/commands/validate.md: all validation paths
- docs/ (13 files): data-entry, telegram, README, CLAUDE.md
- scripts/ (3 files): backup-secrets, restore-secrets, test-docker
- security/ (2 files): git_cleanup, SECURITY_PROCEDURES
- deployment/ & shared/: updated all stale comments

All paths now reflect ultrathin monolith architecture:
- Backend: backend/modules/{reports,data_entry,telegram}/
- Frontend: src/modules/{reports,data-entry}/
- Shared: shared/{auth,database,routes}/

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-30 12:08:20 +02:00

919 lines
23 KiB
Markdown

# ROA2WEB Deployment Guide for Dokploy
This guide provides step-by-step instructions for deploying ROA2WEB to Dokploy, a modern Docker-based deployment platform.
## Table of Contents
- [Prerequisites](#prerequisites)
- [Quick Start](#quick-start)
- [Detailed Setup](#detailed-setup)
- [1. SSH Key Configuration](#1-ssh-key-configuration)
- [2. Environment Variables](#2-environment-variables)
- [3. Repository Setup](#3-repository-setup)
- [4. Deployment](#4-deployment)
- [Post-Deployment](#post-deployment)
- [Monitoring and Maintenance](#monitoring-and-maintenance)
- [Troubleshooting](#troubleshooting)
---
## Prerequisites
Before deploying to Dokploy, ensure you have:
- ✅ A Dokploy instance running (cloud or self-hosted)
- ✅ Access to your Git repository (GitHub, GitLab, Gitea, etc.)
- ✅ SSH private key for Oracle database tunnel (`roa_oracle_server`)
- ✅ Oracle database credentials
- ✅ JWT secret key for authentication
- ✅ Telegram bot token (if using Telegram bot feature)
- ✅ Claude API key (if using Telegram bot with Claude SDK)
---
## Quick Start
### Option 1: Using Pre-Configured Secrets (Recommended)
1. **Add SSH Key to Repository**:
```bash
# In your local repository
cp /path/to/your/roa_oracle_server ./ssh-tunnel/secrets/
chmod 600 ./ssh-tunnel/secrets/roa_oracle_server
git add ssh-tunnel/secrets/roa_oracle_server
git commit -m "Add SSH key for deployment"
git push
```
⚠️ **IMPORTANT**: Only do this if your repository is **private**!
2. **Set Environment Variables in Dokploy**:
- Navigate to your application in Dokploy
- Go to "Environment Variables" section
- Add all required variables (see [Environment Variables](#2-environment-variables))
3. **Deploy**:
- Click "Deploy" in Dokploy
- Wait for build and deployment to complete
- Check logs for any errors
### Option 2: Using Dokploy Secrets Manager (Most Secure)
1. **Upload SSH Key via Dokploy UI**:
- Go to Dokploy → Secrets → Create New Secret
- Name: `SSH_PRIVATE_KEY`
- Content: Paste your SSH private key content
- Save
2. **Modify `docker-compose.yml`** to use the secret:
```yaml
roa-ssh-tunnel:
secrets:
- ssh_private_key
# ... rest of config
secrets:
ssh_private_key:
external: true
```
3. **Update Dockerfile** to use mounted secret:
```dockerfile
# Copy SSH key from mounted secret
RUN --mount=type=secret,id=ssh_private_key \
cp /run/secrets/ssh_private_key /home/tunnel/.ssh/roa_oracle_server && \
chown tunnel:tunnel /home/tunnel/.ssh/roa_oracle_server && \
chmod 600 /home/tunnel/.ssh/roa_oracle_server
```
---
## Detailed Setup
### 1. SSH Key Configuration
The SSH tunnel requires a private key to connect to the Oracle database server. Choose one of the following methods:
#### Method A: Include in Repository (Private Repos Only)
1. **Prepare the SSH Key**:
```bash
cd /mnt/e/proiecte/roa2web
# Copy your SSH key to the secrets directory
cp /path/to/your/roa_oracle_server ./ssh-tunnel/secrets/
# Set proper permissions
chmod 600 ./ssh-tunnel/secrets/roa_oracle_server
# Verify the key
ls -l ./ssh-tunnel/secrets/roa_oracle_server
```
2. **Commit to Repository** (ONLY if private!):
```bash
git add ssh-tunnel/secrets/roa_oracle_server
git commit -m "Add SSH key for production deployment"
git push origin main
```
3. **Test Locally**:
```bash
# Test SSH connection
ssh -i ./ssh-tunnel/secrets/roa_oracle_server \
-p 22122 \
roa2web@83.103.197.79 \
"echo 'Connection successful'"
# Test Docker build
docker build -t test-ssh-tunnel ./ssh-tunnel
```
#### Method B: Use Dokploy Environment Files
1. **In Dokploy UI**:
- Navigate to: Application → Settings → Environment Files
- Click "Add Environment File"
- File path: `/home/tunnel/.ssh/roa_oracle_server`
- Content: Paste your SSH private key
- Permissions: `600`
2. **Mount in `docker-compose.yml`**:
```yaml
roa-ssh-tunnel:
volumes:
- ${SSH_KEY_FILE}:/home/tunnel/.ssh/roa_oracle_server:ro
```
#### Method C: Use Docker BuildKit Secrets
1. **In Dokploy Build Settings**:
- Enable BuildKit
- Add build secret: `id=ssh_key,src=<path_to_key>`
2. **Update Dockerfile**:
```dockerfile
RUN --mount=type=secret,id=ssh_key \
cp /run/secrets/ssh_key /home/tunnel/.ssh/roa_oracle_server && \
chmod 600 /home/tunnel/.ssh/roa_oracle_server && \
chown tunnel:tunnel /home/tunnel/.ssh/roa_oracle_server
```
---
### 2. Environment Variables
Configure these environment variables in Dokploy:
#### Required Variables
| Variable | Description | Example |
|----------|-------------|---------|
| `ORACLE_USER` | Oracle database username | `CONTAFIN_ORACLE` |
| `ORACLE_PASSWORD` | Oracle database password | `your_secure_password` |
| `ORACLE_HOST` | Oracle host (via tunnel) | `roa-ssh-tunnel` (in Docker network) |
| `ORACLE_PORT` | Oracle port (via tunnel) | `1526` |
| `ORACLE_SID` | Oracle SID | `ROA` |
| `JWT_SECRET_KEY` | Secret key for JWT tokens | Generate: `openssl rand -hex 32` |
| `JWT_ALGORITHM` | JWT algorithm | `HS256` |
| `JWT_EXPIRE_MINUTES` | Token expiration time | `30` |
#### SSH Tunnel Variables
| Variable | Description | Example |
|----------|-------------|---------|
| `SSH_SERVER` | Remote SSH server | `83.103.197.79` |
| `SSH_PORT` | SSH port | `22122` |
| `SSH_USER` | SSH username | `roa2web` |
| `REMOTE_HOST` | Oracle database host (remote) | `10.0.20.36` |
| `REMOTE_PORT` | Oracle database port (remote) | `1521` |
#### Telegram Bot Variables (Optional)
| Variable | Description | Example |
|----------|-------------|---------|
| `TELEGRAM_BOT_TOKEN` | Telegram bot token from @BotFather | `123456:ABC-DEF...` |
| `CLAUDE_API_KEY` | Claude API key for agent features | `sk-ant-...` |
| `TELEGRAM_LOG_LEVEL` | Logging level | `INFO` |
#### Optional Variables
| Variable | Description | Default |
|----------|-------------|---------|
| `ENVIRONMENT` | Environment name | `production` |
| `DEBUG` | Enable debug mode | `false` |
| `DOMAIN` | Domain for the application | `roa2web.yourdomain.com` |
| `SSL_EMAIL` | Email for Let's Encrypt SSL | `admin@yourdomain.com` |
| `REDIS_PASSWORD` | Redis password | `roa2web_redis_password` |
#### Setting Variables in Dokploy
1. Go to your application in Dokploy
2. Navigate to **Settings** → **Environment Variables**
3. Click **Add Environment Variable**
4. Add each variable one by one:
- Key: `ORACLE_PASSWORD`
- Value: `your_secure_password`
- Click **Save**
5. Repeat for all required variables
**Alternative: Bulk Import**
Create a `.env` file and import it:
```bash
# .env.production
ORACLE_USER=CONTAFIN_ORACLE
ORACLE_PASSWORD=your_secure_password
ORACLE_HOST=roa-ssh-tunnel
ORACLE_PORT=1526
ORACLE_SID=ROA
JWT_SECRET_KEY=your_generated_secret_key
JWT_ALGORITHM=HS256
JWT_EXPIRE_MINUTES=30
SSH_SERVER=83.103.197.79
SSH_PORT=22122
SSH_USER=roa2web
REMOTE_HOST=10.0.20.36
REMOTE_PORT=1521
TELEGRAM_BOT_TOKEN=your_telegram_token
CLAUDE_API_KEY=your_claude_key
ENVIRONMENT=production
DEBUG=false
```
Then in Dokploy:
- Settings → Environment Variables → Import from file
- Upload `.env.production`
---
### 3. Repository Setup
1. **Connect Your Git Repository**:
- In Dokploy, create a new application
- Choose "Docker Compose"
- Connect your Git repository:
- **Repository URL**: `https://gitea.romfast.ro/romfast/roa2web.git`
- **Branch**: `main` (or your deployment branch)
- **Authentication**: Add Git credentials if private repo
2. **Configure Build Settings**:
- **Dockerfile Path**: Not needed (using docker-compose.yml)
- **Docker Compose File**: `docker-compose.yml`
- **Build Context**: Repository root
- **Enable BuildKit**: ✅ (recommended for better caching)
3. **Configure Deployment Settings**:
- **Auto-deploy**: Enable if you want automatic deployments on git push
- **Health Check**: Enable to verify services are running
- **Restart Policy**: `unless-stopped`
---
### 4. Deployment
#### Initial Deployment
1. **Pre-deployment Checklist**:
- ✅ SSH key is configured (Method A, B, or C)
- ✅ All environment variables are set
- ✅ Repository is connected and accessible
- ✅ Docker Compose file is valid
2. **Start Deployment**:
- In Dokploy dashboard, click **Deploy**
- Monitor the deployment logs
- Look for these success indicators:
```
✅ Cloning Custom Git ...
✅ Building services ...
✅ Starting services ...
✅ Health checks passing ...
```
3. **Expected Build Time**:
- First deployment: 5-10 minutes (depending on network and CPU)
- Subsequent deployments: 2-5 minutes (with caching)
#### Deployment Stages
1. **Clone Repository**:
```
Cloning Custom Git https://...@gitea.romfast.ro/romfast/roa2web.git
```
2. **Build Images**:
- `roa-ssh-tunnel`: SSH tunnel container (~1 min)
- `roa-backend`: FastAPI backend (~3 min)
- `roa-frontend`: Vue.js frontend (~4 min)
- `roa-gateway`: Nginx gateway (~1 min)
- `roa-telegram-bot`: Telegram bot (~2 min)
3. **Start Services**:
- Redis starts first
- SSH tunnel starts and establishes connection
- Backend waits for SSH tunnel health check
- Frontend starts
- Nginx gateway starts and routes traffic
- Telegram bot starts last
4. **Health Checks**:
- Each service runs its health check
- Deployment succeeds when all health checks pass
---
## Post-Deployment
### Verify Deployment
1. **Check Service Status**:
- In Dokploy, navigate to **Containers**
- Verify all services are "Running" (green status):
- `roa-gateway` (Nginx)
- `roa-backend` (FastAPI)
- `roa-frontend` (Vue.js)
- `roa-ssh-tunnel` (SSH)
- `roa-redis` (Redis)
- `roa-telegram-bot` (Telegram)
2. **Check Logs**:
```bash
# In Dokploy UI, click on each container to view logs
# SSH Tunnel should show:
[INFO] SSH tunnel established: localhost:1526 -> 10.0.20.36:1521
[INFO] Tunnel is active and healthy
# Backend should show:
INFO: Application startup complete.
INFO: Uvicorn running on http://0.0.0.0:8000
# Frontend should show:
VITE v5.x ready in XXX ms
# Nginx should show:
nginx: [notice] start worker processes
```
3. **Test Endpoints**:
**Health Check**:
```bash
curl https://your-domain.com/health
# Expected: {"status":"healthy"}
```
**API Health**:
```bash
curl https://your-domain.com/api/health
# Expected: {"status":"ok","database":"connected"}
```
**Frontend**:
- Open `https://your-domain.com` in browser
- You should see the login page
4. **Test Authentication**:
```bash
curl -X POST https://your-domain.com/api/auth/login \
-H "Content-Type: application/json" \
-d '{"username":"test_user","password":"test_password"}'
# Expected: {"access_token":"eyJ...","token_type":"bearer"}
```
5. **Test Database Connection**:
```bash
# Check SSH tunnel logs
docker logs roa-ssh-tunnel
# Should show successful tunnel establishment
# Should show periodic health checks passing
```
### Configure DNS and SSL
1. **DNS Setup**:
- Point your domain to Dokploy server IP
- Add A record: `roa2web.yourdomain.com` → `<dokploy-server-ip>`
2. **SSL Certificate** (if using custom domain):
- Dokploy typically handles SSL automatically via Let's Encrypt
- Or configure in `nginx/ssl/` directory
- Verify SSL: `https://www.ssllabs.com/ssltest/`
3. **Update Environment Variables**:
- Set `DOMAIN=roa2web.yourdomain.com`
- Set `SSL_EMAIL=admin@yourdomain.com`
- Redeploy if needed
### Configure Telegram Bot (Optional)
1. **Test Bot**:
- Open Telegram
- Search for your bot: `@your_bot_name`
- Send `/start`
- Should receive welcome message
2. **Link Account**:
- Login to web app
- Go to Settings → Telegram Integration
- Click "Generate Link Code"
- Copy the 8-character code
- Send to Telegram bot: `/start ABC123XY`
- Verify account is linked
3. **Test Commands**:
```
/help - Show available commands
/companies - List accessible companies
/dashboard - View financial dashboard
```
---
## Monitoring and Maintenance
### Monitor Services
1. **Dokploy Dashboard**:
- View real-time container status
- Monitor CPU/Memory/Disk usage
- Check logs for errors
2. **Health Checks**:
- Automatic health checks every 30 seconds
- Failed health checks trigger alerts
- Configure notifications in Dokploy settings
3. **Logging**:
- Centralized logs in Dokploy UI
- Filter by service, time, log level
- Export logs for analysis
### Backup Strategy
1. **Database Backups** (Oracle):
- Handled by your Oracle DBA
- SSH tunnel only provides access, doesn't store data
2. **Telegram Bot Database** (SQLite):
```bash
# Backup SQLite database
docker exec roa-telegram-bot cp /app/data/telegram_bot.db /app/data/backup/
# Download backup
docker cp roa-telegram-bot:/app/data/backup/telegram_bot.db ./telegram_backup.db
```
3. **Configuration Backups**:
- Environment variables: Export from Dokploy
- Docker Compose: Keep in Git
- SSH keys: Store securely offline
### Update and Rollback
1. **Update Application**:
```bash
# Push changes to git
git add .
git commit -m "Update feature X"
git push origin main
# In Dokploy, click "Redeploy"
# Or enable auto-deploy for automatic updates
```
2. **Rollback to Previous Version**:
- In Dokploy → Deployments → History
- Find previous successful deployment
- Click "Rollback"
- Confirm rollback
3. **Zero-Downtime Updates**:
- Dokploy handles rolling updates automatically
- Old containers stay running until new ones are healthy
- Health checks ensure smooth transitions
### Scaling
1. **Horizontal Scaling** (Multiple Instances):
```yaml
# In docker-compose.yml
roa-backend:
deploy:
replicas: 3 # Run 3 backend instances
```
2. **Vertical Scaling** (More Resources):
```yaml
roa-backend:
deploy:
resources:
limits:
cpus: '2.0'
memory: 2G
```
3. **Load Balancing**:
- Nginx gateway handles load balancing automatically
- Distributes traffic across backend replicas
- Health checks ensure traffic goes to healthy instances
---
## Troubleshooting
### Common Issues
#### 1. SSH Tunnel Connection Failed
**Error**:
```
[ERROR] SSH connection failed: Permission denied (publickey)
```
**Solutions**:
a. **Verify SSH Key**:
```bash
# Check key exists and has correct permissions
docker exec roa-ssh-tunnel ls -l /home/tunnel/.ssh/roa_oracle_server
# Expected: -rw------- 1 tunnel tunnel
# Test SSH connection manually
docker exec roa-ssh-tunnel ssh -i /home/tunnel/.ssh/roa_oracle_server \
-p 22122 roa2web@83.103.197.79 "echo 'Connected'"
```
b. **Verify SSH Key Format**:
```bash
# Key should start with:
# -----BEGIN OPENSSH PRIVATE KEY-----
# or
# -----BEGIN RSA PRIVATE KEY-----
# Check key format
head -1 ./ssh-tunnel/secrets/roa_oracle_server
```
c. **Check Remote Server**:
- Verify public key is in `~/.ssh/authorized_keys` on remote server
- Verify SSH service is running on port 22122
- Check firewall allows connections from Dokploy server IP
#### 2. Oracle Database Connection Failed
**Error**:
```
ORA-12170: TNS:Connect timeout occurred
```
**Solutions**:
a. **Verify SSH Tunnel is Running**:
```bash
# Check tunnel health
curl http://<dokploy-domain>/api/health
# Check tunnel logs
docker logs roa-ssh-tunnel
# Should show: "SSH tunnel established"
```
b. **Test Oracle Connection**:
```bash
# From backend container
docker exec roa-backend python -c "
import oracledb
conn = oracledb.connect(
user='CONTAFIN_ORACLE',
password='${ORACLE_PASSWORD}',
dsn='roa-ssh-tunnel:1526/ROA'
)
print('Connected successfully')
conn.close()
"
```
c. **Check Environment Variables**:
```bash
docker exec roa-backend env | grep ORACLE
# Verify all ORACLE_* variables are set correctly
```
#### 3. Frontend Not Loading
**Error**:
```
502 Bad Gateway
```
**Solutions**:
a. **Check Frontend Container**:
```bash
# View frontend logs
docker logs roa-frontend
# Verify container is running
docker ps | grep roa-frontend
```
b. **Check Nginx Configuration**:
```bash
# Test nginx config
docker exec roa-gateway nginx -t
# View nginx logs
docker logs roa-gateway
```
c. **Verify Network**:
```bash
# Check containers can communicate
docker exec roa-gateway ping roa-frontend
docker exec roa-gateway ping roa-backend
```
#### 4. Backend API Errors
**Error**:
```
{"detail":"Internal server error"}
```
**Solutions**:
a. **Check Backend Logs**:
```bash
docker logs roa-backend --tail 100
```
b. **Check Database Connection**:
```bash
# Test database query
docker exec roa-backend python -c "
from app.database import oracle_pool
async def test():
async with oracle_pool.get_connection() as conn:
cursor = conn.cursor()
cursor.execute('SELECT 1 FROM DUAL')
print(cursor.fetchone())
import asyncio
asyncio.run(test())
"
```
c. **Check JWT Configuration**:
```bash
docker exec roa-backend env | grep JWT
# Verify JWT_SECRET_KEY is set
```
#### 5. Telegram Bot Not Responding
**Error**:
- Bot doesn't respond to commands
**Solutions**:
a. **Check Bot Container**:
```bash
# View bot logs
docker logs roa-telegram-bot --tail 100
# Check if bot is running
docker ps | grep telegram-bot
```
b. **Verify Token**:
```bash
# Check token is set
docker exec roa-telegram-bot env | grep TELEGRAM_BOT_TOKEN
# Test token validity
curl https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/getMe
```
c. **Check Backend Connection**:
```bash
# Test internal API
docker exec roa-telegram-bot curl http://localhost:8002/internal/health
# Test backend connection
docker exec roa-telegram-bot curl http://roa-backend:8000/health
```
#### 6. Environment Variables Not Loading
**Error**:
```
The "ORACLE_PASSWORD" variable is not set. Defaulting to a blank string.
```
**Solutions**:
a. **Set in Dokploy UI**:
- Go to Settings → Environment Variables
- Add missing variable
- Redeploy
b. **Check Variable Names**:
- Ensure no typos in variable names
- Variables are case-sensitive
- No leading/trailing spaces
c. **Use .env File**:
- Create `.env` in project root
- Import via Dokploy UI
- Redeploy
#### 7. Build Failures
**Error**:
```
failed to solve: failed to calculate checksum
```
**Solutions**:
a. **Clear Build Cache**:
- In Dokploy → Settings → Advanced
- Click "Clear Build Cache"
- Redeploy
b. **Check Dockerfile**:
```bash
# Validate Dockerfiles locally
docker build -t test-backend ./backend
docker build -t test-frontend ./src
docker build -t test-tunnel ./ssh-tunnel
```
c. **Check File Paths**:
- Verify COPY paths in Dockerfiles
- Ensure files exist in repository
- Check .dockerignore isn't excluding needed files
### Getting Help
If issues persist:
1. **Check Logs**:
```bash
# Get all container logs
docker-compose logs > deployment_logs.txt
```
2. **Export Configuration**:
```bash
# Export environment variables
# (redact sensitive values before sharing)
docker exec roa-backend env > backend_env.txt
```
3. **Contact Support**:
- Include: logs, error messages, steps to reproduce
- Redact: passwords, tokens, API keys
- Provide: Dokploy version, OS, Docker version
4. **Community Resources**:
- Dokploy documentation: https://docs.dokploy.com
- ROA2WEB repository issues
- Docker documentation
---
## Security Best Practices
1. **SSH Keys**:
- ✅ Use Ed25519 keys (more secure than RSA)
- ✅ Use unique keys for each environment
- ✅ Rotate keys periodically (every 6-12 months)
- ✅ Never commit private keys to public repositories
- ✅ Use secrets management for production
2. **Environment Variables**:
- ✅ Use strong, random JWT secret keys (32+ characters)
- ✅ Use complex Oracle passwords
- ✅ Don't log sensitive values
- ✅ Rotate credentials periodically
3. **Network Security**:
- ✅ Use HTTPS/SSL for all external connections
- ✅ Restrict SSH access by IP if possible
- ✅ Use Dokploy's firewall features
- ✅ Keep all software updated
4. **Container Security**:
- ✅ Run containers as non-root users (already configured)
- ✅ Use minimal base images (alpine)
- ✅ Scan images for vulnerabilities
- ✅ Keep Docker and Dokploy updated
5. **Access Control**:
- ✅ Use strong Dokploy admin password
- ✅ Enable 2FA on Git accounts
- ✅ Limit who has deployment access
- ✅ Audit access logs regularly
---
## Performance Optimization
1. **Enable Caching**:
- Use Redis for session storage
- Enable browser caching in Nginx
- Use Docker build cache (BuildKit)
2. **Resource Limits**:
```yaml
services:
roa-backend:
deploy:
resources:
limits:
cpus: '1.0'
memory: 1G
reservations:
cpus: '0.5'
memory: 512M
```
3. **Database Connection Pooling**:
- Already configured in `shared/database/oracle_pool.py`
- Default: 5 min connections, 20 max connections
- Adjust based on load
4. **Frontend Optimization**:
- Production build already includes:
- Minification
- Tree-shaking
- Code splitting
- Compression (gzip/brotli)
---
## Next Steps
After successful deployment:
1. ✅ **Monitor for 24-48 hours**:
- Check logs for errors
- Monitor resource usage
- Verify all features work
2. ✅ **Set up Alerts**:
- Configure Dokploy notifications
- Set up health check alerts
- Monitor disk space
3. ✅ **Plan Backup Strategy**:
- Schedule regular backups
- Test restore procedures
- Document backup locations
4. ✅ **Document Custom Configuration**:
- Record any changes made
- Document environment-specific settings
- Share knowledge with team
5. ✅ **Performance Testing**:
- Load test the application
- Optimize as needed
- Plan for scaling
---
## Additional Resources
- **ROA2WEB Documentation**:
- `README.md` - Project overview
- `CLAUDE.md` - Development guide
- `DEPLOYMENT_GUIDE.md` - General deployment guide
- `ARCHITECTURE_SCHEMA.md` - Architecture details
- **Dokploy Resources**:
- Documentation: https://docs.dokploy.com
- GitHub: https://github.com/dokploy/dokploy
- Community: Discord/Forums
- **Docker Resources**:
- Docker Compose: https://docs.docker.com/compose/
- Docker Build: https://docs.docker.com/build/
- Best Practices: https://docs.docker.com/develop/dev-best-practices/
---
## Conclusion
You should now have ROA2WEB successfully deployed on Dokploy! 🎉
For questions or issues, refer to the troubleshooting section or check the ROA2WEB repository documentation.
**Happy deploying!** 🚀