Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
68 changes: 68 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# Git
.git
.gitignore

# Python
__pycache__
*.pyc
*.pyo
*.pyd
.Python
env
pip-log.txt
pip-delete-this-directory.txt
.tox
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.log
.git
.mypy_cache
.pytest_cache
.hypothesis

# Django
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal

# Environnements virtuels
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/

# IDE
.vscode/
.idea/
*.swp
*.swo
*~

# OS
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
ehthumbs.db
Thumbs.db

# Tests
htmlcov/
.coverage
.pytest_cache/

# Documentation
README.md
docs/

# CI/CD
.github/
132 changes: 132 additions & 0 deletions .github/workflows/ci-cd.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
# Nom de la pipeline CI/CD
name: CI/CD Pipeline

# Définition des événements qui déclenchent la pipeline
on:
# Se déclenche à chaque push sur la branche main
push:
branches: [ main ]
# Se déclenche à chaque pull request vers la branche main
pull_request:
branches: [ main ]

# Variables d'environnement globales
env:
# Nom de l'image Docker (utilise le nom d'utilisateur DockerHub stocké dans les secrets)
DOCKER_IMAGE: ${{ secrets.DOCKER_USERNAME }}/oc-lettings-site
# Tag de l'image basé sur le SHA du commit
DOCKER_TAG: ${{ github.sha }}

jobs:
# Job de test : vérifie la qualité du code et la couverture des tests
test:
runs-on: ubuntu-latest
steps:
# Récupération du code source
- uses: actions/checkout@v3

# Configuration de l'environnement Python
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.11'

# Installation des dépendances nécessaires
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
pip install pytest pytest-cov flake8

# Vérification de la qualité du code avec Flake8
- name: Run Flake8
run: |
# Première vérification : erreurs critiques (échoue si erreurs trouvées)
# E9: Erreurs de syntaxe
# F63: Problèmes de comparaison
# F7: Problèmes de déclaration
# F82: Problèmes de référence non définie
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
# Deuxième vérification : style du code (n'échoue pas)
# - Complexité maximale de 10
# - Longueur de ligne maximale de 127 caractères
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics

# Exécution des tests avec mesure de la couverture
- name: Run tests with coverage
run: |
pytest --cov=. --cov-report=xml

# Vérification que la couverture de tests est supérieure à 80%
- name: Check coverage threshold
run: |
coverage=$(python -c "import xml.etree.ElementTree as ET; tree = ET.parse('coverage.xml'); root = tree.getroot(); print(float(root.attrib['line-rate']) * 100)")
if (( $(echo "$coverage < 80" | bc -l) )); then
echo "Coverage is below 80%"
exit 1
fi

# Job de test Docker : vérifie que l'image Docker fonctionne
test-docker:
runs-on: ubuntu-latest
needs: test
steps:
- uses: actions/checkout@v3

# Test de build de l'image Docker
- name: Build Docker image
run: docker build -t oc-lettings-site .

# Test que l'image peut démarrer
- name: Test Docker image startup
run: |
docker run -d --name test-container oc-lettings-site
sleep 10
docker logs test-container
docker stop test-container
docker rm test-container

# Job de build et push : crée et publie l'image Docker
build-and-push:
# S'exécute uniquement si les tests sont passés
needs: [test, test-docker]
runs-on: ubuntu-latest
# S'exécute uniquement sur les pushes vers main
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@v3

# Authentification sur DockerHub
- name: Login to DockerHub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}

# Construction et publication de l'image Docker
- name: Build and push Docker image
uses: docker/build-push-action@v4
with:
context: .
push: true
# Tag l'image avec le SHA du commit et 'latest'
tags: ${{ env.DOCKER_IMAGE }}:${{ env.DOCKER_TAG }},${{ env.DOCKER_IMAGE }}:latest
# Cache pour optimiser les builds
cache-from: type=gha
cache-to: type=gha,mode=max

# Job de déploiement : déploie l'application sur Render
deploy:
# S'exécute uniquement si le build est réussi
needs: build-and-push
runs-on: ubuntu-latest
# S'exécute uniquement sur les pushes vers main
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
steps:
# Déploiement sur Render
- name: Deploy to Render
uses: render-actions/deploy@v1
with:
render-token: ${{ secrets.RENDER_TOKEN }}
service-id: ${{ secrets.RENDER_SERVICE_ID }}
environment: production
126 changes: 126 additions & 0 deletions DEPLOYMENT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
# Guide de Déploiement - OC Lettings Site

## Prérequis

- Docker et Docker Compose installés
- Compte DockerHub
- Compte Render (pour le déploiement)
- Variables d'environnement configurées

