Docker on a Saudi Server: From Zero to Production

Docker simplifies deploying applications. Installation on a Saudi server and using Docker Compose for real production environment.
Why Docker on a Saudi Server?
Docker solves an old problem: "It works on my machine but not on the server." With Docker, your application runs the same way everywhere — on your local machine, on the staging server, and in production. Add a Saudi server with very low latency and you get an ideal environment for your applications.
Installing Docker
On Ubuntu 22.04 / 24.04
# Remove old versions
sudo apt remove docker docker-engine docker.io containerd runc 2>/dev/null
# Install prerequisites
sudo apt update
sudo apt install ca-certificates curl gnupg -y
# Add Docker's official GPG key
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
# Add the repository
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo $VERSION_CODENAME) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# Install
sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin -y
# Verify
sudo docker run hello-world
Run Docker Without sudo
sudo usermod -aG docker $USER
# Log out and back in
newgrp docker
Core Concepts
| Concept | Description |
|---|---|
| Image | A ready-made template containing the app and its dependencies |
| Container | A running instance of an Image |
| Dockerfile | Instructions file for building an Image |
| Volume | Persistent storage outside the container |
| Network | A network connecting containers to each other |
Basic Commands
# Run a container
docker run -d --name my-nginx -p 80:80 nginx
# List running containers
docker ps
# List all containers (including stopped)
docker ps -a
# Stop a container
docker stop my-nginx
# Remove a container
docker rm my-nginx
# List local images
docker images
# Remove an image
docker rmi nginx
# Enter a container
docker exec -it my-nginx bash
# View container logs
docker logs my-nginx
docker logs -f my-nginx # follow in real-time
Building Your First Image
Dockerfile for a Laravel Application
# File: Dockerfile
FROM php:8.3-fpm
# Install dependencies
RUN apt-get update && apt-get install -y \
git curl zip unzip libpng-dev libonig-dev libxml2-dev \
libzip-dev libpq-dev \
&& docker-php-ext-install pdo pdo_mysql mbstring exif pcntl bcmath gd zip \
&& apt-get clean && rm -rf /var/lib/apt/lists/*
# Install Composer
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
# Set working directory
WORKDIR /var/www/app
# Copy dependency files first (leverage cache)
COPY composer.json composer.lock ./
RUN composer install --no-dev --no-scripts --no-autoloader
# Copy remaining files
COPY . .
# Complete Composer install
RUN composer dump-autoload --optimize
# Set permissions
RUN chown -R www-data:www-data /var/www/app/storage /var/www/app/bootstrap/cache
EXPOSE 9000
CMD ["php-fpm"]
Build and Run the Image
# Build the image
docker build -t my-laravel-app:1.0 .
# Run the container
docker run -d \
--name laravel-app \
-p 9000:9000 \
-v $(pwd)/.env:/var/www/app/.env \
my-laravel-app:1.0
Data Management with Volumes
Data inside a container is deleted when the container is removed. Use Volumes for persistent data:
# Create a Volume
docker volume create mysql-data
# Run MySQL with a Volume
docker run -d \
--name mysql-db \
-e MYSQL_ROOT_PASSWORD=secret \
-e MYSQL_DATABASE=app_db \
-v mysql-data:/var/lib/mysql \
-p 3306:3306 \
mysql:8.0
# List Volumes
docker volume ls
# Inspect a Volume
docker volume inspect mysql-data
Networks
# Create a network
docker network create app-network
# Run containers on the same network
docker run -d --name db --network app-network mysql:8.0
docker run -d --name app --network app-network my-laravel-app:1.0
# Now the app container can reach db by name:
# DB_HOST=db (instead of IP)
The .dockerignore File
Exclude unnecessary files during build:
# File: .dockerignore
.git
.env
node_modules
vendor
storage/logs/*
storage/framework/cache/*
storage/framework/sessions/*
storage/framework/views/*
tests
docker-compose.yml
README.md
Performance Optimization on Saudi Servers
Speeding Up Image Pulls
# Configure local mirror (optional for large setups)
# File: /etc/docker/daemon.json
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
},
"storage-driver": "overlay2"
}
Cleaning Unused Resources
# Remove stopped containers, unused images, and networks
docker system prune -a
# Show disk usage
docker system df
Security
# Do not run containers as root
USER www-data # in Dockerfile
# Limit resources
docker run -d --name app \
--memory="512m" \
--cpus="1.0" \
my-laravel-app:1.0
# Never store secrets in the Image
# Use environment variables or Docker Secrets
Getting Started with CLOUD
CLOUD (cloud.net.sa) servers are Docker-ready from the first moment. KVM virtualization gives you full isolation and root access — install Docker and start building containers immediately. With fast SSD storage in Riyadh, building images and running containers happens at high speed.
Start with a cloud server from CLOUD at competitive pricing — pricing and plans and transform the way you deploy your applications entirely.
Get Started
Ready to build your project? Configure your cloud server with the specs your app needs, or view plans and pricing.
