diff --git a/README.md b/README.md index 9707433..c43dfcc 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,87 @@ Docker Station ====== -Boilerplate for a (local) development environment running [NGINX](http://nginx.org/), [Node.js](http://nodejs.org/) applications in [Docker](https://www.docker.com/) containers hosted on [Vagrant](https://www.vagrantup.com/) VM boxes on Mac OS X. +The `Docker Station` is a boilerplate project to create a local development environment for running [Node.js](http://nodejs.org/) applications under [nginx](http://nginx.org/) in [Docker](https://www.docker.com/) containers - all hosted on [Vagrant](https://www.vagrantup.com/) virtual machines, therefore ready-to-use on Mac OS X. + +## Dependencies +Please make sure you have the following prerequisites installed: + +- [Node.js & NPM](http://nodejs.org/download/) +- [Vagrant](https://www.vagrantup.com/downloads.html) +- [VirtualBox](https://www.virtualbox.org/wiki/Downloads) + +## Quickstart + +#### 1. Create Project +``` +# checkout ds +$ git clone git@github.com:ezmilhouse/docker-station.git tmp +``` + +``` +# create ds project +$ ./bin/ds.sh -n app -p /path/to/project -r user/repo -i 192.168.33.10 -p 2000 +``` +Now open your browser and see your app running at: [http://192.168.33.10](http://192.168.33.10) + +#### 2. Create Host Entry +Add a new host entry to your `/etc/hosts` file: + +``` +# add host entry +$ sudo /etc/hosts >> 192.168.33.10 example.com + +# flush host cache +$ dscacheutil -flushcache; sudo killall -HUP mDNSResponder +``` +Now open your browser and see your app running at [http://example.com](http://example.com) + +## Project Directory Layout +After checking out `Docker Station` and running `./bin/ds.sh` to [initiate]() your project - it will have following directory layout. + +#### /bin +``` +# shell scripts to provision and manage your box +# and docker containers + +├── bin +│ └── ds.sh +│ └── ds.provision.sh +``` + +#### /etc +``` +# all the docker images supported at this pointn in +# time, more images will be added + +├── etc +│ └── docker +│ │ └── images +│ │ │ └── base +│ │ │ │ │ Dockerfile +│ │ │ └── mongo +│ │ │ │ └── conf +│ │ │ │ │ Dockerfile +│ │ │ └── ... +``` + +#### /var +``` +# holds all Vagrant mounted directories and Docker +# Volumes, it's the persistent layer of your dev +# environment + +├── var +│ └── data +│ │ └── mongo +│ │ └── ... +│ └── log +│ │ └── mongo +│ │ └── ... +│ └── www +│ │ └── [YOUR_APPLICATION_FILES] +``` + + ## Intro diff --git a/Vagrantfile b/Vagrantfile index fe26e09..fbcd4c6 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -1,22 +1,28 @@ +require "yaml" +vconfig = YAML.load(File.open(File.join(File.dirname(__FILE__), "config.yaml"), File::RDONLY).read) + Vagrant.configure("2") do |config| - config.vm.define "app" do |m| + config.vm.define vconfig['VAGRANT_BOX_NAME'] do |m| # set up basic box image m.vm.box = "ubuntu/trusty64" # set host name - m.vm.hostname = "example.com" + m.vm.hostname = vconfig['VAGRANT_HOST_NAME'] # set private network, machine will use this ip - m.vm.network "private_network", ip: "192.168.33.10" + m.vm.network "private_network", ip: vconfig['VAGRANT_HOST_IP'] # provision docker environment m.vm.provision "docker" - # provision docker base image - m.vm.provision "shell", path: "./bin/vagrant.provision.sh" - m.vm.provision "shell", path: "./bin/vagrant.sh" + # provision docker images + m.vm.provision "shell", path: "./bin/ds.sh", args: "-d build-all" + + # provision docker containers + m.vm.provision "shell", path: "./bin/ds.sh", args: "-d new node node" + m.vm.provision "shell", path: "./bin/ds.sh", args: "-d new nginx nginx" end diff --git a/bin/docker.station.sh b/bin/docker.station.sh deleted file mode 100755 index 02aae99..0000000 --- a/bin/docker.station.sh +++ /dev/null @@ -1,80 +0,0 @@ -#!/bin/sh - -### ENVIRONMENT ############################################################### -############################################################################### - -# mounted root -DIR='/vagrant' - -# mounted images folder -DIR_DOCKER='/vagrant/etc/docker/images' - -### CONTAINER: NGINX ########################################################## -############################################################################### - -# docker container name: --name -NGINX_CONTAINER_NAME=nginx - -# docker container port: -p -NGINX_CONTAINER_PORT=80 - -### CONTAINER: NODE ########################################################### -############################################################################### - -# docker container name: --name -NODE_CONTAINER_NAME=node - -# docker container port: -p -NODE_CONTAINER_PORT=2000 - -### SCRIPT #################################################################### -############################################################################### - -case "$1" in - log) - case "$2" in - nginx) - docker logs -f $2 - ;; - node) - docker logs -f $2 - ;; - *) - docker logs -f "node" - ;; - esac - ;; - clean) - echo '==> Removing exited containers ...' - docker ps -a | grep Exit | cut -d ' ' -f 1 | xargs docker rm -f > /dev/null - ;; - state) - docker ps -a --no-trunc=false - ;; - start) - /vagrant/bin/docker.station.sh clean - echo '==> Starting ...' - echo '==> docker: ---> container: '${NGINX_CONTAINER_NAME} - docker run -d -p ${NGINX_CONTAINER_PORT}:${NGINX_CONTAINER_PORT} --name=nginx -v /vagrant/var/www:/var/www -v /vagrant/var/log/nginx:/var/log/nginx local/nginx > /dev/null - echo '==> docker: ---> container: '${NODE_CONTAINER_NAME} - docker run -d -p ${NODE_CONTAINER_PORT}:${NODE_CONTAINER_PORT} --name=node -v /vagrant/var/www:/var/www -v /vagrant/var/log/node:/var/log/node local/node > /dev/null - echo '==> ok!' - echo '' - docker ps -a - echo '' - /vagrant/bin/docker.station.sh log - ;; - stop) - echo '' - echo '==> Stopping ...' - docker stop $(docker ps -a -q) > /dev/null - echo '==> ok!' - ;; - restart) - /vagrant/bin/docker.station.sh stop - /vagrant/bin/docker.station.sh start - ;; - *) - echo 'Try start, stop or restart' - ;; -esac \ No newline at end of file diff --git a/bin/ds.sh b/bin/ds.sh new file mode 100755 index 0000000..e5e9747 --- /dev/null +++ b/bin/ds.sh @@ -0,0 +1,1206 @@ +#!/bin/sh + +# path to local bash's profile settings, mainly used to set `ds` alias +CONFIG_PATH=$HOME/.bash_profile + +# default project repo, sample app +DEFAULT_PROJECT_REPO='git@github.com:ezmilhouse/docker-station-app.git' + +# default directory where to find docker images in running vagrant box +DEFAULT_DOCKER_IMAGES_ROOT='/vagrant/etc/docker/images' + +# mounted root pointing to your local dev dir +DEFAULT_VAGRANT_MOUNTED_ROOT='/vagrant' + +DEFAULT_VAGRANT_CONFIG_PATH=~/.bash_profile + +# docker container name: --name +DEFAULT_NGINX_CONTAINER_NAME=nginx + +# docker container HTTP port +DEFAULT_NGINX_CONTAINER_PORT_HTTP=80 + +# docker container HTTPS port +DEFAULT_NGINX_CONTAINER_PORT_HTTPS=443 + +# docker container name: --name +DEFAULT_NODE_CONTAINER_NAME=node + +# docker container port: -p +DEFAULT_NODE_CONTAINER_PORT=2000 + +### GLOBAL: METHODS ########################################################### +############################################################################### + +ds_stdout() { + echo "$1" +} + +ds_newlne() { + echo "" +} + +### SCRIPT #################################################################### +############################################################################### + +# $ ds [-CONTEXT] [COMMAND] [COMMAND|OPTION] [-FLAG] + +case "$1" in + + # SHORTCUTS + + # $ ds down + down) + $0 -v sleep + ;; + + # $ ds init + init) + $0 -v new $1 + ;; + + # $ ds project + project) + $0 -p new $1 $2 + ;; + + # $ ds this + this) + $0 -p alias + ;; + + # $ ds up + up) + $0 -v wake + ;; + + # $ ds -d + # + # Commands in the docker context (-d) are allow you to manage, build, run, + # your docker containers on a Vagrant machine. There you have to be connected + # to a running Vagrant box when running commands. + -d) + + case "$2" in + + # $ ds -d build IMAGE TAG + ### + # Builds docker images from IMAGE Dockerfile, tags new built with + # prefixed local/TAG + # + # {req}{str} IMAGE + # Valid image name represents folder name in docker + # images dir /etc/docker/images + # + # {req}{str} TAG + # Tag name, you can identify your builds by the tag, in + # all lists, prefixed by local/ + ### + build) + + # validate $3, $4 + if [ ! "$3" -a ! "$4" ] ; then + ds_newlne + ds_stdout "» ERROR" + ds_stdout "» Missing parameters IMAGE, TAG - build failed." + ds_stdout "» USAGE | ds -d build IMAGE TAG" + ds_newlne + exit 1 + fi + + # validate $3 + if [ ! "$3" ] ; then + ds_newlne + ds_stdout "» ERROR" + ds_stdout "» Missing parameter IMAGE - build failed." + ds_stdout "» USAGE | ds -d build IMAGE TAG" + ds_newlne + exit 1 + fi + + # validate $3, existing directory + if [ ! -d "${DEFAULT_DOCKER_IMAGES_ROOT}/$3" ]; then + ds_newlne + ds_stdout "» ERROR" + ds_stdout "» Image /$3 could not be found in ${DEFAULT_DOCKER_IMAGES_ROOT} - build failed." + ds_stdout "» USAGE | ds -d build IMAGE TAG" + ds_newlne + exit 1 + fi + + # validate $4 + if [ ! "$4" ] ; then + ds_newlne + ds_stdout "» ERROR" + ds_stdout "» Missing parameter TAG - build failed." + ds_stdout "» USAGE | ds -d build IMAGE TAG" + ds_newlne + exit 1 + fi + + # build image + docker build --force-rm=true --rm=true -t local/$4 ${DEFAULT_DOCKER_IMAGES_ROOT}/$3 + + # show updated list + ds_newlne + $0 -d list -i + + # exit + ds_stdout "» OK" + ds_stdout "» Image tagged local/$4 built successfully based on image ${DEFAULT_DOCKER_IMAGES_ROOT}/$3." + ds_newlne + + exit 0 + + ;; + + # $ ds -d build-all + ### + # TODO + # Pretty much work in progress, this is the initial build script + # that runs, when vagrant provision is done, list of docker containers + # to be build should come from the outside, for now hardcoded here. + # + # Builds all docker images needed for application to run. + ### + build-all) + + # build base + $0 -d build base base + + # build nginx + $0 -d build nginx nginx + + # build node + $0 -d build node node + + # exit + ds_stdout "» OK" + ds_stdout "» All images build successfully." + ds_newlne + + exit 0 + + ;; + + # $ ds -d clean [-c] [-i] + ### + # While working with docker it tends to leave artefacts that you + # don't use anymore, this command removes all exited containers + # and all untagged images. + # + # {opt}{str} -c + # If set, removes all exited containers. + # + # {opt}{str} -i + # If set, removes all tagged images. + ### + clean) + + # normalize + # if no flags are set, call both recursively, complete cleanup + if [ ! "$3" ] ; then + $0 $1 $2 -c + $0 $1 $2 -i + exit 0 + fi + + # normalize + # if both flags are set, call both recursively, complete cleanup + if [ "$4" ] ; then + $0 $1 $2 -c + $0 $1 $2 -i + exit 0 + fi + + # normalize + # if only one flag is set, cpecific clean up + if [ "$3" ] ; then + + # remove exited containers + if [ "$3" = "-c" ]; then + + # remove exited containers + docker ps -a | grep Exit | cut -d ' ' -f 1 | xargs docker rm -f + + # show updated list + ds_newlne + $0 -d list -c + + # exit + ds_stdout "» OK" + ds_stdout "» Cleaned up containers successfully." + ds_newlne + + exit 0 + + fi + + # remove untagged images + if [ "$3" = "-i" ]; then + + # remove images + docker rmi -f $(docker images -a | grep "" | awk '{print($3)}') > /dev/null + + # show updated list + ds_newlne + $0 -d list -i + + # exit + ds_stdout "» OK" + ds_stdout "» Cleaned up images successfully." + ds_newlne + + exit 0 + + fi + + fi + + ;; + + # $ ds -d log CONTAINER + ### + # Shows logs of specified docker container in tail -f + # fashion. + # + # {req}{str} CONTAINER + # Valid container tag or container id. + ### + log) + + # validate $3 + if [ ! "$3" ] ; then + ds_newlne + ds_stdout "» ERROR" + ds_stdout "» Missing parameter CONTAINER - logs not found." + ds_stdout "» USAGE | ds -d log CONTAINER" + ds_newlne + exit 1 + fi + + ds_newlne + docker logs -f $3 + ds_newlne + + exit 0; + + ;; + + # $ ds -d list [-c] [-i] + ### + # Lists docker assets (containers and images) that are currently + # in the system, no flags set results in showing both lists. + # + # {opt}{str} -c + # If set, show all containers. + # + # {opt}{str} -i + # If set, shows all images. + ### + list) + + case "$3" in + + # ds -d list -c + # lists docker containers (that had been run at least once) + # maybe --no-trunc + -c) + ds_newlne + docker ps -a + ds_newlne + ;; + + # ds -d list -i + # lists docker images (that are already built) + # maybe --no-trunc + -i) + ds_newlne + docker images + ds_newlne + ;; + + # ds -d list + # lists both: docker images and containers + *) + $0 -d list -i + $0 -d list -c + ;; + + esac + + ;; + + # $ ds -d kill + ### + # Stops and removes all running and not running containers, + # removes all docker images, former setup is completely gone, + # all docker container data as well. Handle with care! + ### + kill) + + # remove all containers + docker rm -f $(docker ps -a -q) + + # remove all images + docker rmi $(docker images -a -q) + + # exit + ds_stdout "» OK" + ds_stdout "» Killed successfully, all images gone, all containers removed, no data left." + ds_newlne + + exit 0 + + ;; + + # $ ds -d new TAG NAME + ### + # Creates a new container for the first time, needs TAG of + # built image (the container will be based on that image) + # and a container NAME, that will to identify container + # further on. + # + # {req}{str} TAG + # Valid build image tag (without prefix) or + # container id. + # {req}{str} NAME + # Choose a container name to identify container + # later on. + ### + new) + + # validate $3 + if [ ! "$3" ] ; then + ds_newlne + ds_stdout "» ERROR" + ds_stdout "» Missing parameter TAG - no container created." + ds_stdout "» USAGE | ds -d new TAG NAME" + ds_newlne + exit 1 + fi + + # validate $4 + if [ ! "$4" ] ; then + ds_newlne + ds_stdout "» ERROR" + ds_stdout "» Missing parameter NAME - no container created." + ds_stdout "» USAGE | ds -d new TAG NAME" + ds_newlne + exit 1 + fi + + case "$3" in + + # TODO + # This section is very specific to the built images we what to run, + # mounting of directories, ports to run on, it seems that these are + # specs to be moved away to higher level config files. + + # IMAGE: node + # starts node container, exposing node application's + # port, mounting working dir `/var/www` and log dir + # `/var/log/node` + node) + docker run \ + --name=$4 \ + -d \ + -p ${DEFAULT_NODE_CONTAINER_PORT}:${DEFAULT_NODE_CONTAINER_PORT} \ + -v /vagrant/var/www:/var/www \ + -v /vagrant/var/log/node:/var/log/node \ + local/node \ + > /dev/null + ;; + + # IMAGE: nginx + # starts nginx container, exposing nginx server's + # http/https ports, mounting working dir `/var/www` + # and log dir `/var/log/nginx` + nginx) + docker run \ + --name=$4 \ + -d \ + -p ${DEFAULT_NGINX_CONTAINER_PORT_HTTP}:${DEFAULT_NGINX_CONTAINER_PORT_HTTP} \ + -p ${DEFAULT_NGINX_CONTAINER_PORT_HTTPS}:${DEFAULT_NGINX_CONTAINER_PORT_HTTPS} \ + -v /vagrant/var/www:/var/www \ + -v /vagrant/var/log/nginx:/var/log/nginx \ + local/nginx \ + > /dev/null + ;; + + esac + + # show updated list + $0 -d list + + # exit + ds_stdout "» OK" + ds_stdout "» Container $4 based on local/$3 successfully created." + ds_newlne + + exit 0 + + ;; + + # $ ds -d remove CONTAINER + ### + # Removes specified container (running or not), displays + # updated list of all docker containers available. + # + # {req}{str} CONTAINER + # Valid container tag or container id. + ### + remove) + + # validate $3 + if [ ! "$3" ] ; then + ds_newlne + ds_stdout "» ERROR" + ds_stdout "» Missing parameter CONTAINER - not stopped." + ds_stdout "» USAGE | ds -d stop CONTAINER" + ds_newlne + exit 1 + fi + + # remove container + docker rm -f $3 > /dev/null + + # show updated list + $0 -d list -c + + # exit + ds_stdout "» OK" + ds_stdout "» Container $3 successfully removed." + ds_newlne + + ;; + + # $ ds -d remove-all + ### + # Removes all containers (running or not), displays + # updated list of all docker containers available. + ### + remove-all) + + # remove container + docker rm -f $(docker ps -a -q) > /dev/null + + # show updated list + $0 -d list -c + + # exit + ds_stdout "» OK" + ds_stdout "» All container successfully removed." + ds_newlne + + ;; + + # $ ds -d restart CONTAINER + ### + # Restarts a container that is currently running. + # + # {req}{str} CONTAINER + # Valid container tag or container id. + ### + restart) + + # validate $3 + if [ ! "$3" ] ; then + ds_newlne + ds_stdout "» ERROR" + ds_stdout "» Missing parameter CONTAINER - restart failed." + ds_stdout "» USAGE | ds -d restart CONTAINER" + ds_newlne + exit 1 + fi + + # stop container + $0 -d stop $3 > /dev/null + + # start container + $0 -d start $3 > /dev/null + + # show updated list + $0 -d list -c + + # exit + ds_stdout "» OK" + ds_stdout "» Container $3 successfully restarted." + ds_newlne + + exit 0; + + ;; + + # $ ds -d restart-all + ### + # Restarts all containers that are currently running. + ### + restart-all) + + # stop all containers + $0 -d stop-all > /dev/null + + # start all containers + $0 -d start-all > /dev/null + + # show updated list + $0 -d list -c + + # exit + ds_stdout "» OK" + ds_stdout "» All container successfully restarted." + ds_newlne + + exit 0; + + ;; + + # $ ds -d start CONTAINER + ### + # Starts a container that was stopped before, means a container + # that was run before (and then at some point stopped) - you + # cannot start a unstopped (not yet run) container. + # + # {req}{str} CONTAINER + # Valid container tag or container id. + ### + start) + + # validate $3 + if [ ! "$3" ] ; then + ds_newlne + ds_stdout "» ERROR" + ds_stdout "» Missing parameter CONTAINER - start failed." + ds_stdout "» USAGE | ds -d start CONTAINER" + ds_newlne + exit 1 + fi + + # start container + docker start $3 > /dev/null + + # show updated list + $0 -d list -c + + # exit + ds_stdout "» OK" + ds_stdout "» Container $3 successfully started." + ds_newlne + + exit 0; + + ;; + + # $ ds -d start-all + ### + # Starts all containers that were stopped before. + ### + start-all) + + # start container + docker ps -a | grep Exit | cut -d ' ' -f 1 | xargs docker start + + # show updated list + $0 -d list -c + + # exit + ds_stdout "» OK" + ds_stdout "» All Containers successfully started." + ds_newlne + + exit 0; + + ;; + + # $ ds -d stop CONTAINER + ### + # Stops specified running container, displays updated + # list of all docker containers available. + # + # {req}{str} CONTAINER + # Valid container tag or container id. + ### + stop) + + # validate $3 + if [ ! "$3" ] ; then + ds_newlne + ds_stdout "» ERROR" + ds_stdout "» Missing parameter CONTAINER - not stopped." + ds_stdout "» USAGE | ds -d stop CONTAINER" + ds_newlne + exit 1 + fi + + # stop container + docker stop -t 0 $3 > /dev/null + + # show updated list + $0 -d list -c + + # exit + ds_stdout "» OK" + ds_stdout "» Docker container $3 successfully stopped." + ds_newlne + + ;; + + # $ ds -d stop-all + ### + # Stops all running containers, displays updated + # list of all docker containers. + ### + stop-all) + + # stop all containers, don't wait for graceful + # shutdown (-t 0), just kill + docker ps -a | grep Up | cut -d ' ' -f 1 | xargs docker stop -t 0 > /dev/null + + # show updated list + $0 -d list -c + + # exit + ds_stdout "» OK" + ds_stdout "» All Docker containers stopped." + ds_newlne + + ;; + + esac + + ;; + + # $ ds -p [PATH] + # + # Commands that run on the project level, use them in your local + # environment to set up your Docker Station project. + -p) + + case "$2" in + + # $ ds alias + alias) + + CURRENT_LOCATION=$(pwd)/bin/ds.sh + CURRENT_CONFIG_PATH=~/.bash_profile + + ds_alias_insert() { + + ALIAS_NEW=$1 + + # add alias to profile + echo "" >> ${CURRENT_CONFIG_PATH} + echo "# ALIASES: DOCKER STATION" >> ${CURRENT_CONFIG_PATH} + echo "" >> ${CURRENT_CONFIG_PATH} + echo "${ALIAS_NEW}" >> ${CURRENT_CONFIG_PATH} + + } + + ds_alias_update() { + + ALIAS=$1 + ALIAS_NEW=$2 + + # replacing paths (that contain slashes) + # therefore just change the delimiter + sed -i -e "s|$ALIAS|$ALIAS_NEW|g" ${CURRENT_CONFIG_PATH} + + } + + ds_alias_set() { + + ALIAS_NEW="alias ds=${CURRENT_LOCATION}" + ALIAS=$(grep -F "ds=" ${CURRENT_CONFIG_PATH}) + + # insert if not set yet + if [[ ! "$ALIAS" ]] ; then + #echo '-' + ds_alias_insert "${ALIAS_NEW}" + + # update if already set + else + #echo '+' + ds_alias_update "${ALIAS}" "${ALIAS_NEW}" + fi + + } + + # invoke setting alias + ds_alias_set + + # exit + ds_stdout "» OK" + ds_stdout "» Alias set successfully, pointing to: ${CURRENT_LOCATION}" + ds_stdout "» Please refresh your shell to use new set alias:" + ds_stdout "» $ . ~/.bash_profile" + ds_newlne + + exit 0 + + ;; + + # ds -p new PATH [REPOSITORY] + # Creates a new Docker Station project in PATH, a application + # REPOSITORY is optional, if set ds will clone it into the + # appropriate directory and runs `npm install` on it. If not + # set a sample repo will be cloned. + new) + + if [[ ! "$3" ]] ; then + ds_newlne + ds_stdout "» ERROR" + ds_stdout "» Missing parameter PATH." + ds_stdout "» USAGE | ds -p new PATH [REPOSITORY]" + ds_newlne + exit 1 + fi + + if [ -d "$3" ]; then + ds_newlne + ds_stdout "» ERROR" + ds_stdout "» Directory $3 already exists." + ds_stdout "» USAGE | ds -p new PATH [REPOSITORY]" + ds_newlne + exit 1 + fi + + if [[ ! "$4" ]] ; then + + ds_newlne + ds_stdout "» WARNING" + ds_stdout "» No REPOSITORY specified, cloning default project repo." + ds_stdout "» USAGE | ds -p new PATH [REPOSITORY]" + ds_newlne + + # fallback to demo repo + PROJECT_REPO=${DEFAULT_PROJECT_REPO} + + else + + # use alternate repo + PROJECT_REPO=$4 + + fi + + mkdir -p $3 > /dev/null + mkdir -p $3/bin > /dev/null + mkdir -p $3/etc > /dev/null + mkdir -p $3/var > /dev/null + ds_newlne + ds_stdout "» OK" + ds_stdout "» Project folders created." + ds_newlne + + cp -r ./bin/* $3/bin > /dev/null + cp -r ./etc/* $3/etc > /dev/null + ds_newlne + ds_stdout "» OK" + ds_stdout "» Project folder contents copied." + ds_newlne + + cp ./Vagrantfile $3/Vagrantfile > /dev/null + cp ./.gitignore $3/.gitignore > /dev/null + cp ./config.yaml $3/config.yaml > /dev/null + ds_newlne + ds_stdout "» OK" + ds_stdout "» Project folder and root files copied." + ds_newlne + + # TODO + # at the moment this is a very simple `git clone` feature for + # the most common use case where you want to clone a app's + # repository, in the future we should think about local copies, + # or even symlink solutions (although symlinks might turn out + # to be evil in docker environments) + + git clone -q ${PROJECT_REPO} $3/var/www > /dev/null + ds_newlne + ds_stdout "» OK" + ds_stdout "» Application cloned from repo." + ds_newlne + + cd $3/var/www && npm install --silent > /dev/null + ds_newlne + ds_stdout "» OK" + ds_stdout "» Application dependencies installed." + ds_newlne + + # exit + ds_stdout "» OK" + ds_stdout "» Project built successfully. Switch to project folder here:" + ds_stdout "» $ cd $3" + ds_newlne + + exit 0 + + ;; + + esac + + ;; + + # $ ds -v [COMMAND] [COMMAND|OPTION] [-FLAG] + # + # Commands taht allow you to handle and manage the Vagrant boxes. + -v) + + case "$2" in + + # PRIVATE + + # $ ds -v provision + ### + # Starts vagrant's provisoning process, based in Vagrantfile + # in projects root. + ### + -provision) + + # provision and up + vagrant up --provision + + # exit + ds_newlne + ds_stdout "» OK" + ds_stdout "» Vagrant box provisioned and up." + ds_newlne + + ;; + + -provision-bash) + + # provisioon environment + vagrant ssh -c "${DEFAULT_VAGRANT_MOUNTED_ROOT}/bin/ds.sh -v bash" + + # exit + ds_newlne + ds_stdout "» OK" + ds_stdout "» Bash profile set up on vagrant box." + ds_newlne + + ;; + + # $ ds -v provision-docker + ### + # Enters provisioned vagrant box (via ssh) and makes it docker + # ready, using the ds build + ### + -provision-docker) + + # enter, install docker + vagrant ssh -c "${DEFAULT_VAGRANT_MOUNTED_ROOT}/bin/ds.sh -d build-all" + + # exit + ds_newlne + ds_stdout "» OK" + ds_stdout "» Vagrant box successfully provisioned with docker." + ds_newlne + + ;; + + # PUBLIC + + bash) + + # remove .bash_profiel + rm ./.bash_profile + + # copy .bash_profile into root + cp ${DEFAULT_VAGRANT_MOUNTED_ROOT}/etc/docker/images/base/conf/.bash_profile ./.bash_profile + + # exit + ds_newlne + ds_stdout "» OK" + ds_stdout "» Bash profile set up on vagrant box. Please reload your bash profile:" + ds_stdout "» $ . ./.bash_profile" + ds_newlne + + ;; + + # $ ds -v kill + ### + # Destroys the vagrant box in fornt of you. + ### + kill) + + # destroy docker contents + vagrant ssh -c "${DEFAULT_VAGRANT_MOUNTED_ROOT}/bin/ds.sh -d kill" + + # destroy box + vagrant destroy + + # exit + ds_newlne + ds_stdout "» OK" + ds_stdout "» Vagrant box destroyed successfully." + ds_newlne + + exit 0 + + ;; + + # $ ds -v new [-f] + ### + # TODO: + # There needs to be more configuration coming from the config.yaml, + # also there should be config.local.yaml merged into it first. + # + # Creates a new vagrant box, provisions box, and builds docker + # containers on box, reloads box in between to handle known + # guest addition problems. + # + # {opt}{str} -f + # If set, destroys a existing box before starting + # new one + ### + new) + + case "$3" in + -f) + # detroy box it already exists + $0 -v kill + ;; + esac + + # provisioning box + $0 -v -provision + + # reloading box + $0 -v -reload + + # building docker images + $0 -v -provision-docker + + # exit + ds_newlne + ds_stdout "» OK" + ds_stdout "» Vagrant box created successfully. Use ds -v ssh to enter box." + ds_newlne + + # ssh into box + vagrant ssh -c "${DEFAULT_VAGRANT_MOUNTED_ROOT}/bin/ds.sh -v bash; /bin/bash" + + exit 0 + + ;; + + # $ ds -v reload + ### + # Reloads provisioned vagrant box. + ### + reload) + + # reloads vagrant box, no provisioning + vagrant reload + + exit 0 + + ;; + + # $ ds -v sleep + ### + # Stops all running docker containers on box, tries clean up, + # exits out of box, puts box on hold. It's the one thing you + # do when you stop working. + ### + sleep) + + # ssh into box, stop docker containers + vagrant ssh -c "${DEFAULT_VAGRANT_MOUNTED_ROOT}/bin/ds.sh -d stop-all" + + # suspend box + vagrant halt > /dev/null + + # exit + ds_newlne + ds_stdout "» OK" + ds_stdout "» Vagrant box is sleeping now." + ds_newlne + + exit 0 + + ;; + + # $ ds -v ssh + ### + # Enters vagrant box via ssh. + ### + ssh) + + # ssh into box + vagrant ssh + + exit 0 + + ;; + + # $ ds -v wakeup + ### + # Reloads existing vagrant box, enters box via ssh, runs + # docker logging script in tail -f fashion. This is what + # you do when you start working. + ### + wake) + + # reload box + vagrant up + + # ssh into box, stop docker containers + vagrant ssh -c "${DEFAULT_VAGRANT_MOUNTED_ROOT}/bin/ds.sh -d start-all" + + # exit + ds_newlne + ds_stdout "» OK" + ds_stdout "» Vagrant box is awake now." + ds_newlne + + # ssh back in + # $0 -v ssh + + exit 0 + + ;; + + esac + + ;; + + # $ ds + *) + echo '' + echo '=== DOCKER STATION ==============================================' + echo '=== https://github.com/ezmilhouse/docker-station ================' + echo '' + echo 'Usage: ds [options] []' + echo '' + echo 'Shortcuts:' + echo '' + echo 'down | SHORTCUT: -> ds -p alias' + echo ' | Send Vagrant box to sleep.' + echo '' + echo 'init | SHORTCUT: -> ds -v new [-f]' + echo ' | Provision Vagrant box initially, -f forces destroy first.' + echo '' + echo 'project | SHORTCUT: -> ds -p new PATH [REPOSITORY]' + echo '' + echo 'this | SHORTCUT: -> ds -v sleep' + echo ' | Sets Docker Station alias to current location.' + echo '' + echo 'up | SHORTCUT: -> ds -v wake' + echo ' | Wakes up halted, suspended Vagrant box.' + echo '' + echo 'Context:' + echo '' + echo '-d | commands in context of Docker containers, images' + echo '-p | commands in context of project folders, files' + echo '-v | commands in context of Vagrant boxes' + echo '' + echo 'Commands:' + echo '' + echo '-d | build' + echo ' | USAGE: ds -d build ' + echo ' | Builds image from specific Docker IMAGE (Dockerfile), tagged with TAG, TAG will be prefixed with local/ namespace.' + echo ' |' + echo ' | build-all' + echo ' | USAGE: ds -d build-all' + echo ' | Builds a preset of Docker images.' + echo ' |' + echo ' | clean' + echo ' | USAGE: ds -d clean [-c] [-i]' + echo ' | Tries to clean up Docker artefacts, removes untagged images (-i), removes exited containers [-c], might fail sometimes, known Docker issue' + echo ' |' + echo ' | log' + echo ' | USAGE: ds -d log CONTAINER' + echo ' | Shows logs of specific Docker CONATINER (in tail -f style)' + echo ' |' + echo ' | list' + echo ' | USAGE: ds -d list [-c] [-i]' + echo ' | Lists all available Docker images [-i], containers [-c]' + echo ' |' + echo ' | kill' + echo ' | USAGE: ds -d kill' + echo ' | Removes all containers, all data will be lost, also removes all Docker images, you need to rebuild them afterwards, handle with care.' + echo ' |' + echo ' | new' + echo ' | USAGE: ds -d new TAG NAME' + echo ' | Creates new Docker container based on Docker Image TAG, sets container NAME' + echo ' |' + echo ' | remove' + echo ' | USAGE: ds -d remove CONTAINER' + echo ' | Removes Docker container CONTAINER, running or not.' + echo ' |' + echo ' | remove-all' + echo ' | USAGE: ds -d remove-all' + echo ' | Removes all Docker containers, running or not.' + echo ' |' + echo ' | restart' + echo ' | USAGE: ds -d restart CONTAINER' + echo ' | Restarts running Docker container CONTAINER.' + echo ' |' + echo ' | restart-all' + echo ' | USAGE: ds -d restart-all' + echo ' | Restarts all running Docker containers.' + echo ' |' + echo ' | start' + echo ' | USAGE: ds -d start CONTAINER' + echo ' | Starts stopped Docker container CONTAINER.' + echo ' |' + echo ' | start-all' + echo ' | USAGE: ds -d start CONTAINER' + echo ' | Starts all stopped Docker containers.' + echo ' |' + echo ' | stop' + echo ' | USAGE: ds -d stop CONTAINER' + echo ' | Stops running Docker container CONTAINER.' + echo ' |' + echo ' | stop-all' + echo ' | USAGE: ds -d stop-all' + echo ' | Starts all stopped Docker containers.' + echo '' + echo '' + echo '' + echo '-p | alias' + echo ' | USAGE: ds -p alias' + echo ' | Sets global ds alias (in .bash_profile) to current ./bin/ds.sh shell script' + echo ' |' + echo ' | new' + echo ' | USAGE: ds -p new PATH [REPOSITORY]' + echo ' | Creates new Docker Station project in PATH, copies all files, checks out application REPOSITORY (optional, checks out example application if not set)' + echo '' + echo '' + echo '' + echo '-v | -provision' + echo ' | -provision-bash' + echo ' | -provision-docker' + echo ' |' + echo ' | bash' + echo ' | USAGE: ds -v bash' + echo ' | Copies /etc/docker/.../.bash_profile from host to Vagrant box, setting aliases, you have to source new bash profile manually afterwards with $ . ./.bash_profile' + echo ' |' + echo ' | kill' + echo ' | USAGE: ds -v kill' + echo ' | Destroys Vagrant box and everything on (calls v -d kill on all Docker elements before) it, handle with care.' + echo ' |' + echo ' | new' + echo ' | USAGE: ds -v new [-f]' + echo ' | Provisions a new/existing Vagrant box, including all Docker images, containers, based on Vagrantfile and config.yaml. Use optional flag -f to kill box first.' + echo ' |' + echo ' | reload' + echo ' | USAGE: ds -v reload' + echo ' | Reloads existing Vagrant box, booting it up again' + echo ' |' + echo ' | sleep' + echo ' | USAGE: ds -v sleep' + echo ' | The other half of $ ds -v wake, Stops all Docker containers, then suspends (RAM snapshot) Vagrant box. Best way to end the day.' + echo ' |' + echo ' | ssh' + echo ' | USAGE: ds -v ssh' + echo ' | SSH into vagrant box, no native -c flag.' + echo ' |' + echo ' | wake' + echo ' | USAGE: ds -v wake' + echo ' | The other half of $ ds -v sleep, ups vagrant box, starts containers.' + + ;; + +esac \ No newline at end of file diff --git a/bin/vagrant.provision.sh b/bin/vagrant.provision.sh deleted file mode 100644 index 59d7cc0..0000000 --- a/bin/vagrant.provision.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/bin/sh - -### ENVIRONMENT ############################################################### -############################################################################### - -# mounted root -DIR='/vagrant' - -# mounted images folder -DIR_DOCKER='/vagrant/etc/docker/images' - -### PROVISION ################################################################# -############################################################################### - -echo 'Building general docker Ubuntu image ...' -docker build -t local/base ${DIR_DOCKER}/base - -echo 'Building general docker NGINX image ...' -docker build -t local/nginx ${DIR_DOCKER}/nginx - -echo 'Building general docker Node.js image ...' -docker build -t local/node ${DIR_DOCKER}/node - -echo 'All done ... ok!' \ No newline at end of file diff --git a/bin/vagrant.sh b/bin/vagrant.sh deleted file mode 100755 index 085aa79..0000000 --- a/bin/vagrant.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh -case "$1" in - init) - cd var/www && npm install - vagrant up app --provision - vagrant reload app - ;; - *) - cp /vagrant/etc/docker/images/base/conf/.bash_profile ~/.bash_profile && . ~/.bash_profile - echo "ok!" - echo "Now SSH into your Vagrant box and start Docker Station:" - echo "==> $ vagrant ssh" - echo "==> $ ds start" - ;; -esac \ No newline at end of file diff --git a/config.yaml b/config.yaml new file mode 100644 index 0000000..864f64c --- /dev/null +++ b/config.yaml @@ -0,0 +1,4 @@ +VAGRANT_HOST_IP : '192.168.33.10' +VAGRANT_HOST_NAME : 'example.com' +VAGRANT_BOX_NAME : 'app' +VAGRANT_BASH_PROFILE : './etc/docker/images/base/conf/.bash_profile' \ No newline at end of file diff --git a/docs/cli.txt b/docs/cli.txt new file mode 100644 index 0000000..f15e78d --- /dev/null +++ b/docs/cli.txt @@ -0,0 +1,131 @@ +# ds + +Usage: ds [options] [] + +Shortcuts: + +down | SHORTCUT: -> ds -p alias + | Send Vagrant box to sleep. + +init | SHORTCUT: -> ds -v new [-f] + | Provision Vagrant box initially, -f forces destroy first. + +project | SHORTCUT: -> ds -p new PATH [REPOSITORY] + +this | SHORTCUT: -> ds -v sleep + | Sets Docker Station alias to current location. + +up | SHORTCUT: -> ds -v wake + | Wakes up halted, suspended Vagrant box. + +Context: + +-d | commands in context of Docker containers, images +-p | commands in context of project folders, files +-v | commands in context of Vagrant boxes + +Commands: + +-d | build + | USAGE: ds -d build + | Builds image from specific Docker IMAGE (Dockerfile), tagged with TAG, TAG will be prefixed with local/ namespace. + | + | build-all + | USAGE: ds -d build-all + | Builds a preset of Docker images. + | + | clean + | USAGE: ds -d clean [-c] [-i] + | Tries to clean up Docker artefacts, removes untagged images (-i), removes exited containers [-c], might fail sometimes, known Docker issue + | + | log + | USAGE: ds -d log CONTAINER + | Shows logs of specific Docker CONATINER (in tail -f style) + | + | list + | USAGE: ds -d list [-c] [-i] + | Lists all available Docker images [-i], containers [-c] + | + | kill + | USAGE: ds -d kill + | Removes all containers, all data will be lost, also removes all Docker images, you need to rebuild them afterwards, handle with care. + | + | new + | USAGE: ds -d new TAG NAME + | Creates new Docker container based on Docker Image TAG, sets container NAME + | + | remove + | USAGE: ds -d remove CONTAINER + | Removes Docker container CONTAINER, running or not. + | + | remove-all + | USAGE: ds -d remove-all + | Removes all Docker containers, running or not. + | + | restart + | USAGE: ds -d restart CONTAINER + | Restarts running Docker container CONTAINER. + | + | restart-all + | USAGE: ds -d restart-all + | Restarts all running Docker containers. + | + | start + | USAGE: ds -d start CONTAINER + | Starts stopped Docker container CONTAINER. + | + | start-all + | USAGE: ds -d start CONTAINER + | Starts all stopped Docker containers. + | + | stop + | USAGE: ds -d stop CONTAINER + | Stops running Docker container CONTAINER. + | + | stop-all + | USAGE: ds -d stop-all + | Starts all stopped Docker containers. + + + +-p | alias + | USAGE: ds -p alias + | Sets global ds alias (in .bash_profile) to current ./bin/ds.sh shell script + | + | new + | USAGE: ds -p new PATH [REPOSITORY] + | Creates new Docker Station project in PATH, copies all files, checks out application REPOSITORY (optional, checks out example application if not set) + + + +-v | -provision + | -provision-bash + | -provision-docker + | + | bash + | USAGE: ds -v bash + | Copies /etc/docker/.../.bash_profile from host to Vagrant box, setting aliases, you have to source new bash profile manually afterwards with $ . ./.bash_profile + | + | kill + | USAGE: ds -v kill + | Destroys Vagrant box and everything on (calls v -d kill on all Docker elements before) it, handle with care. + | + | new + | USAGE: ds -v new [-f] + | Provisions a new/existing Vagrant box, including all Docker images, containers, based on Vagrantfile and config.yaml. Use optional flag -f to kill box first. + | + | reload + | USAGE: ds -v reload + | Reloads existing Vagrant box, booting it up again + | + | sleep + | USAGE: ds -v sleep + | The other half of $ ds -v wake, Stops all Docker containers, then suspends (RAM snapshot) Vagrant box. Best way to end the day. + | + | ssh + | USAGE: ds -v ssh + | SSH into vagrant box, no native -c flag. + | + | wake + | USAGE: ds -v wake + | The other half of $ ds -v sleep, ups vagrant box, starts containers. diff --git a/docs/intro.txt b/docs/intro.txt new file mode 100644 index 0000000..67d61dc --- /dev/null +++ b/docs/intro.txt @@ -0,0 +1,3 @@ + +# provision vagrant box, build docker images, start docker containers +$ ds -v new diff --git a/etc/docker/images/base/conf/.bash_profile b/etc/docker/images/base/conf/.bash_profile index 7a417aa..20fea7b 100644 --- a/etc/docker/images/base/conf/.bash_profile +++ b/etc/docker/images/base/conf/.bash_profile @@ -2,5 +2,5 @@ alias d=docker # docker: environment -alias dockerstation=/vagrant/bin/docker.station.sh -alias ds=/vagrant/bin/docker.station.sh \ No newline at end of file +alias dockerstation=/vagrant/bin/ds.sh +alias ds=/vagrant/bin/ds.sh \ No newline at end of file diff --git a/etc/docker/images/node/Dockerfile b/etc/docker/images/node/Dockerfile index 1f39dd2..d54788c 100644 --- a/etc/docker/images/node/Dockerfile +++ b/etc/docker/images/node/Dockerfile @@ -22,7 +22,8 @@ RUN npm install -g \ mocha \ nodemon \ node-inspector \ - phantomjs + phantomjs \ + shelljs ### FOLDERS ################################################################### ############################################################################### diff --git a/package.json b/package.json new file mode 100644 index 0000000..5c960fa --- /dev/null +++ b/package.json @@ -0,0 +1,4 @@ +{ + "name" : "docker-station", + "version" : "0.1.0" +} \ No newline at end of file diff --git a/var/www/index.js b/var/www/index.js deleted file mode 100644 index d20e0f5..0000000 --- a/var/www/index.js +++ /dev/null @@ -1,7 +0,0 @@ -var express = require('express'); - -var app = express(); -app.route('*').all(function(req, res, next) { - res.send('Hello World!'); -}); -app.listen(2000); \ No newline at end of file diff --git a/var/www/nodemon.json b/var/www/nodemon.json deleted file mode 100644 index 47c301e..0000000 --- a/var/www/nodemon.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "restartable" : "rs", - "ignore" : [ - ".git", - "node_modules", - "bower_components", - ".sass-cache", - ".vagrant" - ], - "verbose" : false, - "execMap" : { - "js" : "node" - }, - "watch" : [ - "." - ], - "ext" : "js json" -} \ No newline at end of file diff --git a/var/www/package.json b/var/www/package.json deleted file mode 100644 index 138ec73..0000000 --- a/var/www/package.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "name" : "app", - "dependencies" : { - "express" : "*", - "mongoose" : "*" - }, - "version" : "0.1.0" -}