A full-featured hotel booking web application built with Flask, PostgreSQL, and Tailwind CSS. QuickStay allows users to browse rooms, make bookings, manage profiles, and provides an admin dashboard for hotel management.
- Features
- Tech Stack
- Project Structure
- Prerequisites
- Getting Started
- Environment Variables
- Database Setup
- CI/CD Pipeline
- Deployment
- Screenshots
- Contributing
- License
- π Authentication β Register, Login, Logout with session management
- π Password Recovery β OTP-based password reset via email (Flask-Mail)
- π€ Profile Management β View, edit profile, change password, delete account
- π₯ Data Export β Download personal data as JSON (privacy compliance)
- π Dark/Light Mode β Toggle between themes
- π± Fully Responsive β Works on desktop, tablet, and mobile
- π‘οΈ CSRF Protection β All forms protected with Flask-WTF
- π Password Hashing β Werkzeug security with salted hashes
- π« Account Deactivation β Soft delete with password confirmation
- β±οΈ OTP Expiry β Time-limited OTP codes (10 minutes)
- π Admin Dashboard β Manage users, rooms, and bookings
- π₯ User Management β View, block/unblock users
- π³ Docker β Multi-stage Dockerfile with Docker Compose
- π Jenkins Pipeline β Automated CI/CD with auto-deploy
- π SonarQube β Code quality analysis
- π‘οΈ Trivy β Container security scanning
- π OWASP β Dependency vulnerability check
- ποΈ Auto Migrations β Database migrations on container startup
| Layer | Technology |
|---|---|
| Backend | Flask 3.1 (Python 3.11) |
| Database | PostgreSQL 15 |
| ORM | SQLAlchemy + Flask-Migrate (Alembic) |
| Frontend | Tailwind CSS + Jinja2 Templates |
| Icons | Lucide Icons |
| Auth | Flask-Login + Flask-WTF (CSRF) |
| Flask-Mail (SMTP/Gmail) | |
| Containerization | Docker + Docker Compose |
| CI/CD | Jenkins Pipeline |
| Security Scanning | SonarQube, Trivy, OWASP Dependency-Check |
QuickStay/
β
βββ app/
β βββ init.py # App factory
β βββ config.py # Configuration (dev/prod/test)
β βββ utils.py # Helper functions
β βββ extensions.py # Flask extensions initialization
β β
β βββ models/ # Database models
β β βββ init.py
β β βββ user.py # User model
β β βββ room.py # Room model
β β βββ booking.py # Booking model
β β βββ review.py # Review model
β β
β βββ controllers/ # Route handlers (Blueprints)
β β βββ init.py
β β βββ auth_controller.py # Auth routes (login, register, etc.)
β β βββ main_controller.py # Public pages (home, about, etc.)
β β βββ booking_controller.py # Booking routes
β β βββ profile_controller.py # Profile management routes
β β βββ admin/
β β βββ init.py
β β βββ dashboard_controller.py # Admin dashboard
β β
β βββ templates/ # Jinja2 HTML templates
β β βββ base.html # Base layout
β β βββ auth/ # Auth pages
β β β βββ login.html
β β β βββ register.html
β β β βββ forgot-password.html
β β βββ main/ # Public pages
β β β βββ home.html
β β β βββ rooms.html
β β β βββ about.html
β β β βββ contact.html
β β β βββ faq.html
β β βββ profile/ # Profile pages
β β β βββ view.html
β β β βββ edit.html
β β β βββ change_password.html
β β βββ admin/ # Admin pages
β β βββ extra/ # Error & legal pages
β β β βββ 404.html
β β β βββ 500.html
β β β βββ privacy.html
β β β βββ terms.html
β β
β βββ static/ # Static assets
β βββ css/
β βββ js/
β βββ images/
β
βββ migrations/ # Database migrations (Alembic)
βββ .env # Environment variables (dev)
βββ .env.production # Environment variables (prod)
βββ .dockerignore
βββ .gitignore
βββ deploy.sh # Deployment script
βββ docker-compose.yml # Docker services
βββ Dockerfile # Multi-stage Docker build
βββ entrypoint.sh # Container startup script
βββ Jenkinsfile # CI/CD pipeline
βββ requirements.txt # Python dependencies
βββ run.py # Application entry point
- Docker (v20+)
- Docker Compose (v2+)
- Git
- Python 3.11+
- PostgreSQL 15+
- Git
- pip (Python package manager)
- Jenkins (with Docker)
- SonarQube Server
- Trivy (installed on Jenkins server)
- OWASP Dependency-Check (Jenkins plugin)
Step 1: Clone the repository
git clone https://github.com/mananurrehman/quickstay.git
cd quickstayStep 2: Create environment file
cp .env.example .env.production
Edit .env.production with your values:
# Flask
SECRET_KEY=your-super-secret-key-change-this
FLASK_ENV=production
# Database
DATABASE_URL=postgresql://quickstay_user:quickstay123@db:5432/quickstay
# Email (Gmail SMTP)
MAIL_SERVER=smtp.gmail.com
MAIL_PORT=587
MAIL_USE_TLS=True
MAIL_USERNAME=your-email@gmail.com
MAIL_PASSWORD=your-gmail-app-password
MAIL_DEFAULT_SENDER=your-email@gmail.com
Step 3: Create required directories
sudo mkdir -p /home/ubuntu/quickstay-data/postgres
sudo mkdir -p /home/ubuntu/quickstay-data/uploads
Step 4: Build and run
docker compose up -d --build
Step 5: Verify
# Check containers are running
docker compose ps
# Check logs
docker compose logs -f web
Step 6: Access the application
http://localhost:5000
Step 1: Clone the repository
git clone https://github.com/mananurrehman/quickstay.git
cd quickstay
Step 2: Create Virtual Environment
# Create virtual environment
python -m venv venv
# Activate it
# On Linux/Mac:
source venv/bin/activate
# On Windows:
venv\Scripts\activate
Step 3: Install dependencies
pip install -r requirements.txt
Step 4: Create environment file
cp .env.example .env
Edit .env with your values:
# Flask
SECRET_KEY=your-secret-key
FLASK_ENV=development
FLASK_DEBUG=True
# Database
DATABASE_URL=postgresql://username:password@localhost:5432/quickstay
# Email (Gmail SMTP)
MAIL_SERVER=smtp.gmail.com
MAIL_PORT=587
MAIL_USE_TLS=True
MAIL_USERNAME=your-email@gmail.com
MAIL_PASSWORD=your-gmail-app-password
MAIL_DEFAULT_SENDER=your-email@gmail.com
Step 5: Setup PostgreSQL database
# Login to PostgreSQL
psql -U postgres
# Create database and user
CREATE DATABASE quickstay;
CREATE USER quickstay_user WITH PASSWORD 'your_password';
GRANT ALL PRIVILEGES ON DATABASE quickstay TO quickstay_user;
\q
Step 6: Run database migrations
# Initialize migrations (first time only)
flask db init
# Generate migration files
flask db migrate -m "Initial migration"
# Apply migrations
flask db upgrade
Step 7: Run the application
python run.py
Step 8: Access the application
http://localhost:5000
| Variable | Description | Required | Default |
|---|---|---|---|
| SECRET_KEY | Flask secret key for sessions | β | None |
| FLASK_ENV | Environment (development/production) | β | development |
| FLASK_DEBUG | Debug mode (True/False) | β | False |
| DATABASE_URL | PostgreSQL connection string | β | None |
| MAIL_SERVER | SMTP server address | β | smtp.gmail.com |
| MAIL_PORT | SMTP port | β | 587 |
| MAIL_USE_TLS | Enable TLS | β | True |
| MAIL_USERNAME | SMTP email address | β | None |
| MAIL_PASSWORD | SMTP password/app password | β | None |
| MAIL_DEFAULT_SENDER | Default sender email | β | None |
- Go to Google Account Security
- Enable 2-Step Verification
- Go to App Passwords
- Select app: Mail, device: Other (enter "QuickStay")
- Copy the 16-character password
- Use this as MAIL_PASSWORD in your
.env
ββββββββββββ ββββββββββββ ββββββββββββ
β Users βββββββ Bookings βββββββ Rooms β
β β β β β β
β id β β id β β id β
β username β β user_id β β name β
β email β β room_id β β type β
β password β β check_in β β price β
β role β β check_outβ β status β
ββββββββββββ ββββββββββββ ββββββββββββ
β β
β ββββββββββββ β
ββββββββββββ Reviews βββββββββββββ
β β
β id β
β user_id β
β room_id β
β rating β
β comment β
ββββββββββββ
# Generate new migration after model changes
flask db migrate -m "Description of changes"
# Apply migrations
flask db upgrade
# Rollback last migration
flask db downgrade
# View migration history
flask db history
GitHub Push
β
Jenkins (Poll SCM - every 5 mins)
β
βββββββββββββββββββββββββββββββββββββββ
β Stage 1: Clone Repository β
β Stage 2: SonarQube Analysis β
β Stage 3: Trivy Security Scan β
β Stage 4: OWASP Dependency Check β
β Stage 5: Deploy to Staging β
β Stage 6: Verify Deployment β
βββββββββββββββββββββββββββββββββββββββ
β
β
App Live on Staging Server
| Tool | Purpose |
|---|---|
| SSH Agent Plugin | SSH into staging server |
| SonarQube Scanner | Code quality analysis |
| OWASP Dependency-Check | Vulnerability scanning |
| GitHub Integration | Repository integration |
| Credential ID | Type | Purpose |
|---|---|---|
| oracle-vm-ssh-testuser | SSH Key | Access to staging server |
| SonarQube Token | Secret Text | SonarQube authentication |
The pipeline uses Poll SCM to check for new commits:
Schedule: H/5 * * * * (every 5 minutes)
docker compose up -d --build
β
βββββββββββββββββββββββββββββββ
β PostgreSQL Container β
β - Health check passes β
β - Database ready β
ββββββββββββββββ¬βββββββββββββββ
β
βββββββββββββββββββββββββββββββ
β Flask App Container β
β 1. Wait for database β
β 2. Run migrations β
β 3. Start Flask server β
βββββββββββββββββββββββββββββββ
β
App live on port 5000
# Start all services
docker compose up -d --build
# Stop all services
docker compose down
# View running containers
docker compose ps
# View logs (live)
docker compose logs -f web
# View database logs
docker compose logs -f db
# Restart app only
docker compose restart web
# Rebuild app only
docker compose up -d --build web
# Enter app container
docker exec -it quickstay-web bash
# Enter database container
docker exec -it quickstay-db psql -U quickstay_user -d quickstay
β Set strong SECRET_KEY (use: python -c "import secrets; print(secrets.token_hex(32))")
β Set FLASK_ENV=production
β Set FLASK_DEBUG=False
β Configure real SMTP credentials
β Use strong database password
β Create data directories for volumes
β Setup firewall (allow only ports 5000, 22)
β Configure SSL/HTTPS (recommended)
β Setup regular database backups
- Fork the repository
- Create your feature branch
git checkout -b feature/amazing-feature
- Commit your changes
git commit -m "Add amazing feature"
- Push to the branch
git push origin feature/amazing-feature
- Open a Pull Request
- Follow MVC architecture with Flask Blueprints
- Use Tailwind CSS for styling (match existing design patterns)
- Support dark mode in all templates
- Add CSRF protection on all forms
- Write responsive templates (mobile-first)
- Use Lucide icons consistently
- GitHub: @mananurrehman
- LinkedIn: @mananurrehman







