hyperreal.coffee

Archive ProtonMail with offlineimap and Podman

Problem

Solution

Build OCI image for offlineimap

The first thing I did was create a Dockerfile (or, in OCI parlance, a Containerfile).

FROM fedora:latest
LABEL maintainer "Jeffrey Serio <hyperreal@fedoraproject.org>"

RUN printf "fastestmirror=True\ndeltarpm=True\nmax_parallel_downloads=10\n" | tee -a /etc/dnf/dnf.conf \
    && dnf install -y offlineimap python3-distro \
    && dnf clean all \
    && mkdir /{mail,metadata}

CMD ["/usr/bin/offlineimap", "-o", "-u", "basic", "-c", ".offlineimaprc"]

I then built the container image locally:

podman build -t localhost/offlineimap:latest .

Create container with OCI image

Once that was done, I created a container for it. I mapped the offlineimap metadata directory, mail directory, and offlineimaprc as volumes for the container:

podman create -it --name offlineimap \
    -v ~/mail:/mail:Z \
    -v ~/.offlineimap-metadata:/metadata:Z \
    -v ~/.offlineimaprc:/.offlineimaprc:Z \
    localhost/offlineimap:latest

Note that the use of :Z for volumes only applies to SELinux-enabled hosts. On SELinux hosts, when a container starts, it is given an SELinux context on the host. In order for processes inside the container to write to a volume mapped on the host, the volume needs an SELinux context that those processes can access. We get a permission denied error because the volume’s MLS level and the in-container process’s MLS level are different. For more information, see the link below.

Generate the systemd unit file for container

With the container created, I can now run the podman command to generate the systemd unit file.

podman generate systemd --new --name offlineimap --files

The file looks like this:

# container-offlineimap.service
# autogenerated by Podman 4.1.1
# Tue Aug 16 12:45:40 CDT 2022

[Unit]
Description=Podman container-offlineimap.service
Documentation=man:podman-generate-systemd(1)
Wants=network-online.target
After=network-online.target
RequiresMountsFor=%t/containers

[Service]
Environment=PODMAN_SYSTEMD_UNIT=%n
Restart=on-failure
TimeoutStopSec=70
ExecStartPre=/bin/rm -f %t/%n.ctr-id
ExecStart=/usr/bin/podman run \
	--cidfile=%t/%n.ctr-id \
	--cgroups=no-conmon \
	--rm \
	--sdnotify=conmon \
	-d \
	--replace \
	-it \
	--name offlineimap \
	--network host \
	-v /var/home/jas/mail:/mail:Z \
	-v /var/home/jas/.offlineimap-metadata:/metadata:Z \
	-v /var/home/jas/.offlineimaprc:/.offlineimaprc:Z localhost/offlineimap
ExecStop=/usr/bin/podman stop --ignore --cidfile=%t/%n.ctr-id
ExecStopPost=/usr/bin/podman rm -f --ignore --cidfile=%t/%n.ctr-id
Type=notify
NotifyAccess=all

[Install]
WantedBy=default.target

Create and enable systemd timer

Now I have to create a systemd timer for this service:

[Unit]
Description=Run container-offlineimap.service daily at 22:00:00

[Timer]
OnCalendar=*-*-* 22:00:00
Persistent=true

[Install]
WantedBy=timers.target

I move these files to ~/.config/systemd/user, and enable the timer in user mode:

systemctl --user enable --now container-offlineimap.timer

So now, at 10:00 PM every night, the systemd timer will trigger the container-offlineimap.service, which will pull mail from the remote Proton Mail server and store it in the /var/home/jas/mail directory. Yay!

Last updated: 2023-01-11

#Mail   #Offlineimap   #Podman   #Systemd   #Archiving