13

I would like to run Dropbox inside Docker container. This way I could sync data with docker by uploading it to Dropbox. And also maintain data backup, that will be useful when running new versions of docker images.

Created this simple Dockerfile

FROM phusion/baseimage:0.9.15

#Install wget
RUN apt-get update && \
    apt-get -f install && \
    apt-get install -y wget

#Install Dropbox
RUN mkdir /usr/local/dropbox && \
    cd /usr/local/dropbox && \
    wget -O - "https://www.dropbox.com/download?plat=lnx.x86_64" | tar xzf -

RUN mkdir /etc/service/dropbox
ADD ./dropbox.sh /etc/service/dropbox/run

# Clean up APT when done.
RUN apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

# Use baseimage-docker's init system.
CMD ["/sbin/my_init"]

And service file dropbox.sh

#!/bin/sh
exec /usr/local/dropbox/.dropbox-dist/dropboxd

After building and running Docker image, Dropbox says: This computer isn't linked to any Dropbox account...

and provides link to associate Dropbox account with current computer. After linking, I see a welcome message and data is syncyd inside /root/Dropbox folder.

I commit docker changes

sudo docker commit `sudo docker ps -l -q` imagename

But when killing docker container and running it again Dropbox insists: This computer isn't linked to any Dropbox account...

I confirm that inside container, folder /root/Dropbox exists, and data is there, synced during previous container execution. But my container lost link to Dropbox, and needs to be linked again.

What am I missing? How to persist Dropbox-Docker_container link between container executions?

user606621
  • 493
  • 1
  • 5
  • 16

3 Answers3

8

Having built and run your Dockerfile, the first issue I encountered was runit complaining about missing permissions. You need to add RUN chmod +x /etc/service/dropbox/run after copying the service script.

Researching what changes between restarts, I have found that /root/.dropbox/instance1/hostkeys and /root/.dropbox/instance_db/hostkeys changes. This may be related to the Phusion image you use, though I wouldn't know why exactly. My guess is that it's because you're running dropboxd via exec (therefore not using Bash), every time you run it (= starting the container), there's no user home folder visible to the process from where to get the previous configuration. Possibly, leaving exec out of the service script fixes that.

However, you can slim down the whole process (and the image) with this example Dockerfile I whipped up:

FROM debian:wheezy

RUN \
  apt-get update && \
  apt-get upgrade -y

ADD https://www.dropbox.com/download?plat=lnx.x86_64 /dropbox.tar.gz
RUN tar xfvz /dropbox.tar.gz && rm /dropbox.tar.gz

RUN apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

VOLUME ["/Dropbox"]

CMD /.dropbox-dist/dropboxd

Just run it one time like so: docker -t -h <HOSTNAME> --name dropbox-auth my-dropbox-image. Copy the auth link and Ctrl-C when Dropbox is linked. <HOSTNAME> can be a more descriptive title so you can more easily spot it in the security settings in your Dropbox account.

Commit: docker commit dropbox-auth dropbox

Afterwards just run it: docker run -d --name my-dropbox-container dropbox

As Dropbox stores information about itself in the Dropbox main folder, you cannot change that. You can however use the -v flag (see here) in all the steps above to link to a local folder (outside of the container). This will work 100% on Linux, on Mac OS X it's kind of "sometimes it works and sometimes it doesn't".

Depending on your reason for wanting to run Dropbox inside of a container, the -v flag (by linking a host folder with a container folder) may be exactly what you're looking for, possibly rendering the Dropbox setup unneeded.

Bonus hint: if you want to access a shell within the running container, from Docker 1.3 onwards you don't need SSH anymore. You can just use docker exec -it <CONTAINER> /bin/bash to archive the same goal.

herrbischoff
  • 3,294
  • 1
  • 29
  • 50
2

I managed to get dropboxd working inside a docker container managed in a CoreOS cluster under fleetctl by storing the /root/.dropbox directory on a glusterfs mountpoint. In this way, I can sync the entire Dropbox folder inside the container, then use rsync to copy only the .png and .txt files that I want outside of the container, resetting the ownership and permissions in the process.

The key to this, as alluded to by @herrbischoff, is to present it using the -v option to docker:

docker run -i -t --entrypoint=/bin/bash \
  -v /mnt/static/.dropbox:/root/.dropbox \
  -v /mnt/static/incoming:/incoming \
  -h static_hostname imagename

Then start dropboxd from inside the container and link it to your Dropbox account. This only needs to be done once. After that (assuming your start scripts work), you start it from a fleetd unit service so any machine in the cluster can start it up in detached mode and dropboxd will start sync automatically.

root@hs_dropbox_1001:/# ps -ef f
UID        PID  PPID  C STIME TTY      STAT   TIME CMD
root         1     0  0 04:57 ?        Ss     0:00 runsvdir -P /etc/service log: ....................
root         6     1  0 04:57 ?        Ss     0:00 runsv dropboxd
root         8     6  4 04:57 ?        Sl     1:19  \_ /.dropbox-dist/dropbox-lnx.x86_64-3.2.4/dropbox
root         7     1  0 04:57 ?        Ss     0:00 runsv rsync
root         9     7  0 04:57 ?        S      0:00  \_ /bin/bash ./run
root       664     9  0 05:24 ?        S      0:00      \_ sleep 10

I use runit to start both dropboxd and a simple shell script that calls rsync every 10 seconds.

#!/bin/bash

while :
do
    sleep 10
    # Safety First: only copy the png and txt files (and directories)
    # out of the container to avoid malware
    rsync --delete-after --chmod='Dug=rwx,Do=rx,Fug=rw,Fo=r' \
        --numeric-ids --owner --group --chown='1000:1000' \
        --include='+ */' --include='+ **.png' --include='+ **.txt' --exclude='- *' \
        -ltsr /root/Dropbox/ /mnt/static/incoming
done
Waddles
  • 197
  • 1
  • 5
0

Two existing project include:

You can learn from their approach or just use them.

Hagai Drory
  • 141
  • 1
  • 5