Netatalk v4.2.0 on a Rootless Docker Install

Submitted by Tom Thorp on Friday, May 2, 2025 - 23:28
Modified on Saturday, May 10, 2025 - 12:07
Netatalk v4.2.0 on Rootless Docker

Here’s a comprehensive knowledgebase article for deploying Netatalk in a rootless Docker container on Fedora 41, covering SELinux, UID/GID mapping, Netatalk configuration, networking/firewall, and macOS Time Machine integration.

Summary

You will configure Fedora 41 for rootless Docker, adjust SELinux volume labels, and map host ↔ container UIDs/GIDs correctly. Then you’ll deploy Netatalk with a custom afp.conf and docker-compose.yml, open AFP ports in firewalld, and optionally enable Avahi for service discovery. Finally, you’ll configure macOS Time Machine to use the AFP share, including creating and troubleshooting sparsebundle images.


Prerequisites

  • A Fedora 41 server with kernel ≥ 5.11 and Podman/Docker rootless support.

  • Your user added to /etc/subuid and /etc/subgid for sub-UID/GID ranges rootlesscontaine.rs.

  • Docker Engine installed in rootless mode (e.g., via dnf install docker-ce --allowerasing) netatalk.io.


1. Rootless Docker & UID/GID Mapping

1.1 Configure SubUID/SubGID

Ensure /etc/subuid and /etc/subgid contain lines like

youruser:100000:65536

This allocates 65 536 subuids/subgids for “youruser,” used by newuidmap/newgidmap rootlesscontaine.rs.

1.2 Understanding UID/GID Mismatch

  • Host UID (e.g., 1000) maps to container root (UID 0).

  • Other container UIDs/GIDs shift by your subuid start.

  • Files created by root in container become owned by your host user Stack Overflow.
     

1.3 Set Rootless Docker to access a restricted port range

As Netatalk uses TCP port 548, Rootless Docker (by default) won't have access to the restricted port. (Restricted port range is 0 - 1024.) To enable Rootless Docker access to the restricted port (TCP port 548), a change needs to be made to the account running the Docker Service. You can set this up using two methods : 

a) Environment variables in your shell

export ROOTLESSKIT_PORT_DRIVER=slirp4netns
export ROOTLESSKIT_PORT_DRIVER_FLAGS="--port-range=548:65535"

You can add these to your ~/.bashrc, ~/.zshrc, or systemd user service (see below) to persist them.

b) Systemd --user Service

Create or edit the override file:

systemctl --user edit docker

Add the following section:

[Service]
Environment=ROOTLESSKIT_PORT_DRIVER=slirp4netns
Environment=ROOTLESSKIT_PORT_DRIVER_FLAGS=--port-range=548:65535

Then reload and restart:

systemctl --user daemon-reexec
systemctl --user restart docker

2. SELinux Compatibility with Docker Volumes

Fedora’s default SELinux policy blocks container access to bind mounts. To allow write access:

services:
  netatalk:
    volumes:
      - ./data:/srv/afp:Z

The :Z flag relabels ./data to container_file_t, permitting read/write prefetch.net.
Alternatively, use :z for shared labels across containers discussion.fedoraproject.org.


3. Deploying Netatalk in Docker

3.1 AFP Configuration (afp.conf)

Create afp.conf in your project:

[Global]
  log file = /var/log/afpd.log
  mimic model = TimeCapsule6,106
  time machine = yes
  time machine max size = 1T
[MyBackup]
  path = /srv/afp/backups
  valid users = tmuser
  time machine alphasize = 64 
 

This tells Netatalk to present a Time Machine–compatible volume netatalk.io.

3.2 Docker Compose Example (docker-compose.yml)

services:
  netatalk:
    image: cptactionhank/netatalk:latest
    user: "${UID}:${GID}"
    network_mode: bridge
    ports:
      - "548:548"
    volumes:
      - ./afp.conf:/etc/netatalk/afp.conf:Z
      - ./backups:/srv/afp/backups:Z
    environment:
      - AFP_USER=tmuser
      - AFP_PASS=StrongPass123
      - AVAHI=1
 
  • user: "${UID}:${GID}" ensures files created by Netatalk are owned by your host user Docker Community Forums.

  • AVAHI=1 enables mDNS service discovery if you prefer not to use host network GitHub.

  • You can also mount a separate CNID SQL backend following the Netatalk Docker docs GitHub.


4. Firewalld Configuration

4.1 Open AFP Port

firewall-cmd --permanent --add-service=afp
firewall-cmd --reload

Or explicitly:

firewall-cmd --permanent --add-port=548/tcp
firewall-cmd --reload

This opens port 548 for AFP traffic The world's open source leaderfirewalld.

4.2 Enable mDNS (if using Avahi)

firewall-cmd --permanent --add-service=mdns
firewall-cmd --reload
 

5. Connecting macOS Time Machine

5.1 Mounting the AFP Share

On your Mac:

  1. Finder > Connect to Server (Cmd+K).

  2. Enter afp://fmhost.local/backups.

  3. Provide tmuser / StrongPass123 and save to Keychain openwrt.org.

5.2 Creating and Managing Sparsebundles

  • macOS will auto-create Backups of YourMac.sparsebundle inside /srv/afp/backups.

  • If you need a custom size:

    hdiutil create -size 500g \
      -fs HFS+J -type SPARSEBUNDLE \
      -volname "Backups of YourMac" \
      /path/to/backups/YourMac.sparsebundle
     
  • Troubleshooting:

    • If you see MachineID.plist missing, delete the old bundle and let Time Machine re-create it netatalk.io.

    • Ensure Keychain Access permissions allow backupd and backupd-helper to read the password.


6. Additional Considerations

  • avahi-daemon: For Zeroconf/mDNS advertisement, ensure AVAHI=1 and open UDP port 5353.

  • Spotlight Indexing: You can mount volumes with -v hostpath:containerpath:Z to allow Netatalk to index via Spotlight.

  • Container Logs: Check /var/log/afpd.log inside container for AFP errors.

  • Resource Limits: Adjust Docker resource quotas if backups are large.

  • Backups over TLS: Netatalk supports TLS encryption; see afp.conf for tls keyfile = ... options.


 

About the author

Tom Thorp
Tom Thorp is an IT Consultant living in Miami on Queensland's Gold Coast. With over 30+ years working in the IT industry, Tom's experience is a broad canvas. The IT services Tom provides to his clients, includes :
 
Website development and hosting
Database Administration
Server Administration (Windows, Linux, Apple)
PABX Hosting and Administration
Helpdesk Support (end-user & technical).
  If you like any of my content, consider a donation via Crypto by clicking on one of the payment methods :
 
Categories

Leave a Comment