feat: Reimplement the deployment process through Docker #5
11
.dockerignore
Normal file
11
.dockerignore
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
venv/
|
||||||
|
.venv/
|
||||||
|
__pycache__/
|
||||||
|
*.pyc
|
||||||
|
.git/
|
||||||
|
tests/
|
||||||
|
*.log
|
||||||
|
.env
|
||||||
|
config/
|
||||||
|
/.vscode/
|
||||||
|
*.log
|
||||||
35
Dockerfile
35
Dockerfile
@@ -1,19 +1,36 @@
|
|||||||
FROM python:3.13.14-alpine
|
FROM python:3.13.14-alpine
|
||||||
|
|
||||||
|
RUN apk add --no-cache \
|
||||||
|
build-base \
|
||||||
|
libffi-dev \
|
||||||
|
musl-dev \
|
||||||
|
openssl-dev \
|
||||||
|
python3-dev \
|
||||||
|
geckodriver \
|
||||||
|
firefox-esr
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
COPY requirements.txt .
|
|
||||||
RUN pip install --no-cache-dir -r requirements.txt && \
|
|
||||||
apk add --no-cache firefox geckodriver
|
|
||||||
|
|
||||||
COPY . .
|
|
||||||
|
|
||||||
ENV TOKEN=""
|
ENV TOKEN=""
|
||||||
ENV URL=""
|
|
||||||
ENV CONFIG_PATH="/config"
|
ENV CONFIG_PATH="/config"
|
||||||
ENV COGS=""
|
|
||||||
ENV GECKODRIVER_PATH="/usr/bin/geckodriver"
|
ENV GECKODRIVER_PATH="/usr/bin/geckodriver"
|
||||||
|
|
||||||
RUN mkdir ${CONFIG_PATH}
|
RUN adduser -D bot && \
|
||||||
|
mkdir /logs && \
|
||||||
|
chown -R bot:bot /logs && \
|
||||||
|
chmod 755 /logs && \
|
||||||
|
mkdir -p ${CONFIG_PATH} && \
|
||||||
|
chown -R bot:bot ${CONFIG_PATH} && \
|
||||||
|
chmod 755 ${CONFIG_PATH}
|
||||||
|
|
||||||
|
COPY requirements.txt .
|
||||||
|
RUN pip install --no-cache-dir -r requirements.txt
|
||||||
|
|
||||||
|
COPY . .
|
||||||
|
RUN chown -R bot:bot /app && \
|
||||||
|
chmod -R 755 /app && \
|
||||||
|
chmod +x /app/main.py
|
||||||
|
|
||||||
|
USER bot
|
||||||
|
|
||||||
ENTRYPOINT ["python", "main.py"]
|
ENTRYPOINT ["python", "main.py"]
|
||||||
17
compose.yaml
17
compose.yaml
@@ -6,15 +6,30 @@ networks:
|
|||||||
|
|
||||||
services:
|
services:
|
||||||
botmafieux:
|
botmafieux:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: Dockerfile
|
||||||
image: nebulo9/botmafieux:latest
|
image: nebulo9/botmafieux:latest
|
||||||
container_name: botmafieux
|
container_name: botmafieux
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
networks:
|
networks:
|
||||||
- internal
|
- internal
|
||||||
- outbound
|
- outbound
|
||||||
env_file: ./.env
|
env_file:
|
||||||
|
- ./.env
|
||||||
volumes:
|
volumes:
|
||||||
- ./config:/config
|
- ./config:/config
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "pgrep", "-f", "main.py"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 3
|
||||||
|
start_period: 30s
|
||||||
|
logging:
|
||||||
|
driver: "json-file"
|
||||||
|
options:
|
||||||
|
max-size: "10m"
|
||||||
|
max-file: "3"
|
||||||
deploy:
|
deploy:
|
||||||
resources:
|
resources:
|
||||||
limits:
|
limits:
|
||||||
|
|||||||
6778
config/hltv.html
6778
config/hltv.html
File diff suppressed because one or more lines are too long
@@ -1,27 +0,0 @@
|
|||||||
Ta gueule.
|
|
||||||
Qui a demandé ?
|
|
||||||
Mais tais-toi!
|
|
||||||
zZzZzZzZ......
|
|
||||||
Tout ça ?
|
|
||||||
On peut se passer du message je pense.
|
|
||||||
C'est chiant le message là.
|
|
||||||
Mdr on s'en fout.
|
|
||||||
Pas lu.
|
|
||||||
Trop long j'ai décroché.
|
|
||||||
Il faut quitter le serveur, vous gênez l'espace s'il vous plaît.
|
|
||||||
Gênant...
|
|
||||||
Si je devais noter la pertinence du message ce serait genre 1/10.
|
|
||||||
Tu es ridicule, arrête d'écrire.
|
|
||||||
Ça a intéréssé quelqu'un ?
|
|
||||||
Franchement c'était nécessaire d'écrire ça ?
|
|
||||||
Honestly the most useless thing I read today.
|
|
||||||
Dommage que les hommes soient cons…
|
|
||||||
Ta mère mérite la prison pour avoir mis au monde un HOMME.
|
|
||||||
T'as pas beaucoup de neurones.
|
|
||||||
Arrêtons de normaliser les hommes svp.
|
|
||||||
🚮🚮
|
|
||||||
Ton message me donne envie de vomir.
|
|
||||||
J'ai pas ri perso.
|
|
||||||
Tiens tiens encore une raison de détester les hommes !
|
|
||||||
Y'a moyen ton père c'est Macron.
|
|
||||||
Tu préfères devenir un être humain sympa ou rester un homme ?
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
[{"mentor_id": 264189554582355969, "guild_id": 897157935006900254, "next_roll": "2026-07-22T00:00:00"}]
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
target;weight;take
|
|
||||||
any;1.0;Tu as besoin d'un café ?
|
|
||||||
any;1.0;Je peux te faire un café si tu veux ?
|
|
||||||
any;1.0;Tu as besoin d'un thé ?
|
|
||||||
any;1.0;Je peux te faire un thé si tu veux ?
|
|
||||||
any;1.0;Tu as besoin d'un matcha latte?
|
|
||||||
any;1.0;Je peux te faire un matcha latte si tu veux ?
|
|
||||||
any;1.0;Tu peux m'aider sur un truc ?
|
|
||||||
any;1.0;Désolé, j'ai pas compris.
|
|
||||||
any;1.0;Attends, tu peux réexpliquer ?
|
|
||||||
any;1.0;J'ai fait une bêtise je crois...
|
|
||||||
nebulo;2.0;J'ai un bug dans mon code tu peux regarder ?
|
|
||||||
bluebro;2.0;J'ai un bug dans mon code tu peux regarder ?
|
|
||||||
viebah;2.0;J'ai un bug dans mon code tu peux regarder ?
|
|
||||||
merdix;2.0;Mon modèle 3D est cassé, je fais quoi ?
|
|
||||||
goupzy;2.0;Mon modèle 3D est cassé, je fais quoi ?
|
|
||||||
viebah;2.0;Mon modèle 3D est cassé, je fais quoi ?
|
|
||||||
goupzy;2.0;Mon modèle 3D est cassé, je fais quoi ?
|
|
||||||
nino274;2.0;Mon modèle 3D est cassé, je fais quoi ?
|
|
||||||
cemesah;2.0;J'ai fait une erreur, il faut réimprimer les cartes...
|
|
||||||
cemesah;2.0;J'ai pas sauvegardé et InDesign a planté...
|
|
||||||
cemesah;2.0;Tu veux du bouillon ?
|
|
||||||
|
@@ -7,19 +7,11 @@ class Config:
|
|||||||
|
|
||||||
TOKEN = str(os.getenv("TOKEN", ""))
|
TOKEN = str(os.getenv("TOKEN", ""))
|
||||||
CONFIG_PATH = str(os.getenv("CONFIG_PATH"))
|
CONFIG_PATH = str(os.getenv("CONFIG_PATH"))
|
||||||
COGS = os.getenv("COGS", "")
|
|
||||||
|
|
||||||
GUILDS_IDS:list[int] = []
|
GUILDS_IDS:list[int] = []
|
||||||
|
|
||||||
GUILD_CONFIGS:dict[int,dict] = {}
|
GUILD_CONFIGS:dict[int,dict] = {}
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def get_cogs(cls):
|
|
||||||
raw_value = cls.COGS.strip()
|
|
||||||
if not raw_value:
|
|
||||||
return None
|
|
||||||
return [item.strip().lower() for item in raw_value.split(",") if item.strip()]
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def load_guilds_configs(cls):
|
def load_guilds_configs(cls):
|
||||||
with os.scandir(cls.CONFIG_PATH) as d:
|
with os.scandir(cls.CONFIG_PATH) as d:
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
|
import tempfile
|
||||||
|
import sys
|
||||||
|
|
||||||
# Determine log level from environment variable `LOG_LEVEL` (e.g. DEBUG, INFO)
|
# Determine log level from environment variable `LOG_LEVEL` (e.g. DEBUG, INFO)
|
||||||
raw_level = os.getenv("LOG_LEVEL", "INFO").upper()
|
raw_level = os.getenv("LOG_LEVEL", "INFO").upper()
|
||||||
@@ -15,7 +17,26 @@ else:
|
|||||||
logging.basicConfig(level=level, format='[%(levelname)s] %(asctime)s: %(name)s: %(message)s')
|
logging.basicConfig(level=level, format='[%(levelname)s] %(asctime)s: %(name)s: %(message)s')
|
||||||
LOGGER = logging.getLogger('botmafieux')
|
LOGGER = logging.getLogger('botmafieux')
|
||||||
LOGGER.setLevel(level)
|
LOGGER.setLevel(level)
|
||||||
# File handler (append)
|
|
||||||
handler = logging.FileHandler(filename='botmafieux.log', encoding='utf-8', mode='a')
|
# Decide log file path: prefer LOG_FILE, then CONFIG_PATH/botmafieux.log, then /tmp
|
||||||
handler.setFormatter(logging.Formatter('%(asctime)s:%(levelname)s:%(name)s: %(message)s'))
|
preferred = os.getenv('LOG_FILE')
|
||||||
LOGGER.addHandler(handler)
|
if not preferred:
|
||||||
|
cfg_path = "/logs"
|
||||||
|
if cfg_path:
|
||||||
|
preferred = os.path.join(cfg_path, 'botmafieux.log')
|
||||||
|
else:
|
||||||
|
preferred = os.path.join(tempfile.gettempdir(), 'botmafieux.log')
|
||||||
|
|
||||||
|
formatter = logging.Formatter('%(asctime)s:%(levelname)s:%(name)s: %(message)s')
|
||||||
|
|
||||||
|
try:
|
||||||
|
handler = logging.FileHandler(filename=preferred, encoding='utf-8', mode='a')
|
||||||
|
handler.setFormatter(formatter)
|
||||||
|
LOGGER.addHandler(handler)
|
||||||
|
except (PermissionError, OSError) as e:
|
||||||
|
# Fall back to console logging if file cannot be opened
|
||||||
|
stream_handler = logging.StreamHandler(sys.stdout)
|
||||||
|
stream_handler.setFormatter(formatter)
|
||||||
|
LOGGER.addHandler(stream_handler)
|
||||||
|
# Print a warning directly to stderr in case logging isn't yet configured elsewhere
|
||||||
|
print(f"[WARN] Could not open log file '{preferred}' for writing: {e}. Falling back to stdout.", file=sys.stderr)
|
||||||
Reference in New Issue
Block a user