mirror of
https://github.com/nirvana-7777/script.service.ultimate.git
synced 2026-10-15 04:12:35 +02:00
Dockerize addon
This commit is contained in:
+59
-13
@@ -1,17 +1,20 @@
|
||||
# Git
|
||||
.git
|
||||
.git/
|
||||
.gitignore
|
||||
.gitattributes
|
||||
.gitmodules
|
||||
|
||||
# IDE
|
||||
.vscode
|
||||
.idea
|
||||
.vscode/
|
||||
.idea/
|
||||
*.swp
|
||||
*.swo
|
||||
*~
|
||||
|
||||
# OS
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
desktop.ini
|
||||
|
||||
# Python
|
||||
__pycache__/
|
||||
@@ -19,23 +22,66 @@ __pycache__/
|
||||
*$py.class
|
||||
*.so
|
||||
.Python
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
wheels/
|
||||
share/python-wheels/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
MANIFEST
|
||||
pip-log.txt
|
||||
pip-delete-this-directory.txt
|
||||
|
||||
# Virtual environments
|
||||
.env
|
||||
.venv
|
||||
env/
|
||||
venv/
|
||||
ENV/
|
||||
env/
|
||||
env.bak/
|
||||
venv.bak/
|
||||
|
||||
# Test and coverage
|
||||
.tox/
|
||||
.coverage
|
||||
.coverage.*
|
||||
.cache
|
||||
nosetests.xml
|
||||
coverage.xml
|
||||
*.cover
|
||||
*.py,cover
|
||||
.hypothesis/
|
||||
.pytest_cache/
|
||||
cover/
|
||||
|
||||
# Logs
|
||||
logs/
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
lerna-debug.log*
|
||||
|
||||
# Test and coverage
|
||||
.coverage
|
||||
htmlcov/
|
||||
.pytest_cache/
|
||||
.tox/
|
||||
# Kodi addon specific
|
||||
resources/settings.xml~
|
||||
resources/language/*/strings.xml~
|
||||
addon.xml~
|
||||
|
||||
# Distribution
|
||||
dist/
|
||||
build/
|
||||
*.egg-info/
|
||||
# Docker
|
||||
docker-compose.override.yml
|
||||
.env
|
||||
*.env.local
|
||||
|
||||
# Temporary files
|
||||
tmp/
|
||||
temp/
|
||||
@@ -0,0 +1,89 @@
|
||||
name: Docker Build and Publish
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master, main ]
|
||||
tags: [ 'v*' ]
|
||||
pull_request:
|
||||
branches: [ master, main ]
|
||||
workflow_dispatch: # Manual trigger
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.11'
|
||||
cache: 'pip'
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
pip install -r requirements.txt
|
||||
pip install pytest pytest-asyncio
|
||||
|
||||
- name: Run tests (if any)
|
||||
run: |
|
||||
# Add your test commands here
|
||||
# Example: python -m pytest tests/ -v
|
||||
echo "No tests configured yet"
|
||||
|
||||
docker:
|
||||
needs: test
|
||||
runs-on: ubuntu-latest
|
||||
if: github.event_name != 'pull_request'
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Log in to Docker Hub
|
||||
uses: docker/login-action@v3
|
||||
if: github.event_name != 'pull_request'
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
- name: Extract metadata
|
||||
id: meta
|
||||
uses: docker/metadata-action@v5
|
||||
with:
|
||||
images: nirvana7777/ultimate-backend
|
||||
tags: |
|
||||
type=ref,event=branch
|
||||
type=ref,event=tag
|
||||
type=ref,event=pr
|
||||
type=semver,pattern={{version}}
|
||||
type=semver,pattern={{major}}.{{minor}}
|
||||
type=sha
|
||||
type=raw,value=latest,enable={{is_default_branch}}
|
||||
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
context: .
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
platforms: linux/amd64,linux/arm64
|
||||
build-args: |
|
||||
APP_USER=ultimate
|
||||
|
||||
notify:
|
||||
runs-on: ubuntu-latest
|
||||
needs: [test, docker]
|
||||
if: always()
|
||||
steps:
|
||||
- name: Workflow status
|
||||
run: |
|
||||
echo "Test job: ${{ needs.test.result }}"
|
||||
echo "Docker job: ${{ needs.docker.result }}"
|
||||
+86
-45
@@ -1,19 +1,25 @@
|
||||
# Use Python 3.11 slim as base
|
||||
# Ultimate Backend Streaming Service - Kodi addon in standalone Docker mode
|
||||
FROM python:3.11-slim
|
||||
|
||||
# Set environment variables
|
||||
# Build arguments for user/group configuration
|
||||
ARG USER_ID=1000
|
||||
ARG GROUP_ID=1000
|
||||
ARG APP_USER=ultimate
|
||||
ARG APP_HOME=/app
|
||||
|
||||
# Environment variables
|
||||
ENV PYTHONUNBUFFERED=1 \
|
||||
PYTHONDONTWRITEBYTECODE=1 \
|
||||
TZ=UTC \
|
||||
ULTIMATE_PORT=7777 \
|
||||
ULTIMATE_COUNTRY=DE \
|
||||
PYTHONPATH=/app/lib:$PYTHONPATH
|
||||
|
||||
# Create non-root user
|
||||
RUN useradd -m -u 1000 -s /bin/bash kodi
|
||||
ULTIMATE_DEBUG=false \
|
||||
PYTHONPATH=${APP_HOME}/lib:$PYTHONPATH \
|
||||
HOME=/home/${APP_USER} \
|
||||
PATH=/home/${APP_USER}/.local/bin:$PATH
|
||||
|
||||
# Install system dependencies
|
||||
RUN apt-get update && apt-get install -y \
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
gcc \
|
||||
g++ \
|
||||
libxml2-dev \
|
||||
@@ -23,58 +29,93 @@ RUN apt-get update && apt-get install -y \
|
||||
libxmlsec1-dev \
|
||||
pkg-config \
|
||||
curl \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
ca-certificates \
|
||||
&& apt-get clean \
|
||||
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
|
||||
|
||||
# Create application user and group with configurable UID/GID
|
||||
RUN groupadd -g ${GROUP_ID} ${APP_USER} && \
|
||||
useradd -u ${USER_ID} -g ${APP_USER} -m -s /bin/bash ${APP_USER}
|
||||
|
||||
# Set working directory
|
||||
WORKDIR /app
|
||||
WORKDIR ${APP_HOME}
|
||||
|
||||
# Copy entire project
|
||||
COPY . /app/
|
||||
|
||||
# Create config directory and ensure proper permissions
|
||||
RUN mkdir -p /config && \
|
||||
chown -R kodi:kodi /app /config
|
||||
|
||||
USER kodi
|
||||
# Copy requirements first for better caching
|
||||
COPY requirements.txt /tmp/requirements.txt
|
||||
|
||||
# Install Python dependencies
|
||||
RUN pip install --no-cache-dir --user \
|
||||
bottle \
|
||||
requests \
|
||||
lxml \
|
||||
defusedxml \
|
||||
m3u8 \
|
||||
iso8601 \
|
||||
pycountry \
|
||||
python-dateutil \
|
||||
urllib3 \
|
||||
chardet \
|
||||
pycryptodome \
|
||||
cryptography
|
||||
# If requirements.txt exists, use it. Otherwise install defaults.
|
||||
RUN if [ -f /tmp/requirements.txt ]; then \
|
||||
echo "Installing from requirements.txt..." && \
|
||||
pip install --no-cache-dir --upgrade pip && \
|
||||
pip install --no-cache-dir -r /tmp/requirements.txt; \
|
||||
else \
|
||||
echo "No requirements.txt found, installing default packages..." && \
|
||||
pip install --no-cache-dir --upgrade pip && \
|
||||
pip install --no-cache-dir \
|
||||
bottle>=0.12.25 \
|
||||
requests>=2.31.0 \
|
||||
lxml>=4.9.3 \
|
||||
defusedxml>=0.7.1 \
|
||||
m3u8>=4.0.0 \
|
||||
iso8601>=1.1.0 \
|
||||
pycountry>=23.12.11 \
|
||||
python-dateutil>=2.8.2 \
|
||||
urllib3>=2.0.7 \
|
||||
chardet>=5.2.0 \
|
||||
pycryptodome>=3.19.0 \
|
||||
cryptography>=41.0.0; \
|
||||
fi
|
||||
|
||||
# Create requirements.txt for documentation
|
||||
RUN echo "bottle>=0.12.25" > /app/requirements.txt && \
|
||||
echo "requests>=2.31.0" >> /app/requirements.txt && \
|
||||
echo "lxml>=4.9.3" >> /app/requirements.txt && \
|
||||
echo "defusedxml>=0.7.1" >> /app/requirements.txt && \
|
||||
echo "m3u8>=4.0.0" >> /app/requirements.txt && \
|
||||
echo "iso8601>=1.1.0" >> /app/requirements.txt && \
|
||||
echo "pycountry>=23.12.11" >> /app/requirements.txt && \
|
||||
echo "python-dateutil>=2.8.2" >> /app/requirements.txt && \
|
||||
echo "urllib3>=2.0.7" >> /app/requirements.txt && \
|
||||
echo "chardet>=5.2.0" >> /app/requirements.txt && \
|
||||
echo "pycryptodome>=3.19.0" >> /app/requirements.txt && \
|
||||
echo "cryptography>=41.0.0" >> /app/requirements.txt
|
||||
# Copy application code
|
||||
COPY --chown=${USER_ID}:${GROUP_ID} . ${APP_HOME}/
|
||||
|
||||
# Create necessary directories
|
||||
RUN mkdir -p /config /logs /cache && \
|
||||
chown -R ${USER_ID}:${GROUP_ID} /config /logs /cache
|
||||
|
||||
# Create a requirements.txt if it doesn't exist (for documentation)
|
||||
RUN if [ ! -f requirements.txt ]; then \
|
||||
echo "# Ultimate Backend Service Requirements" > requirements.txt && \
|
||||
echo "# Auto-generated for documentation" >> requirements.txt && \
|
||||
echo "" >> requirements.txt && \
|
||||
echo "bottle>=0.12.25" >> requirements.txt && \
|
||||
echo "requests>=2.31.0" >> requirements.txt && \
|
||||
echo "lxml>=4.9.3" >> requirements.txt && \
|
||||
echo "defusedxml>=0.7.1" >> requirements.txt && \
|
||||
echo "m3u8>=4.0.0" >> requirements.txt && \
|
||||
echo "iso8601>=1.1.0" >> requirements.txt && \
|
||||
echo "pycountry>=23.12.11" >> requirements.txt && \
|
||||
echo "python-dateutil>=2.8.2" >> requirements.txt && \
|
||||
echo "urllib3>=2.0.7" >> requirements.txt && \
|
||||
echo "chardet>=5.2.0" >> requirements.txt && \
|
||||
echo "pycryptodome>=3.19.0" >> requirements.txt && \
|
||||
echo "cryptography>=41.0.0" >> requirements.txt; \
|
||||
fi
|
||||
|
||||
# Switch to non-root user
|
||||
USER ${USER_ID}
|
||||
|
||||
# Create default config if not provided
|
||||
RUN if [ ! -f /config/config.json ]; then \
|
||||
echo '{"default_country": "DE", "server_port": 7777, "debug_mode": false}' > /config/config.json; \
|
||||
fi
|
||||
|
||||
# Expose the service port
|
||||
EXPOSE ${ULTIMATE_PORT}
|
||||
|
||||
# Health check
|
||||
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
|
||||
HEALTHCHECK --interval=30s --timeout=10s --start-period=10s --retries=3 \
|
||||
CMD curl -f http://localhost:${ULTIMATE_PORT}/api/providers || exit 1
|
||||
|
||||
# Labels for better image metadata
|
||||
LABEL maintainer="nirvana-7777" \
|
||||
description="Ultimate Backend Streaming Service" \
|
||||
version="1.0.0" \
|
||||
org.opencontainers.image.source="https://github.com/nirvana-7777/script.service.ultimate"
|
||||
|
||||
# Run in standalone mode (since Kodi isn't available in Docker)
|
||||
ENTRYPOINT ["python", "/app/service.py"]
|
||||
|
||||
# Default command
|
||||
# Default command with configurable options
|
||||
CMD ["--standalone", "--config-dir", "/config"]
|
||||
+17
-6
@@ -2,7 +2,12 @@ version: '3.8'
|
||||
|
||||
services:
|
||||
ultimate-backend:
|
||||
build: .
|
||||
build:
|
||||
context: .
|
||||
args:
|
||||
- USER_ID=1000
|
||||
- GROUP_ID=1000
|
||||
image: nirvana7777/ultimate-backend:latest
|
||||
container_name: ultimate-backend
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
@@ -10,8 +15,8 @@ services:
|
||||
environment:
|
||||
- ULTIMATE_PORT=7777
|
||||
- ULTIMATE_COUNTRY=DE
|
||||
- TZ=Europe/Berlin
|
||||
- DEBUG_MODE=true
|
||||
- ULTIMATE_DEBUG=false
|
||||
- TZ=${TZ:-Europe/Berlin}
|
||||
volumes:
|
||||
- ./config:/config
|
||||
- ./logs:/logs
|
||||
@@ -19,10 +24,16 @@ services:
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:7777/api/providers"]
|
||||
interval: 30s
|
||||
timeout: 3s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 5s
|
||||
start_period: 10s
|
||||
networks:
|
||||
- ultimate-network
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.ultimate.rule=Host(`ultimate.local`)"
|
||||
- "traefik.http.services.ultimate.loadbalancer.server.port=7777"
|
||||
- "traefik.http.services.ultimate.loadbalancer.server.port=7777"
|
||||
|
||||
networks:
|
||||
ultimate-network:
|
||||
driver: bridge
|
||||
Reference in New Issue
Block a user