DockerFile'da "VOLUME" talimatını anlama


136

Aşağıda "Dockerfile" dosyamın içeriği var

FROM node:boron

# Create app directory
RUN mkdir -p /usr/src/app

# change working dir to /usr/src/app
WORKDIR /usr/src/app

VOLUME . /usr/src/app

RUN npm install

EXPOSE 8080

CMD ["node" , "server" ]

Bu dosyada "VOLUME. / Usr / src / app" komutunun ana bilgisayardaki mevcut çalışma dizininin içeriğini konteynerin / usr / src / app klasörüne monte etmesini bekliyorum.

Lütfen doğru yol olup olmadığını bana bildirin.

Yanıtlar:


88

Resmi liman işçisi öğreticisi şunları söylüyor:

Bir veri birimi, Birlik Dosya Sistemini atlayan bir veya daha fazla kapsayıcı içinde özel olarak belirlenmiş bir dizindir. Veri birimleri, kalıcı veya paylaşılan veriler için birkaç yararlı özellik sağlar:

  • Bir kap oluşturulduğunda hacimler başlatılır. Konteynerin temel görüntüsü, belirtilen bağlama noktasında veri içeriyorsa,
    bu mevcut veriler, birim
    başlatıldığında yeni birime kopyalanır . (Bunun bir ana bilgisayar bağlarken geçerli olmadığını unutmayın.
    dizini .)
  • Veri hacimleri, kapsayıcılar arasında paylaşılabilir ve yeniden kullanılabilir.

  • Bir veri hacmindeki değişiklikler doğrudan yapılır.

  • Bir görüntüyü güncellediğinizde, veri hacmindeki değişiklikler dahil edilmeyecektir.

  • Kabın kendisi silinse bile veri hacimleri devam eder.

İçinde Dockerfile, bir konteyner içindeki bir birimin yalnızca hedefini belirtebilirsiniz . Örneğin/usr/src/app .

Eğer bir konteyner, örneğin çalıştırdığınızda docker run --volume=/opt:/usr/src/app my_image, size olabilir ama onun takma noktası (belirtmek gerekmez / opt ana makinede). --volumeBağımsız değişken belirtmezseniz , bağlama noktası genellikle altında otomatik olarak seçilir /var/lib/docker/volumes/.


277

Kısaca: Hayır, senin VOLUME talimatınız doğru değil.

Dockerfile, VOLUMEkonteyner tarafı yolları verilen bir veya daha fazla birimi belirtir. Ancak görüntü yazarının bir ana bilgisayar yolu belirlemesine izin vermez. Ana bilgisayar tarafında, birimler Docker kökü içinde çok uzun bir ID benzeri adla oluşturulur. Benim makinemde bu/var/lib/docker/volumes .

Not: Otomatik olarak oluşturulmuş ad çok uzun olduğundan ve insan açısından bir anlam ifade etmediğinden, bu ciltlere genellikle "adsız" veya "anonim" denir.

Bir '.' Kullanan örneğiniz Noktayı birinci veya ikinci argüman yapsam da karakter makinemde çalışmayacak bile. Bu hata mesajını alıyorum:

docker: daemon'dan gelen hata yanıtı: oci çalışma zamanı hatası: container_linux.go: 265: "process_linux.go: 368: kapsayıcı başlatmaya neden oldu \" open / dev / ptmx: böyle bir dosya veya dizin yok \ "".

Bu noktaya kadar söylenenlerin muhtemelen anlamaya çalışan biri için çok değerli olmadığını VOLUMEve başarmaya çalıştığınız şey -viçin kesinlikle bir çözüm sağlamadığını biliyorum. Bu nedenle, umarım aşağıdaki örnekler bu konulara biraz daha ışık tutacaktır.

Minitutorial: Hacimleri belirleme

Bu Dockerfile verildiğinde:

FROM openjdk:8u131-jdk-alpine
VOLUME vol1 vol2

(Bu mini öğreticinin sonucu için, şunu belirtmemiz fark etmez vol1 vol2veya/vol1 /vol2 - nedenini sorma)

İnşa et:

docker build -t my-openjdk

Çalıştırmak:

docker run --rm -it my-openjdk

Kabın lsiçinde, komut satırında çalıştırın ve iki dizin olduğunu fark edeceksiniz; /vol1ve/vol2 .

Kapsayıcıyı çalıştırmak ayrıca ana bilgisayar tarafında iki dizin veya "birimler" oluşturur.

