容器基础(七): 使用docker compose部署程序

时间:2024-11-14 08:36:44

配置

上一节的基础上,  增加如下的docker-compose.yml文件, 然后用docker-compose up命令启动容器进行部署:

 version: ""
services:
server:
image: update/server:v0.
labels:
description: "tcp server test script"
restart: always
command: -p worker:
image: update/worker:v0.
labels:
description: "tcp client test script"
restart: always
links:
- server:server
command: -d server -p

启动信息:

 linux:/app # docker-compose  up
Creating network "app_default" with the default driver
Creating app_server_1_17e8cbeb1e01 ... done
Creating app_worker_1_bd97b9199c60 ... done
Attaching to app_server_1_74e7ece79785, app_worker_1_bb9dcc04daf9 linux:/app/original/server # docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
81211aa6383c update/worker:v0. "python worker.py ..." About a minute ago Up About a minute app_worker_1_bb9dcc04daf9
76c322567db7 update/server:v0. "python server.py ..." About a minute ago Up About a minute app_server_1_74e7ece79785
linux:/app/original/server # docker exec ^C
linux:/app/original/server # docker exec 81211aa6383c ss -a | grep
tcp ESTAB 172.18.0.3: 172.18.0.2:
linux:/app/original/server # docker exec 76c322567db7 ss -a | grep
tcp LISTEN *: *:*
tcp ESTAB 172.18.0.2: 172.18.0.3:
linux:/app/original/server # docker exec 76c322567db7 tail -f /update/server/log/server.log
-- :: [INFO] Waiting for connection...
-- :: [INFO] ('172.18.0.3', ) connected
tail: unrecognized file system type 0x794c7630 for '/update/server/log/server.log'. please report this to bug-coreutils@gnu.org. reverting to polling
^C
linux:/app/original/server # docker exec 81211aa6383c tail -f /update/worker/log/worker.log
tail: unrecognized file system type 0x794c7630 for '/update/worker/log/worker.log'. please report this to bug-coreutils@gnu.org. reverting to polling
-- :: [INFO] [recv] hello, docker!
-- :: [INFO] [recv] hello, docker!
-- :: [INFO] [recv] hello, docker!
^C
linux:/app/original/server #
linux:/app # docker-compose -f docker-compose.yml down
Stopping app_worker_1_bd97b9199c60 ... done
Stopping app_server_1_17e8cbeb1e01 ... done
Removing app_worker_1_bd97b9199c60 ... done
Removing app_server_1_17e8cbeb1e01 ... done
Removing network app_default
linux:/app #

支持环境变量传参

在上面的基础上,把命令行传参的方式改为通过环境变量传参:

 FROM jason/debian-python27:v1.

 MAINTAINER jason<djsxut@.com>

 RUN mkdir -p /env/server

 COPY . /env/server

 WORKDIR /env/server

 ENV PATH $PATH:/env/server

 ENTRYPOINT ["python", "server.py"]

/app/env/server/Dockerfile

 #!/usr/bin/python
# -*- coding: utf- -*- import os
import sys
import time
import socket
import select
import signal
import threading log_file = "log/server.log" def log(msg):
if not os.path.exists("log"):
os.mkdir("log")
with open(log_file, "a") as wf:
wf.writelines(
time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time())) +
" [INFO] " + msg + "\n") def do_listen(port):
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(('', port))
server_socket.listen()
print 'Waiting for connection...'
log('Waiting for connection...')
server_socket.setblocking() rfd = [server_socket, ] while True:
rlist, wlist, xlist = select.select(rfd, [], [])
for sock in rlist:
if sock == server_socket:
newsock, addr = server_socket.accept()
print '[+] %s connected' % str(addr)
log('%s connected' % str(addr))
rfd.append(newsock)
else:
data = sock.recv()
if data:
sock.send(data)
else:
print '[-] %s closed' % str(sock.getpeername())
log('%s closed' % str(sock.getpeername()))
rfd.remove(sock)
sock.close() def signal_handler(signum, frame):
print '\n[-] signal(%d) received, exit!' % signum
log('signal(%d) received, exit!' % signum)
sys.exit(-) if __name__ == '__main__':
try:
port = int(os.environ['APP_PORT'])
except:
print '[-] environment APP_PORT should be set'
log('environment APP_PORT should be set')
sys.exit(-) signal.signal(signal.SIGINT, signal_handler) try:
do_listen(port)
except Exception, e:
print e
print '\nExit'

/app/env/server/server.py

 FROM jason/debian-python27:v1.

 MAINTAINER jason<djsxut@.com>

 RUN mkdir -p /env/worker

 COPY . /env/worker

 WORKDIR /env/worker

 ENV PATH $PATH:/env/worker

 ENTRYPOINT ["python", "worker.py"]

/app/env/worker/Dockerfile

 #!/usr/bin/python
