[{"data":1,"prerenderedAt":1524},["ShallowReactive",2],{"page-tr-\u002Fblog\u002Fdocker-compose-guide":3},{"id":4,"title":5,"body":6,"date":1512,"description":1513,"extension":1514,"meta":1515,"navigation":235,"path":1516,"seo":1517,"stem":1518,"tags":1519,"translation":1522,"__hash__":1523},"pages_tr\u002Ftr\u002Fblog\u002Fdocker-compose-guide.md","Docker Compose ile Çoklu Servis Çalıştırma",{"type":7,"value":8,"toc":1501},"minimark",[9,14,26,29,51,55,486,489,561,565,578,613,620,651,666,669,689,693,920,988,992,1002,1086,1093,1119,1123,1126,1214,1251,1255,1325,1382,1386,1484,1488,1497],[10,11,13],"h2",{"id":12},"giriş","Giriş",[15,16,17,18,22,23,25],"p",{},"Tek bir container'ı ",[19,20,21],"code",{},"docker run"," ile çalıştırmak kolaydır; ama gerçek bir uygulama genelde bir API, bir veritabanı, bir cache ve belki bir reverse proxy'den oluşur. Bunları tek tek ",[19,24,21],{}," komutlarıyla, doğru network ve volume ayarlarıyla başlatmak hem zahmetli hem de hataya açıktır.",[15,27,28],{},"Docker Compose bu servislerin hepsini tek bir YAML dosyasında tanımlamanızı ve tek komutla yönetmenizi sağlar. Bu yazıda bir Spring Boot API + PostgreSQL + Redis örneği üzerinden ilerleyeceğiz.",[30,31,32],"blockquote",{},[15,33,34,35,38,39,42,43,46,47,50],{},"Compose artık Docker CLI'ın bir parçası: komut ",[19,36,37],{},"docker-compose"," değil ",[19,40,41],{},"docker compose",". Dosya adı olarak da ",[19,44,45],{},"compose.yaml"," önerilir; ",[19,48,49],{},"docker-compose.yml"," hâlâ çalışır.",[10,52,54],{"id":53},"_1-i̇lk-composeyaml","1. İlk compose.yaml",[56,57,62],"pre",{"className":58,"code":59,"language":60,"meta":61,"style":61},"language-yaml shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","services:\n  api:\n    build: .\n    ports:\n      - \"8080:8080\"\n    environment:\n      SPRING_DATASOURCE_URL: jdbc:postgresql:\u002F\u002Fdb:5432\u002Fapp\n      SPRING_DATASOURCE_USERNAME: app\n      SPRING_DATASOURCE_PASSWORD: ${DB_PASSWORD}\n      SPRING_DATA_REDIS_HOST: cache\n    depends_on:\n      db:\n        condition: service_healthy\n      cache:\n        condition: service_started\n    restart: unless-stopped\n\n  db:\n    image: postgres:17\n    environment:\n      POSTGRES_DB: app\n      POSTGRES_USER: app\n      POSTGRES_PASSWORD: ${DB_PASSWORD}\n    volumes:\n      - pgdata:\u002Fvar\u002Flib\u002Fpostgresql\u002Fdata\n    healthcheck:\n      test: [\"CMD-SHELL\", \"pg_isready -U app -d app\"]\n      interval: 5s\n      timeout: 3s\n      retries: 10\n\n  cache:\n    image: redis:7-alpine\n    command: [\"redis-server\", \"--appendonly\", \"yes\"]\n    volumes:\n      - redisdata:\u002Fdata\n\nvolumes:\n  pgdata:\n  redisdata:\n","yaml","",[19,63,64,77,85,98,106,122,130,141,152,163,174,182,190,201,209,219,230,237,245,256,263,273,283,293,301,309,317,349,360,371,382,387,395,405,442,449,457,462,470,478],{"__ignoreMap":61},[65,66,69,73],"span",{"class":67,"line":68},"line",1,[65,70,72],{"class":71},"swJcz","services",[65,74,76],{"class":75},"sMK4o",":\n",[65,78,80,83],{"class":67,"line":79},2,[65,81,82],{"class":71},"  api",[65,84,76],{"class":75},[65,86,88,91,94],{"class":67,"line":87},3,[65,89,90],{"class":71},"    build",[65,92,93],{"class":75},":",[65,95,97],{"class":96},"sbssI"," .\n",[65,99,101,104],{"class":67,"line":100},4,[65,102,103],{"class":71},"    ports",[65,105,76],{"class":75},[65,107,109,112,115,119],{"class":67,"line":108},5,[65,110,111],{"class":75},"      -",[65,113,114],{"class":75}," \"",[65,116,118],{"class":117},"sfazB","8080:8080",[65,120,121],{"class":75},"\"\n",[65,123,125,128],{"class":67,"line":124},6,[65,126,127],{"class":71},"    environment",[65,129,76],{"class":75},[65,131,133,136,138],{"class":67,"line":132},7,[65,134,135],{"class":71},"      SPRING_DATASOURCE_URL",[65,137,93],{"class":75},[65,139,140],{"class":117}," jdbc:postgresql:\u002F\u002Fdb:5432\u002Fapp\n",[65,142,144,147,149],{"class":67,"line":143},8,[65,145,146],{"class":71},"      SPRING_DATASOURCE_USERNAME",[65,148,93],{"class":75},[65,150,151],{"class":117}," app\n",[65,153,155,158,160],{"class":67,"line":154},9,[65,156,157],{"class":71},"      SPRING_DATASOURCE_PASSWORD",[65,159,93],{"class":75},[65,161,162],{"class":117}," ${DB_PASSWORD}\n",[65,164,166,169,171],{"class":67,"line":165},10,[65,167,168],{"class":71},"      SPRING_DATA_REDIS_HOST",[65,170,93],{"class":75},[65,172,173],{"class":117}," cache\n",[65,175,177,180],{"class":67,"line":176},11,[65,178,179],{"class":71},"    depends_on",[65,181,76],{"class":75},[65,183,185,188],{"class":67,"line":184},12,[65,186,187],{"class":71},"      db",[65,189,76],{"class":75},[65,191,193,196,198],{"class":67,"line":192},13,[65,194,195],{"class":71},"        condition",[65,197,93],{"class":75},[65,199,200],{"class":117}," service_healthy\n",[65,202,204,207],{"class":67,"line":203},14,[65,205,206],{"class":71},"      cache",[65,208,76],{"class":75},[65,210,212,214,216],{"class":67,"line":211},15,[65,213,195],{"class":71},[65,215,93],{"class":75},[65,217,218],{"class":117}," service_started\n",[65,220,222,225,227],{"class":67,"line":221},16,[65,223,224],{"class":71},"    restart",[65,226,93],{"class":75},[65,228,229],{"class":117}," unless-stopped\n",[65,231,233],{"class":67,"line":232},17,[65,234,236],{"emptyLinePlaceholder":235},true,"\n",[65,238,240,243],{"class":67,"line":239},18,[65,241,242],{"class":71},"  db",[65,244,76],{"class":75},[65,246,248,251,253],{"class":67,"line":247},19,[65,249,250],{"class":71},"    image",[65,252,93],{"class":75},[65,254,255],{"class":117}," postgres:17\n",[65,257,259,261],{"class":67,"line":258},20,[65,260,127],{"class":71},[65,262,76],{"class":75},[65,264,266,269,271],{"class":67,"line":265},21,[65,267,268],{"class":71},"      POSTGRES_DB",[65,270,93],{"class":75},[65,272,151],{"class":117},[65,274,276,279,281],{"class":67,"line":275},22,[65,277,278],{"class":71},"      POSTGRES_USER",[65,280,93],{"class":75},[65,282,151],{"class":117},[65,284,286,289,291],{"class":67,"line":285},23,[65,287,288],{"class":71},"      POSTGRES_PASSWORD",[65,290,93],{"class":75},[65,292,162],{"class":117},[65,294,296,299],{"class":67,"line":295},24,[65,297,298],{"class":71},"    volumes",[65,300,76],{"class":75},[65,302,304,306],{"class":67,"line":303},25,[65,305,111],{"class":75},[65,307,308],{"class":117}," pgdata:\u002Fvar\u002Flib\u002Fpostgresql\u002Fdata\n",[65,310,312,315],{"class":67,"line":311},26,[65,313,314],{"class":71},"    healthcheck",[65,316,76],{"class":75},[65,318,320,323,325,328,331,334,336,339,341,344,346],{"class":67,"line":319},27,[65,321,322],{"class":71},"      test",[65,324,93],{"class":75},[65,326,327],{"class":75}," [",[65,329,330],{"class":75},"\"",[65,332,333],{"class":117},"CMD-SHELL",[65,335,330],{"class":75},[65,337,338],{"class":75},",",[65,340,114],{"class":75},[65,342,343],{"class":117},"pg_isready -U app -d app",[65,345,330],{"class":75},[65,347,348],{"class":75},"]\n",[65,350,352,355,357],{"class":67,"line":351},28,[65,353,354],{"class":71},"      interval",[65,356,93],{"class":75},[65,358,359],{"class":117}," 5s\n",[65,361,363,366,368],{"class":67,"line":362},29,[65,364,365],{"class":71},"      timeout",[65,367,93],{"class":75},[65,369,370],{"class":117}," 3s\n",[65,372,374,377,379],{"class":67,"line":373},30,[65,375,376],{"class":71},"      retries",[65,378,93],{"class":75},[65,380,381],{"class":96}," 10\n",[65,383,385],{"class":67,"line":384},31,[65,386,236],{"emptyLinePlaceholder":235},[65,388,390,393],{"class":67,"line":389},32,[65,391,392],{"class":71},"  cache",[65,394,76],{"class":75},[65,396,398,400,402],{"class":67,"line":397},33,[65,399,250],{"class":71},[65,401,93],{"class":75},[65,403,404],{"class":117}," redis:7-alpine\n",[65,406,408,411,413,415,417,420,422,424,426,429,431,433,435,438,440],{"class":67,"line":407},34,[65,409,410],{"class":71},"    command",[65,412,93],{"class":75},[65,414,327],{"class":75},[65,416,330],{"class":75},[65,418,419],{"class":117},"redis-server",[65,421,330],{"class":75},[65,423,338],{"class":75},[65,425,114],{"class":75},[65,427,428],{"class":117},"--appendonly",[65,430,330],{"class":75},[65,432,338],{"class":75},[65,434,114],{"class":75},[65,436,437],{"class":117},"yes",[65,439,330],{"class":75},[65,441,348],{"class":75},[65,443,445,447],{"class":67,"line":444},35,[65,446,298],{"class":71},[65,448,76],{"class":75},[65,450,452,454],{"class":67,"line":451},36,[65,453,111],{"class":75},[65,455,456],{"class":117}," redisdata:\u002Fdata\n",[65,458,460],{"class":67,"line":459},37,[65,461,236],{"emptyLinePlaceholder":235},[65,463,465,468],{"class":67,"line":464},38,[65,466,467],{"class":71},"volumes",[65,469,76],{"class":75},[65,471,473,476],{"class":67,"line":472},39,[65,474,475],{"class":71},"  pgdata",[65,477,76],{"class":75},[65,479,481,484],{"class":67,"line":480},40,[65,482,483],{"class":71},"  redisdata",[65,485,76],{"class":75},[15,487,488],{},"Burada dikkat edilmesi gereken birkaç nokta var:",[490,491,492,512,527,543],"ul",{},[493,494,495,499,500,503,504,507,508,511],"li",{},[496,497,498],"strong",{},"Servis adları DNS adıdır."," ",[19,501,502],{},"api"," container'ı veritabanına ",[19,505,506],{},"localhost"," ile değil ",[19,509,510],{},"db"," ile bağlanır. Compose tüm servisleri ortak bir network'e koyar.",[493,513,514,499,520,522,523,526],{},[496,515,516,519],{},[19,517,518],{},"ports"," sadece dışarıya açılacak servislerde gerekir.",[19,521,510],{}," ve ",[19,524,525],{},"cache"," host'a port açmadığı için sadece compose network'ü içinden erişilebilir.",[493,528,529,538,539,542],{},[496,530,531,534,535],{},[19,532,533],{},"depends_on"," + ",[19,536,537],{},"condition: service_healthy",", API'nin veritabanı gerçekten bağlantı kabul etmeye başlayana kadar beklemesini sağlar. Sadece ",[19,540,541],{},"depends_on: [db]"," yazmak container'ın başlamasını bekler, hazır olmasını değil.",[493,544,545,548,549,552,553,556,557,560],{},[496,546,547],{},"Named volume'ler"," (",[19,550,551],{},"pgdata",", ",[19,554,555],{},"redisdata",") ",[19,558,559],{},"docker compose down"," sonrası da kalır; veriniz kaybolmaz.",[10,562,564],{"id":563},"_2-ortam-değişkenleri-ve-env","2. Ortam değişkenleri ve .env",[15,566,567,570,571,573,574,577],{},[19,568,569],{},"${DB_PASSWORD}"," gibi değişkenler, ",[19,572,45],{}," ile aynı klasördeki ",[19,575,576],{},".env"," dosyasından okunur:",[56,579,583],{"className":580,"code":581,"language":582,"meta":61,"style":61},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","# .env\nDB_PASSWORD=local-dev-password\nCOMPOSE_PROJECT_NAME=myapp\n","bash",[19,584,585,591,603],{"__ignoreMap":61},[65,586,587],{"class":67,"line":68},[65,588,590],{"class":589},"sHwdD","# .env\n",[65,592,593,597,600],{"class":67,"line":79},[65,594,596],{"class":595},"sTEyZ","DB_PASSWORD",[65,598,599],{"class":75},"=",[65,601,602],{"class":117},"local-dev-password\n",[65,604,605,608,610],{"class":67,"line":87},[65,606,607],{"class":595},"COMPOSE_PROJECT_NAME",[65,609,599],{"class":75},[65,611,612],{"class":117},"myapp\n",[15,614,615,616,619],{},"Container'a çok sayıda değişken geçirmek için ",[19,617,618],{},"env_file"," daha temizdir:",[56,621,623],{"className":58,"code":622,"language":60,"meta":61,"style":61},"services:\n  api:\n    env_file:\n      - .env.api\n",[19,624,625,631,637,644],{"__ignoreMap":61},[65,626,627,629],{"class":67,"line":68},[65,628,72],{"class":71},[65,630,76],{"class":75},[65,632,633,635],{"class":67,"line":79},[65,634,82],{"class":71},[65,636,76],{"class":75},[65,638,639,642],{"class":67,"line":87},[65,640,641],{"class":71},"    env_file",[65,643,76],{"class":75},[65,645,646,648],{"class":67,"line":100},[65,647,111],{"class":75},[65,649,650],{"class":117}," .env.api\n",[30,652,653],{},[15,654,655,657,658,661,662,665],{},[19,656,576],{}," dosyalarını ",[19,659,660],{},".gitignore","'a ekleyin, repoya bunun yerine ",[19,663,664],{},".env.example"," koyun.",[15,667,668],{},"Compose'un değişkenleri nasıl çözdüğünü görmek için:",[56,670,672],{"className":580,"code":671,"language":582,"meta":61,"style":61},"docker compose config        # değişkenleri yerleştirilmiş son hali yazdırır\n",[19,673,674],{"__ignoreMap":61},[65,675,676,680,683,686],{"class":67,"line":68},[65,677,679],{"class":678},"sBMFI","docker",[65,681,682],{"class":117}," compose",[65,684,685],{"class":117}," config",[65,687,688],{"class":589},"        # değişkenleri yerleştirilmiş son hali yazdırır\n",[10,690,692],{"id":691},"_3-sık-kullanılan-komutlar","3. Sık kullanılan komutlar",[56,694,696],{"className":580,"code":695,"language":582,"meta":61,"style":61},"docker compose up -d                 # tüm servisleri arka planda başlat\ndocker compose up -d --build         # image'ları yeniden build edip başlat\ndocker compose up -d api             # sadece api (ve bağımlılıkları)\ndocker compose ps                    # servislerin durumu\ndocker compose logs -f api           # api loglarını canlı izle\ndocker compose logs --tail=100       # tüm servislerin son 100 satırı\ndocker compose exec db psql -U app   # çalışan container'da komut\ndocker compose run --rm api sh       # tek seferlik yeni container\ndocker compose restart api\ndocker compose stop                  # durdur, container'ları silme\ndocker compose down                  # durdur ve container + network'ü sil\ndocker compose down -v               # volume'leri de sil (veri gider!)\ndocker compose pull                  # image'ların yeni sürümlerini çek\ndocker compose build --no-cache api\ndocker compose top                   # container'lardaki süreçler\n",[19,697,698,713,729,745,757,774,788,812,832,844,856,868,882,894,908],{"__ignoreMap":61},[65,699,700,702,704,707,710],{"class":67,"line":68},[65,701,679],{"class":678},[65,703,682],{"class":117},[65,705,706],{"class":117}," up",[65,708,709],{"class":117}," -d",[65,711,712],{"class":589},"                 # tüm servisleri arka planda başlat\n",[65,714,715,717,719,721,723,726],{"class":67,"line":79},[65,716,679],{"class":678},[65,718,682],{"class":117},[65,720,706],{"class":117},[65,722,709],{"class":117},[65,724,725],{"class":117}," --build",[65,727,728],{"class":589},"         # image'ları yeniden build edip başlat\n",[65,730,731,733,735,737,739,742],{"class":67,"line":87},[65,732,679],{"class":678},[65,734,682],{"class":117},[65,736,706],{"class":117},[65,738,709],{"class":117},[65,740,741],{"class":117}," api",[65,743,744],{"class":589},"             # sadece api (ve bağımlılıkları)\n",[65,746,747,749,751,754],{"class":67,"line":100},[65,748,679],{"class":678},[65,750,682],{"class":117},[65,752,753],{"class":117}," ps",[65,755,756],{"class":589},"                    # servislerin durumu\n",[65,758,759,761,763,766,769,771],{"class":67,"line":108},[65,760,679],{"class":678},[65,762,682],{"class":117},[65,764,765],{"class":117}," logs",[65,767,768],{"class":117}," -f",[65,770,741],{"class":117},[65,772,773],{"class":589},"           # api loglarını canlı izle\n",[65,775,776,778,780,782,785],{"class":67,"line":124},[65,777,679],{"class":678},[65,779,682],{"class":117},[65,781,765],{"class":117},[65,783,784],{"class":117}," --tail=100",[65,786,787],{"class":589},"       # tüm servislerin son 100 satırı\n",[65,789,790,792,794,797,800,803,806,809],{"class":67,"line":132},[65,791,679],{"class":678},[65,793,682],{"class":117},[65,795,796],{"class":117}," exec",[65,798,799],{"class":117}," db",[65,801,802],{"class":117}," psql",[65,804,805],{"class":117}," -U",[65,807,808],{"class":117}," app",[65,810,811],{"class":589},"   # çalışan container'da komut\n",[65,813,814,816,818,821,824,826,829],{"class":67,"line":143},[65,815,679],{"class":678},[65,817,682],{"class":117},[65,819,820],{"class":117}," run",[65,822,823],{"class":117}," --rm",[65,825,741],{"class":117},[65,827,828],{"class":117}," sh",[65,830,831],{"class":589},"       # tek seferlik yeni container\n",[65,833,834,836,838,841],{"class":67,"line":154},[65,835,679],{"class":678},[65,837,682],{"class":117},[65,839,840],{"class":117}," restart",[65,842,843],{"class":117}," api\n",[65,845,846,848,850,853],{"class":67,"line":165},[65,847,679],{"class":678},[65,849,682],{"class":117},[65,851,852],{"class":117}," stop",[65,854,855],{"class":589},"                  # durdur, container'ları silme\n",[65,857,858,860,862,865],{"class":67,"line":176},[65,859,679],{"class":678},[65,861,682],{"class":117},[65,863,864],{"class":117}," down",[65,866,867],{"class":589},"                  # durdur ve container + network'ü sil\n",[65,869,870,872,874,876,879],{"class":67,"line":184},[65,871,679],{"class":678},[65,873,682],{"class":117},[65,875,864],{"class":117},[65,877,878],{"class":117}," -v",[65,880,881],{"class":589},"               # volume'leri de sil (veri gider!)\n",[65,883,884,886,888,891],{"class":67,"line":192},[65,885,679],{"class":678},[65,887,682],{"class":117},[65,889,890],{"class":117}," pull",[65,892,893],{"class":589},"                  # image'ların yeni sürümlerini çek\n",[65,895,896,898,900,903,906],{"class":67,"line":203},[65,897,679],{"class":678},[65,899,682],{"class":117},[65,901,902],{"class":117}," build",[65,904,905],{"class":117}," --no-cache",[65,907,843],{"class":117},[65,909,910,912,914,917],{"class":67,"line":211},[65,911,679],{"class":678},[65,913,682],{"class":117},[65,915,916],{"class":117}," top",[65,918,919],{"class":589},"                   # container'lardaki süreçler\n",[921,922,923,942],"table",{},[924,925,926],"thead",{},[927,928,929,933,936,939],"tr",{},[930,931,932],"th",{},"Komut",[930,934,935],{},"Container",[930,937,938],{},"Network",[930,940,941],{},"Volume",[943,944,945,961,975],"tbody",{},[927,946,947,953,956,959],{},[948,949,950],"td",{},[19,951,952],{},"stop",[948,954,955],{},"Durur, kalır",[948,957,958],{},"Kalır",[948,960,958],{},[927,962,963,968,971,973],{},[948,964,965],{},[19,966,967],{},"down",[948,969,970],{},"Silinir",[948,972,970],{},[948,974,958],{},[927,976,977,982,984,986],{},[948,978,979],{},[19,980,981],{},"down -v",[948,983,970],{},[948,985,970],{},[948,987,970],{},[10,989,991],{"id":990},"_4-geliştirme-ortamı-için-override","4. Geliştirme ortamı için override",[15,993,994,995,997,998,1001],{},"Compose, ",[19,996,45],{}," ile birlikte aynı klasördeki ",[19,999,1000],{},"compose.override.yaml"," dosyasını da otomatik okur. Geliştirmeye özel ayarları buraya koymak, ana dosyayı production'a yakın tutar:",[56,1003,1005],{"className":58,"code":1004,"language":60,"meta":61,"style":61},"# compose.override.yaml\nservices:\n  api:\n    environment:\n      SPRING_PROFILES_ACTIVE: dev\n    ports:\n      - \"5005:5005\"     # remote debug\n  db:\n    ports:\n      - \"5432:5432\"     # DBeaver vb. ile bağlanmak için\n",[19,1006,1007,1012,1018,1024,1030,1040,1046,1060,1066,1072],{"__ignoreMap":61},[65,1008,1009],{"class":67,"line":68},[65,1010,1011],{"class":589},"# compose.override.yaml\n",[65,1013,1014,1016],{"class":67,"line":79},[65,1015,72],{"class":71},[65,1017,76],{"class":75},[65,1019,1020,1022],{"class":67,"line":87},[65,1021,82],{"class":71},[65,1023,76],{"class":75},[65,1025,1026,1028],{"class":67,"line":100},[65,1027,127],{"class":71},[65,1029,76],{"class":75},[65,1031,1032,1035,1037],{"class":67,"line":108},[65,1033,1034],{"class":71},"      SPRING_PROFILES_ACTIVE",[65,1036,93],{"class":75},[65,1038,1039],{"class":117}," dev\n",[65,1041,1042,1044],{"class":67,"line":124},[65,1043,103],{"class":71},[65,1045,76],{"class":75},[65,1047,1048,1050,1052,1055,1057],{"class":67,"line":132},[65,1049,111],{"class":75},[65,1051,114],{"class":75},[65,1053,1054],{"class":117},"5005:5005",[65,1056,330],{"class":75},[65,1058,1059],{"class":589},"     # remote debug\n",[65,1061,1062,1064],{"class":67,"line":143},[65,1063,242],{"class":71},[65,1065,76],{"class":75},[65,1067,1068,1070],{"class":67,"line":154},[65,1069,103],{"class":71},[65,1071,76],{"class":75},[65,1073,1074,1076,1078,1081,1083],{"class":67,"line":165},[65,1075,111],{"class":75},[65,1077,114],{"class":75},[65,1079,1080],{"class":117},"5432:5432",[65,1082,330],{"class":75},[65,1084,1085],{"class":589},"     # DBeaver vb. ile bağlanmak için\n",[15,1087,1088,1089,1092],{},"Production'da farklı bir dosya kullanmak için ",[19,1090,1091],{},"-f"," ile dosyaları açıkça belirtin:",[56,1094,1096],{"className":580,"code":1095,"language":582,"meta":61,"style":61},"docker compose -f compose.yaml -f compose.prod.yaml up -d\n",[19,1097,1098],{"__ignoreMap":61},[65,1099,1100,1102,1104,1106,1109,1111,1114,1116],{"class":67,"line":68},[65,1101,679],{"class":678},[65,1103,682],{"class":117},[65,1105,768],{"class":117},[65,1107,1108],{"class":117}," compose.yaml",[65,1110,768],{"class":117},[65,1112,1113],{"class":117}," compose.prod.yaml",[65,1115,706],{"class":117},[65,1117,1118],{"class":117}," -d\n",[10,1120,1122],{"id":1121},"_5-profiller","5. Profiller",[15,1124,1125],{},"Her zaman çalışması gerekmeyen servisleri (ör. pgAdmin, mail test sunucusu) profile bağlayabilirsiniz:",[56,1127,1129],{"className":58,"code":1128,"language":60,"meta":61,"style":61},"services:\n  pgadmin:\n    image: dpage\u002Fpgadmin4\n    profiles: [\"tools\"]\n    ports:\n      - \"5050:80\"\n    environment:\n      PGADMIN_DEFAULT_EMAIL: admin@example.com\n      PGADMIN_DEFAULT_PASSWORD: admin\n",[19,1130,1131,1137,1144,1153,1171,1177,1188,1194,1204],{"__ignoreMap":61},[65,1132,1133,1135],{"class":67,"line":68},[65,1134,72],{"class":71},[65,1136,76],{"class":75},[65,1138,1139,1142],{"class":67,"line":79},[65,1140,1141],{"class":71},"  pgadmin",[65,1143,76],{"class":75},[65,1145,1146,1148,1150],{"class":67,"line":87},[65,1147,250],{"class":71},[65,1149,93],{"class":75},[65,1151,1152],{"class":117}," dpage\u002Fpgadmin4\n",[65,1154,1155,1158,1160,1162,1164,1167,1169],{"class":67,"line":100},[65,1156,1157],{"class":71},"    profiles",[65,1159,93],{"class":75},[65,1161,327],{"class":75},[65,1163,330],{"class":75},[65,1165,1166],{"class":117},"tools",[65,1168,330],{"class":75},[65,1170,348],{"class":75},[65,1172,1173,1175],{"class":67,"line":108},[65,1174,103],{"class":71},[65,1176,76],{"class":75},[65,1178,1179,1181,1183,1186],{"class":67,"line":124},[65,1180,111],{"class":75},[65,1182,114],{"class":75},[65,1184,1185],{"class":117},"5050:80",[65,1187,121],{"class":75},[65,1189,1190,1192],{"class":67,"line":132},[65,1191,127],{"class":71},[65,1193,76],{"class":75},[65,1195,1196,1199,1201],{"class":67,"line":143},[65,1197,1198],{"class":71},"      PGADMIN_DEFAULT_EMAIL",[65,1200,93],{"class":75},[65,1202,1203],{"class":117}," admin@example.com\n",[65,1205,1206,1209,1211],{"class":67,"line":154},[65,1207,1208],{"class":71},"      PGADMIN_DEFAULT_PASSWORD",[65,1210,93],{"class":75},[65,1212,1213],{"class":117}," admin\n",[56,1215,1217],{"className":580,"code":1216,"language":582,"meta":61,"style":61},"docker compose up -d                     # pgadmin başlamaz\ndocker compose --profile tools up -d     # pgadmin de başlar\n",[19,1218,1219,1232],{"__ignoreMap":61},[65,1220,1221,1223,1225,1227,1229],{"class":67,"line":68},[65,1222,679],{"class":678},[65,1224,682],{"class":117},[65,1226,706],{"class":117},[65,1228,709],{"class":117},[65,1230,1231],{"class":589},"                     # pgadmin başlamaz\n",[65,1233,1234,1236,1238,1241,1244,1246,1248],{"class":67,"line":79},[65,1235,679],{"class":678},[65,1237,682],{"class":117},[65,1239,1240],{"class":117}," --profile",[65,1242,1243],{"class":117}," tools",[65,1245,706],{"class":117},[65,1247,709],{"class":117},[65,1249,1250],{"class":589},"     # pgadmin de başlar\n",[10,1252,1254],{"id":1253},"_6-kaynak-limitleri-ve-restart-politikası","6. Kaynak limitleri ve restart politikası",[56,1256,1258],{"className":58,"code":1257,"language":60,"meta":61,"style":61},"services:\n  api:\n    restart: unless-stopped\n    deploy:\n      resources:\n        limits:\n          cpus: \"1.0\"\n          memory: 512M\n",[19,1259,1260,1266,1272,1280,1287,1294,1301,1315],{"__ignoreMap":61},[65,1261,1262,1264],{"class":67,"line":68},[65,1263,72],{"class":71},[65,1265,76],{"class":75},[65,1267,1268,1270],{"class":67,"line":79},[65,1269,82],{"class":71},[65,1271,76],{"class":75},[65,1273,1274,1276,1278],{"class":67,"line":87},[65,1275,224],{"class":71},[65,1277,93],{"class":75},[65,1279,229],{"class":117},[65,1281,1282,1285],{"class":67,"line":100},[65,1283,1284],{"class":71},"    deploy",[65,1286,76],{"class":75},[65,1288,1289,1292],{"class":67,"line":108},[65,1290,1291],{"class":71},"      resources",[65,1293,76],{"class":75},[65,1295,1296,1299],{"class":67,"line":124},[65,1297,1298],{"class":71},"        limits",[65,1300,76],{"class":75},[65,1302,1303,1306,1308,1310,1313],{"class":67,"line":132},[65,1304,1305],{"class":71},"          cpus",[65,1307,93],{"class":75},[65,1309,114],{"class":75},[65,1311,1312],{"class":117},"1.0",[65,1314,121],{"class":75},[65,1316,1317,1320,1322],{"class":67,"line":143},[65,1318,1319],{"class":71},"          memory",[65,1321,93],{"class":75},[65,1323,1324],{"class":117}," 512M\n",[921,1326,1327,1340],{},[924,1328,1329],{},[927,1330,1331,1337],{},[930,1332,1333,1336],{},[19,1334,1335],{},"restart"," değeri",[930,1338,1339],{},"Davranış",[943,1341,1342,1352,1362,1372],{},[927,1343,1344,1349],{},[948,1345,1346],{},[19,1347,1348],{},"no",[948,1350,1351],{},"Varsayılan, yeniden başlatmaz",[927,1353,1354,1359],{},[948,1355,1356],{},[19,1357,1358],{},"always",[948,1360,1361],{},"Her durumda yeniden başlatır",[927,1363,1364,1369],{},[948,1365,1366],{},[19,1367,1368],{},"on-failure",[948,1370,1371],{},"Sadece hata koduyla çıkarsa",[927,1373,1374,1379],{},[948,1375,1376],{},[19,1377,1378],{},"unless-stopped",[948,1380,1381],{},"Elle durdurulmadıkça yeniden başlatır",[10,1383,1385],{"id":1384},"_7-sorun-giderme","7. Sorun giderme",[921,1387,1388,1398],{},[924,1389,1390],{},[927,1391,1392,1395],{},[930,1393,1394],{},"Sorun",[930,1396,1397],{},"Çözüm",[943,1399,1400,1417,1432,1446,1457,1468],{},[927,1401,1402,1411],{},[948,1403,1404,1407,1408],{},[19,1405,1406],{},"Connection refused"," → ",[19,1409,1410],{},"localhost:5432",[948,1412,1413,1414],{},"Container içinden servis adını kullanın: ",[19,1415,1416],{},"db:5432",[927,1418,1419,1422],{},[948,1420,1421],{},"API veritabanından önce başlayıp çöküyor",[948,1423,1424,534,1426,522,1428,1431],{},[19,1425,533],{},[19,1427,537],{},[19,1429,1430],{},"healthcheck"," ekleyin",[927,1433,1434,1439],{},[948,1435,1436],{},[19,1437,1438],{},"port is already allocated",[948,1440,1441,1442,1445],{},"Host'ta aynı portu kullanan süreç var; ",[19,1443,1444],{},"ss -ltnp"," ile bulun ya da port eşlemesini değiştirin",[927,1447,1448,1451],{},[948,1449,1450],{},"Kod değişikliği container'a yansımıyor",[948,1452,1453,1456],{},[19,1454,1455],{},"docker compose up -d --build"," ile image'ı yeniden build edin",[927,1458,1459,1462],{},[948,1460,1461],{},"Veritabanı şifresini değiştirdim ama eskisi geçerli",[948,1463,1464,1465,1467],{},"Postgres şifreyi ilk kurulumda volume'e yazar; ",[19,1466,981],{}," ile volume'ü silin (veri gider)",[927,1469,1470,1475],{},[948,1471,1472,1474],{},[19,1473,576],{}," değişkenleri boş geliyor",[948,1476,1477,1480,1481,1483],{},[19,1478,1479],{},"docker compose config"," ile kontrol edin; ",[19,1482,576],{}," compose dosyasıyla aynı klasörde olmalı",[10,1485,1487],{"id":1486},"sonuç","Sonuç",[15,1489,1490,1491,1493,1494,1496],{},"Docker Compose, birden fazla servisten oluşan bir uygulamayı tek dosyayla tanımlamanın ve herkesin aynı ortamı tek komutla kurmasının en pratik yoludur. Servis adlarının DNS adı olduğunu, ",[19,1492,1430],{}," ile başlatma sırasını kontrol etmeyi ve ",[19,1495,981],{},"'nin veriyi sildiğini akılda tutmak, karşılaşılan sorunların çoğunu baştan önler.",[1498,1499,1500],"style",{},"html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}",{"title":61,"searchDepth":79,"depth":79,"links":1502},[1503,1504,1505,1506,1507,1508,1509,1510,1511],{"id":12,"depth":79,"text":13},{"id":53,"depth":79,"text":54},{"id":563,"depth":79,"text":564},{"id":691,"depth":79,"text":692},{"id":990,"depth":79,"text":991},{"id":1121,"depth":79,"text":1122},{"id":1253,"depth":79,"text":1254},{"id":1384,"depth":79,"text":1385},{"id":1486,"depth":79,"text":1487},"2026-10-27","Uygulama, veritabanı ve cache'i tek bir compose.yaml ile ayağa kaldırmak — servisler, network, volume, healthcheck, env dosyaları ve sık kullanılan komutlar.","md",{},"\u002Ftr\u002Fblog\u002Fdocker-compose-guide",{"title":5,"description":1513},"tr\u002Fblog\u002Fdocker-compose-guide",[679,1520,1521],"devops","rehber","\u002Fen\u002Fblog\u002Fdocker-compose-guide","hSrScYGSdA7KL5rqvq0Jm7ATJmOVsM7-d6KX9SM36Eg",1793060537178]