├── Dockerfile ├── README.md ├── conf └── nginx.conf ├── example_confs ├── lighttpd.sh └── lighttpd │ ├── conf.d │ └── rainloop.conf │ └── lighttpd.conf ├── init_data_folder.sh ├── nginx.run └── rainloop.run /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM jprjr/php-fpm 2 | MAINTAINER John Regan 3 | 4 | USER root 5 | RUN pacman -Syy --noconfirm --quiet > /dev/null 6 | RUN pacman -S --noconfirm --quiet --needed unzip \ 7 | nginx rsync > /dev/null 8 | 9 | RUN sed -i '/^open_basedir/c \ 10 | open_basedir = /usr/share/webapps/rainloop/:/tmp/:/usr/share/pear/:/var/lib/rainloop/' /etc/php/php.ini 11 | 12 | RUN mkdir -p /usr/share/webapps/rainloop && \ 13 | mkdir -p /var/lib/rainloop && \ 14 | cd /usr/share/webapps/rainloop && \ 15 | curl -R -L -O \ 16 | "http://repository.rainloop.net/v1/rainloop-latest.zip" && \ 17 | unzip rainloop-latest.zip && rm rainloop-latest.zip && \ 18 | mv data /usr/share/webapps/rainloop-default-data && \ 19 | ln -s /var/lib/rainloop/data /usr/share/webapps/rainloop/data && \ 20 | chown -R http:http /var/lib/rainloop && \ 21 | chown -R http:http /usr/share/webapps 22 | 23 | RUN mkdir -p /etc/s6/rainloop && \ 24 | ln -s /bin/true /etc/s6/rainloop/finish && \ 25 | mkdir -p /etc/s6/nginx && \ 26 | ln -s /bin/true /etc/s6/nginx/finish 27 | 28 | COPY rainloop.run /etc/s6/rainloop/run 29 | COPY nginx.run /etc/s6/nginx/run 30 | COPY conf/nginx.conf /etc/nginx/nginx.conf 31 | 32 | VOLUME /usr/share/webapps/rainloop 33 | VOLUME /var/lib/rainloop/data 34 | 35 | ENTRYPOINT ["/usr/bin/s6-svscan","/etc/s6"] 36 | CMD [] 37 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # jprjr/rainloop 2 | 3 | This is an Arch Linux-based image with [Rainloop](http://rainloop.net) (a webmail client) installed. 4 | 5 | It's running as a FastCGI app, listening on port 9000. You'll need to run 6 | some kind of proxy, like nginx or lighttpd. I have an example script + config 7 | for running this with lighttpd in this repo. 8 | 9 | 10 | ## Usage 11 | 12 | Rainloop expects the data folder to have a certain layout. I've made a small 13 | script to setup the data folder structure at `/opt/init_data_folder.sh` - 14 | you should only have to do this once. 15 | 16 | ### Build 17 | 18 | ``` 19 | $ docker build -t . 20 | ``` 21 | 22 | ### Run in foreground 23 | ``` 24 | $ docker run -v /path/to/perm/folder:/var/lib/rainloop/data -p 9000 jprjr/rainloop 25 | ``` 26 | 27 | ### Run with built-in NGINX 28 | ``` 29 | $ docker run -e NGINX=1 -d -v /path/to/perm/folder:/var/lib/rainloop/data -p 80 jprjr/rainloop 30 | ``` 31 | 32 | Alternatively, you should be able to use links and data-only containers for 33 | persistence. 34 | 35 | ## Exposed ports 36 | 37 | * 9000 (fastcgi port) 38 | * 80 (optional built-in nginx) 39 | 40 | ## Exposed volumes 41 | 42 | * `/usr/share/webapps/rainloop` (explicitly from the Dockerfile. You'll want your proxy to access this volume using --volumes-from or similar) 43 | * `/var/lib/rainloop/data` 44 | -------------------------------------------------------------------------------- /conf/nginx.conf: -------------------------------------------------------------------------------- 1 | user http; 2 | worker_processes 1; 3 | daemon off; 4 | events { 5 | worker_connections 1024; 6 | } 7 | http { 8 | server_tokens off; 9 | include /etc/nginx/mime.types; 10 | default_type application/octet-stream; 11 | sendfile on; 12 | tcp_nopush on; 13 | keepalive_timeout 65; 14 | gzip on; 15 | gzip_http_version 1.0; 16 | gzip_comp_level 5; 17 | gzip_min_length 256; 18 | gzip_proxied any; 19 | gzip_vary on; 20 | gzip_types 21 | application/atom+xml 22 | application/javascript 23 | application/json 24 | application/rss+xml 25 | application/vnd.ms-fontobject 26 | application/x-font-ttf 27 | application/x-web-app-manifest+json 28 | application/xhtml+xml 29 | application/xml 30 | font/opentype 31 | image/svg+xml 32 | image/x-icon 33 | text/css 34 | text/plain 35 | text/x-component; 36 | 37 | server { 38 | listen 80 default; 39 | root /usr/share/webapps/rainloop; 40 | index index.php; 41 | location ^~ /data { 42 | deny all; 43 | } 44 | location / { 45 | index index.html index.php; 46 | } 47 | location ~ \.php$ { 48 | fastcgi_pass 127.0.0.1:9000; 49 | fastcgi_index index.php; 50 | fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; 51 | fastcgi_param QUERY_STRING $query_string; 52 | fastcgi_param REQUEST_METHOD $request_method; 53 | fastcgi_param CONTENT_TYPE $content_type; 54 | fastcgi_param CONTENT_LENGTH $content_length; 55 | 56 | fastcgi_param SCRIPT_NAME $fastcgi_script_name; 57 | fastcgi_param REQUEST_URI $request_uri; 58 | fastcgi_param DOCUMENT_URI $document_uri; 59 | fastcgi_param DOCUMENT_ROOT $document_root; 60 | fastcgi_param SERVER_PROTOCOL $server_protocol; 61 | fastcgi_param HTTPS $https if_not_empty; 62 | 63 | fastcgi_param GATEWAY_INTERFACE CGI/1.1; 64 | fastcgi_param SERVER_SOFTWARE nginx/$nginx_version; 65 | 66 | fastcgi_param REMOTE_ADDR $remote_addr; 67 | fastcgi_param REMOTE_PORT $remote_port; 68 | fastcgi_param SERVER_ADDR $server_addr; 69 | fastcgi_param SERVER_PORT $server_port; 70 | fastcgi_param SERVER_NAME $server_name; 71 | 72 | # PHP only, required if PHP was built with --enable-force-cgi-redirect 73 | fastcgi_param REDIRECT_STATUS 200; 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /example_confs/lighttpd.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Do a bunch of crazy stuff to figure out where this script is 4 | abspath_portable() { 5 | [[ $1 = /* ]] && echo "$1" || echo "$PWD/${1#./}" 6 | } 7 | 8 | abs_path=$(abspath_portable "$0") 9 | script_dir=$(dirname "${abs_path}") 10 | script_abs_path=$(readlink "${abs_path}" || echo "${abs_path}") 11 | script_abs_dir=$(cd "$(dirname "${script_abs_path}")" && pwd -P) 12 | 13 | docker run -d --name rainloop_li jprjr/rainloop 14 | docker run -d -v "${script_abs_dir}"/lighttpd:/etc/lighttpd --link rainloop_li:rainloop --volumes-from rainloop_li -p 80:80 jprjr/lighttpd 15 | -------------------------------------------------------------------------------- /example_confs/lighttpd/conf.d/rainloop.conf: -------------------------------------------------------------------------------- 1 | server.modules += ( "mod_fastcgi", 2 | "mod_access", 3 | "mod_rewrite" ) 4 | 5 | index-file.names += ( "index.php" ) 6 | 7 | fastcgi.server = ( 8 | ".php" => ( 9 | "fastcgi-server" => ( 10 | "host" => env.RAINLOOP_PORT_9000_TCP_ADDR, 11 | "port" => env.RAINLOOP_PORT_9000_TCP_PORT, 12 | "broken-scriptfilename" => "enable", 13 | ) 14 | ) 15 | ) 16 | 17 | $HTTP["url"] =~ "^/data/" { 18 | url.access-deny = ("") 19 | } 20 | 21 | -------------------------------------------------------------------------------- /example_confs/lighttpd/lighttpd.conf: -------------------------------------------------------------------------------- 1 | # This is a minimal example config 2 | # See /usr/share/doc/lighttpd 3 | # and http://redmine.lighttpd.net/projects/lighttpd/wiki/Docs:ConfigurationOptions 4 | 5 | server.port = 80 6 | server.username = "http" 7 | server.groupname = "http" 8 | server.document-root = "/usr/share/webapps/rainloop" 9 | server.errorlog = "/dev/null" 10 | dir-listing.activate = "enable" 11 | index-file.names = ( "index.html" ) 12 | mimetype.assign = ( 13 | ".html" => "text/html", 14 | ".txt" => "text/plain", 15 | ".css" => "text/css", 16 | ".js" => "application/x-javascript", 17 | ".jpg" => "image/jpeg", 18 | ".jpeg" => "image/jpeg", 19 | ".gif" => "image/gif", 20 | ".png" => "image/png", 21 | "" => "application/octet-stream" 22 | ) 23 | include "conf.d/rainloop.conf" 24 | -------------------------------------------------------------------------------- /init_data_folder.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | rsync -av /usr/share/webapps/rainloop-default-data/ /var/lib/rainloop/data/ 4 | -------------------------------------------------------------------------------- /nginx.run: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | declare NGINX 4 | 5 | if [[ $NGINX -eq 1 ]]; then 6 | exec nginx -c /etc/nginx/nginx.conf 7 | fi 8 | 9 | touch down 10 | s6-svc -d /etc/s6/nginx 11 | exit 0 12 | -------------------------------------------------------------------------------- /rainloop.run: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | mkdir -p /var/lib/rainloop/data 4 | 5 | shopt -s nullglob 6 | shopt -s dotglob 7 | 8 | declare need_setup_rainloop 9 | 10 | rainloop_files=(/var/lib/rainloop/data/*) 11 | (( ${#rainloop_files[*]} )) && need_setup_rainloop=0 || need_setup_rainloop=1 12 | 13 | shopt -u nullglob 14 | shopt -u dotglob 15 | 16 | if [[ $need_setup_rainloop -eq 1 ]]; then 17 | rsync -av /usr/share/webapps/rainloop-default-data/ /var/lib/rainloop/data/ 18 | fi 19 | 20 | exec s6-setuidgid http php-fpm -F 21 | --------------------------------------------------------------------------------