Install and run Docker on Ubuntu VPS
STEP 1️⃣ Prerequisites (Once per server)
You already have most of this, but for completeness:
sudo apt update
sudo apt install -y nginx mysql-client git curl
Docker (if not installed):
curl -fsSL https://get.docker.com | sudo sh
sudo usermod -aG docker $USER
newgrp docker
Verify:
docker --version
docker compose version
STEP 2️⃣ Create project directory
mkdir -p /var/www/php82-app
cd /var/www/php82-app
Structure:
php82-app/
├── public/
│ └── index.php
├── docker/
│ └── php/
│ ├── Dockerfile
│ └── php.ini
├── docker-compose.yml
├── .env.example
└── .gitignore
STEP 3️⃣ Create PHP app file
📄 public/index.php
<?php
echo "PHP 8.2 Docker is working!";
STEP 4️⃣ PHP 8.2 Dockerfile
📄 docker/php/Dockerfile
FROM php:8.2-fpm
# Install PHP extensions needed for MySQL
RUN docker-php-ext-install pdo pdo_mysql
WORKDIR /var/www/html
COPY php.ini /usr/local/etc/php/conf.d/custom.ini
📄 docker/php/php.ini
memory_limit=256M
display_errors=Off
log_errors=On
error_log=/proc/self/fd/2
max_execution_time=60
STEP 5️⃣ docker-compose.yml
📄 docker-compose.yml
version: "3.9"
services:
php:
build: ./docker/php
container_name: php82_app
volumes:
- .:/var/www/html
ports:
- "127.0.0.1:9005:9000"
restart: unless-stopped
⚠️ Port
9005must be unused.
(Use a different port per project.)
STEP 6️⃣ Environment variables (MySQL on host)
📄 .env.example
DB_HOST=127.0.0.1
DB_PORT=3306
DB_NAME=app_db
DB_USER=app_user
DB_PASS=secret
📄 .gitignore
.env
vendor/
node_modules/
Create real env:
cp .env.example .env
STEP 7️⃣ Build & start PHP container
docker compose build
docker compose up -d
Check:
docker ps
You should see php82_app.
STEP 8️⃣ Configure Nginx (HOST)
📄 /etc/nginx/sites-available/php82-app.conf
server {
listen 80;
server_name php82-app.test;
root /var/www/php82-app/public;
index index.php index.html;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass 127.0.0.1:9005;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
error_log /var/log/nginx/php82-app-error.log;
access_log /var/log/nginx/php82-app-access.log;
}
Enable site:
sudo ln -s /etc/nginx/sites-available/php82-app.conf /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
STEP 9️⃣ Test PHP
Open:
http://php82-app.test
Expected output:
PHP 8.2 Docker is working!
STEP 🔟 Test MySQL connection (IMPORTANT)
📄 public/db-test.php
<?php
$pdo = new PDO(
"mysql:host=127.0.0.1;dbname=app_db",
"app_user",
"secret",
[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
);
echo "MySQL connection OK";
Open:
http://php82-app.test/db-test.php
⚠️ IMPORTANT: MySQL access from Docker
Because MySQL is on host:
✅ Use:
DB_HOST=host.docker.internal
OR (Linux best way):
DB_HOST=172.17.0.1
Find it:
ip route | grep docker0
👉 127.0.0.1 inside container ≠ host
Essential Commands
List of running Docker containers
docker ps
You should see:
CONTAINER ID IMAGE NAMES PORTS
abcd1234 nginx:alpine nginx_proxy 0.0.0.0:8080->80/tcp
Down a container
docker-compose down
Up a Docker container
Go the the container directory first then run
docker-compose up -d
Down & up again a container
docker-compose down
docker-compose up -d
Restart a container
docker restart container_name
Open a container
docker exec -it container_name sh
docker exec -it service_status_prismict bash
🔄 Rebuild & start
docker-compose build --no-cache
docker-compose up -d
🧠 Correct DB_HOST (Linux Docker)
Use in .env:
DB_HOST=172.17.0.1
✅ Final Result
✔ PHP 8.2 isolated
✔ MySQL shared globally
✔ Nginx stays fast on host
✔ Easy to migrate VPS
✔ Everything Git-friendly