This tutorial will walk you through installing the New Relic agent in a Dockerized setup. This example is for Django, but the approach should apply to any setup.
Setting up a quick example Dockerized Django app
We'll use a slightly simplified version of the example from the docker-compose docs:
Dockerfile
FROM python:3.4
ENV PYTHONUNBUFFERED 1
RUN mkdir -p /code
WORKDIR /code
ADD requirements.txt /code/
RUN pip install -r requirements.txt
ADD . /code/
What's happening:
- We're setting up our base image with python 3.4
- We make a working directory inside the container at
/code
- We copy requirements.txt from our machine into the container, then we pip install our requirements.
- Finally, we add our current directory (e.g.: our project) to /code inside the container
docker-compose:
version: '3'
services:
web:
build: .
command: python manage.py runserver 0.0.0.0:8000
volumes:
- .:/code
ports:
- "8000:8000"
(note: I'm specifying the latest version of docker-compose here. If you're using an older version of docker, you can change the version string to 1 or 2 .. but you should consider upgrading. They've done some pretty rad stuff in the new compose.)
What's happening:
- We build the image from our
Dockerfile
- We tell our container to run the
python manage.py runserver
command - We expose port
8000
inside the machine to8000
on our host machine.
Set everything up
Finally, let's get our app running:
# create out django app:
docker-compose run web django-admin.py startproject composeexample .
# run the app:
docker-compose up
You should now be able to see your "it worked" page at: http://localhost:8000
Add the new relic agent
Based on the new relic setup instructions, we're going to need to do the following:
Install the new relic agent:
Edit requirements.txt
and add newrelic
requirements.txt
django==1.10
newrelic
You'll need to build your image again to apply these changes:
docker-compose build web
Create your New Relic config file:
docker-compose run --rm web newrelic-admin generate-config <your-key-goes-here> newrelic.ini
Notes:
- We run this inside our container. Because our
WORKDIR
in the container is mapped to our current directory, a newrelic.ini file will appear in your current directory.
You may want to have a look at that file and edit a few values. In particular app_name
.
NB: remember that we're running the agent inside our container. So your paths will need to reflect this. For example, if you want to turn on the log file, you would set it's value to be something like this:
log_file = /code/newrelic-python-agent.log
Run our app with New Relic:
The last thing we need to do is to wrap our run command with new-relic-admin. Edit docker-compose and change the command to be:
Normally, you would run your command something like this:
NEW_RELIC_CONFIG_FILE=newrelic.ini newrelic-admin run-program YOUR_COMMAND_OPTIONS
But with docker-compose we can make this a little neater. We'll
- Add
NEW_RELIC_CONFIG_FILE=newrelic.ini
as an environment variable - Set
newrelic-admin run-program ..
as our command
docker-compose.yml
version: '3'
services:
web:
build: .
command: newrelic-admin run-program python manage.py runserver 0.0.0.0:8000
volumes:
- .:/code
ports:
- "8000:8000"
environment:
- NEW_RELIC_CONFIG_FILE=/code/newrelic.ini
Notes:
- We've prepended our command with the
newrelic-admin
version. - We've set our
NEW_RELIC_CONFIG_FILE
as an environment variable (note: we used/code/..
as the path)
Now, when you run docker-compose up
your app should start logging to New Relic. You can double-make-sure by testing your configuration:
docker-compose run --rm web newrelic-admin validate-config /code/newrelic.ini
Hopefully you will see output something along the lines of:
Registration successful. Reporting to:
https://rpm.newrelic.com/accounts/../applications/...
So now you know enough to successfully setup New Relic for a Dockerized Django app. In the next section, we'll go over some slightly fancier implementations.
New Relic in production
Now, you probably don't really want to be running the new relic agent on your dev machine (and you prob don't want to be using runserver
on your production deploy btw). So, let's extend this to a slightly more "production ready" imlementation.
Remove New Relic from docker-compose
Revert your docker-compose back to it's original version.
Create a docker-compose.production.yml file
We'll create a production file which will extend our default docker-compose file and apply the necessary changes to run with new relic.
docker-compose.production.yml
version: '3'
services:
web:
command: newrelic-admin run-program gunicorn composeexample.wsgi:application -b :8000 --reload
environment:
- NEW_RELIC_CONFIG_FILE=/code/newrelic.ini
Here we just override the command and environment settings for production.
Finally, we need to add gunicorn
to our requirements.txt
.
Add gunicorn, then build the app:
docker-compose build web
We can now run a productionized version of our app with:
docker-compose -f docker-compose.yml -f docker-compose.production.yml up
Notes:
- We tell docker compose to use the default
docker-compose.yml
file, but to extend that with our production docker-compose file. (which runs our app with gunicorn and new relic
So now, if we run docker-compose up
on dev, we won't be tracking to New Relic.
Bonus section: Celery as a background process
If you're using celery with your Django app, you probably have a worker service. What you want to do is exactly the same setup (use the same newrelic.ini
file and the same app_name
). This way, New Relic will record your celery actions as a background process. Your worker
service might look something like this:
..
worker:
build: .
command: newrelic-admin run-program celery -A composeexample worker
volumes:
- .:/code
environment:
- C_FORCE_ROOT=true
- NEW_RELIC_CONFIG_FILE=/code/newrelic.ini
..