Skip to content

Commit 2a0bcce

Browse files
committed
feat(*): initial commit
1 parent 4569e81 commit 2a0bcce

16 files changed

+463
-2
lines changed

.editorconfig

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
root = true
2+
3+
[*]
4+
charset = utf-8
5+
indent_style = space
6+
indent_size = 2
7+
end_of_line = lf
8+
insert_final_newline = true
9+
trim_trailing_whitespace = true

.env

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#
2+
# *** Global/default environment setting ***
3+
#
4+
5+
#
6+
# Generic settings
7+
# ----------------
8+
# Work directory - it is needed in case executing user is not member of the docker group
9+
#PWD=/path/to/this/project/root
10+
11+
#
12+
# Quickstart
13+
# ----------
14+
# Node image version
15+
NODE_VERSION=13-alpine3.11
16+
17+
#
18+
# Other settings
19+
# --------------
20+
# Docker context
21+
DOCKER_CONTEXT=./docker

.gitattributes

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# source: https://help.github.com/articles/dealing-with-line-endings/
2+
3+
# Set the default behavior, in case people don't have core.autocrlf set.
4+
* text=auto

.gitignore

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
secrets/*
2+
*/secrets/*
3+
4+
data/*
5+
ssl/*
6+
7+
*.swp
8+

README.md

+69-2
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,69 @@
1-
# dcsh
2-
Unified 'docker-compose' and 'docker stack' command builder
1+
# dc.sh
2+
Unified 'docker-compose' and 'docker stack' commands.
3+
4+
Thanks to Docker's team, we can use the same yml files in 'docker-compose' and in 'docker stack', but unfortunately, the commands are slightly different. This project has been born from the frustration of the confusing the commands and their order.
5+
6+
With dc.sh, `./dc.sh service-name up` means executing:
7+
- 'docker-compose -f docker-compose.yml -p service-name up' in development environment,
8+
- 'docker-compose -f docker-compose.yml -p service-name config | docker stack deploy -compose-file - service-name' in production. (Or with `./dc.sh -F service-name up` executing 'docker stack deploy -c docker-compose.yml service-name')
9+
10+
## Get started
11+
Development environment:
12+
1. Download and extract the project.
13+
2. cd into project's main folder: `cd dcsh`
14+
3. Execute: `./dc.sh hello-world up`
15+
16+
Production environment:
17+
1. Initiate Docker Swarm mode (if it hasn't been done already): `docker swarm init`
18+
2. Set the DC_ENV environment variable to 'prod': `export DC_ENV=prod`
19+
3. Follow the instruction described above in the "Development environment". The dc.sh script will translate the 'docker-compose up' command to 'docker stack deploy' command.
20+
21+
For more complex/interesting examples, try out `./dc.sh quickstart up -d` instead of 'hello-world', and hit http://localhost:8080 in the browser.
22+
23+
24+
## Examples
25+
There are two examples:
26+
- hello-world: executes the simple hello-world image that comes with Docker installation in the verification step;
27+
- quickstart: the Docker's [Quickstart Guide](https://docs.docker.com/get-started/) implementation.
28+
29+
30+
## Supported commands
31+
Currently supported command "translations":
32+
33+
dc.sh | docker-compose | docker stack
34+
--- | --- | ---
35+
up | up | deploy
36+
start | start | deploy
37+
config | config | NONE: fall back to docker-compose
38+
build | build | NONE: fall back to docker-compose
39+
< command > | < command > | < command >
40+
41+
42+
## Environment variables
43+
Only the DC_ENV is important to set in the production, others are for more granular control.
44+
* DC_ENV Enviroment [ dev | prod ]; default: dev
45+
* DC_MODE Used docker command [ compose | stack ]; default: if DC_ENV==prod then 'stack' else 'compose'
46+
* DC_FS Way to pass yml file to 'docker stack deploy' [ conf | file ]; default: conf
47+
48+
49+
## dc.sh flags
50+
- E Only show (echo) the command without executing it
51+
- [D|P] Override DC_ENV: D = dev; P = prod
52+
- [C|S] Override DC_MODE: C = docker-compose; S = docker stack
53+
- F Pass yml files directly to 'docker stack deploy' instead of using docker-compose config. Same as DC_FS
54+
55+
56+
## Project structure
57+
The dc.sh script uses the services defined in the services/ folder and the custom docker images defined in the docker/ folder.
58+
59+
* .env: the global/default environment settings
60+
* dc.sh: unified script for running a service in dev/prod environment. See the help (`./dc.sh`) for more info.
61+
* docker-compose.yml: the global yml file. This file contains the settings that all services needs. (e.g.: set network)
62+
* docker: custom docker images per folders
63+
* service: each sub-folder is a service
64+
- docker-compose.base.yml: the base composes setting. The dc.sh combines it with 'dev' or 'prod' adjustments, depending of DC_ENV setting.
65+
- docker-compose.dev.yml: development adjustment. Set here your specific environment. (e.g.: set more detailed log level, etc.)
66+
- docker-compose.prod.yml: the same as the 'dev' above for production. (e.g.: do not expose the unnecessary ports, uses external secrets, set healthcheck, etc.)
67+
68+
69+
Thanks to [Clientele Zone](https://clientelezone.com) for sponsoring this project.

dc.sh

+245
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,245 @@
1+
#!/bin/bash
2+
3+
set -o errexit
4+
5+
# *** GLOBAL VARIABLES ***
6+
# environment: dev/prod (default: dev)
7+
dc_env="${DC_ENV:-dev}"
8+
# mode: compose/stack (default: if dc_env==prod then stack else compose)
9+
dc_mode=$DC_MODE
10+
if [ -z $dc_mode ]; then
11+
dc_mode="compose" # running mode
12+
if [ "$dc_env" == "prod" ]; then
13+
dc_mode="stack"
14+
fi
15+
fi
16+
# fs: ways to pass yml files to 'docker stack deploy'
17+
dc_fs=$DC_FS
18+
if [ -z $dc_fs ]; then
19+
dc_fs="conf"
20+
fi
21+
22+
# cmd="docker-compose" # command
23+
# if [ "$dc_mode" == "stack" ]; then
24+
# cmd="docker stack"
25+
# fi
26+
27+
# service definition yml files
28+
srvs="<file_opt> docker-compose.yml \\"
29+
30+
31+
# *** MAIN ***
32+
main() {
33+
# compose service
34+
srvs_files $svc 'base'
35+
srvs_files $svc $dc_env
36+
37+
# build the command (cmd)
38+
# docker stack
39+
if [ "$dc_mode" == "stack" ]; then
40+
# config -> use docker-compose
41+
if [ "$1" == "config" -o "$1" == "build" ]; then
42+
cmd="$(cmd_compose $@)"
43+
else
44+
cmd="$(cmd_stack $@)"
45+
fi
46+
# up/deploy/start -> deploy
47+
if [ "$1" == "up" -o "$1" == "deploy" -o "$1" == "start" ]; then
48+
#cmd="$cmd deploy \\"$'\n'" $srvs"
49+
shift 1
50+
cmd="$(cmd_stack $(echo deploy $@))"
51+
fi
52+
fi
53+
# docker-compose
54+
if [ "$dc_mode" == "compose" ]; then
55+
cmd="$(cmd_compose $@)"
56+
fi
57+
58+
# display/run the cmd
59+
echo "$cmd"
60+
if [ $cmd_echo == 0 ]; then
61+
echo "----------------------------------------------------"
62+
bash -c "$cmd"
63+
fi
64+
}
65+
66+
# *** HELPERS ***
67+
68+
# -------------------------------------
69+
# Composes the docker-compose command
70+
#
71+
# Globals:
72+
# srvs - service files variable
73+
# Arguments:
74+
# cmd - docker-compose command
75+
# Returns:
76+
# None
77+
cmd_compose() {
78+
local cmdCompose="docker-compose"
79+
80+
# add the name
81+
srvs="${srvs}"$'\n'" -p $svc \\"
82+
cmdCompose="docker-compose \\"$'\n'" $srvs"$'\n'" $@"
83+
84+
# set file option
85+
cmdCompose=$(echo "$cmdCompose" | sed "s/<file_opt>/-f/")
86+
87+
echo "$cmdCompose"
88+
}
89+
90+
# -------------------------------------
91+
# Composes the docker stack command
92+
#
93+
# Globals:
94+
# srvs - service files variable
95+
# $@ -
96+
# Arguments:
97+
# none
98+
# Returns:
99+
# None
100+
cmd_stack() {
101+
local cmdStack="docker stack \\"$'\n'
102+
103+
if [ "$1" == "deploy" ]; then
104+
#cmdStack="$cmdStack deploy \\"
105+
if [ "$dc_fs" == "file" ]; then
106+
cmdStack="$cmdStack"$'\n'" $srvs"
107+
else
108+
cmdC="$(cmd_compose config)"
109+
#cmdC=$(echo "$cmdC" | sed "s/ / /")
110+
cmdStack="$cmdC \\"$'\n'"| $cmdStack deploy \\"$'\n'" --compose-file - \\"
111+
fi
112+
shift 1
113+
else
114+
cmdStack="$cmdStack $1 \\"
115+
shift 1
116+
fi
117+
118+
# add the rest
119+
if [ $# != 0 ]; then
120+
cmdStack="$cmdStack"$'\n'" $@ \\"
121+
fi
122+
123+
# add the name
124+
cmdStack="$cmdStack"$'\n'" $svc"
125+
126+
# set file option
127+
cmdStack=$(echo "$cmdStack" | sed "s/<file_opt>/-c/")
128+
129+
echo "$cmdStack"
130+
}
131+
132+
# -------------------------------------
133+
# Composes the service definition yml files
134+
#
135+
# Globals:
136+
# srvs - service files variable
137+
# Arguments:
138+
# $1 - service name
139+
# $2 - enviroment (default: dev)
140+
# Returns:
141+
# None
142+
srvs_files() {
143+
# service
144+
local service=$1
145+
# enviroment (default: dev)
146+
local env="${2:-dev}"
147+
148+
srvs="${srvs}"$'\n'" <file_opt> services/$service/docker-compose.$env.yml \\"
149+
}
150+
151+
# -------------------------------------
152+
# Shows usage/help
153+
#
154+
# Globals:
155+
# None
156+
# Arguments:
157+
# None
158+
# Returns:
159+
# None
160+
show_usage() {
161+
echo "Run service with docker-compose/docker stack (DC_MODE) in dev/prod (DC_ENV) environment."
162+
echo
163+
echo "Usage:"
164+
echo " ./dc.sh [flag] SERVICE [options] [command] [args...]"
165+
echo
166+
echo "Environment variables:"
167+
echo " DC_ENV Enviroment [ dev | prod ]; default: dev"
168+
echo " DC_MODE Used docker command [ compose | stack ]; default: if DC_ENV==prod then 'stack' else 'compose'"
169+
echo " DC_FS Way to pass yml file to 'docker stack deploy' [ conf | file ]; default: conf"
170+
echo
171+
echo "Flags"
172+
echo " -E Only show (echo) the command without executing it"
173+
echo " -[D|P] Override DC_ENV: D = dev; P = prod"
174+
echo " -[C|S] Override DC_MODE: C = conf; S = stack"
175+
echo " -F Pass yml files directly to 'docker stack deploy' instead of using docker-compose config. Same as DC_FS"
176+
echo
177+
echo "Services:"
178+
find services/ -maxdepth 1 -type d | sed 1d | sed "s/services\// /g"
179+
echo
180+
echo "Options, Commands, Args"
181+
echo " See the same section for docker-compose or docker stack"
182+
echo "docker-compose <=> docker stack commands map"
183+
echo " dc.sh | docker-compose | docker stack"
184+
echo "-----------------------------------------------"
185+
echo " up | up | deploy"
186+
echo " start | start | deploy"
187+
echo " config | config | NONE: fall back to docker-compose"
188+
echo " build | build | NONE: fall back to docker-compose"
189+
echo " <command> | <command> | <command>"
190+
echo
191+
echo "Examples:"
192+
echo " ./dc.sh hello-world up"
193+
echo
194+
echo " ./dc.sh -P hello-world up"
195+
echo " or same as above with env variable:"
196+
echo " DC_ENV=prod ./dc.sh hello-world up"
197+
echo " if the DC_ENV is set ('export DC_ENV=prod') then this does the same as above:"
198+
echo " ./dc.sh hello-world up"
199+
echo
200+
echo " DC_ENV=prod DC_MODE=compose ./dc.sh -E hello-world up"
201+
echo
202+
}
203+
204+
# *** ARGUMENTS ***
205+
if [ $# -eq 0 ]; then
206+
show_usage
207+
exit
208+
else
209+
cmd_echo=0
210+
while getopts "EDPCSF" opt; do
211+
case $opt in
212+
E) cmd_echo=1 ;;
213+
D) dc_env="dev" ;;
214+
P) dc_env="prod" ;;
215+
C) dc_mode="compose" ;;
216+
S) dc_mode="stack" ;;
217+
F) dc_fs="file" ;;
218+
\?) show_usage; exit ;;
219+
esac
220+
done
221+
shift $(expr $OPTIND - 1)
222+
svc=$1
223+
shift
224+
# check if the service directory exists
225+
if [ ! -d "services/$svc" ]; then
226+
echo "$0 [error] '$svc' service could not be found in services (services/$svc)" >&2
227+
exit 1
228+
else
229+
if [ ! -f "services/$svc/docker-compose.base.yml" ]; then
230+
echo "$0 [error] the docker-compose.base.yml is missing in services/$svc/" >&2
231+
exit 1
232+
fi
233+
if [ ! -f "services/$svc/docker-compose.dev.yml" ]; then
234+
echo "$0 [error] the docker-compose.base.yml is missing in services/$svc/" >&2
235+
exit 1
236+
fi
237+
if [ ! -f "services/$svc/docker-compose.prod.yml" ]; then
238+
echo "$0 [error] the docker-compose.base.yml is missing in services/$svc/" >&2
239+
exit 1
240+
fi
241+
fi
242+
fi
243+
# run main process
244+
main "$@"
245+
exit

docker-compose.yml

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#############################
2+
# Global config
3+
#
4+
#############################
5+
6+
version: '3.4'
7+
8+
networks:
9+
docker-net:

docker/READEME.md

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Docker images
2+
3+
## bulletinboard
4+
The image that is used in Docker's [Quickstart](https://docs.docker.com/get-started/part2/).

0 commit comments

Comments
 (0)