🐘 🚀 TuskLang PHP Deployment and CI/CD Guide
🚀 TuskLang PHP Deployment and CI/CD Guide
"We don't bow to any king" - PHP Edition
Master TuskLang deployment and CI/CD in PHP! This guide covers Docker containerization, cloud deployment strategies, automated pipelines, and production deployment patterns that will make your applications deployment-ready and scalable.
🎯 Deployment Overview
TuskLang provides sophisticated deployment and CI/CD features that transform your configuration from development code into production-ready, scalable applications. This guide shows you how to implement enterprise-grade deployment while maintaining TuskLang's power.
<?php
// config/deployment-overview.tsk
[deployment_features]
docker_containerization: @docker.build("php:8.4-fpm", @request.app_config)
cloud_deployment: @cloud.deploy("aws", @request.environment)
ci_cd_pipeline: @ci.pipeline("github_actions", @request.deployment_stages)
auto_scaling: @scaling.auto(@request.load_metrics)
🐳 Docker Containerization
Basic Docker Configuration
<?php
// config/docker-basic.tsk
[dockerfile]
Multi-stage Docker build
base_image: "php:8.4-fpm-alpine"
composer_image: "composer:2.6"
nginx_image: "nginx:1.25-alpine"[build_stages]
Build stages configuration
stage_1: @docker.stage("base", {
"from": "php:8.4-fpm-alpine",
"install": ["git", "unzip", "libzip-dev"],
"extensions": ["pdo", "pdo_pgsql", "redis", "zip"]
})stage_2: @docker.stage("composer", {
"from": "composer:2.6",
"copy": ["composer.json", "composer.lock"],
"run": "composer install --no-dev --optimize-autoloader"
})
stage_3: @docker.stage("app", {
"from": "base",
"copy": ["app", "config", "public"],
"user": "www-data",
"expose": 9000
})
Advanced Docker Configuration
<?php
// config/docker-advanced.tsk
[multi_stage_build]
Multi-stage build with optimization
build_stages: @docker.multi_stage({
"base": {
"from": "php:8.4-fpm-alpine",
"install": ["git", "unzip", "libzip-dev", "supervisor"],
"extensions": ["pdo", "pdo_pgsql", "redis", "zip", "opcache"]
},
"dependencies": {
"from": "composer:2.6",
"copy": ["composer.json", "composer.lock"],
"run": "composer install --no-dev --optimize-autoloader --no-scripts"
},
"app": {
"from": "base",
"copy": ["app", "config", "public", "vendor"],
"user": "www-data",
"expose": 9000,
"healthcheck": "php-fpm-healthcheck"
}
})[optimization]
Docker build optimization
layer_caching: @docker.layer_caching({
"dependencies": ["composer.json", "composer.lock"],
"source_code": ["app", "config"],
"assets": ["public"]
})image_optimization: @docker.optimize({
"multi_stage": true,
"alpine_base": true,
"remove_dev_deps": true,
"compress_layers": true
})
Docker Compose Configuration
<?php
// config/docker-compose.tsk
[services]
Application services
app: @docker.service({
"build": ".",
"ports": ["9000:9000"],
"volumes": ["app_data:/var/www/html"],
"environment": @env.load(".env.production"),
"depends_on": ["database", "redis"]
})nginx: @docker.service({
"image": "nginx:1.25-alpine",
"ports": ["80:80", "443:443"],
"volumes": ["nginx_conf:/etc/nginx/conf.d"],
"depends_on": ["app"]
})
database: @docker.service({
"image": "postgres:15-alpine",
"ports": ["5432:5432"],
"volumes": ["postgres_data:/var/lib/postgresql/data"],
"environment": {
"POSTGRES_DB": @env("DB_DATABASE"),
"POSTGRES_USER": @env("DB_USERNAME"),
"POSTGRES_PASSWORD": @env("DB_PASSWORD")
}
})
redis: @docker.service({
"image": "redis:7-alpine",
"ports": ["6379:6379"],
"volumes": ["redis_data:/data"],
"command": "redis-server --appendonly yes"
})
[volumes]
Persistent volumes
app_data: @docker.volume()
postgres_data: @docker.volume()
redis_data: @docker.volume()
nginx_conf: @docker.volume()
☁️ Cloud Deployment
AWS Deployment
<?php
// config/aws-deployment.tsk
[aws_services]
AWS service configuration
ecs_cluster: @aws.ecs.cluster({
"name": "tusklang-app-cluster",
"capacity_providers": ["FARGATE", "FARGATE_SPOT"],
"default_capacity_provider": "FARGATE"
})ecs_service: @aws.ecs.service({
"cluster": "tusklang-app-cluster",
"task_definition": "tusklang-app-task",
"desired_count": @if(@env("ENVIRONMENT") == "production", 3, 1),
"load_balancer": "tusklang-alb"
})
[auto_scaling]
Auto-scaling configuration
scaling_policy: @aws.ecs.scaling({
"min_capacity": 1,
"max_capacity": 10,
"target_cpu_utilization": 70,
"target_memory_utilization": 80,
"scale_in_cooldown": 300,
"scale_out_cooldown": 60
})[load_balancer]
Application Load Balancer
alb: @aws.alb({
"name": "tusklang-alb",
"subnets": ["subnet-12345678", "subnet-87654321"],
"security_groups": ["sg-tusklang-app"],
"listeners": [
{"port": 80, "protocol": "HTTP", "redirect": 443},
{"port": 443, "protocol": "HTTPS", "certificate": "arn:aws:acm:us-east-1:123456789012:certificate/abcd1234"}
]
})
Google Cloud Deployment
<?php
// config/gcp-deployment.tsk
[gcp_services]
Google Cloud services
cloud_run: @gcp.cloud_run({
"service_name": "tusklang-app",
"image": "gcr.io/tusklang-project/tusklang-app:latest",
"region": "us-central1",
"cpu": "1000m",
"memory": "2Gi",
"max_instances": @if(@env("ENVIRONMENT") == "production", 10, 3),
"concurrency": 80
})[auto_scaling]
Cloud Run auto-scaling
scaling_config: @gcp.cloud_run.scaling({
"min_instances": 0,
"max_instances": @if(@env("ENVIRONMENT") == "production", 10, 3),
"cpu_threshold": 70,
"request_threshold": 1000
})[load_balancer]
Cloud Load Balancer
load_balancer: @gcp.load_balancer({
"name": "tusklang-lb",
"backend": "tusklang-app",
"ssl_certificate": "tusklang-ssl-cert",
"cdn": true
})
Azure Deployment
<?php
// config/azure-deployment.tsk
[azure_services]
Azure services
app_service: @azure.app_service({
"name": "tusklang-app",
"plan": "tusklang-plan",
"runtime": "PHP|8.4",
"region": "East US",
"sku": @if(@env("ENVIRONMENT") == "production", "P1v2", "B1")
})[auto_scaling]
App Service auto-scaling
scaling_rules: @azure.app_service.scaling({
"min_instances": 1,
"max_instances": @if(@env("ENVIRONMENT") == "production", 10, 3),
"cpu_threshold": 70,
"memory_threshold": 80,
"schedule": {
"weekdays": {"min": 2, "max": 5},
"weekends": {"min": 1, "max": 3}
}
})[cdn]
Azure CDN
cdn_profile: @azure.cdn({
"name": "tusklang-cdn",
"origin": "tusklang-app.azurewebsites.net",
"optimization": "general",
"compression": true
})
🔄 CI/CD Pipelines
GitHub Actions
<?php
// config/github-actions.tsk
[ci_cd_pipeline]
GitHub Actions pipeline
workflow: @ci.github_actions({
"name": "TuskLang PHP CI/CD",
"on": ["push", "pull_request"],
"jobs": [
"test",
"build",
"deploy"
]
})[test_job]
Testing job
test: @ci.job("test", {
"runs_on": "ubuntu-latest",
"steps": [
{"name": "Checkout", "uses": "actions/checkout@v4"},
{"name": "Setup PHP", "uses": "shivammathur/setup-php@v2", "with": {"php-version": "8.4"}},
{"name": "Install dependencies", "run": "composer install"},
{"name": "Run tests", "run": "vendor/bin/phpunit"},
{"name": "Code coverage", "run": "vendor/bin/phpunit --coverage-clover coverage.xml"}
]
})[build_job]
Build job
build: @ci.job("build", {
"runs_on": "ubuntu-latest",
"needs": "test",
"steps": [
{"name": "Checkout", "uses": "actions/checkout@v4"},
{"name": "Build Docker image", "run": "docker build -t tusklang-app ."},
{"name": "Push to registry", "run": "docker push tusklang-app:latest"}
]
})[deploy_job]
Deployment job
deploy: @ci.job("deploy", {
"runs_on": "ubuntu-latest",
"needs": "build",
"if": "github.ref == 'refs/heads/main'",
"steps": [
{"name": "Deploy to staging", "run": "@deploy.aws.ecs('staging')"},
{"name": "Run smoke tests", "run": "@test.smoke('staging')"},
{"name": "Deploy to production", "run": "@deploy.aws.ecs('production')"}
]
})
GitLab CI/CD
<?php
// config/gitlab-ci.tsk
[gitlab_pipeline]
GitLab CI/CD pipeline
pipeline: @ci.gitlab({
"stages": ["test", "build", "deploy"],
"variables": {
"DOCKER_DRIVER": "overlay2",
"DOCKER_TLS_CERTDIR": "/certs"
}
})[test_stage]
Test stage
test: @ci.gitlab.job("test", {
"stage": "test",
"image": "php:8.4-fpm",
"services": ["postgres:15", "redis:7"],
"script": [
"composer install",
"vendor/bin/phpunit",
"vendor/bin/phpstan analyse",
"vendor/bin/phpcs"
]
})[build_stage]
Build stage
build: @ci.gitlab.job("build", {
"stage": "build",
"image": "docker:latest",
"services": ["docker:dind"],
"script": [
"docker build -t tusklang-app .",
"docker push tusklang-app:latest"
]
})[deploy_stage]
Deploy stage
deploy: @ci.gitlab.job("deploy", {
"stage": "deploy",
"image": "alpine/helm:latest",
"script": [
"helm upgrade --install tusklang-app ./helm",
"kubectl rollout status deployment/tusklang-app"
],
"environment": {
"name": @if(@env("CI_COMMIT_BRANCH") == "main", "production", "staging"),
"url": @if(@env("CI_COMMIT_BRANCH") == "main", "https://app.tusklang.com", "https://staging.tusklang.com")
}
})
Jenkins Pipeline
<?php
// config/jenkins-pipeline.tsk
[jenkins_pipeline]
Jenkins pipeline
pipeline: @ci.jenkins({
"agent": "any",
"stages": ["Checkout", "Test", "Build", "Deploy"],
"post": ["always", "success", "failure"]
})[checkout_stage]
Checkout stage
checkout: @ci.jenkins.stage("Checkout", {
"steps": [
{"checkout": "scm"},
{"sh": "git log --oneline -10"}
]
})[test_stage]
Test stage
test: @ci.jenkins.stage("Test", {
"steps": [
{"sh": "composer install"},
{"sh": "vendor/bin/phpunit --coverage-html coverage"},
{"publishHTML": {"target": ["reportDir: 'coverage', reportFiles: 'index.html', reportName: 'Coverage Report']}}
]
})[build_stage]
Build stage
build: @ci.jenkins.stage("Build", {
"steps": [
{"sh": "docker build -t tusklang-app ."},
{"sh": "docker tag tusklang-app:latest tusklang-app:$BUILD_NUMBER"}
]
})[deploy_stage]
Deploy stage
deploy: @ci.jenkins.stage("Deploy", {
"when": {"branch": "main"},
"steps": [
{"sh": "docker push tusklang-app:$BUILD_NUMBER"},
{"sh": "kubectl set image deployment/tusklang-app app=tusklang-app:$BUILD_NUMBER"},
{"sh": "kubectl rollout status deployment/tusklang-app"}
]
})
🔧 Infrastructure as Code
Terraform Configuration
<?php
// config/terraform.tsk
[terraform_config]
Terraform configuration
provider: @terraform.provider("aws", {
"region": "us-east-1",
"version": "~> 5.0"
})[ecs_cluster]
ECS cluster
cluster: @terraform.aws_ecs_cluster({
"name": "tusklang-cluster",
"capacity_providers": ["FARGATE"],
"default_capacity_provider_strategy": [
{"capacity_provider": "FARGATE", "weight": 1}
]
})[ecs_service]
ECS service
service: @terraform.aws_ecs_service({
"name": "tusklang-app",
"cluster": "tusklang-cluster",
"task_definition": "tusklang-task",
"desired_count": @if(@env("ENVIRONMENT") == "production", 3, 1),
"launch_type": "FARGATE",
"network_configuration": {
"subnets": ["subnet-12345678", "subnet-87654321"],
"security_groups": ["sg-tusklang-app"],
"assign_public_ip": false
}
})[auto_scaling]
Auto-scaling
scaling: @terraform.aws_appautoscaling_target({
"service_namespace": "ecs",
"scalable_dimension": "ecs:service:DesiredCount",
"resource_id": "service/tusklang-cluster/tusklang-app",
"min_capacity": 1,
"max_capacity": @if(@env("ENVIRONMENT") == "production", 10, 3)
})
Kubernetes Configuration
<?php
// config/kubernetes.tsk
[kubernetes_config]
Kubernetes configuration
namespace: @k8s.namespace({
"name": "tusklang",
"labels": {"app": "tusklang", "environment": @env("ENVIRONMENT")}
})[deployment]
Application deployment
app_deployment: @k8s.deployment({
"name": "tusklang-app",
"replicas": @if(@env("ENVIRONMENT") == "production", 3, 1),
"selector": {"matchLabels": {"app": "tusklang-app"}},
"template": {
"metadata": {"labels": {"app": "tusklang-app"}},
"spec": {
"containers": [{
"name": "app",
"image": "tusklang-app:latest",
"ports": [{"containerPort": 9000}],
"env": @env.load(".env.k8s"),
"resources": {
"requests": {"memory": "256Mi", "cpu": "250m"},
"limits": {"memory": "512Mi", "cpu": "500m"}
}
}]
}
}
})[service]
Service configuration
app_service: @k8s.service({
"name": "tusklang-app-service",
"selector": {"app": "tusklang-app"},
"ports": [{"port": 80, "targetPort": 9000}],
"type": "ClusterIP"
})[ingress]
Ingress configuration
app_ingress: @k8s.ingress({
"name": "tusklang-ingress",
"annotations": {
"kubernetes.io/ingress.class": "nginx",
"cert-manager.io/cluster-issuer": "letsencrypt-prod"
},
"rules": [{
"host": @env("DOMAIN"),
"http": {
"paths": [{
"path": "/",
"pathType": "Prefix",
"backend": {
"service": {"name": "tusklang-app-service", "port": {"number": 80}}
}
}]
}
}],
"tls": [{"hosts": [@env("DOMAIN")], "secretName": "tusklang-tls"}]
})
📊 Monitoring and Observability
Application Monitoring
<?php
// config/monitoring.tsk
[monitoring_config]
Application monitoring
metrics: @monitoring.metrics({
"provider": "cloudwatch",
"namespace": "TuskLang/Application",
"dimensions": ["Environment", "Service"]
})[health_checks]
Health checks
health_check: @monitoring.health_check({
"endpoint": "/health",
"interval": 30,
"timeout": 5,
"healthy_threshold": 2,
"unhealthy_threshold": 3
})[alerts]
Alerting configuration
alerts: @monitoring.alerts({
"high_cpu": {
"metric": "CPUUtilization",
"threshold": 80,
"period": 300,
"evaluation_periods": 2
},
"high_memory": {
"metric": "MemoryUtilization",
"threshold": 85,
"period": 300,
"evaluation_periods": 2
},
"high_error_rate": {
"metric": "ErrorRate",
"threshold": 5,
"period": 300,
"evaluation_periods": 1
}
})
Logging Configuration
<?php
// config/logging.tsk
[logging_config]
Logging configuration
log_groups: @logging.cloudwatch({
"application_logs": {
"name": "/aws/ecs/tusklang-app",
"retention_days": 30,
"metric_filters": ["error", "warning", "info"]
},
"access_logs": {
"name": "/aws/alb/tusklang-alb",
"retention_days": 90,
"metric_filters": ["4xx", "5xx"]
}
})[log_aggregation]
Log aggregation
fluentd_config: @logging.fluentd({
"source": {
"type": "tail",
"path": "/var/log/application/*.log",
"pos_file": "/var/log/fluentd/application.log.pos"
},
"match": {
"type": "cloudwatch_logs",
"log_group_name": "/aws/ecs/tusklang-app",
"region": "us-east-1"
}
})
🔒 Security Configuration
Security Groups and IAM
<?php
// config/security.tsk
[security_groups]
Security group configuration
app_security_group: @aws.security_group({
"name": "tusklang-app-sg",
"description": "Security group for TuskLang application",
"ingress": [
{"port": 80, "protocol": "tcp", "cidr_blocks": ["0.0.0.0/0"]},
{"port": 443, "protocol": "tcp", "cidr_blocks": ["0.0.0.0/0"]}
],
"egress": [
{"port": 0, "protocol": "-1", "cidr_blocks": ["0.0.0.0/0"]}
]
})[iam_roles]
IAM role configuration
ecs_task_role: @aws.iam_role({
"name": "tusklang-ecs-task-role",
"assume_role_policy": {
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {"Service": "ecs-tasks.amazonaws.com"},
"Action": "sts:AssumeRole"
}]
},
"managed_policy_arns": [
"arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy"
]
})
📚 Best Practices
Deployment Best Practices
<?php
// config/deployment-best-practices.tsk
[best_practices]
Deployment best practices
blue_green_deployment: @deployment.blue_green({
"enabled": @if(@env("ENVIRONMENT") == "production", true, false),
"health_check_path": "/health",
"rollback_threshold": 5,
"rollback_timeout": 300
})canary_deployment: @deployment.canary({
"enabled": @if(@env("ENVIRONMENT") == "production", true, false),
"initial_percentage": 10,
"increment_percentage": 20,
"increment_interval": 300,
"success_threshold": 95
})
[rollback_strategy]
Rollback strategy
rollback: @deployment.rollback({
"automatic": true,
"health_check_failure_threshold": 3,
"rollback_timeout": 600,
"notification_channels": ["slack", "email"]
})
📚 Next Steps
Now that you've mastered TuskLang's deployment and CI/CD features in PHP, explore:
1. Advanced Containerization - Multi-architecture builds and optimization 2. Cloud-Native Patterns - Serverless and microservices deployment 3. Security Hardening - Container security and compliance 4. Performance Optimization - Deployment performance tuning 5. Disaster Recovery - Backup and recovery strategies
🆘 Need Help?
- Documentation: https://tuskt.sk/documents/php/deployment - Examples: https://github.com/tusklang/php-examples - Community: https://community.tuskt.sk
---
Ready to deploy your PHP applications with TuskLang? You're now a TuskLang deployment master! 🚀