Where do you place the application inside the Docker image?

In the past, when deploying Python/Django projects, we'd put them in /srv/django-projects/APPNAME on a (possibly shared) machine. The python-virtualenv that came with it, went into /srv/virtualenvs/APPNAME.

Now that we're dockerizing many projects, we don't need the virtualenv (there is only one environment) and we don't need the APPNAME either (there is only one application). So, where should we place the project?

The usual suspects would be one of: /srv, /opt, /usr/src, /usr/local — optionally suffixed by APPNAME. Other common paths are: /app and /code.

  • /app - is not in the Filesystem Hierarchy Standard (FHS). The advantage of this over other paths is that it is just one level deep and short.
  • /code - is not in the FHS either, but it is short. However it feels like it contains source code, not runnable code.
  • /usr/src/APPNAME - anything here feels to me like it still needs compilation and copying to a real location.
  • /usr/local - /usr/local/APPNAME is inconveniently far away, and /usr/local/src/APPNAME suffers from the same problem as /code and /usr/src.
  • /opt - /opt or better /opt/APPNAME has always been my preferred place to put pre-built binary packages (for example Java applications, or other closed-source binaries) that did not arrive through the package manager. Placing my own code here feels wrong.
  • /srv would probably be my preferred location, because it's in the FHS and short enough, and empty. But on the other hand, it's not necessarily immediately clear that the application code resides here.

A quick scan of Dockerfile examples yields this:

golang: /go/src/app  [https://hub.docker.com/_/golang/]
hylang: /usr/src/app [https://hub.docker.com/_/hylang/]
perl:   /usr/src/app [https://hub.docker.com/_/perl/]
python: /app         [https://docs.docker.com/get-started/part2/#your-new-development-environment]
ruby:   /app         [https://github.com/buildkite/ruby-docker-example/blob/master/Dockerfile]

A quick Google search for the phrase COPY . /PATH yields these counts:

26k: /app
25k: /usr/src/app
 3k: /usr/src/APPNAME
 2k: /usr/local/...
 2k: /opt/APPNAME
 1k: /code + /code/APPNAME
 1k: /srv + /srv/APPNAME

Okay, so COPY . /app wins hands down. If we turn a blind eye to the FHS violation, this is the most common and best option. For golang applications we may make an exception, since go is rather picky about its paths.

path docker standards