Skip to content
Open
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
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions .docker/bot/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
FROM python:3.11-slim-bullseye AS base

WORKDIR /app

RUN apt-get update && apt-get install -y --no-install-recommends \
build-essential \
&& rm -rf /var/lib/apt/lists/*

FROM base AS builder

COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

FROM base AS development

COPY --from=builder /usr/local/bin /usr/local/bin
COPY --from=builder /usr/local/lib/python3.11/site-packages /usr/local/lib/python3.11/site-packages

CMD ["python3", "main.py"]

FROM base AS production

COPY --from=builder /usr/local/bin /usr/local/bin
COPY --from=builder /usr/local/lib/python3.11/site-packages /usr/local/lib/python3.11/site-packages

COPY . .

CMD ["python3", "main.py"]
2 changes: 2 additions & 0 deletions .docker/nginx/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
FROM nginx:1.26-alpine
COPY nginx.conf /etc/nginx/conf.d/default.conf
20 changes: 20 additions & 0 deletions .docker/nginx/nginx.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
server {
listen 80;
server_name localhost;
# listen 443 ssl http2;
# server_name localhost;
# ssl_protocols TLSv1.2 TLSv1.3;
# ssl_prefer_server_ciphers on;
# ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;

location / {
proxy_pass http://web:5000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}

access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
}
36 changes: 36 additions & 0 deletions .docker/web/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
FROM python:3.11-slim-bullseye AS base

WORKDIR /app
RUN apt-get update && apt-get install -y --no-install-recommends \
build-essential \
&& rm -rf /var/lib/apt/lists/*

FROM base AS builder
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

FROM base AS development
WORKDIR /app
COPY --from=builder /usr/local/bin /usr/local/bin
COPY --from=builder /usr/local/lib/python3.11/site-packages /usr/local/lib/python3.11/site-packages
ENV FLASK_APP=app.py \
FLASK_ENV=development \
FLASK_RUN_PORT=5000 \
FLASK_RUN_HOST=0.0.0.0
EXPOSE 5000
CMD ["flask", "run"]

FROM base AS gunicorn
RUN pip install --no-cache-dir gunicorn

FROM base AS production

COPY --from=builder /usr/local/bin /usr/local/bin
COPY --from=builder /usr/local/lib/python3.11/site-packages /usr/local/lib/python3.11/site-packages
COPY --from=gunicorn /usr/local/bin /usr/local/bin
COPY --from=gunicorn /usr/local/lib/python3.11/site-packages /usr/local/lib/python3.11/site-packages

COPY . .
ENV GUNICORN_CMD_ARGS="--bind=0.0.0.0:5000 --workers=3"
EXPOSE 5000
CMD ["gunicorn", "app:app"]
179 changes: 179 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class

# C extensions
*.so

# Distribution / packaging
.Python
# build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST

# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/

# Translations
*.mo
*.pot

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

# Flask stuff:
instance/
.webassets-cache

# Scrapy stuff:
.scrapy

# Sphinx documentation
docs/_build/

# PyBuilder
.pybuilder/
target/

# Jupyter Notebook
.ipynb_checkpoints

# IPython
profile_default/
ipython_config.py

# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version

# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock

# poetry
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
#poetry.lock

# pdm
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
#pdm.lock
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
# in version control.
# https://pdm.fming.dev/latest/usage/project/#working-with-version-control
.pdm.toml
.pdm-python
.pdm-build/

# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
__pypackages__/

# Celery stuff
celerybeat-schedule
celerybeat.pid

# SageMath parsed files
*.sage.py

# Environments
# .env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/

# Spyder project settings
.spyderproject
.spyproject

# Rope project settings
.ropeproject

# mkdocs documentation
/site

# mypy
.mypy_cache/
.dmypy.json
dmypy.json

# Pyre type checker
.pyre/

# pytype static type analyzer
.pytype/

# Cython debug symbols
cython_debug/

# PyCharm
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/

# Docker
.docker/
**/docker-compose.yml
**/docker-compose.*.yml
**/docker-compose.yaml
**/docker-compose.*.yaml
**/compose.yml
**/compose.*.yml
**/compose.yaml
**/compose.*.yaml

db-data/
log/

# CI/CD
.github
8 changes: 8 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,14 @@ MYSQL_PORT=資料庫連接埠
MYSQL_DATABASE=資料庫名稱
HOST=資料庫主機位址

# Docker MySQL initialization
MYSQL_ROOT_PASSWORD=資料庫root密碼(Docker用戶必填)
MYSQL_HOST_PORT=本地訪問容器內MySQL的端口號
NGINX_HOST_PORT=本地訪問容器內NGINX的端口號
NGINX_HTTPS_HOST_PORT=本地訪問容器內NGINX用於HTTPS的端口號
FLASK_HOST_PORT=本地訪問容器內商店的端口號
NGINX_LOG_PATH=本地 NGINX Log 儲存位置

# Global configuration
DISCORD_TOKEN=Discord機器人token
GUILD_ID=機器人所在伺服器ID
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,4 @@ read.txt

# Docker
docker-compose.override.yml
log/
13 changes: 13 additions & 0 deletions docker-compose.override.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
version: '3.8'

services:
web:
build:
target: development
volumes:
- .:/app
bot:
build:
target: development
volumes:
- .:/app
9 changes: 9 additions & 0 deletions docker-compose.prod.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
version: '3.8'

services:
web:
build:
target: production
bot:
build:
target: production
71 changes: 71 additions & 0 deletions docker-compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
version: '3.8'

services:
db:
image: mysql:8.0
restart: unless-stopped
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "${MYSQL_USER}", "--password=${MYSQL_PASSWORD}"]
interval: 10s
timeout: 5s
retries: 5
start_period: 600s
volumes:
- db-data:/var/lib/mysql
- ./static:/docker-entrypoint-initdb.d
networks:
- backnet
env_file:
- .env
expose:
- 3306

web:
build:
context: .
dockerfile: .docker/web/Dockerfile
restart: unless-stopped
ports:
- ${FLASK_HOST_PORT}:5000
networks:
- backnet
- frontnet
depends_on:
db:
condition: service_healthy
env_file:
- .env

bot:
build:
context: .
dockerfile: .docker/bot/Dockerfile
restart: unless-stopped
networks:
- backnet
depends_on:
db:
condition: service_healthy
env_file:
- .env

nginx:
build:
context: .docker/nginx
restart: unless-stopped
ports:
- ${NGINX_HOST_PORT}:80
# - ${NGINX_HTTPS_HOST_PORT}:443
depends_on:
- web
volumes:
- "${NGINX_LOG_PATH}:/var/log/nginx"
networks:
- frontnet

volumes:
db-data:

networks:
backnet:
frontnet:
1 change: 1 addition & 0 deletions run-dev.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
docker compose up --build
1 change: 1 addition & 0 deletions run-prod.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
docker compose -f docker-compose.yaml -f docker-compose.prod.yaml up --build