Skip to content

Commit

Permalink
Merge pull request #1 from pythoninthegrass/feat/update_docker
Browse files Browse the repository at this point in the history
Merge docker refactor
  • Loading branch information
pythoninthegrass authored Oct 13, 2024
2 parents f7786d7 + bd4ed23 commit 10f5caf
Show file tree
Hide file tree
Showing 10 changed files with 267 additions and 31 deletions.
4 changes: 4 additions & 0 deletions .dive-ci
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
rules:
lowestEfficiency: 0.97 # ratio between 0-1
highestWastedBytes: 20MB # B, KB, MB, and GB
highestUserWastedPercent: 0.20 # ratio between 0-1
14 changes: 13 additions & 1 deletion .dockerignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
# ETC
.dive-ci
.editorconfig
.env
.hadolint.yaml
**/*.example
**/*.md
LICENSE

# Runtime
audio_cache/
bin/
Expand All @@ -8,13 +17,16 @@ musicbot/lib/__pycache__/

# Docker
.dockerignore
docker-compose.example.yml
docker-compose.yml
Dockerfile

# Git
.git/
.gitattributes
.github/
.gitignore

# IDE
.idea/
.vscode/
.vscode/
34 changes: 34 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# EditorConfig is awesome: https://EditorConfig.org

# top-most EditorConfig file
root = true

# Unix-style newlines and whitespace cleanup
[*]
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
insert_final_newline = true

# Protect whitespace in markdown files
[*.md]
trim_trailing_whitespace = false

# general formatting
[*.{bash,go,sh,zsh,justfile,Makefile}]
indent_style = tab
indent_size = 4

# Set default charset
[*.{html,xml,js,css,py}]
charset = utf-8

# python
[*.py]
indent_style = space
indent_size = 4

# webdev et al
[*.{html,xml,js,mjs,css,json,jsonc,gql,lua,tf,tfvars,yml,yaml}]
indent_style = space
indent_size = 2
4 changes: 4 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
COMPOSE_FILE=docker-compose.yml
COMPOSE_REMOVE_ORPHANS=true
# * Options: linux/amd64 / linux/arm64/v8
PLATFORM=linux/arm64/v8
102 changes: 102 additions & 0 deletions .github/workflows/docker.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
name: Publish Docker images

on:
push:
branches:
- 'main'
- 'master'
- 'feat/**'
tags:
- '*.*.*'
paths:
- '.dockerignore'
- '.env.example'
- '.github/workflows/**'
- '**.bat'
- '**.ps1'
- '**.py'
- '**.sh'
- 'bin/**'
- 'config/**'
- 'Dockerfile*'
- 'musicbot.service'
- 'musicbot/**'
- 'musicbotcmd'
- 'poetry.lock'
- 'pyproject.toml'
- 'requirements.txt'
workflow_dispatch:

env:
REGISTRY_URL: ${{ vars.REGISTRY_URL }}
REGISTRY_USER: ${{ vars.REGISTRY_USER }}
REGISTRY_PASS: ${{ secrets.REGISTRY_PASS }}

jobs:
push_to_registry:
name: Push Docker image to container registry
runs-on: ubuntu-latest
strategy:
matrix:
dockerfile: [Dockerfile]
concurrency:
group: ${{ github.workflow }}-${{ matrix.dockerfile }}-${{ github.ref }}
cancel-in-progress: true
permissions:
packages: write
contents: read
actions: read
steps:
- name: Check out the repo
uses: actions/checkout@v4

- name: Log into container registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY_URL }}
username: ${{ env.REGISTRY_URL == 'ghcr.io' && github.repository_owner || env.REGISTRY_USER }}
password: ${{ env.REGISTRY_URL == 'ghcr.io' && secrets.GITHUB_TOKEN || env.REGISTRY_PASS }}

