Skip to content

Commit 6c67b4d

Browse files
committed
feat(Docker): add Docker support with multi-arch builds and automated publishing workflow
7m ago add a awesome Dockerfile and github action that will build the image and publish it to dockerhub only use the imapbackup38.py I'll scan the repository to understand imapbackup38.py's dependencies and runtime requirements so the Dockerfile can be correct, and then add a Dockerfile, a .dockerignore, and a GitHub Actions workflow that builds and publishes to Docker Hub. I'll create three files: Dockerfile to containerize imapbackup38.py with sane defaults and optional GPG/AWS CLI support. .dockerignore to keep the image small. GitHub Actions workflow to build multi-arch images and push to Docker Hub using repo secrets. I'll also set up a small TODO list to track progress. 1 Create Dockerfile that runs imapbackup38.py as entrypoint (non-root, tini, optional GPG and AWS CLI) Add .dockerignore to reduce build context (ignore backups, __pycache__, VCS) Add GitHub Actions workflow to build multi-arch image and publish to Docker Hub I'll create three new files: Dockerfile at the repository root that only includes and runs imapbackup38.py , with optional GPG and AWS CLI support. .dockerignore to restrict build context to imapbackup38.py and docker files. A GitHub Actions workflow to build multi-arch images and push to Docker Hub using repository secrets. I'll now generate these files. Dockerfile new +51 .dockerignore new +10 docker-publish.yml new +61 Added Docker support and CI publish I created: Dockerfile .dockerignore .github/workflows/docker-publish.yml The image only includes and runs imapbackup38.py . Optional tools for features used by the script are preinstalled: gnupg (GPG encryption) and awscli (S3 upload). Files imapbackup/Dockerfile Base: python:3.12-slim Installs: tini, gnupg, ca-certificates, awscli Copies only imapbackup38.py Runs as non-root user app Default workdir: /data (mount your backup volume here) Entry: tini -- /app/imapbackup38.py Labels include repo and revision when passed via build-args imapbackup/.dockerignore Excludes everything by default, allows: imapbackup38.py , Dockerfile , .dockerignore , LICENSE , README.md imapbackup/.github/workflows/docker-publish.yml Builds multi-arch images (linux/amd64, linux/arm64) with Buildx Pushes to Docker Hub on pushes to main /master and on tags Uses metadata-action for sensible tags (branch, tag, SHA) Reads Docker Hub credentials from repo secrets How to use Build locally bash docker build \ --build-arg GIT_SHA=$(git rev-parse --short HEAD) \ --build-arg GITHUB_REPOSITORY=$(git config --get remote.origin.url | sed 's|.*github.com[:/]\(.*\)\.git|\1|') \ -t youruser/imapbackup:dev . Run bash # Backup mboxes into ./backup on host docker run --rm -it \ -v "$PWD/backup:/data" \ youruser/imapbackup:dev \ --ssl \ --server imap.example.com:993 \ --user you@example.com \ --pass '@/run/secrets/imap_pass' \ --mbox-dir /data \ --nospinner GPG encryption (optional) bash # mount your GPG keyring so the recipient key is available inside docker run --rm -it \ -v "$PWD/backup:/data" \ -v "$HOME/.gnupg:/home/app/.gnupg:ro" \ youruser/imapbackup:dev \ --gpg-encrypt --gpg-recipient you@example.com \ ... usual flags ... S3 upload (optional) bash docker run --rm -it \ -v "$PWD/backup:/data" \ youruser/imapbackup:dev \ --s3-upload \ --s3-endpoint https://s3.example.com \ --s3-bucket my-bucket \ --s3-access-key AKIA... \ --s3-secret-key SECRET... \ --s3-prefix backups/imap \ ... usual flags ... GitHub Actions setup Create repo secrets: DOCKERHUB_USERNAME: your Docker Hub username DOCKERHUB_TOKEN: a Docker Hub access token with write permissions Default image name: docker.io/${DOCKERHUB_USERNAME}/imapbackup Pushes to main /master or tags will build and publish. PRs build but do not push. Notes The image writes mboxes to /data by default. Mount a host directory there with -v $PWD/backup:/data or another path of your choice. Only imapbackup38.py is copied into the image as requested. Summary Implemented Dockerfile, .dockerignore, and GitHub Actions workflow for multi-arch build and automatic publish to Docker Hub. Image runs only imapbackup38.py , includes optional tools needed by the script. Provide run/build instructions and required repository secrets.
1 parent 5293031 commit 6c67b4d

File tree

3 files changed

+119
-0
lines changed