Konteyner çalıştıran sahip iken, yürütme docker volume lsüzerindeki ana makinede ve böyle bir şey göreceksiniz (ben kısalık için üç noktalı adının orta kısmını yerini almıştır):

DRIVER    VOLUME NAME
local     c984...e4fc
local     f670...49f0

Geri içinde konteyner , yürütme touch /vol1/weird-ass-file(söz konusu yerde Boş bir dosya oluşturur).

Bu dosya artık ana makinede, adsız ciltlerden biri olan lol'de mevcuttur. İlk listelenen birimi denediğim için iki denememi aldı, ancak sonunda ana makinede şu komutu kullanarak dosyamı listelenen ikinci ciltte buldum:

sudo ls /var/lib/docker/volumes/f670...49f0/_data

Benzer şekilde, bu dosyayı ana bilgisayardan silmeyi deneyebilirsiniz ve bu dosya da kapsayıcıda silinecektir.

Not: _dataKlasöre ayrıca "bağlama noktası" da denir.

Kapsayıcıdan çıkın ve ana bilgisayardaki birimleri listeleyin. Gittiler. --rmKonteyneri çalıştırırken bayrağı kullandık ve bu seçenek sadece çıkışta konteyneri değil aynı zamanda hacimleri de etkili bir şekilde siler.

Yeni bir kap çalıştırın, ancak şunu kullanarak bir birim belirtin -v:

docker run --rm -it -v /vol3 my-openjdk

Bu , üçüncü bir cilt ekler ve tüm sistem üç adsız cilde sahip olur. Komut sadece biz belirtmiş olsaydık çökebilirdi -v vol3. Argüman , konteyner içinde mutlak bir yol olmalıdır . Ana bilgisayar tarafında, yeni üçüncü cilt anonimdir ve diğer iki cilt ile birlikte/var/lib/docker/volumes/ .

Daha önce, Dockerfileçalışma zamanı sırasında ana bilgisayardan konteynere dosya getirmeye çalışırken bizim için sorun teşkil eden bir ana bilgisayar yoluna eşlenemediği belirtilmişti. Farklı bir -vsözdizimi bu sorunu çözer.

Proje dizinimde, konteynerin içinde ./srcsenkronize etmek istediğim bir alt klasörüm olduğunu düşünün /src. Bu komut hile yapar:

docker run -it -v $(pwd)/src:/src my-openjdk

:Karakterin her iki tarafı da mutlak bir yol bekliyor. Sol taraf, ana makinede mutlak bir yoldur, sağ taraf ise kabın içinde mutlak bir yoldur. pwd"geçerli / çalışma dizini yazdır" komutudur. Komutu devreye sokmak$() parantez içindeki komutu alır, bir alt kabukta çalıştırır ve proje dizinimize mutlak yolu geri verir.

Hepsini bir araya getirerek, ./src/Hello.javaana makinedeki proje klasörümüzde aşağıdaki içeriğe sahip olduğumuzu varsayalım :

public class Hello {
    public static void main(String... ignored) {
        System.out.println("Hello, World!");
    }
}

Bu Dockerfile'ı oluşturuyoruz:

FROM openjdk:8u131-jdk-alpine
WORKDIR /src
ENTRYPOINT javac Hello.java && java Hello

Bu komutu çalıştırıyoruz:

docker run -v $(pwd)/src:/src my-openjdk

Bu, "Merhaba, Dünya!" Yazdırır.

En iyi yanı, .java dosyasını ikinci bir çalıştırmada başka bir çıktı için yeni bir mesajla değiştirmekte tamamen özgür olmamızdır - görüntüyü yeniden oluşturmak zorunda kalmadan =)

Son açıklamalar

Docker'da oldukça yeniyim ve yukarıda bahsedilen "eğitim" 3 günlük bir komut satırı hackathonundan topladığım bilgileri yansıtıyor. İfadelerimi destekleyen net İngilizce benzeri belgelere bağlantı sağlayamadığım için neredeyse utanıyorum, ancak dürüst olmak gerekirse bunun kişisel çaba değil belge eksikliğinden kaynaklandığını düşünüyorum. Örneklerin "Windows 10 -> Vagrant 2.0.0 -> Docker 17.09.0-ce" olan mevcut kurulumumu kullanarak reklamı yapılan şekilde çalıştığını biliyorum.

