Skip to content

Commit

Permalink
Merge pull request #11 from Cleanwalk-org-QNSCNT/feat/discover-view
Browse files Browse the repository at this point in the history
Feature: add mobile V2 version
  • Loading branch information
ArthurFrin authored Jul 25, 2024
2 parents 89ce1c7 + 733f809 commit 0238285
Show file tree
Hide file tree
Showing 98 changed files with 5,441 additions and 1,457 deletions.
30 changes: 30 additions & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: Deploy to VPS

on:
push:
branches:
- release # Déclencher le déploiement uniquement sur la branche release

jobs:
deploy:
runs-on: ubuntu-latest

steps:
- name: Checkout repository
uses: actions/checkout@v3

- name: Set up SSH
uses: webfactory/[email protected]
with:
ssh-private-key: ${{ secrets.SECRET_KEY }} # Utilisation de la clé SSH

- name: Deploy to VPS
env:
VPS_IP: ${{ secrets.VPS_IP }}
run: |
ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null root@$VPS_IP '
cd /home/cleanwalk-org-v2 &&
git pull origin release &&
docker compose -f docker-compose.prod.yml down &&
docker compose -f docker-compose.prod.yml up -d --build
'
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,8 @@ lerna-debug.log*
*.njsproj
*.sln
*.sw?

/uploads

