Adds utility script to ease working with Docker. (#129)

This commit is contained in:
Chuck Harmston 2016-05-11 18:09:50 -06:00
Родитель b5a0cb0a5a
Коммит f21bbeb44c
2 изменённых файлов: 192 добавлений и 71 удалений

Просмотреть файл

@ -1,86 +1,60 @@
## Local Development
# Local Development
A multiple-container Docker configuration is maintained to support local development.
## Architecture
`universal-search-recommendation` is built as a containerized Docker application, but to run it, several additional services are required:
- a [Memcached](http://memcached.org/) cache backend
- a [Celery](http://www.celeryproject.org/) task queue
- a [Redis](http://redis.io/) broker for the task queue
A [Compose](https://docs.docker.com/compose/) configuration is included to streamline setup and management of those services for local development. They are run alongside the application container on a single [Docker Machine](https://docs.docker.com/machine/overview/) VM.
## Usage
A `./server` utility script is included to streamline use of the Docker containers.
### First-time setup
First, run the following script:
```bash
./server init
```
This creates a host VM called `universal-search-dev`. Then, it configures a consistent hostname ([universal-search.dev](http://universal-search.dev/)) for local development (requires `sudo`).
You will need to [install Docker Toolbox](https://www.docker.com/products/docker-toolbox) and configure your shell. The script will walk you through it.
### Configuration
Some environment variables are required. Each of those are contained within `.env.dist`, which should be copied to `.env` and populated as appropriate.
### Services
`universal-search-recommendation` requires several additional services: a [Memcached](http://memcached.org/) cache backend, a [Celery](http://www.celeryproject.org/) task queue, and a [Redis](http://redis.io/) Celery backend. A [Compose](https://docs.docker.com/compose/) configuration is included to streamline setup and management of those services.
- `BING_ACCOUNT_KEY` - account key for Bing's [Web Search API](http://datamarket.azure.com/dataset/bing/searchweb).
- `EMBEDLY_API_KEY` - an API key to access Embedly's [Extract API](http://embed.ly/extract).
- `YAHOO_OAUTH_KEY` and `YAHOO_OAUTH_SECRET` - authentication credentials for Yahoo's [BOSS Search API](https://developer.yahoo.com/boss/search/).
#### Set up Docker host.
### Development
The first time you set up the services, you must create the Docker host.
Finally, you're ready to go. The `./server` script has a number of additional commands to help out.
- [Install Docker Toolbox](https://www.docker.com/products/docker-toolbox).
- Create a Docker host:
- `./server start` - builds and starts the application server and supporting services.
- `./server stop` - kills and removes the application container, then stops the supporting services.
- `./server restart` - runs `./server stop`, then `./server start`.
```bash
docker-machine create --driver virtualbox universal-search-dev
```
You can also start, stop, or restart the app or service containers individually:
- Add an entry to your `hosts` file:
- `./server start app`
- `./server stop app`
- `./server restart app`
- `./server start services`
- `./server stop services`
- `./server restart services`
```bash
sudo sh -c "echo $(docker-machine ip universal-search-dev 2>/dev/null) universal-search.dev >> /etc/hosts"
```
#### Start services.
After the host is set up, you can run each service by:
```
docker-machine start universal-search-dev
eval $(docker-machine env universal-search-dev)
docker-compose up -d
```
To verify that each service is up, run:
```bash
docker-compose ps
```
In the output you should see containers named `recommendation_memcached_1`, `recommendation_redis_1`, and `recommendation_worker_1`. The state for each of these should be `Up`.
### Application
`universal-search-recommendation` is managed as a Docker container that is separately built from the services, but run on the same host as the services.
To build it:
```bash
docker build -t universal-search-recommendation .
```
To run it:
```bash
docker run -d -e "RECOMMENDATION_SERVICES=`docker-machine ip universal-search-dev`" -p 80:8000/tcp universal-search-recommendation
```
To verify that the application is running:
```bash
docker ps --filter ancestor="universal-search-recommendation"
```
You should see one container running, and its status should begin with `Up`.
### Usage
If the application and services are all running, you should be able to access to access the recommendation server at [http://universal-search.dev](http://universal-search.dev). After making changes to the application, you will need to stop it:
```bash
docker stop $(docker ps --filter ancestor="universal-search-recommendation" --format="{{.ID}}")
```
Then rebuild and start it back up, per above.

147
server Executable file
Просмотреть файл

@ -0,0 +1,147 @@
#!/bin/bash
APPLICATION="universal-search-recommendation"
HOST="universal-search.dev"
MACHINE="universal-search-dev"
STATUS="$(docker-machine status $MACHINE)"
# First, let's make sure that Docker Toolbox has been installed.
if ! [ -x "$(command -v docker-machine)" ]; then
echo "Please install Docker Toolbox and try again:"
echo "https://www.docker.com/products/docker-toolbox"
exit 1
fi
# Next, let's make sure that the VM that runs our containers has been started
# and that the shell has been configured appropriately.
if [ ! "$DOCKER_MACHINE_NAME" == "$MACHINE" ]; then
if [ $STATUS == "Stopped" ]; then
echo "Starting VM..."
docker-machine start $MACHINE >/dev/null
fi
# Since this script cannot modify the calling shell's environment, we have to
# do this nasty thing to make sure that the shell is appropriately configured
# for docker-machine.
echo "Unable to find your VM. Please run the following command to configure"
echo "your shell and try again:"
echo "eval \$(docker-machine env universal-search-dev)"
exit 1
fi
# Now that we know the containers are running, some runtime constants.
APP_ID="$(docker ps -a -q --filter name=$APPLICATION)"
# Finally, let's do the important things.
case "$1" in
# Creates the VM and a predictable hostname to point to it.
init)
docker-machine create --driver virtualbox $MACHINE
sudo sh -c "echo $(docker-machine ip $MACHINE 2>/dev/null) $HOST >> /etc/hosts"
;;
# Restarts some/all of the containers.
restart)
case "$2" in
# Restarts the application.
app)
$0 stop app
$0 start app
;;
# Restarts the services.
services)
$0 stop services
$0 start services
;;
# Restarts both the services and application.
*)
$0 stop
$0 start
;;
esac
;;
# Builds and starts some/all of our containers.
start)
case "$2" in
# Builds and starts the application container.
app)
if [ ! -z "$APP_ID" ]; then
$0 stop app
fi
docker build -t $APPLICATION .
docker run -d \
-e "RECOMMENDATION_SERVICES=`docker-machine ip $MACHINE`" \
-p 80:8000/tcp --name="$APPLICATION" $APPLICATION
;;
# Builds and starts the services supporting the application container.
services)
docker-compose build
docker-compose up -d
;;
# Builds and starts the application server and the supporting services.
*)
$0 $1 services
$0 $1 app
;;
esac
;;
# Stops some/all of our containers.
stop)
case "$2" in
# Kills and removes the application container.
app)
if [ $STATUS == "Running" ]; then
if [ ! -z $APP_ID ]; then
docker kill $APP_ID >/dev/null
docker rm $APP_ID >/dev/null
fi
fi
;;
# Stops the service containers.
services)
if [ $STATUS = "Running" ]; then
docker-compose stop
fi
;;
# Kills and removes the application container, then stops the supporting
# services.
*)
$0 $1 app
$0 $1 services
;;
esac
;;
# Shows usage information.
help)
echo "Usage: $0 {start|stop|restart|init|help}"
;;
# Shows help message.
*)
$0 help
;;
esac