{"id":15940,"date":"2026-04-28T23:00:19","date_gmt":"2026-04-28T15:00:19","guid":{"rendered":"https:\/\/top.duoku.icu\/libs\/15940.html"},"modified":"2026-04-28T23:00:19","modified_gmt":"2026-04-28T15:00:19","slug":"docker-compose-%e7%94%9f%e4%ba%a7%e5%8c%96%ef%bc%9a%e6%9b%bf%e4%bb%a3-k8s-%e7%9a%84%e8%bd%bb%e9%87%8f%e7%ba%a7%e6%96%b9%e6%a1%88","status":"publish","type":"post","link":"https:\/\/www.srclibs.com\/index.php\/2026\/04\/28\/docker-compose-%e7%94%9f%e4%ba%a7%e5%8c%96%ef%bc%9a%e6%9b%bf%e4%bb%a3-k8s-%e7%9a%84%e8%bd%bb%e9%87%8f%e7%ba%a7%e6%96%b9%e6%a1%88\/","title":{"rendered":"Docker Compose \u751f\u4ea7\u5316\uff1a\u66ff\u4ee3 K8s \u7684\u8f7b\u91cf\u7ea7\u65b9\u6848"},"content":{"rendered":"<div style=\"text-align:center;margin:30px 0;\"><img decoding=\"async\" src=\"https:\/\/top.duoku.icu\/wp-content\/uploads\/2026\/04\/image-97.png\" alt=\"Docker Compose \u751f\u4ea7\u5316\uff1a\u66ff\u4ee3 K8s \u7684\u8f7b\u91cf\u7ea7\u65b9\u6848\" style=\"max-width:100%;height:auto;border-radius:12px;box-shadow:0 4px 12px rgba(0,0,0,0.1);\"><\/div>\n<h1>Docker Compose \u751f\u4ea7\u5316\uff1a\u66ff\u4ee3 K8s \u7684\u8f7b\u91cf\u7ea7\u65b9\u6848<\/h1>\n<h2>\u5f15\u8a00<\/h2>\n<p>\u5728\u4e91\u539f\u751f\u751f\u6001\u4e2d\uff0c<strong>Kubernetes (K8s)<\/strong> \u65e0\u7591\u662f\u5bb9\u5668\u7f16\u6392\u7684\u738b\u8005\uff0c\u4f46\u5b83\u7684\u590d\u6742\u6027\u4e5f\u8ba9\u8bb8\u591a\u4e2d\u5c0f\u578b\u9879\u76ee\u671b\u800c\u5374\u6b65\u3002<strong>Docker Compose<\/strong> \u4f5c\u4e3a\u8f7b\u91cf\u7ea7\u7684\u5bb9\u5668\u7f16\u6392\u5de5\u5177\uff0c\u901a\u8fc7\u7b80\u5355\u7684 YAML \u914d\u7f6e\uff0c\u5c31\u80fd\u7ba1\u7406\u591a\u5bb9\u5668\u5e94\u7528\uff0c\u6210\u4e3a K8s \u7684\u6709\u529b\u8865\u5145\u751a\u81f3\u66ff\u4ee3\u65b9\u6848\u3002<\/p>\n<p><strong>\u4e3a\u4ec0\u4e48\u9009\u62e9 Docker Compose\uff1f<\/strong><\/p>\n<pre><code>\u274c Kubernetes \u7684\u6311\u6218\uff1a\n<ul>\n<li>\u5b66\u4e60\u66f2\u7ebf\u9661\u5ced\uff08\u9700\u8981 2-3 \u4e2a\u6708\uff09<\/li>\n<li>\u8fd0\u7ef4\u6210\u672c\u9ad8\uff08\u81f3\u5c11 1-2 \u540d\u4e13\u804c SRE\uff09<\/li>\n<li>\u8d44\u6e90\u6d88\u8017\u5927\uff083-5GB \u57fa\u7840\u5185\u5b58\uff09<\/li>\n<li>\u914d\u7f6e\u590d\u6742\uff08CRD\u3001RBAC\u3001Ingress \u7b49\uff09<\/li>\n<\/ul>\n\n\u2705 Docker Compose \u7684\u4f18\u52bf\uff1a\n<ul>\n<li>\u7b80\u5355\u6613\u7528\uff081 \u5c0f\u65f6\u4e0a\u624b\uff09<\/li>\n<li>\u8d44\u6e90\u6d88\u8017\u4f4e\uff08200MB \u57fa\u7840\u5185\u5b58\uff09<\/li>\n<li>\u914d\u7f6e\u7b80\u6d01\uff08\u5355\u6587\u4ef6\u7ba1\u7406\uff09<\/li>\n<li>\u9002\u5408\u4e2d\u5c0f\u89c4\u6a21\u90e8\u7f72<\/li>\n<\/ul>\n<\/code><\/pre>\n<p><strong>\u9002\u7528\u573a\u666f\u5bf9\u6bd4\uff1a<\/strong><\/p>\n<table border=\"1\" cellpadding=\"5\">\n<tr>\n<th>\u573a\u666f<\/th>\n<th>Docker Compose<\/th>\n<th>Kubernetes<\/th>\n<\/tr>\n<tr>\n<td>\u5fae\u670d\u52a1\u6570\u91cf<\/td>\n<td><20 \u4e2a<\/td>\n<td>>20 \u4e2a<\/td>\n<\/tr>\n<tr>\n<td>\u96c6\u7fa4\u89c4\u6a21<\/td>\n<td><10 \u8282\u70b9<\/td>\n<td>>10 \u8282\u70b9<\/td>\n<\/tr>\n<tr>\n<td>\u56e2\u961f\u89c4\u6a21<\/td>\n<td>1-5 \u4eba<\/td>\n<td>>10 \u4eba<\/td>\n<\/tr>\n<tr>\n<td>\u9884\u7b97<\/td>\n<td><5000 \u5143\/\u6708<\/td>\n<td>>10000 \u5143\/\u6708<\/td>\n<\/tr>\n<tr>\n<td>\u8fd0\u7ef4\u80fd\u529b<\/td>\n<td>\u521d\u7ea7<\/td>\n<td>\u9ad8\u7ea7<\/td>\n<\/tr>\n<\/table>\n<p><strong>\u9002\u7528\u8bfb\u8005\uff1a<\/strong> \u5f00\u53d1\u4eba\u5458\u3001\u8fd0\u7ef4\u5de5\u7a0b\u5e08\u3001\u521d\u521b\u56e2\u961f<\/p>\n<p>&#8212;<\/p>\n<h2>Docker Compose \u6838\u5fc3\u6982\u5ff5<\/h2>\n<h3>1. \u6838\u5fc3\u7ec4\u6210<\/h3>\n<pre><code>\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502                 Docker Compose \u6838\u5fc3\u6982\u5ff5                      \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502                                                             \u2502\n\u2502  Service\uff08\u670d\u52a1\uff09                                            \u2502\n\u2502  \u2514\u2500 \u5b9a\u4e49\u5bb9\u5668\u6a21\u677f\uff0c\u5305\u62ec\u955c\u50cf\u3001\u7aef\u53e3\u3001\u73af\u5883\u53d8\u91cf\u7b49                 \u2502\n\u2502      \u2502                                                      \u2502\n\u2502      \u251c\u2500 Volume\uff08\u6570\u636e\u5377\uff09                                    \u2502\n\u2502      \u2502   \u2514\u2500 \u6301\u4e45\u5316\u6570\u636e\u5b58\u50a8                                  \u2502\n\u2502      \u2502                                                             \u2502\n\u2502      \u251c\u2500 Network\uff08\u7f51\u7edc\uff09                                     \u2502\n\u2502      \u2502   \u2514\u2500 \u670d\u52a1\u95f4\u901a\u4fe1                                        \u2502\n\u2502      \u2502                                                             \u2502\n\u2502      \u2514\u2500 Config\uff08\u914d\u7f6e\uff09                                      \u2502\n\u2502          \u2514\u2500 \u73af\u5883\u53d8\u91cf\u3001\u914d\u7f6e\u6587\u4ef6\u7b49                              \u2502\n\u2502                                                             \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n<\/code><\/pre>\n<h3>2. compose.yml \u7ed3\u6784<\/h3>\n<p>&#8220;`yaml<br \/>\nversion: &#8216;3.8&#8217;  # \u7248\u672c\u683c\u5f0f<\/p>\n<p>services:  # \u670d\u52a1\u5b9a\u4e49<br \/>\n  web:<br \/>\n    image: nginx:alpine<br \/>\n    ports:<\/p>\n<ul>\n<li>&#8220;80:80&#8221;<\/li>\n<\/ul>\n<p>    volumes:<\/p>\n<ul>\n<li>.\/html:\/usr\/share\/nginx\/html<\/li>\n<\/ul>\n<p>    networks:<\/p>\n<ul>\n<li>frontend<\/li>\n<\/ul>\n<p>    depends_on:<\/p>\n<ul>\n<li>api<\/li>\n<\/ul>\n<p>    restart: always<\/p>\n<p>  api:<br \/>\n    build: .\/api<br \/>\n    environment:<\/p>\n<ul>\n<li>DB_HOST=db<\/li>\n<li>DB_PORT=5432<\/li>\n<\/ul>\n<p>    networks:<\/p>\n<ul>\n<li>frontend<\/li>\n<li>backend<\/li>\n<\/ul>\n<p>    volumes:<\/p>\n<ul>\n<li>api-data:\/app\/data<\/li>\n<\/ul>\n<p>  db:<br \/>\n    image: postgres:15-alpine<br \/>\n    volumes:<\/p>\n<ul>\n<li>db-data:\/var\/lib\/postgresql\/data<\/li>\n<\/ul>\n<p>    networks:<\/p>\n<ul>\n<li>backend<\/li>\n<\/ul>\n<p>networks:  # \u7f51\u7edc\u5b9a\u4e49<br \/>\n  frontend:<br \/>\n  backend:<\/p>\n<p>volumes:  # \u6570\u636e\u5377\u5b9a\u4e49<br \/>\n  api-data:<br \/>\n  db-data:<\/p>\n<pre><code>\n---\n\n<h2>\u751f\u4ea7\u73af\u5883\u914d\u7f6e<\/h2>\n\n<h3>1. \u73af\u5883\u53d8\u91cf\u7ba1\u7406<\/h3>\n\n<\/code><\/pre>\n<p>yaml<\/p>\n<h1>docker-compose.prod.yml<\/h1>\n<p>version: &#8216;3.8&#8217;<\/p>\n<p>services:<br \/>\n  web:<br \/>\n    image: myapp\/web:latest<br \/>\n    env_file:<\/p>\n<ul>\n<li>.env.prod<\/li>\n<\/ul>\n<p>    environment:<\/p>\n<ul>\n<li>NODE_ENV=production<\/li>\n<li>LOG_LEVEL=error<\/li>\n<\/ul>\n<p>    ports:<\/p>\n<ul>\n<li>&#8220;80:3000&#8221;<\/li>\n<\/ul>\n<p>    restart: always<br \/>\n    deploy:<br \/>\n      resources:<br \/>\n        limits:<br \/>\n          cpus: &#8216;0.5&#8217;<br \/>\n          memory: 512M<br \/>\n        reservations:<br \/>\n          cpus: &#8216;0.25&#8217;<br \/>\n          memory: 256M<\/p>\n<p>  api:<br \/>\n    image: myapp\/api:latest<br \/>\n    env_file:<\/p>\n<ul>\n<li>.env.prod<\/li>\n<\/ul>\n<p>    environment:<\/p>\n<ul>\n<li>DATABASE_URL=postgres:\/\/user:pass@db:5432\/myapp<\/li>\n<li>REDIS_URL=redis:\/\/redis:6379<\/li>\n<\/ul>\n<p>    restart: always<\/p>\n<p>  db:<br \/>\n    image: postgres:15-alpine<br \/>\n    env_file:<\/p>\n<ul>\n<li>.env.prod<\/li>\n<\/ul>\n<p>    environment:<br \/>\n      POSTGRES_DB: myapp<br \/>\n      POSTGRES_USER: user<br \/>\n      POSTGRES_PASSWORD_FILE: \/run\/secrets\/db_password<br \/>\n    volumes:<\/p>\n<ul>\n<li>db-data:\/var\/lib\/postgresql\/data<\/li>\n<\/ul>\n<p>    restart: always<br \/>\n    healthcheck:<br \/>\n      test: [&#8220;CMD-SHELL&#8221;, &#8220;pg_isready -U user&#8221;]<br \/>\n      interval: 10s<br \/>\n      timeout: 5s<br \/>\n      retries: 5<\/p>\n<p>volumes:<br \/>\n  db-data:<\/p>\n<p>networks:<br \/>\n  default:<br \/>\n    name: myapp-network<\/p>\n<pre><code>\n<h3>2. Secret \u7ba1\u7406<\/h3>\n\n<\/code><\/pre>\n<p>bash<\/p>\n<h1>\u521b\u5efa Docker Secret<\/h1>\n<p>echo &#8220;mydbpassword&#8221; | docker secret create db_password &#8211;<br \/>\necho &#8220;redis_password&#8221; | docker secret create redis_password &#8211;<\/p>\n<pre><code>\n<\/code><\/pre>\n<p>yaml<\/p>\n<h1>docker-compose.yml<\/h1>\n<p>version: &#8216;3.8&#8217;<\/p>\n<p>services:<br \/>\n  db:<br \/>\n    image: postgres:15-alpine<br \/>\n    secrets:<\/p>\n<ul>\n<li>db_password<\/li>\n<\/ul>\n<p>    environment:<br \/>\n      POSTGRES_PASSWORD_FILE: \/run\/secrets\/db_password<\/p>\n<p>  api:<br \/>\n    image: myapp\/api:latest<br \/>\n    secrets:<\/p>\n<ul>\n<li>db_password<\/li>\n<li>api_key<\/li>\n<\/ul>\n<p>    environment:<br \/>\n      DATABASE_PASSWORD_FILE: \/run\/secrets\/db_password<br \/>\n      API_KEY_FILE: \/run\/secrets\/api_key<\/p>\n<p>secrets:<br \/>\n  db_password:<br \/>\n    external: true<br \/>\n  api_key:<br \/>\n    external: true<\/p>\n<pre><code>\n<h3>3. \u5065\u5eb7\u68c0\u67e5\u914d\u7f6e<\/h3>\n\n<\/code><\/pre>\n<p>yaml<br \/>\nservices:<br \/>\n  web:<br \/>\n    image: nginx:alpine<br \/>\n    healthcheck:<br \/>\n      test: [&#8220;CMD&#8221;, &#8220;curl&#8221;, &#8220;-f&#8221;, &#8220;http:\/\/localhost\/health&#8221;]<br \/>\n      interval: 30s<br \/>\n      timeout: 10s<br \/>\n      retries: 3<br \/>\n      start_period: 40s<\/p>\n<p>  api:<br \/>\n    image: myapp\/api:latest<br \/>\n    healthcheck:<br \/>\n      test: [&#8220;CMD-SHELL&#8221;, &#8220;wget &#8211;no-verbose &#8211;tries=1 &#8211;spider http:\/\/localhost:3000\/health || exit 1&#8221;]<br \/>\n      interval: 30s<br \/>\n      timeout: 10s<br \/>\n      retries: 3<br \/>\n      start_period: 60s<\/p>\n<p>  db:<br \/>\n    image: postgres:15-alpine<br \/>\n    healthcheck:<br \/>\n      test: [&#8220;CMD-SHELL&#8221;, &#8220;pg_isready -U user -d myapp&#8221;]<br \/>\n      interval: 10s<br \/>\n      timeout: 5s<br \/>\n      retries: 5<\/p>\n<pre><code>\n---\n\n<h2>\u9ad8\u53ef\u7528\u65b9\u6848<\/h2>\n\n<h3>1. \u591a\u5b9e\u4f8b\u90e8\u7f72<\/h3>\n\n<\/code><\/pre>\n<p>yaml<\/p>\n<h1>docker-compose.yml<\/h1>\n<p>version: &#8216;3.8&#8217;<\/p>\n<p>services:<br \/>\n  web:<br \/>\n    image: myapp\/web:latest<br \/>\n    deploy:<br \/>\n      replicas: 3<br \/>\n      restart_policy:<br \/>\n        condition: on-failure<br \/>\n        delay: 10s<br \/>\n        max_attempts: 3<br \/>\n      placement:<br \/>\n        constraints:<\/p>\n<ul>\n<li>node.labels.role == web<\/li>\n<\/ul>\n<p>    ports:<\/p>\n<ul>\n<li>&#8220;80:3000&#8221;<\/li>\n<\/ul>\n<p>    healthcheck:<br \/>\n      test: [&#8220;CMD&#8221;, &#8220;curl&#8221;, &#8220;-f&#8221;, &#8220;http:\/\/localhost\/health&#8221;]<br \/>\n      interval: 30s<\/p>\n<p>  api:<br \/>\n    image: myapp\/api:latest<br \/>\n    deploy:<br \/>\n      replicas: 3<br \/>\n      restart_policy:<br \/>\n        condition: on-failure<br \/>\n        delay: 10s<br \/>\n        max_attempts: 3<br \/>\n    environment:<\/p>\n<ul>\n<li>DB_HOST=db<\/li>\n<\/ul>\n<p>    depends_on:<\/p>\n<ul>\n<li>db<\/li>\n<\/ul>\n<p>  db:<br \/>\n    image: postgres:15-alpine<br \/>\n    deploy:<br \/>\n      replicas: 1<br \/>\n      placement:<br \/>\n        constraints:<\/p>\n<ul>\n<li>node.labels.role == database<\/li>\n<\/ul>\n<p>    volumes:<\/p>\n<ul>\n<li>db-data:\/var\/lib\/postgresql\/data<\/li>\n<\/ul>\n<p>  redis:<br \/>\n    image: redis:alpine<br \/>\n    deploy:<br \/>\n      replicas: 2<br \/>\n      restart_policy:<br \/>\n        condition: on-failure<br \/>\n    volumes:<\/p>\n<ul>\n<li>redis-data:\/data<\/li>\n<\/ul>\n<p>volumes:<br \/>\n  db-data:<br \/>\n  redis-data:<\/p>\n<pre><code>\n<h3>2. \u8d1f\u8f7d\u5747\u8861\u914d\u7f6e<\/h3>\n\n<\/code><\/pre>\n<p>yaml<br \/>\nservices:<br \/>\n  nginx:<br \/>\n    image: nginx:alpine<br \/>\n    ports:<\/p>\n<ul>\n<li>&#8220;80:80&#8221;<\/li>\n<li>&#8220;443:443&#8221;<\/li>\n<\/ul>\n<p>    volumes:<\/p>\n<ul>\n<li>.\/nginx.conf:\/etc\/nginx\/nginx.conf:ro<\/li>\n<li>.\/ssl:\/etc\/nginx\/ssl:ro<\/li>\n<\/ul>\n<p>    depends_on:<\/p>\n<ul>\n<li>web<\/li>\n<li>api<\/li>\n<\/ul>\n<p>    restart: always<br \/>\n    deploy:<br \/>\n      replicas: 2<br \/>\n      restart_policy:<br \/>\n        condition: on-failure<\/p>\n<p>  web:<br \/>\n    image: myapp\/web:latest<br \/>\n    deploy:<br \/>\n      replicas: 3<br \/>\n      restart_policy:<br \/>\n        condition: on-failure<\/p>\n<p>  api:<br \/>\n    image: myapp\/api:latest<br \/>\n    deploy:<br \/>\n      replicas: 3<br \/>\n      restart_policy:<br \/>\n        condition: on-failure<\/p>\n<p>networks:<br \/>\n  default:<br \/>\n    driver: overlay<\/p>\n<pre><code>\n<strong>nginx.conf \u914d\u7f6e\uff1a<\/strong>\n\n<\/code><\/pre>\n<p>nginx<br \/>\nupstream web_backend {<br \/>\n    server web1:3000;<br \/>\n    server web2:3000;<br \/>\n    server web3:3000;<br \/>\n}<\/p>\n<p>upstream api_backend {<br \/>\n    server api1:8080;<br \/>\n    server api2:8080;<br \/>\n    server api3:8080;<br \/>\n}<\/p>\n<p>server {<br \/>\n    listen 80;<br \/>\n    server_name example.com;<\/p>\n<p>    location \/ {<br \/>\n        proxy_pass http:\/\/web_backend;<br \/>\n        proxy_set_header Host $host;<br \/>\n        proxy_set_header X-Real-IP $remote_addr;<br \/>\n    }<\/p>\n<p>    location \/api {<br \/>\n        proxy_pass http:\/\/api_backend;<br \/>\n        proxy_set_header Host $host;<br \/>\n        proxy_set_header X-Real-IP $remote_addr;<br \/>\n    }<br \/>\n}<\/p>\n<pre><code>\n<h3>3. \u6545\u969c\u6062\u590d<\/h3>\n\n<\/code><\/pre>\n<p>yaml<br \/>\nservices:<br \/>\n  db:<br \/>\n    image: postgres:15-alpine<br \/>\n    restart: always<br \/>\n    restart_policy:<br \/>\n      condition: on-failure<br \/>\n      delay: 10s<br \/>\n      max_attempts: 5<br \/>\n      window: 120s<br \/>\n    deploy:<br \/>\n      restart_policy:<br \/>\n        condition: on-failure<br \/>\n        delay: 10s<br \/>\n        max_attempts: 5<\/p>\n<p>  # \u4f7f\u7528 watchdog \u76d1\u63a7<br \/>\n  watchdog:<br \/>\n    image: busybox<br \/>\n    command: ><br \/>\n      sh -c &#8216;<br \/>\n        while true; do<br \/>\n          if ! docker ps -q | grep -q db; then<br \/>\n            echo &#8220;DB container crashed, restarting&#8230;&#8221;<br \/>\n            docker-compose up -d db<br \/>\n          fi<br \/>\n          sleep 30<br \/>\n        done<br \/>\n      &#8216;<br \/>\n    restart: always<\/p>\n<pre><code>\n---\n\n<h2>\u65e5\u5fd7\u4e0e\u76d1\u63a7<\/h2>\n\n<h3>1. \u65e5\u5fd7\u805a\u5408\u914d\u7f6e<\/h3>\n\n<\/code><\/pre>\n<p>yaml<br \/>\nservices:<br \/>\n  web:<br \/>\n    image: myapp\/web:latest<br \/>\n    logging:<br \/>\n      driver: json-file<br \/>\n      options:<br \/>\n        max-size: &#8220;10m&#8221;<br \/>\n        max-file: &#8220;3&#8221;<br \/>\n        compress: &#8220;true&#8221;<\/p>\n<p>  api:<br \/>\n    image: myapp\/api:latest<br \/>\n    logging:<br \/>\n      driver: loki<br \/>\n      options:<br \/>\n        loki-url: http:\/\/loki:3100\/loki\/api\/v1\/push<br \/>\n        loki-pipeline-stages: |<\/p>\n<ul>\n<li>json:<\/li>\n<\/ul>\n<p>              expressions:<br \/>\n                timestamp: time<br \/>\n                level: level<br \/>\n                message: msg<\/p>\n<ul>\n<li>timestamp:<\/li>\n<\/ul>\n<p>              source: timestamp<br \/>\n              format: RFC3339<\/p>\n<ul>\n<li>output:<\/li>\n<\/ul>\n<p>              source: message<\/p>\n<p>  loki:<br \/>\n    image: grafana\/loki:2.9.0<br \/>\n    ports:<\/p>\n<ul>\n<li>&#8220;3100:3100&#8221;<\/li>\n<\/ul>\n<p>    volumes:<\/p>\n<ul>\n<li>loki-data:\/loki<\/li>\n<\/ul>\n<p>  promtail:<br \/>\n    image: grafana\/promtail:2.9.0<br \/>\n    volumes:<\/p>\n<ul>\n<li>\/var\/log:\/var\/log<\/li>\n<\/ul>\n<p>    command: -config.file=\/etc\/promtail\/promtail.yaml<\/p>\n<p>volumes:<br \/>\n  loki-data:<\/p>\n<pre><code>\n<h3>2. Prometheus \u96c6\u6210<\/h3>\n\n<\/code><\/pre>\n<p>yaml<br \/>\nservices:<br \/>\n  prometheus:<br \/>\n    image: prom\/prometheus:latest<br \/>\n    ports:<\/p>\n<ul>\n<li>&#8220;9090:9090&#8221;<\/li>\n<\/ul>\n<p>    volumes:<\/p>\n<ul>\n<li>.\/prometheus.yml:\/etc\/prometheus\/prometheus.yml<\/li>\n<li>prometheus-data:\/prometheus<\/li>\n<\/ul>\n<p>    command:<\/p>\n<ul>\n<li>&#8216;&#8211;config.file=\/etc\/prometheus\/prometheus.yml&#8217;<\/li>\n<li>&#8216;&#8211;storage.tsdb.path=\/prometheus&#8217;<\/li>\n<\/ul>\n<p>  node-exporter:<br \/>\n    image: prom\/node-exporter:latest<br \/>\n    ports:<\/p>\n<ul>\n<li>&#8220;9100:9100&#8221;<\/li>\n<\/ul>\n<p>    volumes:<\/p>\n<ul>\n<li>\/proc:\/host\/proc:ro<\/li>\n<li>\/sys:\/host\/sys:ro<\/li>\n<li>\/:\/rootfs:ro<\/li>\n<\/ul>\n<p>    command:<\/p>\n<ul>\n<li>&#8216;&#8211;path.procfs=\/host\/proc&#8217;<\/li>\n<li>&#8216;&#8211;path.sysfs=\/host\/sys&#8217;<\/li>\n<\/ul>\n<p>  grafana:<br \/>\n    image: grafana\/grafana:latest<br \/>\n    ports:<\/p>\n<ul>\n<li>&#8220;3000:3000&#8221;<\/li>\n<\/ul>\n<p>    environment:<\/p>\n<ul>\n<li>GF_SECURITY_ADMIN_PASSWORD=admin<\/li>\n<\/ul>\n<p>    volumes:<\/p>\n<ul>\n<li>grafana-data:\/var\/lib\/grafana<\/li>\n<\/ul>\n<p>volumes:<br \/>\n  prometheus-data:<br \/>\n  grafana-data:<\/p>\n<pre><code>\n<strong>prometheus.yml \u914d\u7f6e\uff1a<\/strong>\n\n<\/code><\/pre>\n<p>yaml<br \/>\nglobal:<br \/>\n  scrape_interval: 15s<\/p>\n<p>scrape_configs:<\/p>\n<ul>\n<li>job_name: &#8216;docker-compose&#8217;<\/li>\n<\/ul>\n<p>    static_configs:<\/p>\n<ul>\n<li>targets: [&#8216;node-exporter:9100&#8217;]<\/li>\n<\/ul>\n<ul>\n<li>job_name: &#8216;myapp&#8217;<\/li>\n<\/ul>\n<p>    static_configs:<\/p>\n<ul>\n<li>targets: [&#8216;web:3000&#8217;, &#8216;api:8080&#8217;]<\/li>\n<\/ul>\n<pre><code>\n<h3>3. \u6027\u80fd\u76d1\u63a7<\/h3>\n\n<\/code><\/pre>\n<p>yaml<br \/>\nservices:<br \/>\n  cadvisor:<br \/>\n    image: gcr.io\/cadvisor\/cadvisor:latest<br \/>\n    ports:<\/p>\n<ul>\n<li>&#8220;8080:8080&#8221;<\/li>\n<\/ul>\n<p>    volumes:<\/p>\n<ul>\n<li>\/:\/rootfs:ro<\/li>\n<li>\/var\/run:\/var\/run:ro<\/li>\n<li>\/sys:\/sys:ro<\/li>\n<li>\/var\/lib\/docker\/:\/var\/lib\/docker:ro<\/li>\n<\/ul>\n<p>    privileged: true<\/p>\n<p>  containerd:<br \/>\n    image: docker:24<br \/>\n    entrypoint: sh -c &#8221;<br \/>\n      docker inspect \\$(hostname) | jq -r &#8216;.[0].State.Health.Status&#8217; &#038;&#038;<br \/>\n      echo &#8216;Container running healthily&#8217;<br \/>\n    &#8221;<br \/>\n    depends_on:<\/p>\n<ul>\n<li>web<\/li>\n<\/ul>\n<pre><code>\n---\n\n<h2>\u5b9e\u6218\u6848\u4f8b<\/h2>\n\n<h3>1. \u7535\u5546\u7f51\u7ad9\u90e8\u7f72<\/h3>\n\n<\/code><\/pre>\n<p>yaml<\/p>\n<h1>docker-compose.ecommerce.yml<\/h1>\n<p>version: &#8216;3.8&#8217;<\/p>\n<p>services:<br \/>\n  nginx:<br \/>\n    image: nginx:alpine<br \/>\n    ports:<\/p>\n<ul>\n<li>&#8220;80:80&#8221;<\/li>\n<li>&#8220;443:443&#8221;<\/li>\n<\/ul>\n<p>    volumes:<\/p>\n<ul>\n<li>.\/nginx\/nginx.conf:\/etc\/nginx\/nginx.conf:ro<\/li>\n<li>.\/nginx\/ssl:\/etc\/nginx\/ssl:ro<\/li>\n<\/ul>\n<p>    depends_on:<\/p>\n<ul>\n<li>frontend<\/li>\n<li>backend<\/li>\n<\/ul>\n<p>    restart: always<\/p>\n<p>  frontend:<br \/>\n    image: myapp\/frontend:latest<br \/>\n    environment:<\/p>\n<ul>\n<li>NEXT_PUBLIC_API_URL=http:\/\/backend:3001\/api<\/li>\n<\/ul>\n<p>    deploy:<br \/>\n      replicas: 3<br \/>\n      restart_policy:<br \/>\n        condition: on-failure<br \/>\n    depends_on:<\/p>\n<ul>\n<li>backend<\/li>\n<\/ul>\n<p>  backend:<br \/>\n    build: .\/backend<br \/>\n    environment:<\/p>\n<ul>\n<li>DATABASE_URL=postgres:\/\/user:pass@db:5432\/ecommerce<\/li>\n<li>REDIS_URL=redis:\/\/redis:6379<\/li>\n<li>JWT_SECRET_FILE=\/run\/secrets\/jwt_secret<\/li>\n<\/ul>\n<p>    deploy:<br \/>\n      replicas: 3<br \/>\n      restart_policy:<br \/>\n        condition: on-failure<br \/>\n    depends_on:<\/p>\n<ul>\n<li>db<\/li>\n<li>redis<\/li>\n<\/ul>\n<p>    secrets:<\/p>\n<ul>\n<li>jwt_secret<\/li>\n<\/ul>\n<p>  db:<br \/>\n    image: postgres:15-alpine<br \/>\n    volumes:<\/p>\n<ul>\n<li>db-data:\/var\/lib\/postgresql\/data<\/li>\n<li>.\/db\/init.sql:\/docker-entrypoint-initdb.d\/init.sql:ro<\/li>\n<\/ul>\n<p>    environment:<br \/>\n      POSTGRES_DB: ecommerce<br \/>\n      POSTGRES_USER: user<br \/>\n      POSTGRES_PASSWORD_FILE: \/run\/secrets\/db_password<br \/>\n    secrets:<\/p>\n<ul>\n<li>db_password<\/li>\n<\/ul>\n<p>    deploy:<br \/>\n      replicas: 1<br \/>\n      restart_policy:<br \/>\n        condition: on-failure<\/p>\n<p>  redis:<br \/>\n    image: redis:alpine<br \/>\n    volumes:<\/p>\n<ul>\n<li>redis-data:\/data<\/li>\n<\/ul>\n<p>    deploy:<br \/>\n      replicas: 2<br \/>\n      restart_policy:<br \/>\n        condition: on-failure<\/p>\n<p>  worker:<br \/>\n    build: .\/worker<br \/>\n    environment:<\/p>\n<ul>\n<li>DATABASE_URL=postgres:\/\/user:pass@db:5432\/ecommerce<\/li>\n<li>REDIS_URL=redis:\/\/redis:6379<\/li>\n<\/ul>\n<p>    depends_on:<\/p>\n<ul>\n<li>db<\/li>\n<li>redis<\/li>\n<\/ul>\n<p>    deploy:<br \/>\n      replicas: 2<br \/>\n      restart_policy:<br \/>\n        condition: on-failure<br \/>\n        delay: 10s<br \/>\n        max_attempts: 3<\/p>\n<p>  monitoring:<br \/>\n    profiles:<\/p>\n<ul>\n<li>monitoring<\/li>\n<\/ul>\n<p>    image: myapp\/monitoring:latest<br \/>\n    ports:<\/p>\n<ul>\n<li>&#8220;9090:9090&#8221;<\/li>\n<\/ul>\n<p>    depends_on:<\/p>\n<ul>\n<li>prometheus<\/li>\n<li>grafana<\/li>\n<\/ul>\n<p>volumes:<br \/>\n  db-data:<br \/>\n  redis-data:<\/p>\n<p>secrets:<br \/>\n  db_password:<br \/>\n    external: true<br \/>\n  jwt_secret:<br \/>\n    external: true<\/p>\n<p>networks:<br \/>\n  default:<br \/>\n    driver: overlay<\/p>\n<pre><code>\n<h3>2. Django \u9879\u76ee\u90e8\u7f72<\/h3>\n\n<\/code><\/pre>\n<p>yaml<\/p>\n<h1>docker-compose.django.yml<\/h1>\n<p>version: &#8216;3.8&#8217;<\/p>\n<p>services:<br \/>\n  web:<br \/>\n    build:<br \/>\n      context: .\/django<br \/>\n      dockerfile: Dockerfile<br \/>\n    command: ><br \/>\n      sh -c &#8221;<br \/>\n        python manage.py migrate &#038;&#038;<br \/>\n        gunicorn myapp.wsgi:application<br \/>\n        &#8211;bind 0.0.0.0:8000<br \/>\n        &#8211;workers 4<br \/>\n      &#8221;<br \/>\n    ports:<\/p>\n<ul>\n<li>&#8220;8000:8000&#8221;<\/li>\n<\/ul>\n<p>    depends_on:<\/p>\n<ul>\n<li>db<\/li>\n<li>redis<\/li>\n<\/ul>\n<p>    environment:<\/p>\n<ul>\n<li>DEBUG=False<\/li>\n<li>SECRET_KEY_FILE=\/run\/secrets\/secret_key<\/li>\n<li>DATABASE_URL=postgres:\/\/user:pass@db:5432\/myapp<\/li>\n<\/ul>\n<p>    restart: always<br \/>\n    deploy:<br \/>\n      replicas: 2<\/p>\n<p>  db:<br \/>\n    image: postgres:15-alpine<br \/>\n    volumes:<\/p>\n<ul>\n<li>postgres-data:\/var\/lib\/postgresql\/data<\/li>\n<\/ul>\n<p>    environment:<br \/>\n      POSTGRES_DB: myapp<br \/>\n      POSTGRES_USER: user<br \/>\n      POSTGRES_PASSWORD_FILE: \/run\/secrets\/db_password<br \/>\n    secrets:<\/p>\n<ul>\n<li>db_password<\/li>\n<\/ul>\n<p>    restart: always<\/p>\n<p>  redis:<br \/>\n    image: redis:alpine<br \/>\n    volumes:<\/p>\n<ul>\n<li>redis-data:\/data<\/li>\n<\/ul>\n<p>    restart: always<\/p>\n<p>  celery:<br \/>\n    build: .\/django<br \/>\n    command: celery -A myapp worker -l info<br \/>\n    depends_on:<\/p>\n<ul>\n<li>db<\/li>\n<li>redis<\/li>\n<\/ul>\n<p>    environment:<\/p>\n<ul>\n<li>DATABASE_URL=postgres:\/\/user:pass@db:5432\/myapp<\/li>\n<\/ul>\n<p>    secrets:<\/p>\n<ul>\n<li>db_password<\/li>\n<\/ul>\n<p>    deploy:<br \/>\n      replicas: 2<\/p>\n<p>  celery-beat:<br \/>\n    build: .\/django<br \/>\n    command: celery -A myapp beat -l info<br \/>\n    depends_on:<\/p>\n<ul>\n<li>db<\/li>\n<li>redis<\/li>\n<\/ul>\n<p>    secrets:<\/p>\n<ul>\n<li>db_password<\/li>\n<\/ul>\n<p>  nginx:<br \/>\n    image: nginx:alpine<br \/>\n    ports:<\/p>\n<ul>\n<li>&#8220;80:80&#8221;<\/li>\n<\/ul>\n<p>    volumes:<\/p>\n<ul>\n<li>.\/nginx.conf:\/etc\/nginx\/nginx.conf:ro<\/li>\n<\/ul>\n<p>    depends_on:<\/p>\n<ul>\n<li>web<\/li>\n<\/ul>\n<p>    restart: always<\/p>\n<p>volumes:<br \/>\n  postgres-data:<br \/>\n  redis-data:<\/p>\n<p>secrets:<br \/>\n  db_password:<br \/>\n    external: true<br \/>\n  secret_key:<br \/>\n    external: true<\/p>\n<pre><code>\n<h3>3. Node.js \u9879\u76ee\u90e8\u7f72<\/h3>\n\n<\/code><\/pre>\n<p>yaml<\/p>\n<h1>docker-compose.nodejs.yml<\/h1>\n<p>version: &#8216;3.8&#8217;<\/p>\n<p>services:<br \/>\n  app:<br \/>\n    build:<br \/>\n      context: .\/app<br \/>\n      dockerfile: Dockerfile<br \/>\n    ports:<\/p>\n<ul>\n<li>&#8220;3000:3000&#8221;<\/li>\n<\/ul>\n<p>    environment:<\/p>\n<ul>\n<li>NODE_ENV=production<\/li>\n<li>PORT=3000<\/li>\n<li>DATABASE_URL=postgres:\/\/user:pass@db:5432\/myapp<\/li>\n<li>REDIS_URL=redis:\/\/redis:6379<\/li>\n<\/ul>\n<p>    depends_on:<br \/>\n      db:<br \/>\n        condition: service_healthy<br \/>\n      redis:<br \/>\n        condition: service_healthy<br \/>\n    restart: always<br \/>\n    deploy:<br \/>\n      replicas: 3<br \/>\n      resources:<br \/>\n        limits:<br \/>\n          cpus: &#8216;0.5&#8217;<br \/>\n          memory: 512M<br \/>\n        reservations:<br \/>\n          cpus: &#8216;0.25&#8217;<br \/>\n          memory: 256M<\/p>\n<p>  db:<br \/>\n    image: postgres:15-alpine<br \/>\n    volumes:<\/p>\n<ul>\n<li>postgres-data:\/var\/lib\/postgresql\/data<\/li>\n<\/ul>\n<p>    environment:<br \/>\n      POSTGRES_DB: myapp<br \/>\n      POSTGRES_USER: user<br \/>\n      POSTGRES_PASSWORD_FILE: \/run\/secrets\/db_password<br \/>\n    secrets:<\/p>\n<ul>\n<li>db_password<\/li>\n<\/ul>\n<p>    healthcheck:<br \/>\n      test: [&#8220;CMD-SHELL&#8221;, &#8220;pg_isready -U user&#8221;]<br \/>\n      interval: 10s<br \/>\n      timeout: 5s<br \/>\n      retries: 5<br \/>\n    restart: always<\/p>\n<p>  redis:<br \/>\n    image: redis:alpine<br \/>\n    volumes:<\/p>\n<ul>\n<li>redis-data:\/data<\/li>\n<\/ul>\n<p>    healthcheck:<br \/>\n      test: [&#8220;CMD&#8221;, &#8220;redis-cli&#8221;, &#8220;ping&#8221;]<br \/>\n      interval: 10s<br \/>\n      timeout: 5s<br \/>\n      retries: 5<br \/>\n    restart: always<\/p>\n<p>  nginx:<br \/>\n    image: nginx:alpine<br \/>\n    ports:<\/p>\n<ul>\n<li>&#8220;80:80&#8221;<\/li>\n<\/ul>\n<p>    volumes:<\/p>\n<ul>\n<li>.\/nginx.conf:\/etc\/nginx\/nginx.conf:ro<\/li>\n<\/ul>\n<p>    depends_on:<\/p>\n<ul>\n<li>app<\/li>\n<\/ul>\n<p>    restart: always<\/p>\n<p>volumes:<br \/>\n  postgres-data:<br \/>\n  redis-data:<\/p>\n<p>secrets:<br \/>\n  db_password:<br \/>\n    external: true<\/p>\n<pre><code>\n---\n\n<h2>\u6700\u4f73\u5b9e\u8df5<\/h2>\n\n<h3>1. \u7248\u672c\u63a7\u5236<\/h3>\n\n<\/code><\/pre>\n<p>yaml<\/p>\n<h1>docker-compose.yaml<\/h1>\n<p>version: &#8216;3.8&#8217;  # \u4f7f\u7528\u6700\u65b0\u7a33\u5b9a\u7248<\/p>\n<p>services:<br \/>\n  web:<br \/>\n    image: myapp\/web:1.2.3  # \u6307\u5b9a\u5177\u4f53\u7248\u672c\uff0c\u4e0d\u4f7f\u7528 latest<br \/>\n    # \u274c \u907f\u514d\uff1aimage: myapp\/web:latest<\/p>\n<pre><code>\n<strong>\u63a8\u8350\u5b9e\u8df5\uff1a<\/strong>\n\n<\/code><\/pre>\n<p>yaml<\/p>\n<h1>\u4f7f\u7528\u6807\u7b7e\u7ba1\u7406\u7248\u672c<\/h1>\n<p>services:<br \/>\n  web:<br \/>\n    image: myapp\/web:${IMAGE_TAG:-1.2.3}<\/p>\n<h1>docker-compose.prod.yml<\/h1>\n<p>version: &#8216;3.8&#8217;<\/p>\n<p>services:<br \/>\n  web:<br \/>\n    image: myapp\/web:${DOCKER_TAG:-2.0.0}<\/p>\n<pre><code>\n<h3>2. CI\/CD \u96c6\u6210<\/h3>\n\n<\/code><\/pre>\n<p>yaml<\/p>\n<h1>.github\/workflows\/docker-compose.yml<\/h1>\n<p>name: Docker Compose CI<\/p>\n<p>on:<br \/>\n  push:<br \/>\n    branches: [main]<br \/>\n  pull_request:<br \/>\n    branches: [main]<\/p>\n<p>jobs:<br \/>\n  test:<br \/>\n    runs-on: ubuntu-latest<\/p>\n<p>    steps:<\/p>\n<ul>\n<li>uses: actions\/checkout@v3<\/li>\n<\/ul>\n<ul>\n<li>name: Set up Docker Buildx<\/li>\n<\/ul>\n<p>        uses: docker\/setup-buildx-action@v3<\/p>\n<ul>\n<li>name: Run tests<\/li>\n<\/ul>\n<p>        run: docker-compose -f docker-compose.test.yml up &#8211;exit-code-from web<\/p>\n<ul>\n<li>name: Build images<\/li>\n<\/ul>\n<p>        run: docker-compose build<\/p>\n<ul>\n<li>name: Login to Registry<\/li>\n<\/ul>\n<p>        run: echo ${{ secrets.DOCKER_PASSWORD }} | docker login -u ${{ secrets.DOCKER_USERNAME }} &#8211;password-stdin<\/p>\n<ul>\n<li>name: Push images<\/li>\n<\/ul>\n<p>        run: docker-compose push<\/p>\n<pre><code>\n<h3>3. \u5b89\u5168\u52a0\u56fa<\/h3>\n\n<\/code><\/pre>\n<p>yaml<br \/>\nservices:<br \/>\n  web:<br \/>\n    image: myapp\/web:latest<br \/>\n    user: &#8220;1000:1000&#8221;  # \u975e root \u7528\u6237\u8fd0\u884c<br \/>\n    read_only: true  # \u53ea\u8bfb\u6587\u4ef6\u7cfb\u7edf<br \/>\n    tmpfs:<\/p>\n<ul>\n<li>\/tmp<\/li>\n<\/ul>\n<p>    security_opt:<\/p>\n<ul>\n<li>no-new-privileges:true<\/li>\n<\/ul>\n<p>    cap_drop:<\/p>\n<ul>\n<li>ALL<\/li>\n<\/ul>\n<p>    cap_add:<\/p>\n<ul>\n<li>NET_BIND_SERVICE<\/li>\n<\/ul>\n<p>    secrets:<\/p>\n<ul>\n<li>db_password<\/li>\n<\/ul>\n<p>    healthcheck:<br \/>\n      test: [&#8220;CMD&#8221;, &#8220;curl&#8221;, &#8220;-f&#8221;, &#8220;http:\/\/localhost\/health&#8221;]<br \/>\n      interval: 30s<br \/>\n      timeout: 10s<br \/>\n      retries: 3<\/p>\n<p>  # \u9650\u5236\u7f51\u7edc\u8bbf\u95ee<br \/>\n  networks:<br \/>\n    default:<br \/>\n      driver: bridge<br \/>\n      ipam:<br \/>\n        config:<\/p>\n<ul>\n<li>subnet: 172.28.0.0\/16<\/li>\n<\/ul>\n<pre><code>\n<strong>\u5b89\u5168\u6700\u4f73\u5b9e\u8df5\u6e05\u5355\uff1a<\/strong>\n\n<\/code><\/pre>\n<p>markdown<br \/>\n\u2705 \u5b89\u5168\u52a0\u56fa\uff1a<\/p>\n<ul>\n<li>\u4f7f\u7528\u975e root \u7528\u6237\u8fd0\u884c\u5bb9\u5668<\/li>\n<li>\u542f\u7528\u53ea\u8bfb\u6587\u4ef6\u7cfb\u7edf<\/li>\n<li>\u6700\u5c0f\u5316\u6743\u9650\uff08cap_drop: ALL\uff09<\/li>\n<li>\u4f7f\u7528 Docker Secrets \u7ba1\u7406\u654f\u611f\u6570\u636e<\/li>\n<li>\u9650\u5236\u5bb9\u5668\u8d44\u6e90\uff08CPU\u3001\u5185\u5b58\uff09<\/li>\n<li>\u5b9a\u671f\u626b\u63cf\u955c\u50cf\u6f0f\u6d1e<\/li>\n<\/ul>\n<p>\u2705 \u7f51\u7edc\u9694\u79bb\uff1a<\/p>\n<ul>\n<li>\u4f7f\u7528\u81ea\u5b9a\u4e49\u7f51\u7edc<\/li>\n<li>\u9650\u5236\u7aef\u53e3\u66b4\u9732<\/li>\n<li>\u914d\u7f6e\u7f51\u7edc\u7b56\u7565<\/li>\n<\/ul>\n<p>\u2705 \u7248\u672c\u7ba1\u7406\uff1a<\/p>\n<ul>\n<li>\u56fa\u5b9a\u955c\u50cf\u7248\u672c<\/li>\n<li>\u7981\u7528 latest \u6807\u7b7e<\/li>\n<li>\u4f7f\u7528\u8bed\u4e49\u5316\u7248\u672c<\/li>\n<\/ul>\n<pre><code>\n---\n\n<h2>\u603b\u7ed3<\/h2>\n\n<h3>\u6838\u5fc3\u8981\u70b9\u56de\u987e<\/h3>\n\n\u2705 <strong>Docker Compose \u4f18\u52bf<\/strong>\uff1a\u7b80\u5355\u3001\u8f7b\u91cf\u3001\u6613\u7528  \n\u2705 <strong>\u6838\u5fc3\u6982\u5ff5<\/strong>\uff1aService\u3001Volume\u3001Network\u3001Config  \n\u2705 <strong>\u751f\u4ea7\u914d\u7f6e<\/strong>\uff1a\u73af\u5883\u53d8\u91cf\u3001Secret\u3001\u5065\u5eb7\u68c0\u67e5  \n\u2705 <strong>\u9ad8\u53ef\u7528<\/strong>\uff1a\u591a\u5b9e\u4f8b\u3001\u8d1f\u8f7d\u5747\u8861\u3001\u6545\u969c\u6062\u590d  \n\u2705 <strong>\u65e5\u5fd7\u76d1\u63a7<\/strong>\uff1aPrometheus\u3001Grafana\u3001Loki  \n\u2705 <strong>\u6700\u4f73\u5b9e\u8df5<\/strong>\uff1a\u7248\u672c\u63a7\u5236\u3001CI\/CD\u3001\u5b89\u5168\u52a0\u56fa  \n\n<h3>Docker Compose vs K8s \u5bf9\u6bd4<\/h3>\n\n<\/code><\/pre>\n<p>\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510<br \/>\n\u2502  \u9009\u62e9\u6307\u5357                                                \u2502<br \/>\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524<br \/>\n\u2502  \u9009\u62e9 Docker Compose \u5982\u679c\uff1a                              \u2502<br \/>\n\u2502  \u2705 \u56e2\u961f\u89c4\u6a21 < 10 \u4eba                                      \u2502\n\u2502  \u2705 \u670d\u52a1\u6570\u91cf < 20 \u4e2a                                      \u2502\n\u2502  \u2705 \u9884\u7b97\u6709\u9650                                             \u2502\n\u2502  \u2705 \u8fd0\u7ef4\u80fd\u529b\u6709\u9650                                         \u2502\n\u2502  \u2705 \u90e8\u7f72\u5728\u5355\u8282\u70b9\u6216\u5c11\u6570\u8282\u70b9                              \u2502\n\u2502                                                          \u2502\n\u2502  \u9009\u62e9 Kubernetes \u5982\u679c\uff1a                                  \u2502\n\u2502  \u2705 \u56e2\u961f\u89c4\u6a21 > 10 \u4eba                                     \u2502<br \/>\n\u2502  \u2705 \u670d\u52a1\u6570\u91cf > 20 \u4e2a                                     \u2502<br \/>\n\u2502  \u2705 \u9700\u8981\u5f39\u6027\u4f38\u7f29                                         \u2502<br \/>\n\u2502  \u2705 \u591a\u533a\u57df\/\u591a\u4e91\u90e8\u7f72                                      \u2502<br \/>\n\u2502  \u2705 \u590d\u6742\u7684\u670d\u52a1\u7f51\u683c\u9700\u6c42                                   \u2502<br \/>\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518<\/p>\n<pre><code>\n<h3>\u63a8\u8350\u5de5\u4f5c\u6d41<\/h3>\n\n<\/code><\/pre>\n<p>Docker Compose \u751f\u4ea7\u90e8\u7f72\u6d41\u7a0b\uff1a<\/p>\n<ol>\n<li>\u672c\u5730\u5f00\u53d1<\/li>\n<\/ul>\n<p>   \u251c\u2500 docker-compose.yml (\u5f00\u53d1\u73af\u5883)<br \/>\n   \u251c\u2500 docker-compose.dev.yml (\u5f00\u53d1\u914d\u7f6e)<br \/>\n   \u2514\u2500 \u672c\u5730\u6d4b\u8bd5<\/p>\n<ol>\n<li>\u6d4b\u8bd5\u73af\u5883<\/li>\n<\/ul>\n<p>   \u251c\u2500 docker-compose.test.yml<br \/>\n   \u251c\u2500 \u81ea\u52a8\u5316\u6d4b\u8bd5<br \/>\n   \u2514\u2500 \u6027\u80fd\u6d4b\u8bd5<\/p>\n<ol>\n<li>\u751f\u4ea7\u90e8\u7f72<\/li>\n<\/ul>\n<p>   \u251c\u2500 docker-compose.prod.yml<br \/>\n   \u251c\u2500 \u591a\u5b9e\u4f8b\u90e8\u7f72<br \/>\n   \u251c\u2500 \u5065\u5eb7\u68c0\u67e5<br \/>\n   \u2514\u2500 \u76d1\u63a7\u544a\u8b66<\/p>\n<ol>\n<li>\u6301\u7eed\u4f18\u5316<\/li>\n<\/ul>\n<p>   \u251c\u2500 \u8d44\u6e90\u76d1\u63a7<br \/>\n   \u251c\u2500 \u6027\u80fd\u8c03\u4f18<br \/>\n   \u2514\u2500 \u5b9a\u671f\u66f4\u65b0<br \/>\n&#8220;`<\/p>\n<p>&#8212;<\/p>\n<p>*\u672c\u6587\u6863\u6700\u540e\u66f4\u65b0\u65f6\u95f4\uff1a2026 \u5e74 04 \u6708 28 \u65e5*<br \/>\n*\u4f5c\u8005\uff1acreator | \u9002\u7528 Docker 24.x + Compose 2.x*<\/p>\n<p>![](https:\/\/img.freepik.com\/free-vector\/docker-compose-production-deployment-concept-illustration_114360-12345.jpg)<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Docker Compose \u751f\u4ea7\u5316\uff1a\u66ff\u4ee3 K8s \u7684\u8f7b\u91cf\u7ea7\u65b9\u6848 \u5f15\u8a00 \u5728\u4e91\u539f\u751f\u751f\u6001\u4e2d\uff0cKubernetes &#8230;<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-15940","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/www.srclibs.com\/index.php\/wp-json\/wp\/v2\/posts\/15940","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.srclibs.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.srclibs.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.srclibs.com\/index.php\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.srclibs.com\/index.php\/wp-json\/wp\/v2\/comments?post=15940"}],"version-history":[{"count":0,"href":"https:\/\/www.srclibs.com\/index.php\/wp-json\/wp\/v2\/posts\/15940\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.srclibs.com\/index.php\/wp-json\/wp\/v2\/media?parent=15940"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.srclibs.com\/index.php\/wp-json\/wp\/v2\/categories?post=15940"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.srclibs.com\/index.php\/wp-json\/wp\/v2\/tags?post=15940"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}