/data-nginx
/letsencrypt
47 changes: 45 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,49 @@ To shutdown all stack or just a specific one:
docker compose down
```

### Production
## Production

### config nginx proxy manager

**first login**: connect to @server_ip:81
- username: [email protected]
- password: changeme **! change admin info**

**proxy hosts**
Go to Hosts > Proxy Hosts and click on Add Proxy Host.

**frontend**
- Domain Names: yourdomain.example, www.yourdomain.example
- Scheme: http
- Forward Hostname / IP: frontend
- Forward Port: 80

**API**
- Domain Names: api.yourdomain.example
- Scheme: http
- Forward Hostname / IP: api
- Forward Port: 5000

**uploads**
- Domain Names : uploads.yourdomain.example
- Scheme : http
- Forward Hostname / IP : nginx-proxy-manager
- Forward Port : 81

in advanced add:
```
location / {
alias /var/www/uploads/;
autoindex on;
}
```

**SSL Config**
- check Force SSL
- select Request a new SSL certificate
- add email and save





Use Portainer for easier management. To install it, launch the script named "install-portainer.sh" and to access it you can check the service on port 9000.
4 changes: 3 additions & 1 deletion api/.env.example
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
DATABASE_URI=mysql+mysqlconnector://root:root@localhost:3306/cleanwalk_db
DATABASE_URI=mysql+pymysql://user:password@localhost/cleanwalk_db
API_KEY=1234567890
JWT_SECRET_KEY=098765433
UPLOAD_FOLDER=uploads
UPLOADS_URL=https://uploads.cleanwalk.org
23 changes: 0 additions & 23 deletions api/Dockerfile

This file was deleted.

20 changes: 20 additions & 0 deletions api/Dockerfile.dev
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Utilisez une image Python comme image de base
FROM python:3.8-alpine

# Définissez le répertoire de travail dans le conteneur
WORKDIR /app

# Copiez les fichiers de dépendances dans le conteneur
COPY requirements.txt .

# Installez les dépendances
RUN pip install --no-cache-dir -r requirements.txt

# Copiez le reste du code dans le conteneur
COPY . .

# Exposez le port sur lequel l'API s'exécute
EXPOSE 5000

# Démarrez l'API
CMD ["python3", "app.py"]
23 changes: 23 additions & 0 deletions api/Dockerfile.prod
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Utiliser une image Python comme image de base
FROM python:3.8-alpine

# Définir le répertoire de travail dans le conteneur
WORKDIR /app

# Copier les fichiers de dépendances dans le conteneur
COPY requirements.txt .

# Installer les dépendances
RUN pip install --no-cache-dir -r requirements.txt

# Copier le reste du code dans le conteneur
COPY . .

# Créer le dossier pour les uploads et définir les permissions
RUN mkdir -p /app/uploads && chmod -R 755 /app/uploads

# Exposer le port sur lequel l'API s'exécute
EXPOSE 5000

# Démarrer l'API avec Gunicorn
CMD ["gunicorn", "--bind", "0.0.0.0:5000", "wsgi:app"]
40 changes: 3 additions & 37 deletions api/app.py
Original file line number Diff line number Diff line change
@@ -1,41 +1,7 @@
from flask import Flask
from flask_jwt_extended import JWTManager
from app.models import db
from dotenv import load_dotenv
import os
from datetime import timedelta

# load environement variables from .env file
load_dotenv()

ACCESS_EXPIRES = timedelta(minutes=1)

app = Flask(__name__)

#configure the SQLAlchemy database using environment variables
app.config['SQLALCHEMY_DATABASE_URI'] = os.getenv('DATABASE_URI')
app.config['API_KEY'] = os.getenv('API_KEY')
app.config['JWT_SECRET_KEY'] = os.getenv('JWT_SECRET_KEY')
app.config["JWT_ACCESS_TOKEN_EXPIRES"] = ACCESS_EXPIRES

#Init the JWTManager extension
jwt = JWTManager(app)

# Init the SQLAlchemy database
db.init_app(app)

from app.routes.users import users_bp
from app.routes.articles import articles_bp
from app.routes.cleanwalks import cleanwalks_bp
from app.routes.cities import cities_bp
from app.routes.admin import admin_bp

app.register_blueprint(users_bp , url_prefix='/users')
app.register_blueprint(articles_bp , url_prefix='/articles')
app.register_blueprint(cleanwalks_bp , url_prefix='/cleanwalks')
app.register_blueprint(cities_bp , url_prefix='/cities')
app.register_blueprint(admin_bp , url_prefix='/admin')
# app.py
from app import create_app

app = create_app()

if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000, debug=True)
46 changes: 46 additions & 0 deletions api/app/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# app/__init__.py
from flask import Flask
from flask_jwt_extended import JWTManager
from flask_sqlalchemy import SQLAlchemy
from flask_cors import CORS
from dotenv import load_dotenv
import os
from datetime import timedelta

# Charger les variables d'environnement
load_dotenv()

# Initialiser l'extension SQLAlchemy
db = SQLAlchemy()

def create_app():
app = Flask(__name__)
CORS(app)
# Configurer l'application
app.config['SQLALCHEMY_DATABASE_URI'] = os.getenv('DATABASE_URI')
app.config['API_KEY'] = os.getenv('API_KEY')
app.config['JWT_SECRET_KEY'] = os.getenv('JWT_SECRET_KEY')
app.config["JWT_ACCESS_TOKEN_EXPIRES"] = timedelta(days=30)
app.config['UPLOAD_FOLDER'] = os.getenv('UPLOAD_FOLDER')
app.config['UPLOADS_URL'] = os.getenv('UPLOADS_URL')

# Initialiser les extensions
db.init_app(app)
JWTManager(app)

# Enregistrer les blueprints
from app.routes.users import users_bp
from app.routes.articles import articles_bp
from app.routes.cleanwalks import cleanwalks_bp
from app.routes.cities import cities_bp
from app.routes.admin import admin_bp
from app.routes.upload import upload_bp

app.register_blueprint(users_bp, url_prefix='/users')
app.register_blueprint(articles_bp, url_prefix='/articles')
app.register_blueprint(cleanwalks_bp, url_prefix='/cleanwalks')
app.register_blueprint(cities_bp, url_prefix='/cities')
app.register_blueprint(admin_bp, url_prefix='/admin')
app.register_blueprint(upload_bp, url_prefix='/upload')

return app
19 changes: 14 additions & 5 deletions api/app/models.py
Original file line number Diff line number Diff line change
@@ -1,26 +1,35 @@
from flask_sqlalchemy import SQLAlchemy

db = SQLAlchemy()
from app import db

class User(db.Model):
__tablename__ = 'users'
id = db.Column(db.Integer, primary_key=True)
firstname = db.Column(db.String(255), nullable=False)
lastname = db.Column(db.String(255), nullable=False)
name = db.Column(db.String(255), nullable=False)
email = db.Column(db.String(255), unique=True, index=True, nullable=False)
password = db.Column(db.String(255), nullable=False)
salt = db.Column(db.BINARY(16), nullable=True)
created_at = db.Column(db.TIMESTAMP, nullable=False)
profile_picture = db.Column(db.String(255), nullable=True)
role_id = db.Column(db.Integer, db.ForeignKey('roles.id'), nullable=False)

class Organisation(db.Model):
__tablename__ = 'organisations'
user_id = db.Column(db.Integer, db.ForeignKey('users.id'), primary_key=True)
description = db.Column(db.String(255), nullable=True)
web_site = db.Column(db.String(255), nullable=True)
social_media = db.Column(db.JSON, nullable=True)
banner_img = db.Column(db.String(255), nullable=True)

# Relation vers User
user = db.relationship('User', backref=db.backref('organisation', uselist=False))

class Cleanwalk(db.Model):
__tablename__ = 'cleanwalks'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(255), nullable=False)
pos_lat = db.Column(db.Float, nullable=False)
pos_long = db.Column(db.Float, nullable=False)
date_begin = db.Column(db.TIMESTAMP, nullable=False)
img_url = db.Column(db.String(255), nullable=True)
duration = db.Column(db.Integer, nullable=False)
description = db.Column(db.String(255), nullable = False)
address = db.Column(db.String(255), nullable=False)
Expand Down
2 changes: 2 additions & 0 deletions api/app/routes/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@

@admin_bp.before_request
def check_api_key():
if request.method == 'OPTIONS': # Handle preflight requests to enable CORS
return
api_key = request.headers.get('X-API-Key') # Get the api key from the header

# Verify the api key
Expand Down
2 changes: 2 additions & 0 deletions api/app/routes/articles.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

@articles_bp.before_request
def check_api_key():
if request.method == 'OPTIONS': # Handle preflight requests to enable CORS
return
api_key = request.headers.get('X-API-Key') # Get the api key from the header

# Verify the api key
Expand Down
2 changes: 2 additions & 0 deletions api/app/routes/cities.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

@cities_bp.before_request
def check_api_key():
if request.method == 'OPTIONS': # Handle preflight requests to enable CORS
return
api_key = request.headers.get('X-API-Key') # Get the api key from the header

# Verify the api key
Expand Down
Loading

0 comments on commit 0238285

Please sign in to comment.