torchbox / wagtail-template

A Django template for starting new Wagtail projects with Vagrant. NO LONGER MAINTANED
19 stars 8 forks source link

Docker support #16

Closed kaedroho closed 9 years ago

kaedroho commented 9 years ago

This pull request adds Docker support into the Wagtail template. Not something we use at Torchbox but it's pretty damn handy!

It allows developers to define the environment that their app should run in with a Dockerfile and non-pip dependencies can be easily encapsulated.

This pull request adds production-ready docker configuration into the Wagtail template.

Create a new project with this template, and run the following commands (you only need Docker installed).

# Start databases (will download images if they don't exist)
docker run --name postgres -d -e "POSTGRES_PASSWORD=password123" postgres
docker run --name redis -d redis
docker run --name elasticsearch dockerfile/elasticsearch

# Create database
docker exec postgres createdb -Upostgres my_lovely_website

# Build image for this app
docker build -t my_lovely_website .

# Run the app
docker run --name=my_lovely_website -d -p 8000:80 -e "POSTGRES_PASSWORD=password123" -e "SECRET_KEY=test123" -e "ALLOWED_HOSTS=localhost" --link postgres:postgres --link redis:redis --link elasticsearch:elasticsearch my_lovely_website

# Run post-deploy tasks (collectstatic, migrate, etc)
docker exec my_lovely_website deploy

The site should be running at localhost:8000.

Commands

The Dockerfile installs two commands which can be called with docker exec on a running container.

dj

Like in our Vagrant config, this gives you access to the django admin commands. All commands run using production settings by default.

Example: docker exec -ti my_lovely_website dj update_index

deploy

This command runs post-deployment tasks (collectstatic, compress, migrate and update_index). It should be run when the app is first installed and on each deployment.

Environment variables

The container can be configured using environment variables. Docker lets you set these using the -e option of the docker run command.

Container management systems such as Dokku or Deis can manage these for you.

Required variables

ALLOWED_HOSTS This is a comma separated list of hostnames to put in Djangos ALLOWED_HOSTS setting

Example: -e "ALLOWED_HOSTS=example.com,myawesomewebsite.com"

SECRET_KEY This gets put into Djangos SECRET_KEY setting

PostgreSQL

You can link this container to an instance of the official postgres container by adding --link postgres:postgres to the docker run command.

When the container is linked in this way, the following variables become available (all are optional):

POSTGRES_USER (default: postgres) POSTGRES_PASSWORD (default: nothing) POSTGRES_DB (default: project name) POSTGRES_USE_POSTGIS (set this to 1 to use the postgis backend. default: 0)

External PostgreSQL

It's also possible to connect to a PostgreSQL instance that is not managed by Docker using the DATABASE_URL variable.

This uses the dj_database_url module documented here: https://github.com/kennethreitz/dj-database-url

Example: -e "DATABASE_URL=postgres://user:password@host:5432/database"

It is possible to connect to other DBMSes such as MySQL using this method.

Elasticsearch

Connecting to an Elasticsearch container managed by Docker is similar to connecting to a postgres one. Except you use different variables:

ELASTICSEARCH_INDEX (default: project name) ELASTICSEARCH_URL_PREFIX (must start with /. default: /)

To connect to an external Elasticsearch instance, use the ELASTICSEARCH_URL variable (this has the same format as is used in Wagtails settings). You use the ELASTICSEARCH_INDEX setting to specify which index to use on the remote host.

Redis

Again, Redis connections are configured in a similar way to PostgreSQL and Elasticsearch connections.

To connect to an external Redis server, use the REDIS_LOCATION variable. the format of this is <hostname>:<port>.

Example: ``-e "REDIS_LOCATION=123.1.2.3:6379"

Both when connecting to Redis using a Docker link and using the REDIS_LOCATION variable, all of the following variables are available:

REDIS_DB (default: 0) REDIS_PASSWORD (default: nothing) REDIS_KEY_PREFIX (default: project name)

kaedroho commented 9 years ago

The approach I plan on taking with static media is to serve everything through uWSGI by default and also set the static/media directories as docker volumes so somebody can setup a frontend web server (either on the host machine or in another container) to serve them directly if they wanted to.

tomdyson commented 9 years ago

See also https://github.com/kennethreitz/dj-static

kaedroho commented 9 years ago

Perfect! Will look into that. Thanks!

kaedroho commented 9 years ago

This is now done and ready for merge, I've added some docs above.

kaedroho commented 9 years ago

I might switch this to use uWSGI for serving static files: http://uwsgi-docs.readthedocs.org/en/latest/StaticFiles.html

TODO: