├── LICENSE ├── README.md ├── commands ├── docker-args ├── install ├── pre-build ├── pre-build-buildstep ├── pre-deploy └── update /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License 2 | 3 | Copyright (c) 2010-2014 Olivier Hardy 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Volume (persistent storage) plugin for Dokku 2 | 3 | Project: https://github.com/progrium/dokku 4 | 5 | ## Installation 6 | 7 | ``` 8 | cd /var/lib/dokku/plugins 9 | git clone https://github.com/ohardy/dokku-volume volume 10 | dokku plugins-install 11 | ``` 12 | 13 | 14 | ## Commands 15 | ``` 16 | $ dokku help 17 | volume:env Get generated environment variables for 18 | volume:add Mount a folder in at 19 | volume:remove Remove folder in at 20 | volume:dump > filename.tar.gz Dump volume data to filename.tar.gz 21 | volume:restore < filename.tar.gz Restore volume data from filename.tar.gz 22 | volume:list Give list of volumes for 23 | volume:update Update this plugin 24 | volume:migrate Migrate 25 | ``` 26 | 27 | ## Updating this plugin 28 | Dokku doesn't handle plugin update. I made a pull request to dokku for that (https://github.com/progrium/dokku/pull/669) 29 | 30 | So, each time you update this plugin with `git pull`, you need to call: 31 | ``` 32 | $ dokku volume:migrate 33 | ``` 34 | 35 | ## Info 36 | This plugin mount container_path to a generated folder in /home/dokku/.o_volume : 37 | 38 | ## Usage 39 | 40 | ### Add volume: 41 | ``` 42 | $ dokku volume:add foo /path/in/container # Server side 43 | ..or.. 44 | $ ssh dokku@server volume:add foo /path/in/container # Client side 45 | 46 | ``` 47 | 48 | ### Remove volume: 49 | ``` 50 | $ dokku volume:remove foo /path/in/container # Server side 51 | ..or.. 52 | $ ssh dokku@server volume:remove foo /path/in/container # Client side 53 | 54 | ``` 55 | 56 | ### Dump volume to tar.gz archive: 57 | ``` 58 | $ dokku volume:dump foo /path/in/container > foo.tar.gz # Server side 59 | ..or.. 60 | $ ssh dokku@server volume:dump foo /path/in/container > foo.tar.gz # Client side 61 | ``` 62 | 63 | ### Restore volume from archive: 64 | ``` 65 | $ dokku volume:restore foo /path/in/container < foo.tar.gz # Server side 66 | ..or.. 67 | $ ssh dokku@server volume:restore foo /path/in/container < foo.tar.gz # Client side 68 | ``` 69 | -------------------------------------------------------------------------------- /commands: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | _path=".o_volume" 4 | version="1.0" 5 | 6 | APP=$2 7 | OLDHOME=$HOME 8 | HOME="$DOKKU_ROOT/$_path" 9 | 10 | uuid() { 11 | cat /proc/sys/kernel/random/uuid 12 | } 13 | 14 | check_exists() { 15 | if [[ ! -f "$HOME/volume_$APP" ]]; then 16 | echo "No database configured with name : $APP" 17 | exit 1 18 | fi 19 | } 20 | 21 | check_app() { 22 | if [[ -z "$APP" ]]; then 23 | echo "You must specify an app name" 24 | exit 1 25 | fi 26 | } 27 | 28 | migrate() { 29 | : 30 | } 31 | 32 | env_for() { 33 | _env="" 34 | if [[ -f "$HOME/volumes_$APP" ]]; then 35 | IFS=$'\n' 36 | file_content=$(cat "$HOME/volumes_$APP") 37 | 38 | for LINE in $file_content; do 39 | _env="$_env -v $LINE" 40 | done 41 | fi 42 | 43 | echo "$_env" 44 | } 45 | 46 | path_for() { 47 | _app=$1 48 | _path_to_search=$2 49 | _path="" 50 | 51 | if [[ -f "$HOME/volumes_$APP" ]]; then 52 | IFS=$'\n' 53 | file_content=$(cat "$HOME/volumes_$APP") 54 | 55 | for LINE in $file_content; do 56 | real_path=$(echo "$LINE" | cut -d : -f 1) 57 | virtual_path=$(echo "$LINE" | cut -d : -f 2) 58 | 59 | if [[ "$_path_to_search" = "$virtual_path" ]]; then 60 | _path=$real_path 61 | break 62 | fi 63 | done 64 | fi 65 | 66 | if [[ -n "$_path" ]]; then 67 | echo "$_path" 68 | fi 69 | } 70 | 71 | restart_app() { 72 | _app=$1 73 | if [[ -n "$_app" ]]&&[[ -d "$DOKKU_ROOT/$_app" ]]; then 74 | echo "-----> Restarting application : $_app" 75 | dokku release $_app 76 | dokku deploy $_app 77 | fi 78 | } 79 | 80 | case "$1" in 81 | volume:add) 82 | check_app 83 | 84 | _container_path=$3 85 | _uuid=$(uuid) 86 | 87 | mkdir -m 777 -p "$HOME/data/$_uuid" 88 | 89 | echo $HOME/data/$_uuid:$_container_path >> "$HOME/volumes_$APP" 90 | 91 | ;; 92 | volume:remove) 93 | check_app 94 | 95 | _container_path=$3 96 | _real_path=$(path_for $APP $_container_path) 97 | 98 | if [[ -f "$HOME/volumes_$APP" ]]; then 99 | if [[ -f "$HOME/_volumes_$APP" ]]; then 100 | rm -f "$HOME/_volumes_$APP" 101 | fi 102 | IFS=$'\n' 103 | file_content=$(cat "$HOME/volumes_$APP") 104 | 105 | for LINE in $file_content; do 106 | real_path=$(echo "$LINE" | cut -d : -f 1) 107 | virtual_path=$(echo "$LINE" | cut -d : -f 2) 108 | 109 | if [[ "$_container_path" != "$virtual_path" ]]; then 110 | echo "$LINE" >> "$HOME/_volumes_$APP" 111 | fi 112 | done 113 | 114 | rm -f "$HOME/volumes_$APP" 115 | if [[ -f "$HOME/_volumes_$APP" ]]; then 116 | mv "$HOME/_volumes_$APP" "$HOME/volumes_$APP" 117 | fi 118 | 119 | rm -rf "$_real_path" 120 | fi 121 | 122 | ;; 123 | volume:list) 124 | check_app 125 | 126 | if [[ -f "$HOME/volumes_$APP" ]]; then 127 | cat "$HOME/volumes_$APP" 128 | fi 129 | ;; 130 | 131 | volume:pre_build) 132 | : 133 | 134 | ;; 135 | 136 | volume:migrate) 137 | migrate 138 | ;; 139 | 140 | volume:env) 141 | env_for $APP 142 | ;; 143 | 144 | volume:path_for) 145 | path_for $APP $3 146 | ;; 147 | 148 | volume:dump) 149 | check_app 150 | 151 | _container_path=$3 152 | _uuid=$(uuid) 153 | _filename="$HOME/dump_$_uuid" 154 | 155 | _real_path=$(path_for $APP $_container_path) 156 | 157 | if [[ -d $_real_path ]]; then 158 | cd $_real_path 159 | tar -zcf $_filename . >/dev/null 2>&1 160 | 161 | cat $_filename 162 | fi 163 | rm -f $_filename 164 | ;; 165 | 166 | volume:restore) 167 | check_app 168 | 169 | _uuid=$(uuid) 170 | _filename="$HOME/restore_$_uuid" 171 | 172 | cat - > $_filename 173 | 174 | _container_path=$3 175 | _real_path=$(path_for $APP $_container_path) 176 | _mimetype=$(file -b --mime-type $_filename) 177 | _temp_folder=$(mktemp -d) 178 | 179 | if [[ "$_mimetype" = "application/x-tar" ]]||[[ "$_mimetype" = "application/gzip" ]]; then 180 | tar -tf $_filename >/dev/null 181 | 182 | if [[ $? -eq 0 ]]; then 183 | tar -xf $_filename --directory=$_temp_folder 184 | else 185 | tar -zxf $_filename --directory=$_temp_folder 186 | fi 187 | else 188 | echo "Restore with file of type $_mimetype unsupported" 189 | fi 190 | 191 | if [[ -d $_real_path ]]&&[[ -d $_temp_folder ]]; then 192 | rm -rf $_real_path 193 | mv $_temp_folder $_real_path 194 | else 195 | rm -rf $_temp_folder 196 | fi 197 | 198 | chmod -R 777 $_real_path 199 | ;; 200 | 201 | volume:install) 202 | if [[ -d "$HOME" ]]; then 203 | migrate 204 | else 205 | mkdir -p "$HOME/data" 206 | 207 | echo "$version" > "$HOME/version" 208 | 209 | chown -R dokku: "$HOME" 210 | fi 211 | ;; 212 | 213 | volume:update) 214 | DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 215 | dokku volume:migrate 216 | ;; 217 | 218 | help) 219 | cat && cat< Get generated environment variables for 221 | volume:add Mount a folder in at 222 | volume:remove Remove folder in at 223 | volume:dump > filename.tar.gz Dump volume data to filename.tar.gz 224 | volume:restore < filename.tar.gz Restore volume data from filename.tar.gz 225 | volume:list Give list of volumes for 226 | volume:update Update this plugin 227 | volume:migrate Migrate 228 | EOF 229 | ;; 230 | *) 231 | exit $DOKKU_NOT_IMPLEMENTED_EXIT 232 | ;; 233 | esac 234 | -------------------------------------------------------------------------------- /docker-args: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x 3 | 4 | STDIN=$(cat) 5 | APP="$1"; PHASE="$2" 6 | 7 | output="" 8 | _env=$(dokku volume:env "$APP") 9 | if [[ $? -eq 0 ]] && [[ "$PHASE" != "build" ]]; then 10 | output="$output $_env" 11 | fi 12 | 13 | echo "$STDIN$output" 14 | -------------------------------------------------------------------------------- /install: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [[ ! -z "$DOKKU_DEV" ]]; then 4 | ./commands volume:install 5 | else 6 | dokku volume:install 7 | fi 8 | -------------------------------------------------------------------------------- /pre-build: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x 3 | 4 | dokku volume:pre_build $1 5 | -------------------------------------------------------------------------------- /pre-build-buildstep: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x 3 | 4 | dokku volume:pre_build $1 5 | -------------------------------------------------------------------------------- /pre-deploy: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x 3 | 4 | dokku volume:pre_build $1 5 | -------------------------------------------------------------------------------- /update: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [[ ! -z "$DOKKU_DEV" ]]; then 4 | ./commands volume:update 5 | else 6 | dokku volume:update 7 | fi 8 | --------------------------------------------------------------------------------