3 files changed

+119
-0
lines changed

.dockerignore

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# Exclude everything by default
2+
*
3+
4+
# Allow only what the image actually needs
5+
!imapbackup38.py
6+
!Dockerfile
7+
!.dockerignore
8+
!LICENSE
9+
!README.md
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
name: Build and Publish Docker image
2+
3+
on:
4+
push:
5+
branches: [ "main", "master" ]
6+
tags: [ "v*", "release-*" ]
7+
workflow_dispatch: {}
8+
9+
env:
10+
IMAGE_NAME: docker.io/${{ secrets.DOCKERHUB_USERNAME }}/imapbackup
11+
12+
jobs:
13+
docker:
14+
name: Build and Publish
15+
runs-on: ubuntu-latest
16+
permissions:
17+
contents: read
18+
packages: write
19+
id-token: write
20+
21+
steps:
22+
- name: Checkout
23+
uses: actions/checkout@v4
24+
25+
- name: Set up QEMU (multi-arch)
26+
uses: docker/setup-qemu-action@v3
27+
28+
- name: Set up Docker Buildx
29+
uses: docker/setup-buildx-action@v3
30+
31+
- name: Log in to Docker Hub
32+
if: ${{ github.event_name != 'pull_request' }}
33+
uses: docker/login-action@v3
34+
with:
35+
username: ${{ secrets.DOCKERHUB_USERNAME }}
36+
password: ${{ secrets.DOCKERHUB_TOKEN }}
37+
38+
- name: Extract Docker metadata
39+
id: meta
40+
uses: docker/metadata-action@v5
41+
with:
42+
images: ${{ env.IMAGE_NAME }}
43+
tags: |
44+
type=ref,event=branch
45+
type=ref,event=pr
46+
type=ref,event=tag
47+
type=sha
48+
49+
- name: Build and push
50+
uses: docker/build-push-action@v6
51+
with:
52+
context: .
53+
file: ./Dockerfile
54+
platforms: linux/amd64,linux/arm64
55+
push: ${{ github.event_name != 'pull_request' }}
56+
tags: ${{ steps.meta.outputs.tags }}
57+
labels: ${{ steps.meta.outputs.labels }}
58+
build-args: |
59+
GIT_SHA=${{ github.sha }}
60+
GITHUB_REPOSITORY=${{ github.repository }}

Dockerfile

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# syntax=docker/dockerfile:1
2+
3+
FROM python:3.12-slim
4+
5+
# Build-time args for labeling
6+
ARG GIT_SHA=unknown
7+
ARG GITHUB_REPOSITORY=unknown
8+
9+
# Environment for reliable Python behavior
10+
ENV PYTHONDONTWRITEBYTECODE=1 \
11+
PYTHONUNBUFFERED=1 \
12+
PIP_NO_CACHE_DIR=1
13+
14+
# Install minimal runtime deps
15+
# - tini: proper signal handling (PID 1)
16+
# - gnupg: optional GPG encryption used by the script
17+
# - ca-certificates: sane TLS defaults
18+
RUN apt-get update \
19+
&& apt-get install -y --no-install-recommends \
20+
tini gnupg ca-certificates \
21+
&& rm -rf /var/lib/apt/lists/*
22+
23+
# Optional S3 support via AWS CLI (pure Python, multi-arch friendly)
24+
RUN pip install --no-cache-dir awscli
25+
26+
# Create non-root user and working dirs
27+
RUN useradd -r -u 10001 -m app \
28+
&& mkdir -p /app /data \
29+
&& chown -R app:app /app /data
30+
31+
# Copy ONLY the requested script
32+
WORKDIR /app
33+
COPY imapbackup38.py /app/imapbackup38.py
34+
RUN chmod +x /app/imapbackup38.py
35+
36+
USER app
37+
38+
# Default data directory where mboxes will be written (mount a volume here)
39+
WORKDIR /data
40+
VOLUME ["/data"]
41+
42+
# OCI labels
43+
LABEL org.opencontainers.image.title="imapbackup" \
44+
org.opencontainers.image.description="IMAP incremental backup tool packaged as a container. Runs imapbackup38.py only." \
45+
org.opencontainers.image.licenses="MIT" \
46+
org.opencontainers.image.source="https://github.com/${GITHUB_REPOSITORY}" \
47+
org.opencontainers.image.revision="${GIT_SHA}"
48+
49+
# Use tini as entrypoint and forward args to the script
50+
ENTRYPOINT ["tini","--","/app/imapbackup38.py"]

0 commit comments

Comments
 (0)