AutoDock Vina Tutorial for Beginners: Dock Your First Ligand From Scratch (2026)
By the end of this tutorial you will have run a complete molecular docking calculation — receptor prepared, ligand prepared, config file written, Vina executed, and results visualized. No prior experience with docking software required. Exact commands for every step.
What you’ll need before starting
This tutorial picks up where the previous two left off. Before starting, you should have:
- AutoDock Vina installed and working (
vina --versionreturns a version number) - AutoDockTools (MGLTools) installed — download free from ccsb.scripps.edu/mgltools
- PyMOL installed —
conda install -c conda-forge pymol-open-source - Open Babel installed —
conda install -c conda-forge openbabel - About 30–45 minutes and a working internet connection
Set up your working directory
Keep everything organized in a single folder from the start. A messy working directory is one of the most common causes of “I can’t find my output” problems.
mkdir -p ~/docking/cox2_ibuprofen
cd ~/docking/cox2_ibuprofen
mkdir receptor ligand output
You’ll end up with this structure:
cox2_ibuprofen/
├── receptor/
│ ├── 5KIR.pdb
│ ├── 5KIR_clean.pdb
│ └── 5KIR_receptor.pdbqt
├── ligand/
│ ├── ibuprofen.sdf
│ └── ibuprofen.pdbqt
├── config.txt
└── output/
├── docked.pdbqt
└── docking.log
Step 1 — Prepare the receptor
Download the COX-2 structure directly into your receptor folder:
cd ~/docking/cox2_ibuprofen/receptor
wget https://files.rcsb.org/download/5KIR.pdb
Now clean it using PyMOL — remove waters, the co-crystallized ligand, and crystallization artifacts:
# Load the raw structure
load 5KIR.pdb
# Remove water molecules
remove resn HOH
# Check what ligands are present
select hetatms, hetatm
iterate hetatms, print(resn)
# Remove the co-crystallized ligand (residue name varies — check your output above)
remove resn IMN
# Remove common crystallization artifacts
remove resn SO4+GOL+EDO+PEG
# Save the cleaned structure
save 5KIR_clean.pdb
Now use the AutoDockTools preparation script to add hydrogens, assign Gasteiger charges, and generate the PDBQT file in one command:
prepare_receptor4.py \
-r 5KIR_clean.pdb \
-o 5KIR_receptor.pdbqt \
-A hydrogens \
-U nphs_lps_waters_deleteAltB
Verify it worked — you should see your receptor PDBQT file:
ls -lh 5KIR_receptor.pdbqt
# Should show a file of several hundred KB
grep -c "^ATOM" 5KIR_receptor.pdbqt
# Should return several thousand — the number of protein atoms
grep " \? " 5KIR_receptor.pdbqt
# Should return nothing — no unknown atom types
~/MGLTools-1.5.7/bin/prepare_receptor4.py. Run it as python prepare_receptor4.py if it’s not on your PATH. On Windows, find it in the MGLTools installation directory and run it from there.
Step 2 — Prepare the ligand
Go to pubchem.ncbi.nlm.nih.gov and search for ibuprofen. On the compound page, click Download → SDF → 3D Conformer. Save the file as ibuprofen.sdf in your ligand/ folder.
Or download it directly from the command line using the PubChem API (compound ID for ibuprofen is 3672):
cd ~/docking/cox2_ibuprofen/ligand
wget "https://pubchem.ncbi.nlm.nih.gov/rest/pug/compound/CID/3672/SDF?record_type=3d" \
-O ibuprofen.sdf
Now convert the SDF to PDBQT format using Open Babel. This handles 3D conformer generation, charge assignment, and format conversion in one step:
obabel ibuprofen.sdf \
-O ibuprofen.pdbqt \
--gen3d \
-p 7.4 \
--partialcharge gasteiger
The flags here: --gen3d generates or refines the 3D conformation, -p 7.4 sets the protonation state at pH 7.4 (physiological), --partialcharge gasteiger assigns Gasteiger charges compatible with AutoDock’s scoring function.
Inspect the output to confirm it looks right:
cat ibuprofen.pdbqt
You should see ATOM/HETATM records with two extra columns at the end (the charge and atom type), and a TORSDOF line near the top indicating the number of rotatable bonds. For ibuprofen this should be 4.
Step 3 — Define the search space (grid box)
The grid box tells Vina where to search. It needs to be centered on the binding site and large enough to accommodate the ligand with room to explore — but not so large that the search becomes unfocused and slow.
Finding the binding site center
The easiest method when a co-crystallized ligand exists (as in 5KIR) is to use the centroid of that ligand as the box center. Load both the cleaned receptor and the original PDB in PyMOL to find it:
# Load original structure to see where the ligand was
load 5KIR.pdb, original
load 5KIR_clean.pdb, receptor
# Select the co-crystallized ligand in the original
select coligand, original and resn IMN
# Get the centroid coordinates
centerofmass coligand
PyMOL will print the XYZ centroid coordinates to the command line — something like [15.234, -8.441, 22.178]. Write these down: they become your center_x, center_y, center_z in the config file.
Setting the box size
For a typical drug-like molecule, a box of 20×20×20 Å is a safe starting point. This gives the ligand enough room to explore the binding pocket and find its optimal pose. If your target has a very large or elongated binding site, increase the box dimensions accordingly.
Step 4 — Write the config file
AutoDock Vina takes all its settings from a plain text config file. Create config.txt in your working directory (~/docking/cox2_ibuprofen/):
Use your actual centroid coordinates from Step 3 in place of the example values above. Everything else can stay as written for this tutorial.
Step 5 — Run AutoDock Vina
Navigate to your working directory and run Vina pointing at your config file:
cd ~/docking/cox2_ibuprofen
vina --config config.txt
Vina will print its progress to the terminal. A typical run with exhaustiveness = 8 takes 30–90 seconds on a modern laptop. Here is what the output looks like:
Reading input … done.
Setting up the scoring function … done.
Analyzing the binding site … done.
Using random seed: 1842039521
Performing docking (random seed: 1842039521) …
0% 10 20 30 40 50 60 70 80 90 100%
|—-|—-|—-|—-|—-|—-|—-|—-|—-|—-|
***************************************************
mode | affinity | dist from best mode
| (kcal/mol) | rmsd l.b.| rmsd u.b.
—–+————+———-+———-
1 -8.3 0.000 0.000
2 -7.9 1.823 2.541
3 -7.6 2.104 3.872
4 -7.4 1.951 4.103
5 -7.2 3.218 5.641
6 -7.1 2.874 5.102
7 -6.9 3.541 6.204
8 -6.8 4.102 6.891
9 -6.6 4.823 7.341
Example Vina output for ibuprofen docked into COX-2. Your exact scores will differ slightly due to the random seed.
The three columns are: mode (pose number, ranked best to worst), affinity (predicted binding free energy in kcal/mol — more negative is better), rmsd l.b. / u.b. (how different this pose is from the top-ranked pose, lower and upper bound estimates).
If Vina exits immediately with no output, check that your file paths in config.txt are correct and that both PDBQT files exist where specified.
Step 6 — Interpret and visualize the results
Understanding the binding affinity scores
| Score range | Predicted binding strength | Interpretation |
|---|---|---|
| −11 to −14 | Very strong | Exceptional hit — prioritize for experimental follow-up |
| −9 to −11 | Strong | Solid predicted binder — worth testing |
| −7 to −9 | Moderate | Reasonable — context-dependent; our ibuprofen score of −8.3 falls here |
| Above −7 | Weak | Unlikely to be a useful hit at this score |
Our top score of −8.3 kcal/mol for ibuprofen in COX-2 is in the moderate-to-strong range and consistent with its known experimental affinity — a good sign our protocol is working correctly.
Visualizing poses in PyMOL
Load the receptor and all docked poses into PyMOL to inspect them visually:
# Load receptor and docked poses
load receptor/5KIR_receptor.pdbqt, receptor
load output/docked.pdbqt, poses
# Show receptor as cartoon with binding site as sticks
hide everything
show cartoon, receptor
show sticks, receptor and (byres poses expand 5)
# Show all poses as sticks, colored by pose number
show sticks, poses
spectrum count, rainbow, poses
# Zoom to the binding site
zoom poses
The output PDBQT contains all 9 poses as separate MODEL entries. PyMOL loads them as individual states. Use the arrow keys or the state slider at the bottom to cycle through poses.
What to look for when inspecting poses
distance in PyMOL to measure — H-bonds are 2.5–3.5 Å.Step 7 — Validate your protocol with self-docking
Before you trust any results from this protocol, validate it. Self-docking means re-docking the co-crystallized ligand back into the receptor and comparing the resulting pose to the experimentally observed crystal pose. If your protocol is working correctly, the top-ranked docked pose should reproduce the crystal pose with an RMSD below 2.0 Å.
Extract the co-crystallized ligand from the original PDB file and prepare it exactly as you prepared ibuprofen:
# Extract only the co-crystallized ligand from the original structure
load 5KIR.pdb
select native_ligand, resn IMN
save ligand/native_ligand.pdb, native_ligand
# Convert to PDBQT
obabel ligand/native_ligand.pdb \
-O ligand/native_ligand.pdbqt \
--partialcharge gasteiger
Now run Vina again using native_ligand.pdbqt as the ligand input (same config file, same grid box). Then compare the top-ranked pose to the original crystal structure in PyMOL using the RMSD measurement tool:
# Load crystal pose and best docked pose
load 5KIR.pdb, crystal
load output/docked_native.pdbqt, redocked
# Calculate RMSD between crystal ligand and top docked pose
rms_cur crystal and resn IMN, redocked and state 1
RMSD 1.0–2.0 Å — acceptable. Minor deviations are normal; overall binding mode is captured.
RMSD > 2.0 Å — validation failed. Something is wrong with your preparation — check protonation states, grid box position, and whether you removed alternate conformations.
You’ve completed your first docking run
You downloaded a protein structure, cleaned it, prepared a ligand, defined a search space, ran AutoDock Vina, and got a set of ranked binding poses. That’s the full workflow — everything from here is either refinement (better preparation, higher exhaustiveness, GNINA instead of Vina) or scale (virtual screening of a compound library instead of a single ligand).
The next tutorial applies this workflow to virtual screening — running the same docking calculation against hundreds of compounds at once to find the best binders in a chemical library.
- Working directory created with
receptor/,ligand/, andoutput/subfolders - Receptor cleaned, hydrogens added, Gasteiger charges assigned, PDBQT generated
- Ligand downloaded from PubChem, converted to PDBQT with Open Babel
- Grid box center determined from co-crystallized ligand centroid
config.txtwritten with correct file paths, center coordinates, and box size- Vina ran successfully and returned 9 poses with binding scores
- Top poses inspected visually in PyMOL — ligand inside pocket, reasonable contacts
- Self-docking validation performed — RMSD below 2.0 Å