diff --git a/doc/requirements.txt b/doc/requirements.txt
new file mode 100644
index 0000000000..ea4c643b95
--- /dev/null
+++ b/doc/requirements.txt
@@ -0,0 +1,3 @@
+openstackdocstheme>=1.17.0 # Apache-2.0
+reno>=2.5.0 # Apache-2.0
+sphinx>=1.6.2 # BSD
diff --git a/test-requirements.txt b/test-requirements.txt
index 0c64e906a0..2aac28a916 100644
--- a/test-requirements.txt
+++ b/test-requirements.txt
@@ -7,12 +7,9 @@ coverage!=4.4,>=4.0 # Apache-2.0
 fixtures>=3.0.0 # Apache-2.0/BSD
 flake8-import-order==0.13 # LGPLv3
 mock>=2.0.0 # BSD
-openstackdocstheme>=1.17.0 # Apache-2.0
 oslotest>=1.10.0 # Apache-2.0
-reno>=2.5.0 # Apache-2.0
 requests>=2.14.2 # Apache-2.0
 requests-mock>=1.1.0 # Apache-2.0
-sphinx>=1.6.2 # BSD
 stevedore>=1.20.0 # Apache-2.0
 os-client-config>=1.28.0 # Apache-2.0
 stestr>=1.0.0 # Apache-2.0
diff --git a/tox.ini b/tox.ini
index 8b5454f4ac..ca30150d25 100644
--- a/tox.ini
+++ b/tox.ini
@@ -105,10 +105,20 @@ commands =
     oslo_debug_helper -t openstackclient/tests {posargs}
 
 [testenv:docs]
-commands = python setup.py build_sphinx
+deps =
+  -c{env:UPPER_CONSTRAINTS_FILE:https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt}
+  -r{toxinidir}/requirements.txt
+  -r{toxinidir}/doc/requirements.txt
+commands =
+  sphinx-build -b html doc/source doc/build/html
 
 [testenv:releasenotes]
-commands = sphinx-build -a -E -W -d releasenotes/build/doctrees -b html releasenotes/source releasenotes/build/html
+deps =
+  -c{env:UPPER_CONSTRAINTS_FILE:https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt}
+  -r{toxinidir}/requirements.txt
+  -r{toxinidir}/doc/requirements.txt
+commands =
+  sphinx-build -a -E -W -d releasenotes/build/doctrees -b html releasenotes/source releasenotes/build/html
 
 [flake8]
 show-source = True