-
Notifications
You must be signed in to change notification settings - Fork 0
Deployment
This guide walks you through deploying the TrueHour using Portainer with automated updates.
β Portainer installed and accessible β Docker Hub account (ryakel) β GitHub repository access β Nginx reverse proxy configured (optional for production)
-
Navigate to Stacks
- In Portainer, go to Stacks β Add stack
-
Configure Stack
-
Name:
flight-budget - Build method: Select Git Repository
-
Repository URL:
https://github.com/ryakel/flight-budget -
Repository reference:
refs/heads/main -
Compose path:
docker-compose.yml
-
Name:
-
Environment Variables (optional)
APP_PORT=8181 TIMEZONE=UTC -
Deploy
- Click Deploy the stack
- Wait for deployment to complete
-
Verify
- Navigate to
http://your-server:8181 - You should see the TrueHour
- Navigate to
-
Navigate to Stacks
- In Portainer, go to Stacks β Add stack
-
Configure Stack
-
Name:
flight-budget - Build method: Select Web editor
-
Name:
-
Paste Docker Compose
- Copy contents from
docker-compose.yml - Paste into the web editor
- Copy contents from
-
Set Environment Variables (optional)
APP_PORT=8181 TIMEZONE=UTC -
Deploy
- Click Deploy the stack
-
Access Your Stack
- In Portainer, navigate to Stacks
- Click on your
flight-budgetstack
-
Create Webhook
- Scroll down to the Webhooks section
- Click Add webhook
-
Configure Webhook
-
Service: Select
flight-budget(or leave empty for entire stack) -
Action: Select
Repull image and redeploy
-
Service: Select
-
Copy Webhook URL
- Click the webhook you just created
- Copy the webhook URL
- Format:
https://your-portainer.com/api/webhooks/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx - Keep this URL secure! Anyone with this URL can trigger your deployment
-
Navigate to Repository Settings
- Go to
https://github.com/ryakel/flight-budget - Click Settings β Secrets and variables β Actions
- Go to
-
Add Docker Hub Credentials
- Click New repository secret
-
Name:
DOCKER_USERNAME -
Value:
ryakel - Click Add secret
-
Add Docker Hub Token
- Click New repository secret
-
Name:
DOCKER_PASSWORD - Value: Your Docker Hub access token (create at https://hub.docker.com/settings/security)
- Click Add secret
-
Add Portainer Webhook
- Click New repository secret
-
Name:
PORTAINER_WEBHOOK_URL - Value: The webhook URL you copied from Portainer
- Click Add secret
Your repository now has two automated workflows:
Triggers:
- Push to
mainbranch - Manual trigger via GitHub Actions UI
Steps:
- Builds multi-architecture Docker image (amd64, arm64)
- Pushes to Docker Hub (
ryakel/flight-budget:latest) - Triggers Portainer webhook
- Portainer automatically redeploys with new image
Test It:
# Make a small change and push
git add .
git commit -m "test: trigger automated deployment"
git push origin mainMonitor Progress:
- GitHub: Actions tab β Watch the workflow run
- Docker Hub: Check for new image push
- Portainer: Watch stack redeploy automatically
Triggers:
- Weekly schedule: Sundays at 2 AM UTC
- Manual trigger via GitHub Actions UI
Steps:
- Downloads latest versions of JavaScript libraries
- Creates a Pull Request if updates are found
- Review and merge the PR to deploy updates
Developer pushes to main
β
GitHub Actions triggered
β
Build Docker image
(multi-arch: amd64, arm64)
β
Push to Docker Hub
(ryakel/flight-budget:latest)
β
Trigger Portainer webhook
β
Portainer pulls new image
β
Stack redeployed automatically
β
Live! π
Total time: ~2-5 minutes from push to live deployment
For production deployment with SSL:
Create /etc/nginx/sites-available/flight-budget:
server {
listen 80;
server_name budget.yourdomain.com;
# Redirect HTTP to HTTPS
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name budget.yourdomain.com;
# SSL certificates (managed by Certbot)
ssl_certificate /etc/letsencrypt/live/budget.yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/budget.yourdomain.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
# Proxy to Docker container
location / {
proxy_pass http://localhost:8181;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# Optional: Increase timeouts for large CSV uploads
proxy_read_timeout 300s;
proxy_connect_timeout 75s;
}
# Health check endpoint
location /health {
proxy_pass http://localhost:8181/health;
access_log off;
}
}Enable the site:
ln -s /etc/nginx/sites-available/flight-budget /etc/nginx/sites-enabled/
nginx -t
systemctl reload nginx# Install Certbot
apt install certbot python3-certbot-nginx
# Generate certificate
certbot --nginx -d budget.yourdomain.com
# Auto-renewal is configured automatically
# Test renewal:
certbot renew --dry-runIf you need to manually update the stack:
# Pull latest image
docker pull ryakel/flight-budget:latest
# Redeploy via Portainer UI or CLI
docker-compose up -d --force-recreateIn Portainer:
- Navigate to Containers
- Click on
flight-budget-app - Click Logs
Or via CLI:
docker logs -f flight-budget-appAircraft configurations are stored in a volume. To backup:
# Create backup directory
mkdir -p ~/backups
# Backup volume
docker run --rm \
-v flight-budget_flight-budget-data:/data \
-v ~/backups:/backup \
alpine tar czf /backup/flight-budget-data-$(date +%Y%m%d).tar.gz -C /data .# Restore volume
docker run --rm \
-v flight-budget_flight-budget-data:/data \
-v ~/backups:/backup \
alpine tar xzf /backup/flight-budget-data-YYYYMMDD.tar.gz -C /dataCheck GitHub Actions logs:
- Go to Actions tab in GitHub
- Click on the latest workflow run
- Check the "Trigger Portainer webhook" step
Common issues:
-
PORTAINER_WEBHOOK_URLsecret not set or incorrect - Portainer webhook deleted or expired
- Network connectivity issues
- Verify webhook URL is correct in GitHub secrets
- Check Portainer webhook exists in stack settings
-
Manually trigger update in Portainer:
- Go to Stacks β
flight-budget - Click Update the stack
- Enable Re-pull image
- Click Update
- Go to Stacks β
If port 8181 is already in use:
- Edit
.envfile or Portainer environment variables - Change
APP_PORTto another port (e.g., 8282) - Update your nginx proxy configuration
- Redeploy the stack
β Keep webhook URL secret (it's in GitHub secrets, don't share it) β Use SSL/TLS in production (Let's Encrypt) β Restrict Portainer access with strong passwords β Enable two-factor authentication on Docker Hub β Regularly update the base image (automated via GitHub Actions) β Monitor container logs for suspicious activity
- β Deploy stack in Portainer
- β Create and configure webhook
- β Add GitHub secrets
- β Test automated deployment
- β Configure nginx reverse proxy (production)
- β Set up SSL certificate
- βοΈ Fix aircraft persistence logic (see TODO)
For issues:
- Check container logs:
docker logs flight-budget-app - Review GitHub Actions runs: Repository β Actions tab
- Verify webhook status in Portainer
- Check nginx logs:
tail -f /var/log/nginx/error.log
Need help? Create an issue in the GitHub repository.
π View on GitHub | π³ Docker Hub
π Report Issue | π¬ Discussions
License: MIT License | Copyright (c) 2024-2025 FliteAxis
π Getting Started
π¦ Deployment
π§ Development
π Security
- Security Setup Guide
- Security CI/CD Pipeline
- Code Quality & Linting
- SBOM Management
- Vulnerability Scanning
π Dependencies
π³ Docker
π Reference
π Links