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:
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/
- We're setting up our base image with python 3.4
- We make a working directory inside the container at
- 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
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.)
- We build the image from our
- We tell our container to run the
python manage.py runservercommand
- We expose port
8000inside the machine to
8000on 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:
requirements.txt and add
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
- We run this inside our container. Because our
WORKDIRin 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
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
NEW_RELIC_CONFIG_FILE=newrelic.inias an environment variable
newrelic-admin run-program ..as our command
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
- We've prepended our command with the
- We've set our
NEW_RELIC_CONFIG_FILEas 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.
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
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
- We tell docker compose to use the default
docker-compose.ymlfile, 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 ..