A mobile-first web application for managing Arrowhead Maintenance Availability 2026 work item documentation.
# Create virtual environment
python3 -m venv venv
source venv/bin/activate
# Install dependencies
pip install -r requirements.txt
# Run the app
python run.py- Open browser:
http://localhost:5001 - Crew Login: Password:
crew2026 - Admin Login: Username:
admin, Password:admin2026
Note: Port changed to 5001 due to macOS AirTunes using port 5000
SHIP_MAINTENANCE_APP_BUILD_GUIDE.md- Complete build instructionsrequirements.txt- Python dependenciesrun.py- Application entry pointconfig.py- Configuration settings
admin_login.html- Admin authenticationadmin_view_item.html- View work item details- Additional templates in
/app/templates/(see build guide)
ship-maintenance-tracker/
βββ app/
β βββ __init__.py
β βββ models.py
β βββ auth.py
β βββ crew.py
β βββ admin.py
β βββ docx_generator.py
β βββ utils.py
β βββ static/
β β βββ css/style.css
β β βββ js/main.js
β βββ templates/
β βββ base.html
β βββ login.html
β βββ crew_form.html
β βββ crew_success.html
β βββ admin_login.html
β βββ admin_dashboard.html
β βββ admin_view_item.html
βββ uploads/
βββ generated_docs/
βββ config.py
βββ requirements.txt
βββ run.py
βββ README.md
For complete step-by-step build instructions, see:
SHIP_MAINTENANCE_APP_BUILD_GUIDE.md
This guide includes:
- Detailed implementation phases
- Complete code for all files
- Deployment instructions
- Troubleshooting tips
- Testing checklist
Railway provides a seamless deployment experience with PostgreSQL database support and persistent storage options.
- GitHub repository with your code
- Railway account (https://railway.app)
- Updated credentials (see Security section below)
-
Prepare Your Code
# Ensure all files are committed git add . git commit -m "Prepare for production deployment" git push origin main
-
Create Railway Project
# Install Railway CLI (optional) npm install -g railway # Login to Railway railway login # Create new project railway init
Or use the Railway web dashboard:
- Go to https://railway.app/new
- Select "Deploy from GitHub repo"
- Choose your repository
-
Configure Environment Variables
In Railway dashboard, go to your project β Variables β Add all of these:
Required Variables:
# Application Security SECRET_KEY=<generate-random-64-char-string> ADMIN_USERNAME=<your-admin-username> ADMIN_PASSWORD=<strong-password-here> CREW_PASSWORD=<strong-password-here> # Database (automatically set by Railway if you add PostgreSQL) DATABASE_URL=<automatically-provided-by-railway> # Python Environment PYTHONUNBUFFERED=1
Optional Variables (for SMS notifications):
ENABLE_NOTIFICATIONS=True TWILIO_ACCOUNT_SID=<your-twilio-sid> TWILIO_AUTH_TOKEN=<your-twilio-token> TWILIO_PHONE_NUMBER=<your-twilio-number> # Crew member phone numbers (E.164 format: +1234567890) DP_PHONE=+1234567890 AL_PHONE=+1234567890 KAITLYN_PHONE=+1234567890 MARK_PHONE=+1234567890 ART_PHONE=+1234567890 D2_PHONE=+1234567890
Generate SECRET_KEY:
import secrets print(secrets.token_hex(32))
-
Add PostgreSQL Database
- In Railway dashboard, click "New" β "Database" β "Add PostgreSQL"
- Railway automatically sets the
DATABASE_URLenvironment variable - Database tables will be created automatically on first run
-
Configure File Storage (Critical!)
Railway uses ephemeral filesystem - uploaded files are lost on restart. Choose one option:
Option A: Railway Volumes (Simpler)
- In Railway dashboard, go to Settings β Volumes
- Add volume: Mount path
/app/uploads - Add volume: Mount path
/app/generated_docs - Redeploy application
Option B: Cloud Storage (Recommended for production)
- Use AWS S3, Google Cloud Storage, or Cloudinary
- See
ENGINEER_TASKS.mdTask 1.5 for implementation details - Update code to store files in cloud instead of local filesystem
-
Deploy
# Using Railway CLI railway up # Or push to GitHub (if auto-deploy enabled) git push origin main
-
Monitor Deployment
- Watch build logs in Railway dashboard
- Verify deployment succeeds
- Check for any error messages
-
Access Your Application
- Railway provides a public URL:
https://your-app.up.railway.app - Test login functionality
- Verify database connectivity
- Upload test photo and verify persistence
- Railway provides a public URL:
- Application accessible via HTTPS
- Admin login works with new credentials
- Crew login works with new password
- Database persists data after restart
- Photo uploads work and persist
- Document generation works
- Mobile UI functions correctly on iPhone and Android
- SMS notifications working (if enabled)
- Check Railway logs for errors
- Monitor application performance
# Make changes locally
git add .
git commit -m "Update: description of changes"
git push origin main
# Railway auto-deploys (if enabled)
# Or manually trigger: railway upCreate railway.json in project root (optional):
{
"build": {
"builder": "NIXPACKS"
},
"deploy": {
"startCommand": "python run.py",
"restartPolicyType": "ON_FAILURE",
"restartPolicyMaxRetries": 10
}
}Or create Procfile:
web: python run.py
-
Create Render Account
- Go to https://render.com
- Sign up with GitHub
-
Create New Web Service
- Click "New" β "Web Service"
- Connect your GitHub repository
- Configure:
- Name: arrowhead-mta-2026
- Environment: Python 3
- Build Command:
pip install -r requirements.txt - Start Command:
python run.py
-
Add PostgreSQL Database
- Click "New" β "PostgreSQL"
- Note the internal database URL
-
Configure Environment Variables
- Add all variables listed in Railway section above
- Set
DATABASE_URLto your Render PostgreSQL URL
-
Deploy
- Render automatically deploys on push to main branch
- Monitor build logs
- Access via provided URL:
https://your-app.onrender.com
-
Install Heroku CLI
brew install heroku/brew/heroku # macOS # Or download from heroku.com
-
Login and Create App
heroku login heroku create arrowhead-mta-2026
-
Add PostgreSQL
heroku addons:create heroku-postgresql:mini
-
Configure Environment Variables
heroku config:set SECRET_KEY=your-secret-key heroku config:set ADMIN_USERNAME=your-admin heroku config:set ADMIN_PASSWORD=your-password heroku config:set CREW_PASSWORD=your-crew-password
-
Create Procfile
web: python run.py -
Deploy
git push heroku main heroku open
Create Dockerfile:
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 5001
CMD ["python", "run.py"]Create docker-compose.yml:
version: '3.8'
services:
web:
build: .
ports:
- "5001:5001"
environment:
- DATABASE_URL=postgresql://user:password@db:5432/maintenance
- SECRET_KEY=${SECRET_KEY}
volumes:
- ./uploads:/app/uploads
- ./generated_docs:/app/generated_docs
depends_on:
- db
db:
image: postgres:15
environment:
- POSTGRES_USER=user
- POSTGRES_PASSWORD=password
- POSTGRES_DB=maintenance
volumes:
- postgres_data:/var/lib/postgresql/data
volumes:
postgres_data:Deploy:
docker-compose up -d| Variable | Required | Default | Description |
|---|---|---|---|
SECRET_KEY |
Yes* | dev_key_change_in_production |
Flask session secret (change in prod!) |
ADMIN_USERNAME |
Yes* | admin |
Admin login username (change in prod!) |
ADMIN_PASSWORD |
Yes* | admin350 |
Admin login password (change in prod!) |
CREW_PASSWORD |
Yes* | crew350 |
Crew login password (change in prod!) |
DATABASE_URL |
No | sqlite:///maintenance.db |
PostgreSQL connection string |
ENABLE_NOTIFICATIONS |
No | False |
Enable SMS notifications |
TWILIO_ACCOUNT_SID |
No | - | Twilio account SID (for SMS) |
TWILIO_AUTH_TOKEN |
No | - | Twilio auth token (for SMS) |
TWILIO_PHONE_NUMBER |
No | - | Twilio phone number (for SMS) |
DP_PHONE |
No | - | DP crew member phone |
AL_PHONE |
No | - | AL crew member phone |
KAITLYN_PHONE |
No | - | Kaitlyn crew member phone |
MARK_PHONE |
No | - | Mark crew member phone |
ART_PHONE |
No | - | Art crew member phone |
D2_PHONE |
No | - | D2 crew member phone |
*Required in production - defaults are insecure and should only be used for local development.
- Check Railway/Render logs for Python errors
- Verify all required environment variables are set
- Ensure
requirements.txtincludes all dependencies - Check Python version compatibility (requires 3.8+)
- Verify
DATABASE_URLis set correctly - Ensure PostgreSQL service is running
- Check database credentials
- Test connection manually:
psql $DATABASE_URL
- Railway/Render use ephemeral filesystems
- Must use Railway Volumes or cloud storage (S3, Cloudinary)
- See Task 1.5 in
ENGINEER_TASKS.mdfor implementation
- Ensure
/app/static/folder exists - Check file permissions
- Verify static file paths in templates
- Verify
ENABLE_NOTIFICATIONS=True - Check Twilio credentials are correct
- Verify phone numbers in E.164 format (+1234567890)
- Check Twilio account balance
- Review application logs for Twilio errors
- Enable database connection pooling
- Optimize image processing (see Task 4.4 in
ENGINEER_TASKS.md) - Consider caching with Redis
- Monitor Railway metrics (CPU, memory, response times)
- Add database indexes for frequently queried fields
- Railway and Render provide HTTPS automatically
- If using custom domain, configure DNS correctly
- Ensure SSL certificate is valid
- Access logs: Railway dashboard β Deployments β View logs
- Monitor metrics: CPU, memory, disk usage
- Set up alerts for downtime
- Enable auto-scaling if needed
Create /health endpoint in app/__init__.py:
@app.route('/health')
def health_check():
try:
# Test database connection
db.session.execute('SELECT 1')
return {'status': 'healthy', 'database': 'connected'}, 200
except Exception as e:
return {'status': 'unhealthy', 'error': str(e)}, 500- Railway PostgreSQL: Enable automated backups
- Export database regularly:
pg_dump $DATABASE_URL > backup.sql - Backup uploaded photos to S3/cloud storage
- Keep copies of generated documents
# Add structured logging
import logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s [%(levelname)s] %(message)s'
)-
Change All Default Credentials
- Generate strong passwords (16+ characters)
- Use password manager (1Password, Bitwarden)
- Never commit credentials to Git
-
Enable HTTPS Only
- Railway/Render provide HTTPS automatically
- Set
SESSION_COOKIE_SECURE = Truein production
-
Secure File Uploads
- Validate file types and sizes
- Scan for malware (optional: use ClamAV)
- Store files outside web root
-
Database Security
- Use strong PostgreSQL password
- Limit database access by IP (if possible)
- Regular security updates
-
Regular Updates
- Keep Python dependencies updated:
pip list --outdated - Monitor security advisories
- Update Flask and Pillow regularly
- Keep Python dependencies updated:
-
Rate Limiting
- Add Flask-Limiter to prevent abuse
- Limit login attempts
- Throttle API endpoints
-
Error Handling
- Never expose stack traces in production
- Log errors securely
- Use custom error pages
-
Database Optimization
- Add indexes:
db.Index('idx_status', 'status') - Use database connection pooling
- Optimize slow queries
- Add indexes:
-
Caching
- Cache rendered pages (Flask-Caching)
- Cache database queries
- Use CDN for static assets
-
Image Optimization
- Process images asynchronously (Celery + Redis)
- Use WebP format for smaller file sizes
- Implement lazy loading
-
Code Optimization
- Use pagination for large result sets
- Minimize database queries (eager loading)
- Profile slow endpoints
As your application grows, consider:
-
Horizontal Scaling
- Multiple Railway instances behind load balancer
- Stateless application design
- Shared PostgreSQL database
-
Vertical Scaling
- Upgrade Railway plan for more CPU/memory
- Optimize application performance first
-
Microservices (Future)
- Separate document generation service
- Separate notification service
- API gateway
-
CDN Integration
- CloudFlare for static assets
- Faster photo delivery worldwide
- DDoS protection
- β Mobile-optimized submission form
- β Photo upload with auto-resize (4" width)
- β Generates .docx files matching template
- β Admin dashboard with status tracking
- β Batch download as .zip
- β Works on iPhone and Android
IMPORTANT: Change these defaults in production:
SECRET_KEYin config.pyCREW_PASSWORDin config.pyADMIN_PASSWORDin config.py
Edit config.py:
CREW_MEMBERS = [
'Your',
'Crew',
'Names',
'Here'
]Edit config.py:
PHOTO_MAX_WIDTH = 576 # 4 inches at 144 DPI
PHOTO_MIN_COUNT = 2
PHOTO_MAX_COUNT = 6- ModuleNotFoundError: Run
pip install -r requirements.txt - Database errors: Delete
maintenance.dband restart - Port in use: Change port in
run.py - Photos not uploading: Check folder permissions
- Build Guide:
SHIP_MAINTENANCE_APP_BUILD_GUIDE.md- Complete step-by-step build instructions - Testing Checklist:
TESTING_CHECKLIST.md- Comprehensive manual test scenarios for all features - Engineer Tasks:
ENGINEER_TASKS.md- Task breakdown and implementation guide for junior engineers - README:
README.md- This file - overview and deployment guide
- Flask Docs: https://flask.palletsprojects.com/
- python-docx Docs: https://python-docx.readthedocs.io/
- Pillow Docs: https://pillow.readthedocs.io/
- Railway Docs: https://docs.railway.app/
- Twilio SMS API: https://www.twilio.com/docs/sms
Built for maritime maintenance tracking operations.
Proprietary - For internal use only.