├── .env ├── docker-compose.yml ├── Dockerfile ├── README.md └── docker-entrypoint.sh /.env: -------------------------------------------------------------------------------- 1 | COMPOSE_PROJECT_NAME=cdash 2 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3.3' 2 | services: 3 | cdash: 4 | image: "kitware/cdash-docker" 5 | build: . 6 | depends_on: 7 | - mysql 8 | links: 9 | - mysql 10 | ports: 11 | - "8080:80" 12 | environment: 13 | CDASH_ROOT_ADMIN_PASS: secret 14 | 15 | CDASH_CONFIG: | 16 | $$CDASH_DB_HOST = 'mysql'; 17 | $$CDASH_DB_NAME = 'cdash'; 18 | $$CDASH_DB_TYPE = 'mysql'; 19 | $$CDASH_DB_LOGIN = 'root'; 20 | $$CDASH_DB_PORT = ''; 21 | $$CDASH_DB_PASS = ''; 22 | $$CDASH_DB_CONNECTION_TYPE = 'host'; 23 | 24 | CDASH_STATIC_USERS: | 25 | USER jdoe@acme.com jdoe_secret 26 | John Doe "ACME Inc." 27 | 28 | ADMIN admin@example.org admin_secret 29 | Admin User "Example Foundation" 30 | 31 | donotreply@example.org oldsecret newsecret 32 | 33 | strange.name@gmail.com strange_secret 34 | INFO Str@nge N@me "Str@nge Rese@rch Gr0up LLC." 35 | 36 | DELETE remove.this.user@example.org delete_secret 37 | 38 | mysql: 39 | image: "mysql/mysql-server:5.5" 40 | environment: 41 | MYSQL_ALLOW_EMPTY_PASSWORD: 'yes' 42 | MYSQL_ROOT_PASSWORD: '' 43 | MYSQL_DATABASE: 'cdash' 44 | MYSQL_ROOT_HOST: '%' 45 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM php:7.0-apache 2 | 3 | LABEL maintainer="Omar Padron " 4 | 5 | RUN curl -sL https://deb.nodesource.com/setup_6.x | bash \ 6 | && apt-get install -y git libbz2-dev libfreetype6-dev libjpeg62-turbo-dev \ 7 | libmcrypt-dev libpng12-dev libpq-dev libxslt-dev libxss1 nodejs unzip wget \ 8 | zip \ 9 | && docker-php-ext-configure pgsql --with-pgsql=/usr/local/pgsql \ 10 | && docker-php-ext-configure gd --with-freetype-dir=/usr/include/ \ 11 | --with-jpeg-dir=/usr/include/ \ 12 | && docker-php-ext-install -j$(nproc) bcmath bz2 gd pdo_mysql pdo_pgsql xsl \ 13 | && pecl install xdebug-2.5.5 \ 14 | && docker-php-ext-enable xdebug \ 15 | && ( \ 16 | echo '544e09ee 996cdf60 ece3804a bc52599c' \ 17 | ; echo '22b1f40f 4323403c 44d44fdf dd586475' \ 18 | ; echo 'ca9813a8 58088ffb c1f233e9 b180f061' \ 19 | ) | tr -d "\\n " | sed 's/$/ -/g' > checksum \ 20 | && curl -o - 'https://getcomposer.org/installer' \ 21 | | tee composer-setup.php \ 22 | | sha384sum -c checksum \ 23 | && rm checksum \ 24 | || ( rm -f checksum composer-setup.php && false ) \ 25 | && php composer-setup.php --install-dir=/usr/local/bin --filename=composer \ 26 | && php -r "unlink('composer-setup.php');" \ 27 | && composer self-update --no-interaction 28 | 29 | RUN mkdir -p /var/www \ 30 | && git clone git://github.com/kitware/cdash /var/www/cdash \ 31 | && rm -rf /var/www/cdash/.git \ 32 | && cd /var/www/cdash \ 33 | && composer install --no-interaction --no-progress --prefer-dist \ 34 | && npm install \ 35 | && node_modules/.bin/gulp \ 36 | && chmod 777 backup log public/rss public/upload \ 37 | && rm -rf /var/www/html \ 38 | && ln -s /var/www/cdash/public /var/www/html 39 | 40 | COPY docker-entrypoint.sh /docker-entrypoint.sh 41 | RUN chmod +x /docker-entrypoint.sh 42 | 43 | WORKDIR /var/www/cdash 44 | EXPOSE 80 45 | 46 | HEALTHCHECK --interval=30s --timeout=5s --start-period=5m \ 47 | CMD ["curl", "-f", "http://localhost/viewProjects.php"] 48 | 49 | ENTRYPOINT ["/bin/bash", "/docker-entrypoint.sh"] 50 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # cdash-docker 2 | Deploy a cdash instance with docker and zero guess work! 3 | 4 | ## How? 5 | 6 | Build with docker: 7 | 8 | ```bash 9 | docker build -t "kitware/cdash-docker" . 10 | ``` 11 | 12 | ...or build with docker-compose 13 | 14 | ```bash 15 | docker-compose build 16 | ``` 17 | 18 | ## Deploy example application using docker-compose 19 | 20 | See `docker-compose.yml` for an example of how to deploy using the 21 | `cdash-docker` image. Add your own customizations, or deploy the example as-is! 22 | 23 | ```bash 24 | docker-compose up -d 25 | ``` 26 | 27 | Check on your instance's status: 28 | 29 | ```bash 30 | docker-compose ps 31 | ``` 32 | 33 | Once docker reports that cdash is "healthy", you're good to go! Browse your 34 | cdash instance at `localhost:8080`. 35 | 36 | ## Container Variables 37 | 38 | ### `CDASH_CONFIG` 39 | 40 | The contents, verbatim, to be included in the local CDash configuration file 41 | (`/var/www/cdash/config/config.local.php`), excluding the initial ` /dev/null ; do 41 | result="$tmpdir/sessions/$RANDOM" 42 | done 43 | echo "$result" 44 | } 45 | 46 | ajax() { 47 | local method 48 | local session 49 | local route 50 | local curl_args 51 | local arg 52 | 53 | method="$1" ; shift 54 | session="$1" ; shift 55 | route="$1" ; shift 56 | 57 | if [ "$method" '=' 'POST' ] ; then 58 | for arg in "$@" ; do 59 | curl_args="$curl_args --form '$arg'" 60 | done 61 | fi 62 | 63 | local oldcookies 64 | local newcookies 65 | 66 | oldcookies="$session/cookies.txt" 67 | newcookies="$session/cookies.tmp" 68 | 69 | if [ "$session" '!=' '-' ] ; then 70 | if [ -f "$oldcookies" ] ; then 71 | curl_args="$curl_args --cookie '$oldcookies'" 72 | fi 73 | curl_args="$curl_args --cookie-jar '$newcookies'" 74 | fi 75 | 76 | local port="$PORT" 77 | if [ -n "$port" ] ; then 78 | port=":$port" 79 | fi 80 | 81 | curl_args="$curl_args 'http://localhost${port}/$route" 82 | 83 | if [ "$method" '=' 'GET' ] ; then 84 | arg="$1" ; shift 85 | if [ -n "$arg" ] ; then 86 | curl_args="${curl_args}?$arg" 87 | fi 88 | 89 | for arg in "$@" ; do 90 | curl_args="${curl_args}&$arg" 91 | done 92 | fi 93 | 94 | curl_args="${curl_args}'" 95 | 96 | eval "curl $curl_args" 2>&- 97 | 98 | if [ "$session" '!=' '-' ] ; then 99 | if [ -f "$newcookies" ] ; then 100 | mv "$newcookies" "$oldcookies" 101 | fi 102 | fi 103 | 104 | sleep 0.2 105 | } 106 | 107 | get() { 108 | ajax GET "$@" 109 | } 110 | 111 | post() { 112 | ajax POST "$@" 113 | } 114 | 115 | user_prefix="__user" 116 | user_set() { 117 | email="$1" ; shift 118 | key="$1" ; shift 119 | value="$1" ; shift 120 | email_hash="$( echo "$email" | sha1sum | cut -d\ -f 1 )" 121 | eval "${user_prefix}_${email_hash}_${key}=\"${value}\"" 122 | } 123 | 124 | user_get() { 125 | email="$1" ; shift 126 | key="$1" ; shift 127 | email_hash="$( echo "$email" | sha1sum | cut -d\ -f 1 )" 128 | eval "echo \"\$${user_prefix}_${email_hash}_${key}\"" 129 | } 130 | 131 | DEBUG() { 132 | if [ -n "$DEBUG" ] ; then 133 | echo -n "DEBUG:: " 134 | echo "$@" 135 | fi 136 | } 137 | 138 | if [ -z "$CDASH_ROOT_ADMIN_PASS" ] ; then 139 | cat << ____EOF 140 | error: This container requires the CDASH_ROOT_ADMIN_PASS 141 | environment variable to be defined. 142 | ____EOF 143 | exit 1 144 | fi 1>&2 145 | 146 | local_config_file="/var/www/cdash/config/config.local.php" 147 | 148 | ( 149 | echo ' "$local_config_file" 154 | 155 | PORT="$(( (RANDOM % 20000) + 10000 ))" 156 | sed -i 's/^Listen [0-9][0-9]*/Listen '"$PORT"'/g' /etc/apache2/ports.conf 157 | sed -i 's/^//g' \ 158 | /etc/apache2/sites-enabled/000-default.conf 159 | echo "\$CDASH_FULL_EMAIL_WHEN_ADDING_USER = '1';" >> "$local_config_file" 160 | 161 | /usr/sbin/apache2ctl -D FOREGROUND & 162 | apache_pid="$!" 163 | onexit ' 164 | if [ -n "$apache_pid" ] ; then 165 | /usr/sbin/apache2ctl graceful-stop 166 | wait 167 | fi' 168 | 169 | sleep 10 170 | 171 | # ENSURE ROOT ADMIN USER 172 | final_root_pass="$CDASH_ROOT_ADMIN_PASS" 173 | if [ -n "$CDASH_ROOT_ADMIN_NEW_PASS" ] ; then 174 | final_root_pass="$CDASH_ROOT_ADMIN_NEW_PASS" 175 | fi 176 | 177 | post - install.php admin_email='rootadmin@docker.container' \ 178 | admin_password="$final_root_pass" \ 179 | Submit=Install &> /dev/null 180 | 181 | if [ -n "$CDASH_ROOT_ADMIN_NEW_PASS" ] ; then 182 | root_session="$( mksession )" 183 | post "$root_session" user.php login='rootadmin@docker.container' \ 184 | passwd="$final_root_pass" \ 185 | sent='Login >>' \ 186 | | grep 'Wrong email or password' \ 187 | | ( read X ; DEBUG "|$X|" ; [ -z "$X" ] ) 188 | 189 | if [ "$?" '!=' '0' -a \ 190 | "$CDASH_ROOT_ADMIN_PASS" '!=' "$final_root_pass" ] ; then 191 | 192 | # login failure 193 | post "$root_session" user.php login='rootadmin@docker.container' \ 194 | passwd="$CDASH_ROOT_ADMIN_PASS" \ 195 | sent='Login >>' \ 196 | | grep 'Wrong email or password' \ 197 | | ( read X ; DEBUG "|$X|" ; [ -z "$X" ] ) 198 | 199 | if [ "$?" '=' '0' ] ; then 200 | post "$root_session" editUser.php \ 201 | oldpasswd="$CDASH_ROOT_ADMIN_PASS" \ 202 | passwd="$final_root_pass" \ 203 | passwd2="$final_root_pass" \ 204 | updatepassword='Update Password' &> /dev/null 205 | else 206 | echo "Warning: could not log in as the root admin user:" \ 207 | "Wrong email or password" >&2 208 | root_login_failed=1 209 | fi 210 | fi 211 | fi 212 | 213 | if [ "$root_login_failed" '!=' '1' ] ; then 214 | declare -a users_list 215 | if [ '!' -z ${CDASH_STATIC_USERS+x} ] ; then 216 | ensure_tmp 217 | mkfifo "$tmpdir/fifo" 218 | eval "exec 3<>$tmpdir/fifo" 219 | unlink "$tmpdir/fifo" 220 | 221 | echo "$CDASH_STATIC_USERS" >&3 222 | echo EOF >&3 223 | 224 | oldifs="$IFS" 225 | IFS=$'\n' 226 | 227 | while read -u 3 line ; do 228 | processed_line="$( echo "$line" | 229 | sed $'s/\t\t*/ /g' | sed 's/ */ /g' | sed 's/#.*//g')" 230 | 231 | if [ "$processed_line" '=' 'EOF' ] ; then 232 | break 233 | fi 234 | 235 | if [ -z "$( echo "$processed_line" | sed $'s/[ \t]*//g' )" ] ; then 236 | DEBUG "SKIPPING LINE" 237 | DEBUG "[$line]" 238 | continue 239 | fi 240 | 241 | eval "entry=($processed_line)" 242 | _disp= 243 | _email= 244 | _pass= 245 | _newpass= 246 | 247 | if [ "${entry[0]}" '=' 'USER' -o \ 248 | "${entry[0]}" '=' 'ADMIN' -o \ 249 | "${entry[0]}" '=' 'DELETE' ] ; then 250 | 251 | # explicit user entry line 252 | _disp="${entry[0]}" 253 | _email="${entry[1]}" 254 | _pass="${entry[2]}" 255 | _newpass="${entry[3]}" 256 | parsed_user=1 257 | 258 | elif [ "${entry[0]}" '!=' "${entry[0]/@*}" ] ; then 259 | # implicit user entry line 260 | _disp=USER 261 | _email="${entry[0]}" 262 | _pass="${entry[1]}" 263 | _newpass="${entry[2]}" 264 | parsed_user=1 265 | 266 | elif [ "${entry[0]}" '=' 'INFO' ] ; then 267 | # explicit user info line 268 | first="${entry[1]}" 269 | last="${entry[2]}" 270 | institution="${entry[3]}" 271 | parsed_user=0 272 | 273 | else 274 | # implicit user info line 275 | first="${entry[0]}" 276 | last="${entry[1]}" 277 | institution="${entry[2]}" 278 | parsed_user=0 279 | fi 280 | 281 | if [ -n "$email" ] ; then 282 | user_set "$email" disp "$disp" 283 | user_set "$email" pass "$pass" 284 | user_set "$email" newpass "$newpass" 285 | 286 | if [ "$parsed_user" '=' '0' ] ; then 287 | user_set "$email" first "$first" 288 | user_set "$email" last "$last" 289 | user_set "$email" institution "$institution" 290 | fi 291 | 292 | if [ "$( user_get "$email" listed )" '!=' 1 ] ; then 293 | users_list[${#users_list[@]}]="$email" 294 | user_set "$email" listed 1 295 | fi 296 | fi 297 | 298 | email="$_email" 299 | disp="$_disp" 300 | pass="$_pass" 301 | newpass="$_newpass" 302 | 303 | if [ -n "$DEBUG" ] ; then 304 | if [ "$parsed_user" '=' '0' ] ; then 305 | DEBUG "PARSED USER INFO" 306 | DEBUG " First Name: |$first|" 307 | DEBUG " Last Name: |$last|" 308 | DEBUG " Institution: |$institution|" 309 | else 310 | DEBUG "PARSED USER ENTRY" 311 | DEBUG " email: |$email|" 312 | DEBUG " disposition: |$disp|" 313 | DEBUG " password: |$pass|" 314 | DEBUG " new password: |$newpass|" 315 | fi 316 | fi 317 | done 318 | 319 | if [ -n "$email" ] ; then 320 | user_set "$email" disp "$disp" 321 | user_set "$email" pass "$pass" 322 | user_set "$email" newpass "$newpass" 323 | 324 | if [ "$( user_get "$email" listed )" '!=' 1 ] ; then 325 | users_list[${#users_list[@]}]="$email" 326 | user_set "$email" listed 1 327 | fi 328 | fi 329 | 330 | exec 3<&- 331 | IFS="$oldifs" 332 | fi 333 | 334 | DEBUG "BEGIN DUMP OF USER TABLE" 335 | if [ -n "$DEBUG" ] ; then 336 | for (( i=0; i < ${#users_list[@]} ; ++i )) ; do 337 | email="${users_list[$i]}" 338 | 339 | for tuple in "disp" "pass" "newpass" "first:NONE" \ 340 | "last:NONE" "institution:NONE" ; do 341 | fragment="${tuple/:*}" 342 | tuple="${tuple:$(( ${#fragment} + 1 ))}" 343 | param="$fragment" 344 | fragment="${tuple/:*}" 345 | tuple="${tuple:$(( ${#fragment} + 1 ))}" 346 | default="$fragment" 347 | 348 | value="$( user_get "$email" "$param" )" 349 | if [ -z "$value" -a -n "$default" ] ; then 350 | value="$default" 351 | fi 352 | eval "${param}=\"$value\"" 353 | done 354 | DEBUG "$i:" 355 | DEBUG " $email" 356 | DEBUG " disposition: $disp" 357 | DEBUG " password: $pass" 358 | DEBUG " new pass: $newpass" 359 | DEBUG " First Name: $first" 360 | DEBUG " Last Name: $last" 361 | DEBUG " Institution: $institution" 362 | done 363 | fi 364 | 365 | for (( i=0; i < ${#users_list[@]} ; ++i )) ; do 366 | email="${users_list[$i]}" 367 | if [ "$email" '=' 'rootadmin@docker.conatiner' ] ; then 368 | echo 'Warning: refusing to modify the root admin account!' \ 369 | "Use the CDASH_ROOT_ADMIN_NEW_PASS environment variable" \ 370 | "to update the root account password." >&2 371 | continue 372 | fi 373 | 374 | if [ -z "$root_session" ] ; then 375 | root_session="$( mksession )" 376 | 377 | # LOGIN AS ROOT ADMIN USER 378 | post "$root_session" user.php \ 379 | login='rootadmin@docker.container' \ 380 | passwd="$final_root_pass" \ 381 | sent='Login >>' \ 382 | | grep 'Wrong email or password' \ 383 | | ( read X ; DEBUG "|$X|" ; [ -z "$X" ] ) 384 | 385 | if [ "$?" '!=' '0' ] ; then 386 | echo "Warning: could not log in as the root admin user:" \ 387 | "Wrong email or password" >&2 388 | break 389 | fi 390 | fi 391 | 392 | for tuple in "disp" "pass" "newpass" "first:NONE" \ 393 | "last:NONE" "institution:NONE" ; do 394 | fragment="${tuple/:*}" 395 | tuple="${tuple:$(( ${#fragment} + 1 ))}" 396 | param="$fragment" 397 | fragment="${tuple/:*}" 398 | tuple="${tuple:$(( ${#fragment} + 1 ))}" 399 | default="$fragment" 400 | 401 | value="$( user_get "$email" "$param" )" 402 | if [ -z "$value" -a -n "$default" ] ; then 403 | value="$default" 404 | fi 405 | eval "${param}=\"$value\"" 406 | done 407 | 408 | ids=($( \ 409 | get "$root_session" ajax/findusers.php search="$email" \ 410 | | grep ' /dev/null 424 | else 425 | echo "Warning: could not remove user" \ 426 | "$email: user not found" >&2 427 | fi 428 | 429 | continue 430 | fi 431 | 432 | final_pass="$pass" 433 | if [ -n "$newpass" ] ; then 434 | final_pass="$newpass" 435 | fi 436 | 437 | login_pass="$pass" 438 | 439 | if [ -z "$user_id" ] ; then 440 | login_pass="$final_pass" 441 | 442 | # CREATE USER 443 | DEBUG "CREATING USER: $email" 444 | post "$root_session" manageUsers.php \ 445 | fname="$first" \ 446 | lname="$last" \ 447 | email="$email" \ 448 | passwd="$final_pass" \ 449 | passwd2="$final_pass" \ 450 | institution="$institution" \ 451 | adduser='Add user >>' &> /dev/null 452 | 453 | ids=($( \ 454 | get "$root_session" ajax/findusers.php search="$email" \ 455 | | grep '&2 465 | continue 466 | fi 467 | fi 468 | 469 | if [ "$disp" '=' 'ADMIN' ] ; then 470 | DEBUG "PROMOTING USER: $email" 471 | post "$root_session" manageUsers.php \ 472 | userid="$user_id" \ 473 | makeadmin="make admin" &> /dev/null 474 | fi 475 | 476 | if [ "$disp" '=' 'USER' ] ; then 477 | DEBUG "DEMOTING USER: $email" 478 | post "$root_session" manageUsers.php \ 479 | userid="$user_id" \ 480 | makenormaluser="make normal user" \ 481 | &> /dev/null 482 | fi 483 | 484 | user_session="$( mksession )" 485 | 486 | # LOGIN AS NORMAL USER 487 | login_success=0 488 | DEBUG "LOGGING IN AS USER: $email" 489 | post "$user_session" user.php login="$email" \ 490 | passwd="$login_pass" \ 491 | sent='Login >>' \ 492 | | grep 'Wrong email or password' \ 493 | | ( read X ; DEBUG "|$X|" ; [ -z "$X" ] ) 494 | 495 | if [ "$?" '=' '0' ] ; then # login success 496 | login_success=1 497 | elif [ "$login_pass" '!=' "$newpass" ] ; then # login failure 498 | login_pass="$newpass" 499 | DEBUG "LOGGING IN (FALLBACK) AS USER: $email" 500 | post "$user_session" user.php login="$email" \ 501 | passwd="$login_pass" \ 502 | sent='Login >>' \ 503 | | grep 'Wrong email or password' \ 504 | | ( read X ; DEBUG "|$X|" ; [ -z "$X" ] ) 505 | 506 | if [ "$?" '=' '0' ] ; then 507 | login_success=1 508 | fi 509 | fi 510 | 511 | if [ "$login_success" '=' '0' ] ; then 512 | echo "Warning: could not log in as user" \ 513 | "$email: Wrong email or password" >&2 514 | continue 515 | fi 516 | 517 | DEBUG "UPDATING USER PROFILE: $email" 518 | post "$user_session" editUser.php fname="$first" \ 519 | lname="$last" \ 520 | email="$email" \ 521 | institution="$institution" \ 522 | updateprofile='Update Profile' \ 523 | &> /dev/null 524 | 525 | if [ -n "$newpass" -a "$login_pass" '!=' "$newpass" ] ; then 526 | # update user's password 527 | DEBUG "UPDATING USER PASSWORD: $email" 528 | post "$user_session" editUser.php \ 529 | oldpasswd="$login_pass" \ 530 | passwd="$newpass" \ 531 | passwd2="$newpass" \ 532 | updatepassword='Update Password' &> /dev/null 533 | fi 534 | 535 | get "$user_session" user.php logout=1 &> /dev/null 536 | done 537 | 538 | get "$root_session" user.php logout=1 &> /dev/null 539 | fi 540 | 541 | /usr/sbin/apache2ctl graceful-stop 542 | unset apache_pid 543 | wait 544 | sleep 10 545 | 546 | sed -i 's/^Listen [0-9][0-9]*/Listen 80/g' /etc/apache2/ports.conf 547 | sed -i 's/^//g' \ 548 | /etc/apache2/sites-enabled/000-default.conf 549 | tmp="$( mktemp )" 550 | head -n -1 "$local_config_file" > "$tmp" 551 | cat "$tmp" > "$local_config_file" 552 | rm "$tmp" 553 | 554 | EXEC /usr/sbin/apache2ctl -D FOREGROUND 555 | --------------------------------------------------------------------------------