Docker Compose
介紹
是用於定義和運行多容器 Docker 應用程序的工具。通過 Compose,您可以使用 YML 文件來配置應用程序需要的所有服務。然后,使用一個命令,就可以從 YML 文件配置中創建並啟動所有服務。
DockerFile讓程序在任何地方運行。web服務、redis、mysql、nginx.....多個容器。run
docker-compose.yml
version: "3.8"
services:
web:
build: .
ports:
- "5000:5000"
volumes:
- .:/code
- logvolume01:/var/log
links:
- redis
redis:
image: redis
volumes:
logvolume01: {}
安裝
方式一
1、下載
# 這個下載很慢 我們使用下面的
sudo curl -L "https://github.com/docker/compose/releases/download/1.27.4/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudu curl -L https://get.daocloud.io/docker/compose/releases/download/1.25.5/docker-compose-`uname -S`-`uname -m` > /usr/local/bin/docker-compose
2、給文件授權
sudo chmod +x docker-compose
3、查看版本
docker-compose version
方式二
1、安裝python-pip
yum -y install epel-release
yum -y install python-pip
2、安裝docker-compose
pip install docker-compose
3、查看版本
docker-compose version
Compose 初體驗
我們按照官方給的案例來體驗一下。
我們先來看一下docker中的狀態
接下來我們就來完成官網上的案例
1、創建composetest文件夾
2、編寫一個app.py文件,這個是一個Python web應用
import time
import redis
from flask import Flask
app = Flask(__name__)
cache = redis.Redis(host='redis', port=6379)
def get_hit_count():
retries = 5
while True:
try:
return cache.incr('hits')
except redis.exceptions.ConnectionError as exc:
if retries == 0:
raise exc
retries -= 1
time.sleep(0.5)
@app.route('/')
def hello():
count = get_hit_count()
return 'Hello World! I have been seen {} times.\n'.format(count)
這就是一個利用redis來完成統計訪問次數功能的web應用。
3、創建一個requirements.txt文件
flask
redis
4、創建一個dockerfile文件
FROM python:3.7-alpine
WORKDIR /code
ENV FLASK_APP=app.py
ENV FLASK_RUN_HOST=0.0.0.0
RUN apk add --no-cache gcc musl-dev linux-headers
COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt
EXPOSE 5000
COPY . .
CMD ["flask", "run"]
5、創建docker-compose.yml文件
version: "3.8"
services:
web:
build: .
ports:
- "5000:5000"
redis:
image: "redis:alpine"
6、運行 (docker-compose.yml一定要存在)
docker-compose build
docker-compose up
先查看docker 中正在運行的容器,可以看出,多了兩個redis:alpine、composetest_web
訪問:http://192.168.31.131:5000/
部署成功!!!
部署完成了,我們先來看看他有那些默認規則。
1、docker-compose.yml配置的依賴自動給我們下載下來了
2、
[root@aubin composetest]# docker service ls
Error response from daemon: This node is not a swarm manager. Use "docker swarm init" or "docker swarm join" to connect this node to swarm and try again.
默認的服務名: 文件名_服務名_num
未來有多個服務器。集群 _num 表示副本數量
3、網絡規則
比如說我們有10個服務,項目上線后對內網絡規則很復雜,不好配置。docker-compose自動為我們維護了一個網絡,也就是項目中的內容都在同一個網絡下面。
7、停止docker-compose
docker-compose stop ctrl+c
docker-compose down
總結:以前都是單個docker run啟動容器,現在使用docker-compose,通過編寫的yaml配置文件,可以通過compose一鍵啟動
Docker-compose的yaml配置規則
https://docs.docker.com/compose/compose-file/#compose-file-structure-and-examples
我們先來看看官方示例:
version: "3.8"
services:
redis:
image: redis:alpine
ports:
- "6379"
networks:
- frontend
deploy:
replicas: 2
update_config:
parallelism: 2
delay: 10s
restart_policy:
condition: on-failure
db:
image: postgres:9.4
volumes:
- db-data:/var/lib/postgresql/data
networks:
- backend
deploy:
placement:
max_replicas_per_node: 1
constraints:
- "node.role==manager"
vote:
image: dockersamples/examplevotingapp_vote:before
ports:
- "5000:80"
networks:
- frontend
depends_on:
- redis
deploy:
replicas: 2
update_config:
parallelism: 2
restart_policy:
condition: on-failure
result:
image: dockersamples/examplevotingapp_result:before
ports:
- "5001:80"
networks:
- backend
depends_on:
- db
deploy:
replicas: 1
update_config:
parallelism: 2
delay: 10s
restart_policy:
condition: on-failure
worker:
image: dockersamples/examplevotingapp_worker
networks:
- frontend
- backend
deploy:
mode: replicated
replicas: 1
labels: [APP=VOTING]
restart_policy:
condition: on-failure
delay: 10s
max_attempts: 3
window: 120s
placement:
constraints:
- "node.role==manager"
visualizer:
image: dockersamples/visualizer:stable
ports:
- "8080:8080"
stop_grace_period: 1m30s
volumes:
- "/var/run/docker.sock:/var/run/docker.sock"
deploy:
placement:
constraints:
- "node.role==manager"
networks:
frontend:
backend:
volumes:
db-data:
compose只有三層
#
version:'' #版本
services: #代表我們的服務
服務1:web
#服務配置
images:
build:
port:
network:
...
服務2:redis
# 其他配置 網絡、卷掛載、全局規則
volumes:
network:
configs:
我們來看一下具體怎么寫的
service下:
#depends_on:表示如果該服務依賴於那個項目的話,這里來指定啟動順序
比如:
services:
web:
depends_on:
-db
-redis
# 這里依賴了db和redis,啟動順序就是db、redis、web
--------------------------------------------------------------------
#deploy 用於部署的,都是集群相關的一些東西
deploy:
replicas:6
#表示有6個副本
yaml中的services下的所有命令,在dockerfile中都有,也可以查看官網上的
https://docs.docker.com/compose/compose-file/#compose-file-structure-and-examples
利用compose搭建博客
https://docs.docker.com/compose/wordpress/
新建一個文件夾
編寫docker-compose.yml。
version: '3.3'
services:
db:
image: mysql:5.7
volumes:
- db_data:/var/lib/mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: somewordpress
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress
wordpress:
depends_on:
- db
image: wordpress:latest
ports:
- "8000:80"
restart: always
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress
WORDPRESS_DB_NAME: wordpress
volumes:
db_data: {}
執行docker-compose up
命令
訪問http://192.168.31.131:8000/
實戰-計數器
編寫自己的微服務
1、編寫項目微服務
@RestController
public class HelloController {
@Autowired
private StringRedisTemplate redisTemplate;
@GetMapping("/hello")
public String hello(){
Long views = redisTemplate.opsForValue().increment( "views" );
return "hello,baoge。views:"+views;
}
}
2、dockerfile構建:
FROM java:8
COPY *.jar /app.jar
CMD ["--server.port=80"]
EXPOSE 80
ENTRYPOINT ["java","-jar","app.jar"]
3、docker-compose.yml編排項目
version: '3.8'
services:
linapp:
build: .
image: linapp
depends_on:
- redis
ports:
- "80:80"
redis:
image: "library/redis:alpine"
4、放到服務器,docker-compose up
4.1、上傳文件到服務器
4.2、執行docker-compose up
命令
5、訪問項目
Docker swarm
創建4台虛擬機
安裝Docker
# 安裝docker
yum -y install gcc
yum install -y gcc-c++
yum remove docker \
docker-client\
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
# 安裝所需要的軟件包
yum install -y yum-utils
# 設置鏡像倉庫
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# 更新yum軟件包索引
yum makecache fast
#安裝Docker CE
yum install docker-ce docker-ce-cli containerd.io
# 啟動Docker
systemctl start docker
# 開機啟動Docker
systemctl enable docker
測試:
# 配置aliyun鏡像
[root@aubin ~]# cat /etc/docker/daemon.json
{
"registry-mirrors": ["https://vgiqiiwr.mirror.aliyuncs.com"]
}
[root@aubin ~]# systemctl daemon-reload
[root@aubin ~]# systemctl restart docker
swarm相關配置https://docs.docker.com/engine/swarm/
他是如何工作的?
這里有幾個工作節點和管理節點。
1、管理節點和管理節點之間是可以通信的,管理節點可以管理工作節點。
2、操作都是在Manager
中進行的,worker節點是不能操作的。
3、這里還有個Raft
一致性算法,這個算法是來保證絕大多數服務可用。
管理節點至少有三個。
搭建集群
1、查看網絡
docker network ls
這時剛初始化,只有三個網絡。
查看swarm有哪些命令
[root@aubin ~]# docker swarm --help
Usage: docker swarm COMMAND
Manage Swarm
Commands:
ca Display and rotate the root CA
init # 初始化一個集群
join # 加入一個集群
join-token # 加入一個token
leave # 移除集群
unlock # 解鎖集群
unlock-key Manage the unlock key
update # 更新集群
2、初始化集群
查看初始化命令
[root@aubin ~]# docker swarm init --help
Usage: docker swarm init [OPTIONS]
Initialize a swarm
Options:
--advertise-addr string Advertised address (format: <ip|interface>[:port]) # 廣播地址
--autolock Enable manager autolocking (requiring an unlock key to start a stopped manager)
--availability string Availability of the node ("active"|"pause"|"drain") (default "active")
--cert-expiry duration Validity period for node certificates (ns|us|ms|s|m|h) (default 2160h0m0s)
--data-path-addr string Address or interface to use for data path traffic (format: <ip|interface>)
--data-path-port uint32 Port number to use for data path traffic (1024 - 49151). If no value is set or is set to 0, the default port (4789) is used.
--default-addr-pool ipNetSlice default address pool in CIDR format (default [])
--default-addr-pool-mask-length uint32 default address pool subnet mask length (default 24)
--dispatcher-heartbeat duration Dispatcher heartbeat period (ns|us|ms|s|m|h) (default 5s)
--external-ca external-ca Specifications of one or more certificate signing endpoints
--force-new-cluster Force create a new cluster from current state
--listen-addr node-addr Listen address (format: <ip|interface>[:port]) (default 0.0.0.0:2377)
--max-snapshots uint Number of additional Raft snapshots to retain
--snapshot-interval uint Number of log entries between Raft snapshots (default 10000)
--task-history-limit int Task history retention limit (default 5)
--advertise-addr:告訴別人我的地址是在那里,地址分為公網、私網。這里我們走私網-192.168.31.131。
讓192.168.31.131這個ip下的docker成為主節點
# docker swarm init --advertise-addr ip地址
docker swarm init --advertise-addr 192.168.31.131
由信息可知,
1、當前地址已經加入到了swarm
2、使用docker swarm join --token xxx
命令讓其他節點加入到這個主節點。
3、使用docker swarm join-token manager
獲取一個管理節點的令牌
3、讓其他節點加入到主節點
# 獲取令牌
docker swarm join-token manager
docker swarm join-token worker
# 192.168.31.132加入到主節點192.168.31.131
docker swarm join --token SWMTKN-1-1c7pl7vjpijeqokx5nawfzp2txt4xrv6p5y3a3ef1axofmx7fa-1u9a47t7oxzkv9pr1uoxwfnnf 192.168.31.131:2377
在主節點中查看
我們把192.168.31.133這個ip下的docker以工作節點的方式加入到131這個ip下的管理節點
# 生成token
[root@aubin ~]# docker swarm join-token worker
To add a worker to this swarm, run the following command:
docker swarm join --token SWMTKN-1-45pjpjt5syhuz70f9vk8olhrjhckwk3f7x8sy4szhmcq8xxx6c-cgjoxznlu5s23mbtw55s84cfd 192.168.31.131:2377
# 133節點
docker swarm join --token SWMTKN-1-45pjpjt5syhuz70f9vk8olhrjhckwk3f7x8sy4szhmcq8xxx6c-cgjoxznlu5s23mbtw55s84cfd 192.168.31.131:2377
把134這個節點以管理節點的方式加入到131這個管理節點
[root@aubin ~]# docker swarm join-token manager
To add a manager to this swarm, run the following command:
docker swarm join --token SWMTKN-1-45pjpjt5syhuz70f9vk8olhrjhckwk3f7x8sy4szhmcq8xxx6c-dwrm5w7j1jldxb24a9uqd2oz1 192.168.31.131:2377
docker swarm join --token SWMTKN-1-45pjpjt5syhuz70f9vk8olhrjhckwk3f7x8sy4szhmcq8xxx6c-dwrm5w7j1jldxb24a9uqd2oz1 192.168.31.131:2377
可以看到131這個節點是Reachable(可觸達的節點),這也是一個主節點
這是一個雙主雙從的模式,這是不科學的,我們要設置為至少三個主節點。
Raft一致性協議
上面我們搭上了一個雙主雙從的集群。假設一個節點掛了,其他節點是否可用?
Raft協議:保證大多數節點存活才可以用,只要至少大於3太才行。如果是雙出雙從模式,主節點掛了,其他管理節點也會不可用。
實驗:
1、停止131的docker,然后在134上執行docker node ls
重啟131上的docker
2、移除133這個節點
[root@aubin ~]# docker swarm leave
Node left the swarm.
# 在主節點上查看狀態
docker node ls
3、生成三主
將133這個節點變為主節點
[root@aubin ~]# docker swarm join-token manager
To add a manager to this swarm, run the following command:
docker swarm join --token SWMTKN-1-45pjpjt5syhuz70f9vk8olhrjhckwk3f7x8sy4szhmcq8xxx6c-dwrm5w7j1jldxb24a9uqd2oz1 192.168.31.131:2377
[root@aubin ~]# docker swarm join --token SWMTKN-1-45pjpjt5syhuz70f9vk8olhrjhckwk3f7x8sy4szhmcq8xxx6c-dwrm5w7j1jldxb24a9uqd2oz1 192.168.31.131:2377
This node joined a swarm as a manager.
#查看docker node ls
可以看出131變為Reachable,而且前面的Down掉的節點沒有移除
3、在worker節點(132)上執行docker swarm node ls
worker就是工作的,管理節點的操作不能在worker節點上使用。
3個主節點,至少保證2太機器存活
體驗
體驗集群的彈性、擴縮容。
用docker service
命令來啟動容器
有創建服務、動態擴展服務、動態更新服務、日志...
[root@aubin ~]# docker service --help
Usage: docker service COMMAND
Manage services
Commands:
create Create a new service
inspect Display detailed information on one or more services
logs Fetch the logs of a service or task
ls List services
ps List the tasks of one or more services
rm Remove one or more services
rollback Revert changes to a service's configuration
scale Scale one or multiple replicated services
update Update a service
Run 'docker service COMMAND --help' for more information on a command.
灰度發布
[root@aubin ~]# docker service create --help
Usage: docker service create [OPTIONS] IMAGE [COMMAND] [ARG...]
Create a new service
Options:
--config config Specify configurations to expose to the service
--constraint list Placement constraints
--container-label list Container labels
--credential-spec credential-spec Credential spec for managed service account (Windows only)
-d, --detach Exit immediately instead of waiting for the service to converge
--dns list Set custom DNS servers
--dns-option list Set DNS options
--dns-search list Set custom DNS search domains
--endpoint-mode string Endpoint mode (vip or dnsrr) (default "vip")
--entrypoint command Overwrite the default ENTRYPOINT of the image
-e, --env list Set environment variables
--env-file list Read in a file of environment variables
--generic-resource list User defined resources
--group list Set one or more supplementary user groups for the container
--health-cmd string Command to run to check health
--health-interval duration Time between running the check (ms|s|m|h)
--health-retries int Consecutive failures needed to report unhealthy
--health-start-period duration Start period for the container to initialize before counting retries towards unstable (ms|s|m|h)
--health-timeout duration Maximum time to allow one check to run (ms|s|m|h)
--host list Set one or more custom host-to-IP mappings (host:ip)
--hostname string Container hostname
--init Use an init inside each service container to forward signals and reap processes
--isolation string Service container isolation mode
-l, --label list Service labels
--limit-cpu decimal Limit CPUs
--limit-memory bytes Limit Memory
--log-driver string Logging driver for service
--log-opt list Logging driver options
--mode string Service mode (replicated or global) (default "replicated")
--mount mount Attach a filesystem mount to the service
--name string Service name
--network network Network attachments
--no-healthcheck Disable any container-specified HEALTHCHECK
--no-resolve-image Do not query the registry to resolve image digest and supported platforms
--placement-pref pref Add a placement preference
-p, --publish port Publish a port as a node port
-q, --quiet Suppress progress output
--read-only Mount the container's root filesystem as read only
--replicas uint Number of tasks
--replicas-max-per-node uint Maximum number of tasks per node (default 0 = unlimited)
--reserve-cpu decimal Reserve CPUs
--reserve-memory bytes Reserve Memory
--restart-condition string Restart when condition is met ("none"|"on-failure"|"any") (default "any")
--restart-delay duration Delay between restart attempts (ns|us|ms|s|m|h) (default 5s)
--restart-max-attempts uint Maximum number of restarts before giving up
--restart-window duration Window used to evaluate the restart policy (ns|us|ms|s|m|h)
--rollback-delay duration Delay between task rollbacks (ns|us|ms|s|m|h) (default 0s)
--rollback-failure-action string Action on rollback failure ("pause"|"continue") (default "pause")
--rollback-max-failure-ratio float Failure rate to tolerate during a rollback (default 0)
--rollback-monitor duration Duration after each task rollback to monitor for failure (ns|us|ms|s|m|h) (default 5s)
--rollback-order string Rollback order ("start-first"|"stop-first") (default "stop-first")
--rollback-parallelism uint Maximum number of tasks rolled back simultaneously (0 to roll back all at once) (default 1)
--secret secret Specify secrets to expose to the service
--stop-grace-period duration Time to wait before force killing a container (ns|us|ms|s|m|h) (default 10s)
--stop-signal string Signal to stop the container
--sysctl list Sysctl options
-t, --tty Allocate a pseudo-TTY
--update-delay duration Delay between updates (ns|us|ms|s|m|h) (default 0s)
--update-failure-action string Action on update failure ("pause"|"continue"|"rollback") (default "pause")
--update-max-failure-ratio float Failure rate to tolerate during an update (default 0)
--update-monitor duration Duration after each task update to monitor for failure (ns|us|ms|s|m|h) (default 5s)
--update-order string Update order ("start-first"|"stop-first") (default "stop-first")
--update-parallelism uint Maximum number of tasks updated simultaneously (0 to update all at once) (default 1)
-u, --user string Username or UID (format: <name|uid>[:<group|gid>])
--with-registry-auth Send registry authentication details to swarm agents
-w, --workdir string Working directory inside the container
這個命令跟docker run命令一樣,可以指定端口、名字...
運行nginx
docker service create -p 8888:80 --name mynginx nginx
docker run 容器啟動,不具備擴縮容的功能
docker service 服務,具有擴縮容、滾動更新的功能
啟動容器:
docker service create -p 8888:80 --name mynginx nginx
查看服務
docker service ps mynginx
docker service ls
可以看到只有一個副本,也就是運行了一台。
如果想在多台節點上運行,我們看看如何操作
[root@aubin ~]# docker service update --help
Usage: docker service update [OPTIONS] SERVICE
Update a service
Options:
--args command Service command args
--config-add config Add or update a config file on a service
--config-rm list Remove a configuration file
--constraint-add list Add or update a placement constraint
--constraint-rm list Remove a constraint
--container-label-add list Add or update a container label
--container-label-rm list Remove a container label by its key
--credential-spec credential-spec Credential spec for managed service account (Windows only)
-d, --detach Exit immediately instead of waiting for the service to converge
--dns-add list Add or update a custom DNS server
--dns-option-add list Add or update a DNS option
--dns-option-rm list Remove a DNS option
--dns-rm list Remove a custom DNS server
--dns-search-add list Add or update a custom DNS search domain
--dns-search-rm list Remove a DNS search domain
--endpoint-mode string Endpoint mode (vip or dnsrr)
--entrypoint command Overwrite the default ENTRYPOINT of the image
--env-add list Add or update an environment variable
--env-rm list Remove an environment variable
--force Force update even if no changes require it
--generic-resource-add list Add a Generic resource
--generic-resource-rm list Remove a Generic resource
--group-add list Add an additional supplementary user group to the container
--group-rm list Remove a previously added supplementary user group from the container
--health-cmd string Command to run to check health
--health-interval duration Time between running the check (ms|s|m|h)
--health-retries int Consecutive failures needed to report unhealthy
--health-start-period duration Start period for the container to initialize before counting retries towards unstable (ms|s|m|h)
--health-timeout duration Maximum time to allow one check to run (ms|s|m|h)
--host-add list Add a custom host-to-IP mapping (host:ip)
--host-rm list Remove a custom host-to-IP mapping (host:ip)
--hostname string Container hostname
--image string Service image tag
--init Use an init inside each service container to forward signals and reap processes
--isolation string Service container isolation mode
--label-add list Add or update a service label
--label-rm list Remove a label by its key
--limit-cpu decimal Limit CPUs
--limit-memory bytes Limit Memory
--log-driver string Logging driver for service
--log-opt list Logging driver options
--mount-add mount Add or update a mount on a service
--mount-rm list Remove a mount by its target path
--network-add network Add a network
--network-rm list Remove a network
--no-healthcheck Disable any container-specified HEALTHCHECK
--no-resolve-image Do not query the registry to resolve image digest and supported platforms
--placement-pref-add pref Add a placement preference
--placement-pref-rm pref Remove a placement preference
--publish-add port Add or update a published port
--publish-rm port Remove a published port by its target port
-q, --quiet Suppress progress output
--read-only Mount the container's root filesystem as read only
--replicas uint Number of tasks
--replicas-max-per-node uint Maximum number of tasks per node (default 0 = unlimited)
--reserve-cpu decimal Reserve CPUs
--reserve-memory bytes Reserve Memory
--restart-condition string Restart when condition is met ("none"|"on-failure"|"any")
--restart-delay duration Delay between restart attempts (ns|us|ms|s|m|h)
--restart-max-attempts uint Maximum number of restarts before giving up
--restart-window duration Window used to evaluate the restart policy (ns|us|ms|s|m|h)
--rollback Rollback to previous specification
--rollback-delay duration Delay between task rollbacks (ns|us|ms|s|m|h)
--rollback-failure-action string Action on rollback failure ("pause"|"continue")
--rollback-max-failure-ratio float Failure rate to tolerate during a rollback
--rollback-monitor duration Duration after each task rollback to monitor for failure (ns|us|ms|s|m|h)
--rollback-order string Rollback order ("start-first"|"stop-first")
--rollback-parallelism uint Maximum number of tasks rolled back simultaneously (0 to roll back all at once)
--secret-add secret Add or update a secret on a service
--secret-rm list Remove a secret
--stop-grace-period duration Time to wait before force killing a container (ns|us|ms|s|m|h)
--stop-signal string Signal to stop the container
--sysctl-add list Add or update a Sysctl option
--sysctl-rm list Remove a Sysctl option
-t, --tty Allocate a pseudo-TTY
--update-delay duration Delay between updates (ns|us|ms|s|m|h)
--update-failure-action string Action on update failure ("pause"|"continue"|"rollback")
--update-max-failure-ratio float Failure rate to tolerate during an update
--update-monitor duration Duration after each task update to monitor for failure (ns|us|ms|s|m|h)
--update-order string Update order ("start-first"|"stop-first")
--update-parallelism uint Maximum number of tasks updated simultaneously (0 to update all at once)
-u, --user string Username or UID (format: <name|uid>[:<group|gid>])
--with-registry-auth Send registry authentication details to swarm agents
-w, --workdir string Working directory inside the container
# -d:后台
# -t:分配一個偽tty
# -q:限制輸出
# -u:設置用戶名
# -w:容器內的工作目錄
可以利用replicas uint命令來設置運行台數
docker service update --replicas 3 mynginx
可以看出有三台機器運行了
可以看到在131、132、133三台服務器上啟動了nginx。我們來訪問看看
可以看出131、132、133、134都能訪問,這是為啥呢?
只要在集群中,無論那台機器都能訪問nginx。服務有多個副本,可以動態擴縮容。
也可以使用scale
來進行擴縮容
docker service scale mynginx=5
刪除服務
# docker service rm 服務名
docker service rm mynginx