- Created `deploy-dev.yml` for automated deployment to the development server on push to the `dev` branch. - Created `deploy.yml` for automated deployment to the production server on push to the `main` or `master` branches. - Added deployment instructions in `DEPLOYMENT-PORTAINER.md` for using Portainer and Traefik. - Documented Gitea Actions deployment process in `DEPLOYMENT.md`. - Configured Traefik SSL settings in `TRAEFIK-SSL-CONFIG.md` for both development and production environments. - Implemented a deployment script `deploy.sh` for manual deployments. - Added Docker Compose configurations for development (`docker-compose.portainer.dev.yml`) and production (`docker-compose.portainer.yml`) environments. - Updated main `docker-compose.yml` to support Traefik integration and environment variable configurations.
8.2 KiB
Deployment with Portainer and Traefik
This guide covers deploying MerchBay Admin using your existing Portainer and Traefik setup.
Prerequisites
- ✅ Gitea self-hosted with Gitea runners configured
- ✅ Portainer installed and accessible
- ✅ Traefik reverse proxy running with:
webentrypoint (port 80)websecureentrypoint (port 443)- Let's Encrypt certificate resolver named
letsencrypt - External network named
traefik
Deployment Methods
Method 1: Portainer Stack Deployment (Recommended)
Step 1: Prepare the Image
Build the Docker image via Gitea Actions or manually:
# Using Gitea Actions (will build automatically on push)
git push origin main
# OR build manually
docker build -t merchbay_admin:latest .
Step 2: Deploy in Portainer
-
Access Portainer →
Stacks→Add stack -
Stack Configuration:
- Name:
merchbay-admin - Build method:
Web editor
- Name:
-
Paste the content from
docker-compose.portainer.ymland update:APP_URL: Your domain (e.g.,https://merchbay-admin.yourdomain.com)DB_HOST: Your MySQL hostDB_DATABASE: Database nameDB_USERNAME: Database usernameDB_PASSWORD: Database password- Traefik Host rule: Replace
merchbay-admin.yourdomain.comwith your actual domain
-
Deploy the stack
-
Run Initial Setup:
- Go to
Containers→ Findmerchbay_admin_app - Click
Console→ Connect with/bin/bash - Run:
php artisan migrate --force php artisan config:cache php artisan route:cache
- Go to
Method 2: Gitea Actions CI/CD (Automated)
Step 1: Configure Gitea Secrets
In your Gitea repository → Settings → Secrets → Actions, add:
| Secret Name | Value | Description |
|---|---|---|
DEPLOY_HOST |
192.168.1.100 |
Your server IP/hostname |
DEPLOY_USER |
deploy |
SSH username |
DEPLOY_SSH_KEY |
-----BEGIN RSA... |
Private SSH key |
DEPLOY_PORT |
22 |
SSH port (optional) |
DEPLOY_DIR |
/var/www/merchbay_admin |
Deployment directory |
DOMAIN |
merchbay-admin.yourdomain.com |
Your domain for Traefik |
Step 2: Prepare Deployment Server
# SSH into your server
ssh deploy@your-server
# Create deployment directory
sudo mkdir -p /var/www/merchbay_admin
sudo chown $USER:$USER /var/www/merchbay_admin
cd /var/www/merchbay_admin
# Create .env file
nano .env
Add to .env:
APP_ENV=production
APP_DEBUG=false
APP_URL=https://merchbay-admin.yourdomain.com
DB_HOST=your-mysql-host
DB_PORT=3306
DB_DATABASE=merchbay_admin
DB_USERNAME=your-mysql-user
DB_PASSWORD=your-mysql-password
DOMAIN=merchbay-admin.yourdomain.com
Step 3: Ensure Traefik Network Exists
docker network inspect traefik >/dev/null 2>&1 || docker network create traefik
Step 4: Deploy
Simply push to your main branch:
git add .
git commit -m "Deploy application"
git push origin main
Gitea Actions will automatically:
- Build the Docker image
- Transfer to your server
- Deploy with docker-compose
- Connect to Traefik network
- Run migrations
- Cache configurations
Method 3: Manual Deployment with Script
# On your server
cd /var/www/merchbay_admin
# Pull latest code
git pull origin main
# Run deployment script
./deploy.sh
Traefik Configuration
Verify Traefik Setup
Ensure your Traefik configuration includes:
# traefik.yml or docker-compose.yml
entryPoints:
web:
address: ":80"
websecure:
address: ":443"
certificatesResolvers:
letsencrypt:
acme:
email: your-email@example.com
storage: /letsencrypt/acme.json
httpChallenge:
entryPoint: web
External Network
Ensure Traefik network exists and is external:
# Create network if it doesn't exist
docker network create traefik
# Verify
docker network inspect traefik
DNS Configuration
Point your domain to your server:
Type: A Record
Name: merchbay-admin (or @ for root domain)
Value: YOUR_SERVER_IP
TTL: 3600
Verification
1. Check Container Status
Via Portainer:
- Navigate to
Containers - Verify
merchbay_admin_appis running
Via CLI:
docker ps | grep merchbay_admin
2. Check Traefik Dashboard
If you have Traefik dashboard enabled:
- Look for
merchbay-admin@dockerrouter - Verify it's connected to the correct service
3. Test Application
# Test HTTPS
curl -I https://merchbay-admin.yourdomain.com
# Should return: HTTP/2 200
4. Check Logs
Via Portainer:
Containers→merchbay_admin_app→Logs
Via CLI:
docker logs merchbay_admin_app -f
Troubleshooting
Issue: Container not accessible via domain
Check Traefik labels:
docker inspect merchbay_admin_app | grep -A 20 Labels
Verify network connection:
docker network inspect traefik | grep merchbay_admin
Solution:
# Reconnect to Traefik network
docker network connect traefik merchbay_admin_app
Issue: SSL certificate not generating
Check Traefik logs:
docker logs traefik | grep letsencrypt
Common fixes:
- Ensure port 80 is accessible (Let's Encrypt HTTP challenge)
- Verify DNS is pointing to your server
- Check email in Traefik's ACME configuration
- Ensure
acme.jsonhas correct permissions (600)
Issue: Database connection failed
Check environment variables:
docker exec merchbay_admin_app env | grep DB_
Test connection:
docker exec merchbay_admin_app php artisan tinker
>>> DB::connection()->getPdo();
Issue: 502 Bad Gateway
Possible causes:
- Application not fully started
- Wrong port in Traefik label (should be 80)
- Application crashed
Check:
# Container status
docker ps -a | grep merchbay_admin
# Application logs
docker logs merchbay_admin_app --tail 100
# Restart container
docker restart merchbay_admin_app
Updating the Application
Via Gitea Actions (Automatic)
git add .
git commit -m "Update application"
git push origin main
Via Portainer
- Go to
Stacks→merchbay-admin - Click
Editor - Update image or configuration
- Click
Update the stack - Enable "Re-pull image and redeploy"
Manual Update
ssh deploy@your-server
cd /var/www/merchbay_admin
./deploy.sh
Rollback
Via Portainer
- Go to
Stacks→merchbay-admin - Click on the stack
- Find previous version in
Stack History(if available) - Revert to previous version
Manual Rollback
# List available backups
ls -lh /var/www/merchbay_admin/backups/
# Restore from backup
cd /var/www/merchbay_admin
tar -xzf backups/backup_YYYYMMDD_HHMMSS.tar.gz
# Restart
docker compose restart
Security Best Practices
- Use Strong Database Passwords: Generate with
openssl rand -base64 32 - Restrict SSH Access: Use key-based authentication only
- Firewall Rules: Only allow necessary ports (80, 443, 22)
- Regular Backups: Automated backups of database and storage
- Keep Docker Updated: Regularly update Docker and images
- Monitor Logs: Set up log monitoring/alerting
- Use Secrets: Never commit sensitive data to repository
- HTTPS Only: Ensure HTTP redirects to HTTPS
Performance Optimization
PHP-FPM Configuration
Consider switching to PHP-FPM for better performance:
FROM php:7.4-fpm-alpine
# ... additional configuration
Use Redis for Cache/Sessions
CACHE_DRIVER=redis
SESSION_DRIVER=redis
REDIS_HOST=redis
Add Redis service to docker-compose:
services:
redis:
image: redis:alpine
networks:
- default
Enable OPcache
Already included in Dockerfile, verify:
docker exec merchbay_admin_app php -i | grep opcache
Monitoring
View Real-time Logs in Portainer
- Navigate to
Containers - Click on
merchbay_admin_app - Select
Logstab - Enable
Auto-refresh
Set Up Alerts
Configure Portainer notifications:
Settings→Notifications- Add webhook or email notification
- Set up container health checks
Support
For issues:
- Check application logs in Portainer
- Verify Traefik configuration
- Test database connectivity
- Review Gitea Actions logs if using CI/CD