06.实战案例
19. 案例一:搭建 Nginx 静态网站
最简单的入门案例:
目录结构:
1 2 3 4
| project/ ├── docker-compose.yml └── html/ └── index.html
|
docker-compose.yml:
1 2 3 4 5 6 7 8 9 10 11
| version: "3.8"
services: nginx: image: nginx:alpine container_name: nginx-web ports: - "80:80" volumes: - ./html:/usr/share/nginx/html:ro restart: unless-stopped
|
html/index.html:
1 2 3 4 5 6 7 8 9
| <!DOCTYPE html> <html> <head> <title>Hello Docker</title> </head> <body> <h1>Hello from Docker!</h1> </body> </html>
|
运行:
20. 案例二:部署 WordPress 博客
docker-compose.yml:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| version: "3.8"
services: wordpress: image: wordpress:latest container_name: wordpress ports: - "8080:80" environment: WORDPRESS_DB_HOST: mysql WORDPRESS_DB_USER: wordpress WORDPRESS_DB_PASSWORD: wordpress_password WORDPRESS_DB_NAME: wordpress volumes: - wordpress-data:/var/www/html depends_on: mysql: condition: service_healthy networks: - wp-network restart: unless-stopped
mysql: image: mysql:8.0 container_name: wordpress-db environment: MYSQL_ROOT_PASSWORD: root_password MYSQL_DATABASE: wordpress MYSQL_USER: wordpress MYSQL_PASSWORD: wordpress_password volumes: - mysql-data:/var/lib/mysql networks: - wp-network healthcheck: test: ["CMD", "mysqladmin", "ping", "-h", "localhost"] interval: 10s timeout: 5s retries: 5 restart: unless-stopped
networks: wp-network: driver: bridge
volumes: wordpress-data: mysql-data:
|
运行:
21. 案例三:Node.js + MySQL + Redis 开发环境
目录结构:
1 2 3 4 5 6 7
| project/ ├── docker-compose.yml ├── .env ├── Dockerfile ├── package.json └── src/ └── index.js
|
docker-compose.yml:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
| version: "3.8"
services: app: build: . container_name: node-app ports: - "3000:3000" environment: NODE_ENV: development DB_HOST: mysql DB_PORT: 3306 DB_NAME: ${DB_NAME:-myapp} DB_USER: ${DB_USER:-root} DB_PASSWORD: ${DB_PASSWORD:-123456} REDIS_HOST: redis REDIS_PORT: 6379 volumes: - ./src:/app/src - /app/node_modules depends_on: mysql: condition: service_healthy redis: condition: service_started networks: - dev-network restart: unless-stopped
mysql: image: mysql:8.0 container_name: mysql-db ports: - "3306:3306" environment: MYSQL_ROOT_PASSWORD: ${DB_PASSWORD:-123456} MYSQL_DATABASE: ${DB_NAME:-myapp} volumes: - mysql-data:/var/lib/mysql networks: - dev-network healthcheck: test: ["CMD", "mysqladmin", "ping", "-h", "localhost"] interval: 10s timeout: 5s retries: 5 restart: unless-stopped
redis: image: redis:7-alpine container_name: redis-cache ports: - "6379:6379" volumes: - redis-data:/data networks: - dev-network restart: unless-stopped
networks: dev-network: driver: bridge
volumes: mysql-data: redis-data:
|
Dockerfile:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| FROM node:18-alpine
WORKDIR /app
COPY package*.json ./ RUN npm install
COPY . .
EXPOSE 3000
CMD ["npm", "run", "dev"]
|
.env:
1 2 3
| DB_NAME=myapp DB_USER=root DB_PASSWORD=123456
|
22. 案例四:企业级日志收集系统(Loki + Grafana)
相比 ELK,Loki + Grafana 更轻量,适合中小规模项目。
docker-compose.yml:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
| version: "3.8"
services: loki: image: grafana/loki:2.9.0 container_name: loki ports: - "3100:3100" volumes: - ./loki-config.yml:/etc/loki/local-config.yaml - loki-data:/loki command: -config.file=/etc/loki/local-config.yaml networks: - monitoring restart: unless-stopped
promtail: image: grafana/promtail:2.9.0 container_name: promtail volumes: - ./promtail-config.yml:/etc/promtail/config.yml - /var/log:/var/log:ro - /var/lib/docker/containers:/var/lib/docker/containers:ro command: -config.file=/etc/promtail/config.yml networks: - monitoring restart: unless-stopped
grafana: image: grafana/grafana:10.0.0 container_name: grafana ports: - "3000:3000" environment: - GF_SECURITY_ADMIN_USER=admin - GF_SECURITY_ADMIN_PASSWORD=admin123 volumes: - grafana-data:/var/lib/grafana depends_on: - loki networks: - monitoring restart: unless-stopped
app: image: nginx:alpine container_name: demo-app ports: - "80:80" logging: driver: json-file options: max-size: "10m" max-file: "3" networks: - monitoring restart: unless-stopped
networks: monitoring: driver: bridge
volumes: loki-data: grafana-data:
|
loki-config.yml:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| auth_enabled: false
server: http_listen_port: 3100
ingester: lifecycler: ring: kvstore: store: inmemory replication_factor: 1 chunk_idle_period: 5m chunk_retain_period: 30s
schema_config: configs: - from: 2020-10-24 store: boltdb-shipper object_store: filesystem schema: v11 index: prefix: index_ period: 24h
storage_config: boltdb_shipper: active_index_directory: /loki/index cache_location: /loki/cache shared_store: filesystem filesystem: directory: /loki/chunks
limits_config: enforce_metric_name: false reject_old_samples: true reject_old_samples_max_age: 168h
chunk_store_config: max_look_back_period: 0s
table_manager: retention_deletes_enabled: false retention_period: 0s
|
promtail-config.yml:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| server: http_listen_port: 9080 grpc_listen_port: 0
positions: filename: /tmp/positions.yaml
clients: - url: http://loki:3100/loki/api/v1/push
scrape_configs: - job_name: containers static_configs: - targets: - localhost labels: job: containerlogs __path__: /var/lib/docker/containers/*/*log pipeline_stages: - json: expressions: output: log stream: stream time: time - output: source: output
|