Öğretici, "kapsayıcının Dockerfile içindeki yolunu nasıl belirtiriz ve çalıştır komutunun yalnızca ana bilgisayar yolunu belirtmesine izin veririz" sorununu çözmez. Bir yolu olabilir, sadece bulamadım.

Son olarak, VOLUMEDockerfile'da belirtmenin sadece alışılmadık bir şey değil, muhtemelen asla kullanılmaması gereken en iyi uygulama olduğuna dair içimden bir his var VOLUME. İki nedenden dolayı. Önceden belirlemiş olmamızın ilk nedeni: Ana bilgisayar yolunu belirleyemiyoruz - bu iyi bir şey çünkü Dockerfiles, bir ana makinenin özelliklerine çok agnostik olmalıdır. Ancak ikinci neden, insanların --rmkonteyneri çalıştırırken bu seçeneği kullanmayı unutabilmeleridir . Kişi kabı çıkarmayı hatırlayabilir ancak hacmi çıkarmayı unutabilir. Ayrıca, en iyi insan belleğiyle bile, tüm anonim ciltlerden hangilerinin kaldırılmasının güvenli olduğunu bulmak göz korkutucu bir görev olabilir.


2
Adsız / anonim ciltleri ne zaman kullanmalıyız?
Searene

10
@Martin çok teşekkür ederim. Hackathon'unuz ve bunun sonucunda ortaya çıkan eğitim burada çok takdir edilmektedir.
Beezer

6
"İngilizce benzeri net belgelere bağlantılar sağlayamadım ... Dürüst olmak gerekirse, bunun belge eksikliğinden kaynaklandığını düşünüyorum". Teyit edebilirim. Bu bulduğum en kapsamlı ve güncel belgeler ve saatlerdir arıyordum.
user697576

4
docker volume pruneçalışan kapsayıcılara takılı olmayan kalan birimleri temizlemek için kullanılabilir. Potansiyel olarak önemli olanları tek başına id ile ayırt etmenin kolay olacağını söylemiyorum ...
Jeremy

4
"Bu minitutorial'ın sonucu için, vol1 vol2 veya / vol1 / vol2'yi belirtmemiz fark etmez - bana nedenini sorma". @MartinAndersson, çünkü geçerli çalışma dizini /, yani vol1göreceli /olduğu için çözülür /vol1. Eğer kullanırsanız WORKDIRdışında bir çalışma dizini belirtmek için /, vol1ve /vol1artık aynı dizine işaret olacaktır.
sebastian

41

VOLUMEDockerfile'da bir satır belirtmek , görüntünüzde biraz meta veri yapılandırır, ancak bu meta verilerin nasıl kullanıldığı önemlidir.

İlk olarak, bu iki satır ne yaptı:

WORKDIR /usr/src/app
VOLUME . /usr/src/app

Buradaki WORKDIRsatır, yoksa dizini oluşturur ve bazı görüntü meta verilerini, tüm göreceli yolları belirtmek RUNiçin ve bu konumda olacak gibi komutlar için geçerli dizinle birlikte günceller . Buradaki VOLUMEsatır , biri göreceli yol ve diğeri de aynı dizin olmak üzere iki cilt belirtir . Çoğu zaman satır yalnızca tek bir dizin içerir, ancak sizin yaptığınız gibi birden çok dizini içerebilir veya json formatlı bir dizi olabilir../usr/src/appVOLUME

Dockerfile'da bir birim kaynağı belirtemezsiniz : Bir Dockerfile'da birimleri belirtirken yaygın bir karışıklık kaynağı, görüntü oluşturma zamanında bir kaynağın ve hedefin çalışma zamanı sözdizimiyle eşleşmeye çalışıyor, bu işe yaramayacak . Dockerfile yalnızca birimin hedefini belirtebilir. Kök dizini konteynere monte etmek için docker hub üzerindeki ortak bir imajı güncelleyebildikleri ve ardından konteynerin içinde bir giriş noktasının parçası olarak / etc / passwd'ye girişler ekler, systemd'yi bir sonraki yeniden başlatmada bir bitcoin madencisi çalıştıracak şekilde yapılandırır veya uzak bir siteye göndermek için dosya sisteminde kredi kartları, SSN'ler ve özel anahtarlar için arama yapar.