- name: Extract image name from Dockerfile
id: image_name
run: |
IMAGE=$(grep "LABEL org.opencontainers.image.title" ${{ matrix.dockerfile }} | cut -d'"' -f2)
echo "IMAGE=$IMAGE" >> $GITHUB_OUTPUT
- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@v5
with:
images: |
${{ env.REGISTRY_URL }}/${{ env.REGISTRY_URL == 'ghcr.io' && github.repository_owner || env.REGISTRY_USER }}/${{ steps.image_name.outputs.IMAGE }}
tags: |
type=raw,value=latest,enable=${{ github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master' }}
type=ref,event=branch
type=semver,pattern={{version}}
flavor: |
latest=false
- name: Set up QEMU
uses: docker/setup-qemu-action@v3

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

# TODO: fix tagging
# ! 'manifest unknown' via `docker pull ghcr.io/pythoninthegrass/musicbot:feat-update_docker`
# ! `docker pull ghcr.io/pythoninthegrass/musicbot@sha256:40b2474ed9a12a7276196e1e09956c2b94ddd379ba46c6859ed40740ea41039a` works
# ! annotations also only apply to sha256 -- not 'branch/tag' versions
- name: Build and push Docker image
uses: docker/build-push-action@v6
with:
context: .
file: ./${{ matrix.dockerfile }}
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
platforms: linux/amd64,linux/arm64/v8
cache-from: type=registry,ref=${{ steps.meta.outputs.tags }}
cache-to: type=registry,ref=${{ steps.meta.outputs.tags }},mode=max
outputs: >
type=image,name=${{ steps.meta.outputs.tags }},
annotation-index.org.opencontainers.image.description=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.description'] }}
23 changes: 18 additions & 5 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,14 +1,24 @@
# editor settings
.idea/
.vscode/

# python bytecode
*.pyc

# temp files
~*/
.vscode/

# directories
audio_cache/
dectalk/

discord.log
logs/
data/
media/

# logs
discord.log

# configs
config/options.ini
config/permissions.ini
config/aliases.json
Expand All @@ -20,7 +30,10 @@ config/blacklist.txt
config/blocklist_users.txt
config/blocklist_songs.txt
config/playlists/
media/
config/autoplaylist.cachemap.json

# docker
docker-compose.yml
config/autoplaylist.cachemap.json

# inclusions (has to be declared last)
!**/*.example
12 changes: 12 additions & 0 deletions .hadolint.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
failure-threshold: info # error|warning|info|style|ignore|none

ignored:
- DL3008 # pin versions in apt
- DL3013 # pin versions in pip
- DL3018 # pin versions in apk
- DL3042 # pip --no-cache-dir

trustedRegistries:
- docker.io
- "*.gcr.io"
- localhost:32000
82 changes: 61 additions & 21 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,35 +1,75 @@
FROM python:3.8-alpine
# syntax=docker/dockerfile:1.7.0

# Add project source
WORKDIR /musicbot
COPY . ./
COPY ./config sample_config
# Build stage
FROM python:3.8-alpine3.20 AS builder

# pip env vars
ENV PIP_NO_CACHE_DIR=off
ENV PIP_DISABLE_PIP_VERSION_CHECK=on
ENV PIP_DEFAULT_TIMEOUT=100

# standardise on locale, don't generate .pyc, enable tracebacks on seg faults
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONFAULTHANDLER=1

# set locale
ENV LANG=C.UTF-8
ENV LC_ALL=C.UTF-8

# Install build dependencies
RUN apk update && apk add --no-cache --virtual .build-deps \
build-base \
libffi-dev \
libsodium-dev
RUN apk update && apk add --no-cache \
build-base \
libffi-dev \
libsodium-dev \
git \
&& rm -rf /var/cache/apk/*

WORKDIR /musicbot

# Install dependencies
# Install pip and dependencies
COPY requirements.txt .
RUN python -m pip install --no-cache-dir --upgrade pip \
&& python -m pip install --no-cache-dir -r requirements.txt

# Final stage
FROM python:3.8-alpine3.20 AS runner

# pip env vars
ENV PIP_NO_CACHE_DIR=off
ENV PIP_DISABLE_PIP_VERSION_CHECK=on
ENV PIP_DEFAULT_TIMEOUT=100

# standardise on locale, don't generate .pyc, enable tracebacks on seg faults
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONFAULTHANDLER=1

# set locale
ENV LANG=C.UTF-8
ENV LC_ALL=C.UTF-8

# Install runtime dependencies
RUN apk update && apk add --no-cache \
ca-certificates \
ffmpeg \
opus-dev \
libffi \
libsodium \
gcc \
git
ca-certificates \
ffmpeg \
git \
libffi \
libsodium \
opus-dev \
&& rm -rf /var/cache/apk/*

# Install pip dependencies
RUN pip3 install --no-cache-dir -r requirements.txt
# Copy only necessary files from builder stage
COPY --from=builder /usr/local/lib/python3.8/site-packages /usr/local/lib/python3.8/site-packages
COPY --from=builder /usr/local/bin /usr/local/bin

# Clean up build dependencies
RUN apk del .build-deps
WORKDIR /musicbot
COPY . .
COPY ./config sample_config

# Create volumes for audio cache, config, data and logs
VOLUME ["/musicbot/audio_cache", "/musicbot/config", "/musicbot/data", "/musicbot/logs"]

ENV APP_ENV=docker

ENTRYPOINT ["/bin/sh", "docker-entrypoint.sh"]

LABEL org.opencontainers.image.title="musicbot"
17 changes: 16 additions & 1 deletion docker-compose.example.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,23 @@
services:
musicbot:
build: .
container_name: musicbot
build:
context: .
dockerfile: Dockerfile
hostname: musicbot
platform: ${PLATFORM:-linux/amd64}
env_file:
- .env
volumes:
- ./config:/musicbot/config/
- ./audio_cache:/musicbot/audio_cache
- ./data:/musicbot/data
- ./logs:/musicbot/logs
networks:
- musicbot
working_dir: /musicbot

networks:
musicbot:
name: musicbot
driver: bridge
6 changes: 3 additions & 3 deletions docker-entrypoint.sh
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/bin/sh
#!/usr/bin/env sh

if [[ ! -f "/musicbot/config/example_options.ini" ]]; then
if [ ! -f "/musicbot/config/example_options.ini" ]; then
cp -r /musicbot/sample_config/* /musicbot/config
fi

exec python3 run.py $@
exec python3 run.py "$@"

0 comments on commit 10f5caf

Please sign in to comment.