• Stars
    star
    534
  • Rank 83,095 (Top 2 %)
  • Language
    Shell
  • License
    Apache License 2.0
  • Created about 8 years ago
  • Updated 11 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Docker image to run Samba (compatible Time Machine for macOS)

mbentley/timemachine

docker image to run Samba or AFP (netatalk) to provide a compatible Time Machine for MacOS

Image Tags

Multi-arch Tags

The following tags have multi-arch support for amd64, armv7l, and arm64 and will automatically pull the correct tag based on your system's architecture:

latest, smb

Note: The afp tag has been deprecated in terms of new feature updates and is only available for amd64.

Date Specific Tags

The smb tags also have unique manifests that are generated daily. These are in the format smb-YYYYMMDD (e.g. - smb-20210730) and can be viewed on Docker Hub. Each one of these tags will be generated daily and is essentially a point in time snapshot of the smb tag's manifest that you can pin to if you wish. Please note that these tags will remain available on Docker Hub for 6 months and will not receive security fixes. You will need to update to newer tags as they are published in order to get updated images. If you do not care about specific image digests to pin to, I would suggest just using the smb tag.

Explicit Architecture Tags

These tags will explicitly pull the image for the listed architecture and are bit for bit identical to the multi-arch tags images.

amd64

  • latest-smb-amd64, smb-amd64 - SMB image based off of alpine:latest
  • afp, afp-amd64 - AFP image based off of debian:jessie
    • Deprecated but still available; not being regularly built - This image may have unpatched security vulnerabilities

armv7l

  • latest-smb-armv7l, smb-armv7l - SMB image based off of alpine:latest for the armv7l architecture

arm64

  • latest-smb-arm64, smb-arm64 - SMB image based off of alpine:latest for the arm64 architecture

Warning: I would strongly suggest migrating to the SMB image as AFP is being deprecated by Apple and I've found it to be much more stable. I do not plan on adding any new features to the AFP based config and I switched the default image in the latest tag to the SMB variant on October 15, 2020.

To pull this image: docker pull mbentley/timemachine:smb

Example usage for SMB

Example usage with --net=host to allow Avahi discovery; all available environment variables set to their default values:

docker run -d --restart=always \
  --name timemachine \
  --net=host \
  -e ADVERTISED_HOSTNAME="" \
  -e CUSTOM_SMB_CONF="false" \
  -e CUSTOM_USER="false" \
  -e DEBUG_LEVEL="1" \
  -e MIMIC_MODEL="TimeCapsule8,119" \
  -e EXTERNAL_CONF="" \
  -e HIDE_SHARES="no" \
  -e TM_USERNAME="timemachine" \
  -e TM_GROUPNAME="timemachine" \
  -e TM_UID="1000" \
  -e TM_GID="1000" \
  -e PASSWORD="timemachine" \
  -e SET_PERMISSIONS="false" \
  -e SHARE_NAME="TimeMachine" \
  -e SMB_INHERIT_PERMISSIONS="no" \
  -e SMB_NFS_ACES="yes" \
  -e SMB_METADATA="stream" \
  -e SMB_PORT="445" \
  -e SMB_VFS_OBJECTS="acl_xattr fruit streams_xattr" \
  -e VOLUME_SIZE_LIMIT="0" \
  -e WORKGROUP="WORKGROUP" \
  -v /path/on/host/to/backup/to/for/timemachine:/opt/timemachine \
  -v timemachine-var-lib-samba:/var/lib/samba \
  -v timemachine-var-cache-samba:/var/cache/samba \
  -v timemachine-run-samba:/run/samba \
  mbentley/timemachine:smb

Example usage with exposing ports without Avahi discovery; all available environment variables set to their default values:

docker run -d --restart=always \
  --name timemachine \
  --hostname timemachine \
  -p 137:137/udp \
  -p 138:138/udp \
  -p 139:139 \
  -p 445:445 \
  -e ADVERTISED_HOSTNAME="" \
  -e CUSTOM_SMB_CONF="false" \
  -e CUSTOM_USER="false" \
  -e DEBUG_LEVEL="1" \
  -e HIDE_SHARES="no" \
  -e EXTERNAL_CONF="" \
  -e MIMIC_MODEL="TimeCapsule8,119" \
  -e TM_USERNAME="timemachine" \
  -e TM_GROUPNAME="timemachine" \
  -e TM_UID="1000" \
  -e TM_GID="1000" \
  -e PASSWORD="timemachine" \
  -e SET_PERMISSIONS="false" \
  -e SHARE_NAME="TimeMachine" \
  -e SMB_INHERIT_PERMISSIONS="no" \
  -e SMB_NFS_ACES="yes" \
  -e SMB_METADATA="stream" \
  -e SMB_PORT="445" \
  -e SMB_VFS_OBJECTS="acl_xattr fruit streams_xattr" \
  -e VOLUME_SIZE_LIMIT="0" \
  -e WORKGROUP="WORKGROUP" \
  -v /path/on/host/to/backup/to/for/timemachine:/opt/timemachine \
  -v timemachine-var-lib-samba:/var/lib/samba \
  -v timemachine-var-cache-samba:/var/cache/samba \
  -v timemachine-run-samba:/run/samba \
  mbentley/timemachine:smb

Kubernetes support

The images are also compatible with Kubernetes. Checkout timemachine-k3s.yaml as an example for running a TimeMachine backup server on a single-node k3s cluster running (on a Raspberry Pi 4).

Tips for Automatic Discovery w/Avahi