VOLUME satırı ne işe yarar? Belirtildiği gibi, görüntünün içindeki bir dizinin bir birim olduğunu söylemek için bazı görüntü meta verilerini ayarlar. Bu meta veriler nasıl kullanılır? Bu görüntüden her konteyner oluşturduğunuzda, docker bu dizini bir birim olmaya zorlar. Çalıştırma komutunuzda bir birim sağlamazsanız veya dosya oluşturmazsanız, docker için tek seçenek anonim bir birim oluşturmaktır. Bu, ad için uzun bir benzersiz kimliğe sahip yerel adlandırılmış bir birimdir ve neden oluşturulduğuna veya hangi verileri içerdiğine dair başka hiçbir gösterge yoktur (anonim birimler, verilerin kaybolmaya gitmesidir). Bir adlandırılmış veya ana bilgisayar birimini işaret ederek birimi geçersiz kılarsanız, verileriniz bunun yerine oraya gidecektir.

VOLUME bazı şeyleri bozar: Dockerfile'da tanımlandıktan sonra bir birimi devre dışı bırakamazsınız. Daha da önemlisi, RUNdocker'daki komut geçici kapsayıcılarla uygulanır. Bu geçici kapsayıcılar geçici bir anonim cilt alacaktır. Bu anonim cilt, görüntünüzün içeriğiyle başlatılacaktır. RUNKomutunuzdan konteynerin içine yazılan herhangi bir şey bu birime yapılacaktır. Ne zaman RUNkomut yüzeyler, görüntüye değişiklikler kaydedilir ve anonim hacme değişiklikler atılır. Bu nedenle VOLUME, Dockerfile içinde a tanımlanmamasını şiddetle tavsiye ediyorum. Görüntüyü birim konumundaki ilk verilerle genişletmek isteyen görüntünüzün alt kullanıcıları için beklenmeyen davranışlara neden olur.

Bir hacmi nasıl belirlemelisiniz? Görüntünüzle birlikte ciltleri dahil etmek istediğiniz yeri belirtmek için, bir docker-compose.yml. Kullanıcılar, birim konumunu yerel ortamlarına göre ayarlamak için bunu değiştirebilir ve bu, yayınlama bağlantı noktaları ve ağ oluşturma gibi diğer çalışma zamanı ayarlarını yakalar.

Birisi bunu belgelemeli! Onlar sahip. Docker, Dockerfile üzerindeki belgelerinde VOLUME kullanımıyla ilgili uyarıların yanı sıra çalışma zamanında kaynağı belirtme önerilerini içerir:

  • Birimi Dockerfile içinden değiştirme: Herhangi bir derleme adımı, bildirildikten sonra birim içindeki verileri değiştirirse, bu değişiklikler atılır.

...

  • Ana bilgisayar dizini, kapsayıcı çalışma zamanında bildirilir: Ana bilgisayar dizini (bağlama noktası), doğası gereği ana bilgisayara bağlıdır. Bu, belirli bir ana bilgisayar dizininin tüm ana bilgisayarlarda kullanılabilir olması garanti edilemeyeceğinden, görüntü taşınabilirliğini korumak içindir. Bu nedenle, Dockerfile içinden bir ana bilgisayar dizini bağlayamazsınız. VOLUME Talimat belirtmeksizin desteklemiyor host-dirparametresi. Konteyneri oluşturduğunuzda veya çalıştırdığınızda bağlama noktasını belirtmelisiniz.

36

VOLUMEBir komut Dockerfilekesinlikle iyi kullanımına tamamen geleneksel, oldukça okunaklı ve yine kullanımdan kaldırılmış değildir. Sadece anlamalıyım.

Kaptaki uygulamanın çok yazacağı herhangi bir dizini işaret etmek için kullanıyoruz. VOLUMEKonfigürasyon dosyası gibi ana bilgisayar ve kapsayıcı arasında paylaşmak istediğimiz için kullanmıyoruz .

Komutun basitçe bir parametreye ihtiyacı vardır; WORKDIRkapsayıcı içinden ayarlanmışsa göreceli olarak bir klasöre giden yol . Daha sonra docker, grafiğinde (/ var / lib / docker) bir birim oluşturacak ve bunu konteynerdeki klasöre bağlayacaktır. Artık konteynerin yüksek performansla yazabileceği bir yer olacak. VOLUMEKomut olmadan, belirtilen klasöre yazma hızı çok yavaş olacaktır çünkü artık konteyner copy on writekonteynerin kendi stratejisini kullanıyor . copy on writeStrateji hacimleri muhakkak önemli bir ana nedenidir.