## Configuration des Variables d'Environnement

### GitHub Secrets (pour la CI/CD)

Configurez ces secrets dans votre repository GitHub :

- `DOCKER_USERNAME` : Votre nom d'utilisateur DockerHub
- `DOCKER_PASSWORD` : Votre token d'accès DockerHub
- `RENDER_TOKEN` : Votre token d'API Render
- `RENDER_SERVICE_ID` : L'ID de votre service Render

### Variables d'Environnement pour la Production

- `SECRET_KEY` : Clé secrète Django (générée automatiquement si non définie)
- `DEBUG` : `False` pour la production
- `ALLOWED_HOSTS` : Liste des domaines autorisés (séparés par des virgules)
- `DATABASE_URL` : URL de la base de données (optionnel, SQLite par défaut)
- `SENTRY_DSN` : URL Sentry pour le monitoring (optionnel)

## Test Local avec Docker

### 1. Build de l'image Docker

```bash
docker build -t oc-lettings-site .
```

### 2. Test avec Docker Compose

```bash
# Démarrer l'application
docker-compose up web

# Exécuter les tests
docker-compose run test
```

### 3. Test direct de l'image

```bash
# Démarrer le conteneur
docker run -p 8000:8000 oc-lettings-site

# Accéder à l'application
open http://localhost:8000
```

## Pipeline CI/CD

La pipeline GitHub Actions s'exécute automatiquement sur chaque push vers `main` :

1. **Tests** : Vérification de la qualité du code et couverture des tests (>80%)
2. **Test Docker** : Vérification que l'image Docker fonctionne
3. **Build & Push** : Construction et publication de l'image sur DockerHub
4. **Déploiement** : Déploiement automatique sur Render

## Déploiement sur Render

### Configuration du Service

1. Créez un nouveau service Web sur Render
2. Connectez votre repository GitHub
3. Configurez les variables d'environnement :
- `DOCKER_IMAGE` : `votre-username/oc-lettings-site`
- `SECRET_KEY` : Clé secrète Django
- `DEBUG` : `False`
- `ALLOWED_HOSTS` : Votre domaine Render

### Désactivation du Déploiement Automatique

⚠️ **Important** : Désactivez le déploiement automatique sur Render car la CI/CD GitHub Actions gère le déploiement.

## Structure des Fichiers

```
├── Dockerfile # Configuration Docker
├── docker-compose.yml # Configuration Docker Compose
├── start.sh # Script de démarrage
├── requirements.txt # Dépendances Python
├── .dockerignore # Fichiers exclus de Docker
├── oc_lettings_site/
│ ├── settings.py # Configuration développement
│ └── settings_production.py # Configuration production
└── .github/workflows/
└── ci-cd.yml # Pipeline CI/CD
```

## Sécurité

- Utilisateur non-root dans le conteneur
- Variables d'environnement pour les secrets
- Configuration de sécurité Django pour la production
- Headers de sécurité configurés

## Monitoring

- Logs structurés avec Django
- Intégration Sentry (optionnelle)
- Métriques de couverture de tests

## Troubleshooting

### Problèmes Courants

1. **Erreur de permissions** : Vérifiez que `start.sh` est exécutable
2. **Fichiers statiques manquants** : Vérifiez la configuration WhiteNoise
3. **Base de données** : Vérifiez les variables d'environnement DATABASE_URL

### Logs

```bash
# Voir les logs du conteneur
docker logs <container-id>

# Logs en temps réel
docker logs -f <container-id>
```
44 changes: 44 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
FROM python:3.11-slim

# Set the working directory
WORKDIR /app

# Install required system dependencies
RUN apt-get update && apt-get install -y \
gcc \
&& rm -rf /var/lib/apt/lists/*

# Copy dependency files
COPY requirements.txt .

# Install Python dependencies globally
RUN pip install --no-cache-dir -r requirements.txt

# Create a non-root user for security
RUN groupadd -r django && useradd -r -g django django

# Copy the source code
COPY . .

# Make the startup script executable
RUN chmod +x start.sh

# Create the directory for static files
RUN mkdir -p /app/staticfiles

# Collect static files (as root before changing permissions)
RUN python manage.py collectstatic --noinput --settings=oc_lettings_site.settings_production

# Change permissions for the django user
RUN chown -R django:django /app
# Switch to the django user
USER django
# Expose port 8000
EXPOSE 8000

# Default environment variables
ENV PYTHONUNBUFFERED=1
ENV DJANGO_SETTINGS_MODULE=oc_lettings_site.settings_production

# Default command to start the application
CMD ["./start.sh"]
Loading