Jawaban @ T0xicCode benar, tetapi saya pikir saya akan memperluas detailnya karena sebenarnya saya membutuhkan waktu sekitar 20 jam untuk akhirnya mendapatkan solusi yang berfungsi.
Jika Anda ingin menjalankan Nginx dalam wadahnya sendiri dan menggunakannya sebagai reverse proxy untuk menyeimbangkan beberapa aplikasi di server yang sama, maka langkah-langkah yang perlu Anda ikuti adalah:
Tautkan Penampung Anda
Saat Anda docker run
menggunakan container, biasanya dengan memasukkan skrip shell ke User Data
, Anda dapat mendeklarasikan link ke container lain yang sedang berjalan . Ini berarti Anda perlu memulai penampung Anda secara berurutan dan hanya penampung terakhir yang dapat ditautkan ke penampung sebelumnya. Seperti:
#!/bin/bash
sudo docker run -p 3000:3000 --name API mydockerhub/api
sudo docker run -p 3001:3001 --link API:API --name App mydockerhub/app
sudo docker run -p 80:80 -p 443:443 --link API:API --link App:App --name Nginx mydockerhub/nginx
Jadi dalam contoh ini, API
penampung tidak ditautkan ke yang lain, tetapi
App
penampung ditautkan ke API
dan Nginx
ditautkan ke API
dan App
.
Hasilnya adalah perubahan pada env
vars dan /etc/hosts
file yang berada di dalam container API
dan App
. Hasilnya terlihat seperti ini:
/ etc / hosts
Menjalankan cat /etc/hosts
dalam Nginx
wadah Anda akan menghasilkan yang berikut:
172.17.0.5 0fd9a40ab5ec
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.3 App
172.17.0.2 API
ENV Vars
Menjalankan env
dalam Nginx
wadah Anda akan menghasilkan yang berikut:
API_PORT=tcp://172.17.0.2:3000
API_PORT_3000_TCP_PROTO=tcp
API_PORT_3000_TCP_PORT=3000
API_PORT_3000_TCP_ADDR=172.17.0.2
APP_PORT=tcp://172.17.0.3:3001
APP_PORT_3001_TCP_PROTO=tcp
APP_PORT_3001_TCP_PORT=3001
APP_PORT_3001_TCP_ADDR=172.17.0.3
Saya telah memotong banyak vars yang sebenarnya, tetapi di atas adalah nilai kunci yang Anda perlukan untuk membuat proxy lalu lintas ke penampung Anda.
Untuk mendapatkan shell untuk menjalankan perintah di atas dalam container yang sedang berjalan, gunakan yang berikut ini:
sudo docker exec -i -t Nginx bash
Anda dapat melihat bahwa Anda sekarang memiliki /etc/hosts
entri file dan env
vars yang berisi alamat IP lokal untuk salah satu wadah yang ditautkan. Sejauh yang saya tahu, ini semua yang terjadi ketika Anda menjalankan container dengan opsi tautan yang dinyatakan. Namun sekarang Anda dapat menggunakan informasi ini untuk mengonfigurasi nginx
dalam Nginx
penampung Anda .
Konfigurasi Nginx
Di sinilah menjadi sedikit rumit, dan ada beberapa opsi. Anda dapat memilih untuk mengkonfigurasi situs Anda agar mengarah ke entri dalam /etc/hosts
file yang docker
dibuat, atau Anda dapat menggunakan ENV
vars dan menjalankan penggantian string (saya gunakan sed
) pada nginx.conf
file conf Anda dan file conf lainnya yang mungkin ada di /etc/nginx/sites-enabled
folder Anda untuk memasukkan IP nilai-nilai.
OPSI A: Konfigurasi Nginx Menggunakan ENV Vars
Ini adalah opsi yang saya gunakan karena saya tidak bisa mendapatkan
/etc/hosts
opsi file untuk berfungsi. Saya akan mencoba Opsi B segera dan memperbarui posting ini dengan temuan apa pun.
Perbedaan utama antara opsi ini dan menggunakan /etc/hosts
opsi file adalah bagaimana Anda menulis Dockerfile
untuk menggunakan skrip shell sebagai CMD
argumen, yang pada gilirannya menangani penggantian string untuk menyalin nilai IP dari ENV
ke file conf Anda.
Berikut kumpulan file konfigurasi yang saya dapatkan:
Dockerfile
FROM ubuntu:14.04
MAINTAINER Your Name <you@myapp.com>
RUN apt-get update && apt-get install -y nano htop git nginx
ADD nginx.conf /etc/nginx/nginx.conf
ADD api.myapp.conf /etc/nginx/sites-enabled/api.myapp.conf
ADD app.myapp.conf /etc/nginx/sites-enabled/app.myapp.conf
ADD Nginx-Startup.sh /etc/nginx/Nginx-Startup.sh
EXPOSE 80 443
CMD ["/bin/bash","/etc/nginx/Nginx-Startup.sh"]
nginx.conf
daemon off;
user www-data;
pid /var/run/nginx.pid;
worker_processes 1;
events {
worker_connections 1024;
}
http {
# Basic Settings
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 33;
types_hash_max_size 2048;
server_tokens off;
server_names_hash_bucket_size 64;
include /etc/nginx/mime.types;
default_type application/octet-stream;
# Logging Settings
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
# Gzip Settings
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 3;
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_types text/plain text/xml text/css application/x-javascript application/json;
gzip_disable "MSIE [1-6]\.(?!.*SV1)";
# Virtual Host Configs
include /etc/nginx/sites-enabled/*;
# Error Page Config
#error_page 403 404 500 502 /srv/Splash;
}
CATATAN: Penting untuk disertakan daemon off;
dalam nginx.conf
file Anda untuk memastikan bahwa penampung Anda tidak segera keluar setelah peluncuran.
api.myapp.conf
upstream api_upstream{
server APP_IP:3000;
}
server {
listen 80;
server_name api.myapp.com;
return 301 https://api.myapp.com/$request_uri;
}
server {
listen 443;
server_name api.myapp.com;
location / {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_cache_bypass $http_upgrade;
proxy_pass http://api_upstream;
}
}
Nginx-Startup.sh
#!/bin/bash
sed -i 's/APP_IP/'"$API_PORT_3000_TCP_ADDR"'/g' /etc/nginx/sites-enabled/api.myapp.com
sed -i 's/APP_IP/'"$APP_PORT_3001_TCP_ADDR"'/g' /etc/nginx/sites-enabled/app.myapp.com
service nginx start
Saya akan menyerahkan kepada Anda untuk mengerjakan pekerjaan rumah Anda tentang sebagian besar konten nginx.conf
dan api.myapp.conf
.
Keajaiban terjadi di Nginx-Startup.sh
tempat kami menggunakan sed
untuk melakukan penggantian string pada APP_IP
placeholder yang telah kami tulis ke dalam upstream
blok api.myapp.conf
dan app.myapp.conf
file kami.
Pertanyaan ask.ubuntu.com ini menjelaskannya dengan sangat baik:
Temukan dan ganti teks di dalam file menggunakan perintah
GOTCHA
Di OSX, sed
menangani opsi secara berbeda, -i
khususnya bendera. Di Ubuntu, -i
bendera akan menangani penggantian 'di tempat'; itu akan membuka file, mengubah teks, dan kemudian 'menyimpan' file yang sama. Di OSX, -i
bendera memerlukan ekstensi file yang Anda inginkan dari file yang dihasilkan. Jika Anda bekerja dengan file yang tidak memiliki ekstensi, Anda harus memasukkan '' sebagai nilai untuk -i
bendera.
GOTCHA
Untuk menggunakan ENV vars dalam regex yang sed
digunakan untuk menemukan string yang ingin Anda ganti, Anda perlu membungkus var dalam tanda kutip ganda. Jadi sintaks yang benar, meskipun tampak miring, seperti di atas.
Jadi buruh pelabuhan telah meluncurkan penampung kami dan memicu Nginx-Startup.sh
skrip untuk dijalankan, yang telah digunakan sed
untuk mengubah nilai APP_IP
ke ENV
variabel terkait yang kami berikan di sed
perintah. Kami sekarang memiliki file conf dalam /etc/nginx/sites-enabled
direktori kami yang memiliki alamat IP dari ENV
vars yang ditetapkan oleh pekerja galangan saat memulai penampung. Di dalam api.myapp.conf
file Anda, Anda akan melihat upstream
blok telah berubah menjadi ini:
upstream api_upstream{
server 172.0.0.2:3000;
}
Alamat IP yang Anda lihat mungkin berbeda, tetapi saya memerhatikan biasanya 172.0.0.x
.
Anda sekarang harus memiliki semua perutean dengan benar.
GOTCHA
Anda tidak dapat memulai ulang / menjalankan kembali kontainer apa pun setelah Anda menjalankan peluncuran instans awal. Docker menyediakan setiap container dengan IP baru pada saat peluncuran dan sepertinya tidak menggunakan kembali IP yang digunakan sebelumnya. Jadi api.myapp.com
akan mendapatkan 172.0.0.2 pertama kali, tetapi kemudian mendapatkan 172.0.0.4 di waktu berikutnya. Tetapi Nginx
akan telah mengatur IP pertama ke dalam file conf-nya, atau dalam /etc/hosts
file -nya , sehingga tidak dapat menentukan IP baru untuk api.myapp.com
. Solusi untuk ini kemungkinan menggunakan CoreOS
dan etcd
layanannya yang, dalam pemahaman saya yang terbatas, bertindak seperti yang dibagikan ENV
untuk semua mesin yang terdaftar ke dalam CoreOS
cluster yang sama . Ini mainan berikutnya yang akan saya mainkan dengan penyiapan.
OPSI B: Gunakan /etc/hosts
Entri File
Ini seharusnya menjadi cara yang lebih cepat dan mudah untuk melakukan ini, tetapi saya tidak bisa membuatnya bekerja. Seolah-olah Anda hanya memasukkan nilai /etc/hosts
entri ke dalam file api.myapp.conf
dan Anda app.myapp.conf
, tetapi saya tidak dapat membuat metode ini berfungsi.
PEMBARUAN:
Lihat jawaban @Wes Tod untuk instruksi tentang cara membuat metode ini berfungsi.
Inilah upaya yang saya lakukan api.myapp.conf
:
upstream api_upstream{
server API:3000;
}
Menimbang bahwa ada entri di /etc/hosts
file saya seperti ini: 172.0.0.2 API
Saya pikir itu hanya akan menarik nilainya, tetapi sepertinya tidak.
Saya juga memiliki beberapa masalah tambahan dengan Elastic Load Balancer
sumber saya dari semua AZ sehingga mungkin menjadi masalah ketika saya mencoba rute ini. Sebaliknya saya harus belajar bagaimana menangani penggantian string di Linux, jadi itu menyenangkan. Saya akan mencobanya sebentar dan melihat bagaimana kelanjutannya.