This works best with --net=host so that discovery can be broadcast. Otherwise, you will need to expose the above ports and then you must manually map the share in Finder for it to show up (open Finder, click Shared, and connect as smb://hostname-or-ip/TimeMachine with your TimeMachine credentials). Using --net=host only works if you do not already run Samba or Avahi on the host! Alternatively, you can use the SMB_PORT option to change the port that Samba uses. See below for another workaround if you do not wish to change the Samba port.

Known Issues

Processes fail to start; container has high CPU usage

If the container isn't starting and you're seeing logs like Failed to start message bus: Failed to bind socket, and possibly have other symptoms like seeing high CPU usage from the container, it could be that your are hitting the nofile ulimit. Make sure your compose file or docker run command have the nofile ulimits adjusted to increase the defaults. Check the examples in the README or the example compose files in this repository.

Unable to start the armv7l image

If you are running the armv7l image, you may see and error when trying to start the container:

s6-svscan: warning: unable to iopause: Operation not permitted

This is due to an issue with the libseccomp2 package. You have two options:

  1. Disable seccomp for the container by adding the --security-opt seccomp=unconfined argument (this has security implications)

  2. Install a backported version of libseccomp2:

    wget http://ftp.us.debian.org/debian/pool/main/libs/libseccomp/libseccomp2_2.5.1-1~bpo10+1_armhf.deb
    sudo dpkg -i libseccomp2_2.5.1-1~bpo10+1_armhf.deb
    

This issue has been observed on Raspberry Pi OS (formerly known as Raspbian) based on Debian 10 (Buster) but may also be found on other distros as they may commonly use the libseccomp2 package version 2.3.3-4.

Conflicts with Samba and/or Avahi on the Host

Note: If you are already running Samba/Avahi on your Docker host (or you're wanting to run this on your NAS), you should be aware that using --net=host will cause a conflict with the Samba/Avahi install. Raspberry Pi users: be aware that there is already an mDNS responder running on the stock Raspberry Pi OS image that will conflict with the mDNS responder in the container.

If your host is running Avahi, you can configure it to act as a reflector, and the container advertisements will be broadcast to your host network without using --net=host. To do this, edit the avahi config (/etc/avahi/avahi-daemon.conf) on the host:

Then set the ADVERTISED_HOSTNAME environment variable in your container config to the mDNS hostname of your host, without the .local suffix.

As an alternative, you can use the macvlan driver in Docker which will allow you to map a static IP address to your container. If you have issues setting up Time Machine with the configuration, feel free to open an issue and I can assist - this is how I persoanlly run time machine.

  1. Create a macvlan Docker network (assuming your local subnet is 192.168.1.0/24, the default gateway is 192.168.1.1, and eth0 for the host's network interface):
docker network create -d macvlan --subnet=192.168.1.0/24 --gateway=192.168.1.1 -o parent=eth0 macvlan1

On devices such as Synology DSM, the primary network interface may be ovs_eth0 due to the usage of Open vSwitch. If you are unsure of your primary network interface, this command may help:

$ route | grep ^default | awk '{print $NF}'
eth0

The macvlan driver can use another network interface as the documentation states above but in cases where multiple network interfaces may exist and they might not all be connected, choosing the primary network interface is generally safe.

  1. Add --network macvlan1 and --ip 192.168.1.x to your docker run command where 192.168.1.x is a static IP to assign to Time Machine
Example macvlan setup using docker-compose
services:
  timemachine:
    hostname: timemachine
    mac_address: "AA:BB:CC:DD:EE:FF"
    networks:
      timemachine:
        ipv4_address: 192.168.1.x

networks:
  timemachine:
    driver: macvlan
    driver_opts:
      parent: eth0
    ipam:
      config:
        - subnet: 192.168.1.0/24
          ip_range: 192.168.1.0/24
          gateway: 192.168.1.1
  1. hostname, mac_address, and ipv4_address are optional, but can be used to control how it is configured on the network. If not defined, random values will be used.
  2. This config requires docker-compose version 1.27.0+ which implements the compose specification.

Volume & File system Permissions

If you're using an external volume like in the example above, you will need to set the filesystem permissions on disk. By default, the timemachine user is 1000:1000.

The backing data store for your persistent time machine data must support extended file attributes (xattr). Remote file systems, such as NFS, will very likely not support xattrs. See #61 for more details. This image will check and try to set xattrs to a test file in /opt/${TM_USERNAME} to warn the user if they are not supported but this will not prevent the image from running.

Also note that if you change the TM_USERNAME value that it will change the data path from /opt/timemachine to /opt/<value-of-TM_USERNAME>.

Default credentials:

  • Username: timemachine
  • Password: timemachine

Optional variables for SMB

Variable Default Description
ADVERTISED_HOSTNAME not set Avahi will advertise the smb services at this hostname instead of the local hostname (useful in Docker without --net=host)
CUSTOM_SMB_AUTH no set to yes, indicates that you want Samba to attempt to authenticate users using the NTLM Encrypted Password Response
CUSTOM_SMB_CONF false indicates that you are going to bind mount a custom config to /etc/samba/smb.conf if set to true
CUSTOM_SMB_PROTO SMB2 indicates that you want to allow another value from Samba Protocol List
CUSTOM_USER false indicates that you are going to bind mount /etc/password, /etc/group, and /etc/shadow; and create data directories if set to true
DEBUG_LEVEL 1 sets the debug level for nmbd and smbd
EXTERNAL_CONF not set specifies a directory in which individual variable files, ending in .conf, for multiple users; see Adding Multiple Users & Shares for more info
HIDE_SHARES no set to yes if you would like only the share(s) a user can access to appear
MIMIC_MODEL TimeCapsule8,119 sets the value of time machine to mimic
TM_USERNAME timemachine sets the username time machine runs as
TM_GROUPNAME timemachine sets the group name time machine runs as
TM_UID 1000 sets the UID of the TM_USERNAME user
TM_GID 1000 sets the GID of the TM_GROUPNAME group
PASSWORD timemachine sets the password for the timemachine user
SET_PERMISSIONS false set to true to have the entrypoint set ownership and permission on the /opt/<username> in the container
SHARE_NAME TimeMachine sets the name of the timemachine share to TimeMachine by default
SMB_INHERIT_PERMISSIONS no if yes, permissions for new files will be forced to match the parent folder
SMB_NFS_ACES yes value of fruit:nfs_aces; support for querying and modifying the UNIX mode of directory entries via NFS ACEs
SMB_METADATA stream value of fruit:metadata; controls where the OS X metadata stream is stored
SMB_PORT 445 sets the port that Samba will be available on
SMB_VFS_OBJECTS acl_xattr fruit streams_xattr value of vfs objects
VOLUME_SIZE_LIMIT 0 sets the maximum size of the time machine backup; a unit can also be passed (e.g. - 1 T). See the Samba docs under the fruit:time machine max size section for more details
WORKGROUP WORKGROUP set the Samba workgroup name

Adding Multiple Users & Shares

In order to add multiple users who have their own shares, you will need to create a file for each user and put them in a directory. The file name must end in .conf or it will not be parsed and the contents must be environment variable formatted proper and include all of the values below in the example. Only VOLUME_SIZE_LIMIT can be empty if you do not want to set a quota.

Example EXTERNAL_CONF File

This is an example to create a user named foo. The EXTERNAL_CONF variable should point to the directory that contains the user definition files. Create multiple files with different attributes to create multiple users and shares.

foo.conf

TM_USERNAME=foo
TM_GROUPNAME=foogroup
PASSWORD=foopass
SHARE_NAME=foo
VOLUME_SIZE_LIMIT="1 T"
TM_UID=1000
TM_GID=1000

Example run command for EXTERNAL_CONF

This run command has the necessary path to where the external user files will be mounted (set in EXTERNAL_CONF) and the volume mount that matches the path specified in EXTERNAL_CONF.

Note: You will need to either bind mount /opt or each SHARE_NAME directory under /opt for each user.

docker run -d --restart=always \
  --name timemachine \
  --net=host \
  --ulimit nofile=65536:65536 \
  -e ADVERTISED_HOSTNAME="" \
  -e CUSTOM_SMB_CONF="false" \
  -e CUSTOM_USER="false" \
  -e DEBUG_LEVEL="1" \
  -e MIMIC_MODEL="TimeCapsule8,119" \
  -e EXTERNAL_CONF="/users" \
  -e HIDE_SHARES="no" \
  -e TM_USERNAME="timemachine" \
  -e TM_GROUPNAME="timemachine" \
  -e TM_UID="1000" \
  -e TM_GID="1000" \
  -e PASSWORD="timemachine" \
  -e SET_PERMISSIONS="false" \
  -e SHARE_NAME="TimeMachine" \
  -e SMB_INHERIT_PERMISSIONS="no" \
  -e SMB_NFS_ACES="yes" \
  -e SMB_METADATA="stream" \
  -e SMB_PORT="445" \
  -e SMB_VFS_OBJECTS="acl_xattr fruit streams_xattr" \
  -e VOLUME_SIZE_LIMIT="0" \
  -e WORKGROUP="WORKGROUP" \
  -v /path/on/host/to/backup/to/for/timemachine:/opt \
  -v timemachine-var-lib-samba:/var/lib/samba \
  -v timemachine-var-cache-samba:/var/cache/samba \
  -v timemachine-run-samba:/run/samba \
  -v /path/on/host/to/user/file/directory:/users \
  mbentley/timemachine:smb

Using a password file

This is an example to using Docker secrets to pass the password via a file

password.txt

my_secret_password

Example docker-compose file

The follow example shows the key values required for in your compose file.

version: "3.3" # or greater
services:
  timemachine:
    # ...
    environment:
      - PASSWORD_FILE=/run/secrets/password
      # ...
    secrets:
      - password

secrets:
  password:
    file: ./password.txt

AFP Examples and Variables

Click to expand

Example docker-compose usage for AFP

docker-compose -f timemachine-compose.yml up -d

Example docker run usage for AFP

Example usage with --net=host to allow Avahi discovery to function:

docker run -d --restart=always \
  --net=host \
  --name timemachine \
  -e CUSTOM_AFP_CONF="false" \
  -e CUSTOM_USER="false" \
  -e LOG_LEVEL="info" \
  -e MIMIC_MODEL="TimeCapsule6,106" \
  -e TM_USERNAME="timemachine" \
  -e TM_GROUPNAME="timemachine" \
  -e TM_UID="1000" \
  -e TM_GID="1000" \
  -e PASSWORD="timemachine" \
  -e SET_PERMISSIONS="false" \
  -e SHARE_NAME="TimeMachine" \
  -e VOLUME_SIZE_LIMIT="0" \
  -v /path/on/host/to/backup/to/for/timemachine:/opt/timemachine \
  -v timemachine-netatalk:/var/netatalk \
  -v timemachine-logs:/var/log/supervisor \
  mbentley/timemachine:afp

Example usage with exposing ports without Avahi discovery:

docker run -d --restart=always \
  --name timemachine \
  --hostname timemachine \
  -p 548:548 \
  -p 636:636 \
  -e CUSTOM_AFP_CONF="false" \
  -e CUSTOM_USER="false" \
  -e LOG_LEVEL="info" \
  -e MIMIC_MODEL="TimeCapsule6,106" \
  -e TM_USERNAME="timemachine" \
  -e TM_GROUPNAME="timemachine" \
  -e TM_UID="1000" \
  -e TM_GID="1000" \
  -e PASSWORD="timemachine" \
  -e SET_PERMISSIONS="false" \
  -e SHARE_NAME="TimeMachine" \
  -e VOLUME_SIZE_LIMIT="0" \
  -v /path/on/host/to/backup/to/for/timemachine:/opt/timemachine \
  -v timemachine-netatalk:/var/netatalk \
  -v timemachine-logs:/var/log/supervisor \
  mbentley/timemachine:afp

This works best with --net=host so that discovery can be broadcast. Otherwise, you will need to expose the above ports and then you must manually map the share in Finder for it to show up (open Finder, click Shared, and connect as afp://hostname-or-ip/TimeMachine with your TimeMachine credentials).

Optional variables for AFP:

Variable Default Description
CUSTOM_AFP_CONF false indicates that you are going to bind mount a custom config to /etc/netatalk/afp.conf if set to true
CUSTOM_USER false indicates that you are going to bind mount /etc/password, /etc/group, and /etc/shadow; and create data directories if set to true
LOG_LEVEL info sets the netatalk log level
MIMIC_MODEL TimeCapsule6,106 sets the value of time machine to mimic
TM_USERNAME timemachine sets the username time machine runs as
TM_GROUPNAME timemachine sets the group name time machine runs as
TM_UID 1000 sets the UID of the TM_USERNAME user
TM_GID 1000 sets the GID of the TM_GROUPNAME group
PASSWORD timemachine sets the password for the timemachine user
SET_PERMISSIONS false set to true to have the entrypoint set ownership and permission on /opt/timemachine
SHARE_NAME TimeMachine sets the name of the timemachine share to TimeMachine by default
VOLUME_SIZE_LIMIT 0 sets the maximum size of the time machine backup in MiB (mebibyte)

Thanks for odarriba and arve0 for their examples to start from.

More Repositories

1

docker-omada-controller

Docker image to run TP-Link Omada Controller
Shell
725
star
2

docker-teamspeak

TeamSpeak 3 Server Docker Image
Shell
57
star
3

docker-django-uwsgi-nginx

Shell
47
star
4

dockerfiles

My collection of Dockerfiles
Shell
31
star
5

docker-in-docker

Run one or many Docker daemons inside Docker as containers
Shell
28
star
6

docker-virt-manager

Docker image for virt-manager
Dockerfile
20
star
7

docker-ums

Docker image for Universal Media Server (UMS)
Roff
18
star
8

docker-apt-cacher-ng

Shell
17
star
9

Dockerfile.nanorc

Dockerfile syntax highlighting for nano
13
star
10

docker-kimchi

13
star
11

docker-runtime-user

Example of creating a user at runtime for a dynamic Docker image
Shell
11
star
12

overclockix

A Debian based Live distro for i386 and amd64 based systems customized for overclockers and computer enthusiasts
Shell
7
star
13

docker-devicemapper-setup

Simple script to setup `devicemapper` on CentOS or RHEL for use with Docker
Shell
6
star
14

docker-fsv

Dockerfile
6
star
15

docker-tomcat7

Shell
6
star
16

vmware-view-client

VMware has released a VMware View Client .deb files for i386 but not amd64. The aim of this project is to provide amd64 ready .deb files for Debian and Ubuntu.
JavaScript
5
star
17

docker-grip

grip - Preview GitHub Markdown
Dockerfile
5
star
18

docker-windows-containers-examples

Examples of Dockerfiles for Windows Containers
PowerShell
4
star
19

docker-trustdtr

Easily trust a self-signed SSL certificate for a DTR/registry instance
Shell
4
star
20

docker-tomcat7-oracle

Shell
4
star
21

docker-cowsay

Dockerfile
3
star
22

docker-notary-easy-button

Script that makes it easier to create delegations with the notary CLI and a Docker Trusted Registry (DTR)
Shell
3
star
23

docker-k0s

k0s - Zero Friction Kubernetes
Logos
3
star
24

docker-jenkins

Dockerfile
2
star
25

docker-cs-engine-downloader

Tool to download the DEBs or RPMs for the Docker CS engine for offline installation
2
star
26

docker-healthcheck-demos

Healthcheck Demos for Docker Indy Meetup
Dockerfile
2
star
27

docker-nginx-php5

Docker image for nginx + php5-fpm
Dockerfile
2
star
28

docker-acme.sh

Docker Image for Neilpang/acme.sh - Simplest shell script for LetsEncrypt free Certificate client
Dockerfile
2
star
29

docker-chrome

Docker image to run Google Chrome and other X apps over VNC
Shell
2
star
30

docker-apprise

Docker image for caronc/apprise
Dockerfile
2
star
31

docker-aws-manage-user

Script to add/remove AWS users
Shell
2
star
32

docker-live-build

Shell
2
star
33

docker-tsung

2
star
34

docker-crond

Docker image that uses crond from Alpine Linux
2
star
35

libseccomp2-perf-test

Docker performance test for libseccomp2
Shell
2
star
36

docker-speedtest

Docker image for taganaka/SpeedTest
Dockerfile
2
star
37

solutions-gogs

Pre-populated Gogs Docker image for demos
Shell
1
star
38

docker-app-advisor

Dockerfile for Spring Application Advisor
Dockerfile
1
star
39

docker-s6-example

Simple s6 example for Docker
Shell
1
star
40

docker-figlet

1
star
41

docker-base-alpine

Base images based on the official Alpine images
Dockerfile
1
star
42

docker-minecraft

Docker image for Minecraft Server (Bedrock)
Java
1
star
43

docker-nextcloud-client

Docker image for Nextcloud Client
Shell
1
star
44

docker-discord

Dockerfile
1
star
45

docker-ucp-clear-users

Shell
1
star
46

docker-context-root-example

Context root routing example w/nginx
Makefile
1
star
47

docker-dropbox

Docker image for Dropbox
Shell
1
star
48

docker-php5-fpm

Docker image for php5-fpm
Shell
1
star
49

docker-containerd

Docker image with containerd from Docker, Inc.
Dockerfile
1
star
50

docker-dpinger

Docker image for dpinger
Dockerfile
1
star
51

docker-base-ubuntu

Base images based on the official Ubuntu images
Dockerfile
1
star
52

docker-base-debian

Base images based on the official Debian images
Dockerfile
1
star
53

docker-tomcat-bootstrap

Shell
1
star
54

hostpath-provisioner

fork of MaZderMind/hostpath-provisioner
Go
1
star
55

interlock-demo

Shell
1
star
56

dotnetdemo

Simple .NET Core 2.0 demo application
HTML
1
star
57

docker-youtube-dl

Docker image for youtube-dl
Dockerfile
1
star
58

docker-db_bootstrap

Shell
1
star
59

docker-testssl

Dockerfile
1
star
60

ucp-demos

Docker Compose Demo Applications
1
star
61

aptitude-gui

Debian packaging of Stratus_ss's aptitude-gui application for Overclockix
1
star
62

docker-omada-controller-url

API that returns URLs for the Omada Controller as a simple server response
Shell
1
star
63

docker-postgres-upgrade

Docker image to help with postgres upgrades
Shell
1
star
64

docker-crudini

docker image for crudini (https://github.com/pixelb/crudini)
Shell
1
star
65

docker-bind-tools

Docker image for bind-tools (dig, nslookup, etc)
Dockerfile
1
star
66

docker-rsyslog

Dockerfile
1
star
67

docker-tox

Docker image for tox
Shell
1
star