# -*- coding: utf- -*- import os
import sys
import time
import socket
import signal
import getopt
import threading log_file = "log/worker.log" def log(msg):
if not os.path.exists("log"):
os.mkdir("log")
with open(log_file, "a") as wf:
wf.writelines(
time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time())) +
" [INFO] " + msg + "\n") class Handler:
def __init__(self, domain, port):
self.domain = domain
self.port = port
self.sock = None def get_socket(self):
for res in socket.getaddrinfo(self.domain, self.port,
socket.AF_INET, socket.SOCK_STREAM):
family, socktype, proto, canonname, sa = res
try:
self.sock = socket.socket(family, socktype, proto)
#self.sock.setblocking()
#sock.settimeout(0.5)
self.sock.connect(sa)
except socket.error, msg:
if self.sock != None:
self.sock.close()
self.sock = None
else:
return True return False def do_handler(self):
while self.sock == None and self.get_socket() == False:
print '[-] connect failed...'
log('connect failed...')
time.sleep() print '[+] %s connected' % str(self.sock.getpeername())
log('[+] %s connected' % str(self.sock.getpeername()))
while True:
# do something
self.sock.send('hello, docker!')
data = self.sock.recv()
if data:
print '[+][recv] %s' % data
log('[recv] %s' % data)
time.sleep()
else:
print '[-] server closed, exit'
log('server closed, exit')
self.sock.close()
self.sock = None
break def signal_handler(signum, frame):
print '\n[-] signal(%d) received, exit!' % signum
log('signal(%d) received, exit!' % signum)
sys.exit(-) if __name__ == '__main__':
signal.signal(signal.SIGINT, signal_handler) try:
domain = os.environ['APP_DOMAIN']
port = int(os.environ['APP_PORT'])
except:
print '[-] environment APP_PORT/APP_DOMAIN should be set'
log('environment APP_PORT/APP_DOMAIN should be set')
sys.exit(-) try:
handler = Handler(domain, port)
handler.do_handler()
except Exception, e:
print e
print '\nExit'

/app/env/worker/worker.py

简单修改下docker-compose.yml文件:

 version: ""
services:
server:
image: env/server:v0.
build:
context: /app/env/server
dockerfile: Dockerfile
labels:
description: "tcp server test script"
restart: always
environment:
- APP_PORT=${APP_PORT-}
volumes:
- /app/env/server/log:/env/server/log worker:
image: env/worker:v0.
build: /app/env/worker
labels:
description: "tcp client test script"
restart: always
links:
- server
environment:
- APP_PORT=${APP_PORT-}
- APP_DOMAIN=server
volumes:
- /app/env/worker/log:/env/worker/log
deploy:
replicas:

执行结果如下所示:

 linux:/app/env/server # APP_PORT= docker-compose up -d
WARNING: Some services (worker) use the 'deploy' key, which will be ignored. Compose does not support 'deploy' configuration - use `docker stack deploy` to deploy to a swarm.
Creating network "env_default" with the default driver
Building server
Step / : FROM jason/debian-python27:v1.
---> cd0b2f7d8d04
Step / : MAINTAINER jason<djsxut@.com>
---> Using cache
---> d239a9d50575
Step / : RUN mkdir -p /env/server
---> Running in f1802bbbf5f8
---> b196dec5ece6
Removing intermediate container f1802bbbf5f8
Step / : COPY . /env/server
---> 789a69dde7bc
Removing intermediate container 53d720f6e28d
Step / : WORKDIR /env/server
---> 8bc3b957a769
Removing intermediate container dfd8c4cecd45
Step / : ENV PATH $PATH:/env/server
---> Running in 0935ca701a19
---> d6fdd5814444
Removing intermediate container 0935ca701a19
Step / : ENTRYPOINT python server.py
---> Running in 9209e05da1a9
---> c34b7a72cb0b
Removing intermediate container 9209e05da1a9
Successfully built c34b7a72cb0b
WARNING: Image for service server was built because it did not already exist. To rebuild this image you must use `docker-compose build` or `docker-compose up --build`.
Building worker
Step / : FROM jason/debian-python27:v1.
---> cd0b2f7d8d04
Step / : MAINTAINER jason<djsxut@.com>
---> Using cache
---> d239a9d50575
Step / : RUN mkdir -p /env/worker
---> Running in de82f380b738
---> 480f67b5dc6a
Removing intermediate container de82f380b738
Step / : COPY . /env/worker
---> c7b98717c8c8
Removing intermediate container 1d0857c192e6
Step / : WORKDIR /env/worker
---> a6cedc9734a0
Removing intermediate container cd648d954ada
Step / : ENV PATH $PATH:/env/worker
---> Running in 977e0045899e
---> 5d20c078708d
Removing intermediate container 977e0045899e
Step / : ENTRYPOINT python worker.py
---> Running in 3f92d15c16f0
---> bd3579c73bd3
Removing intermediate container 3f92d15c16f0
Successfully built bd3579c73bd3
WARNING: Image for service worker was built because it did not already exist. To rebuild this image you must use `docker-compose build` or `docker-compose up --build`.
Creating env_server_1_be9373e6fe83 ... done
Creating env_worker_1_e4e9c2ece128 ... done
linux:/app/env/server #
linux:/app/env/server #
linux:/app/env/server # docker images | grep env
env/worker v0. bd3579c73bd3 seconds ago 207MB
env/server v0. c34b7a72cb0b seconds ago 207MB
linux:/app/env/server # docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
93c7d5f760e8 env/worker:v0. "python worker.py" seconds ago Up seconds env_worker_1_57f3186eefba
0712a2615e12 env/server:v0. "python server.py" seconds ago Up seconds env_server_1_1615d4c9ff54
linux:/app/env/server # cat log/server.log
-- :: [INFO] Waiting for connection...
-- :: [INFO] ('172.18.0.3', ) connected
linux:/app/env/server # cat ../worker/log/worker.log
-- :: [INFO] [+] ('172.18.0.2', ) connected
-- :: [INFO] [recv] hello, docker!
linux:/app/env/server # docker-compose down
WARNING: Some services (worker) use the 'deploy' key, which will be ignored. Compose does not support 'deploy' configuration - use `docker stack deploy` to deploy to a swarm.
Stopping env_worker_1_57f3186eefba ... done
Stopping env_server_1_1615d4c9ff54 ... done
Removing env_worker_1_57f3186eefba ... done
Removing env_server_1_1615d4c9ff54 ... done
Removing network env_default
linux:/app/env/server #

result