VOLUMEKomut tarafından belirtilen klasörün üzerine monte ederseniz , komut asla çalıştırılmaz çünkü VOLUMEsadece konteyner başladığında çalıştırılır, bir nevi ENV.

Temel olarak VOLUMEkomutla herhangi bir birimi harici olarak monte etmeden performans elde edersiniz. Veriler, herhangi bir harici bağlantı olmadan konteyner çalışmalarında da kaydedilecektir. Sonra hazır olduğunuzda üzerine bir şey monte edin.

Bazı iyi örnekler kullanım durumları:
- günlükler
- geçici klasörler

Bazı kötü kullanım durumları:
- statik dosyalar
- yapılandırmalar
- kod


2
İyi ve kötü örnek kullanım durumlarıyla ilgili olarak, Docker'ın "dockerfile en iyi uygulamaları" sayfası şöyle der: "Görüntünüzün değiştirilebilir ve / veya kullanıcı tarafından bakımı yapılabilen parçaları için VOLUME kullanmanız şiddetle tavsiye edilir." Sanırım yapılandırmalar orada.
OmerSch

2
VOLUMEYapılandırmalar için dizinler hakkında açık olmakta sakınca yoktur . Bununla birlikte, bir yapılandırmayı gerçekten bağladığınızda, o dizinin üzerine bağlamanız gerekir ve bu nedenle VOLUMEkomut çalışmaz. Bu nedenle, VOLUMEbir yapılandırma için belirtilen bir dizinde komut kullanmak anlamsızdır . Ayrıca, tek bir statik salt okunur dosya ile bir hacim grafiğini başlatmak ciddi bir abartıdır. Bu yüzden söylediklerimin yanında duruyorum, gerek yokVOLUME , yapılandırmalara komuta .
bay haven

Birimler , uygulama detaylarından dolayı farklı performans özellikleri getirebilir. Veritabanı veri dosyaları bu kullanım durumuna uygundur, ancak verileri (geçici) konteyner depolamasının yanında depolamanın anlamı ne olabilir? Yani hacim varlığını performansa atfetmek yanlıştır.
André Werlang

33

volumeDockerfile'daki talimatı daha iyi anlamak için , mysql resmi docker dosyası uygulamasındaki tipik birim kullanımını öğrenelim.

VOLUME /var/lib/mysql

Referans: https://github.com/docker-library/mysql/blob/3362baccb4352bcf0022014f67c1ec7e6808b8c5/8.0/Dockerfile

/var/lib/mysqlMySQL varsayılan konumu saklayan veri dosyalarını olduğunu.

Test kabını yalnızca test amacıyla çalıştırdığınızda, montaj noktasını belirtemezsiniz, örn.

docker run mysql:8

daha sonra mysql kapsayıcı örneği, volumedockerfile'daki talimat tarafından belirtilen varsayılan bağlama yolunu kullanacaktır. birimler Docker kökü içinde çok uzun bir kimlik benzeri adla oluşturulur, buna "adsız" veya "anonim" birim denir. Temel ana sistem / var / lib / docker / volumes klasöründe.

/var/lib/docker/volumes/320752e0e70d1590e905b02d484c22689e69adcbd764a69e39b17bc330b984e4

Bu, montaj noktasını belirtmeye gerek kalmadan hızlı test amaçları için çok uygundur, ancak yine de kapsayıcı katmanı yerine veri deposu için Hacmi kullanarak en iyi performansı elde edebilir.

Resmi bir kullanım için, adlandırılmış birim veya bağlama bağlama kullanarak bağlama yolunu belirtmeniz gerekir, örn.

docker run  -v /my/own/datadir:/var/lib/mysql mysql:8

Komut, / my / own / datadir dizinini temeldeki ana sistemden konteynerin içine / var / lib / mysql olarak bağlar. / My / own / datadir veri dizini, konteyner silinse bile otomatik olarak silinmez.

Mysql resmi resminin kullanımı (Lütfen "Verilerin Nerede Saklanacağı" bölümünü kontrol edin):

Referans: https://hub.docker.com/_/mysql/


2
Açıklamanı çok beğendim.
LukaszTaraszka

Ancak docker, değişiklikleri yine de kaydeder. Ayrıca -vDockerfile
Alex78191

1

