Adds utility script to ease working with Docker. (#129)
This commit is contained in:
Родитель
b5a0cb0a5a
Коммит
f21bbeb44c
116
docs/local.md
116
docs/local.md
|
@ -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.
|
||||
|
|
|
@ -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
|
Загрузка…
Ссылка в новой задаче