[Disclaimer: I am the guy who was running OpenVZ since the very beginning, and if you hate OpenVZ name/logo, I am the one to blame. Also, take everything I say with a grain of salt -- although I know, use, like and develop for Docker, my expertise is mostly within OpenVZ domain, and my point of view is skewed towards OpenVZ]

Technologically, both OpenVZ and Docker are similar, i.e. they are containers -- isolated userspace instances, relying on Linux Kernel features such as namespaces. [Shameless plug: most of namespaces functionality is there because of OpenVZ engineers work on upstreaming]. Both Docker and OpenVZ has tools to set up and run containers. This is there the similarities end.

The differences are:

1 system containers vs application containers

OpenVZ containers are very much like VMs, except for the fact they are not VMs but containers, i.e. all containers on a host are running on top of one single kernel. Each OpenVZ container has everything (init, sshd, syslogd etc.) except the kernel (which is shared).

Docker containers are application containers, meaning Docker only runs a single app inside (i.e. a web server, a SQL server etc).

2 Custom kernel vs vanilla kernel

OpenVZ currently comes with its own kernel. 10 years ago there were very few container features in the upstream kernel, so OpenVZ has to provide their own kernel, patched for containers support. That support includes namespaces, resource management mechanisms (CPU scheduler, I/O scheduler, User Beancounters, two-level disk quota etc), virtualization of /proc and /sys, and live migration. Over ten years of work of OpenVZ kernel devs and other interesting parties (such as Google and IBM) a lot of this functionality is now available in the upstream Linux kernel. That opened a way for other container orchestration tools to exist -- including Docker, LXC, LXD, CoreOS etc. While there are many small things missing, the last big thing -- checkpointing and live migration -- was also recently implemented in upstream, see CRIU project (a subproject of OpenVZ, so another shameless plug -- it is OpenVZ who brought live migration to Docker). Still, OpenVZ comes with its own custom kernel, partly due to retain backward compatibility, partly due to some features still missing from the upstream kernel. Nowadays that kernel is optional but still highly recommended.

Docker, on the other side, runs on top of a recent upstream kernel, i.e. it does not need a custom kernel.

3 Scope

Docker has a broader scope than that of OpenVZ. OpenVZ just provides you with a way to run secure, isolated containers, manage those, tinker with resources, live migrate, snapshot, etc. But most of OpenVZ stuff is in the kernel.

Docker has some other things in store, such as Docker Hub -- a global repository of Docker images, Docker Swarm -- a clustering mechanism to work with a pool of Docker servers, etc.

4 Commercial stuff

OpenVZ is a base for commercial solution called Virtuozzo, which is not available for free but adds some more features, such as cluster filesystem for containers, rebootless kernel upgrades, more/better tools, better containers density etc. With Docker there's no such thing. I am not saying it's good or bad, just stating the difference.

This is probably it. Now, it's not that OpenVZ and Docker are opposed to each other, in fact we work together on a few things:

1. OpenVZ developers are authors of CRIU, P.Haul, and CRIU integration code in Docker's libcontainer. This is the software that enables checkpoint/restore support for Docker.

2. Docker containers can run inside OpenVZ containers (https://openvz.org/Docker_inside_CT)

3. OpenVZ devs are authors of libct, a C library to manage containers, a proposed replacement or addition to Docker's libcontainer. When using libct, you can use enhanced OpenVZ kernel for Docker containers.

There's more to come, stay tuned.