Kendiniz için bir görüntü oluşturuyorsanız ve hiç kimse onu kullanmayacaksa, VOLUME kullanımının hiçbir durumda iyi olduğunu düşünmüyorum.

Uzattığım temel görüntülerde açığa çıkan VOLUME nedeniyle olumsuz etkilendim ve sorunu yalnızca görüntü zaten çalıştıktan sonra öğrenmeye başladım, /var/www/htmlklasörü bir VOLUME olarak ilan eden wordpress gibi ve bu, sırasında eklenen veya değiştirilen tüm dosyalar anlamına geliyordu. inşa aşaması dikkate alınmaz ve canlı değişiklikler, bilmeseniz bile devam eder. Web dizinini başka bir yerde tanımlamak için çirkin bir çözüm var, ancak bu sadece daha basit olana kötü bir çözüm: sadece VOLUME direktifini kaldırın.

-vSeçeneği kullanarak hacmin amacına kolayca ulaşabilirsiniz , bu yalnızca konteynerin hacimlerinin ne olacağını netleştirmekle kalmaz (Dockerfile ve ana Dockerfile dosyalarına göz atmak zorunda kalmadan), aynı zamanda tüketiciye şu seçeneği de sunar: hacmi kullanın ya da kullanmayın.

Bu yanıtta belirtildiği gibi, aşağıdaki nedenlerden dolayı HACİM kullanmak temelde kötüdür :

Ancak, VOLUME talimatının bir bedeli vardır.

  • Kullanıcılar, oluşturulmakta olan adlandırılmamış birimlerin farkında olmayabilir ve konteynerler kaldırıldıktan sonra Docker ana bilgisayarlarında depolama alanı kullanmaya devam edebilir.
  • Dockerfile'da bildirilen bir birimi kaldırmanın bir yolu yoktur. Akış aşağı görüntüler, birimlerin bulunduğu yollara veri ekleyemez.

İkinci sorun, bunun gibi sorunlara yol açar.

Ancak, yardımcı olacak bir hacme undeclare seçeneğine sahip olmak sadece bilmek görüntü oluşturduğu dockerfile tanımlanan hacimleri (ve ebeveyn dockerfiles!). Ayrıca, bir Dockerfile'ın daha yeni sürümlerine bir VOLUME eklenebilir ve görüntünün tüketicileri için beklenmedik bir şekilde işleri bozabilir.

(Bir başka iyi açıklama torpil görüntü olan hacim yaklaşık edildi çıkarıldı ): https://github.com/oracle/docker-images/issues/640#issuecomment-412647328

VOLUME'un insanlar için işleri bozduğu diğer durumlar:

Bir çekme isteği , kapatıldı özelliklerini (hacim dahil) ana görüntüyü sıfırlamak için seçenekler eklemek ve tartışılıyor burada (ve görebileceğiniz birkaç vaka ait insanların bir olan, yüzünden dockerfiles tanımlanan hacimler için olumsuz etkilenen) yorumunu iyi olan VOLUME'a karşı açıklama:

Dockerfile'da VOLUME kullanımı değersizdir. Bir kullanıcının kalıcılığa ihtiyacı varsa, belirtilen kapsayıcıyı çalıştırırken bir hacim eşlemesi sağladığından emin olacaktır. Bir dizinin sahipliğini (/ var / lib / influxdb) ayarlayamama sorunumun InfluxDB'nin Dockerfile'ındaki VOLUME bildiriminden kaynaklandığını tespit etmek çok zordu. UNVOLUME tipi bir seçenek olmadan veya tamamen ortadan kalkmadan, belirtilen klasörle ilgili hiçbir şeyi değiştiremiyorum. Bu idealden daha azdır, özellikle güvenlik bilincindeyseniz ve belirli bir UID belirtmek istediğinizde görüntü, ana makinenizde yazılım çalıştıran rastgele bir kullanıcıdan kaçınmak için gerekli olandan daha fazla izinle çalıştırılmalıdır.

Ayrıca EXPOSE'u kötü buluyorum, ancak daha az yan etkisi var. VOLUME ve EXPOSE hakkında görebildiğim tek iyi şey dokümantasyonla ilgili ve sadece bunun için hizmet etselerdi (herhangi bir yan etki olmaksızın) onları iyi bulabilirim.

TL; DR

VOLUME'un en iyi kullanımının kullanımdan kaldırılması olduğunu düşünüyorum.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.