-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathgenerate_ubuntu.sh
executable file
·367 lines (284 loc) · 9.03 KB
/
generate_ubuntu.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
#! /bin/bash
# Copyright 2016 Bryan J. Hong
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# This script generates a general Docker "framework" based on the public Docker Ubuntu LTS image. The
# goal is to create a standardized foundation for building Docker containers to speed up the development
# process. For more detail, see README.md
#### BEGIN VARIABLES
# Base name of the Docker container
APP_NAME=mycontainer
# Remote Docker registry username (Docker Hub)
# Example of a private registry: docker-registry.example.com:5000
REPO_NAME="dockerhub_username"
# Your email address
# Major version of Ubuntu to build the container with
UBUNTU_MAJOR_VERSION=14
#### END VARIABLES
#### BEGIN VARS HEREDOC
if [[ ! -f vars ]]; then
cat << EOF > vars
#!/bin/bash
#### BEGIN DOCKER RUN VARIABLES
APP_NAME=${APP_NAME}
REPO_NAME="${REPO_NAME}"
#### END DOCKER RUN VARIABLES
EOF
cat << 'EOF' >> vars
#### BEGIN FRAMEWORK VARIABLES
# Get an SHA sum of all files involved in building the image so the image can be tagged
# this will provide assurance that any image with the same tag was built the same way.
SHASUM=`find . -type f \
-not -path "*/.git/*" \
-not -path "*.gitignore*" \
-not -path "*builds*" \
-not -path "*run.sh*" \
-exec shasum {} + | awk '{print $1}' | sort | shasum | cut -c1-4`
TAG="`date +%Y%m%d`-${SHASUM}"
#### END FRAMEWORK VARIABLES
EOF
fi
#### END VARS HEREDOC
#### BEGIN BUILD.SH HEREDOC
if [[ ! -f build.sh ]]; then
cat << 'EOF' > build.sh
#!/bin/bash
source vars
docker build -t "${REPO_NAME}/${APP_NAME}:${TAG}" .
# If the build was successful (0 exit code)...
if [ $? -eq 0 ]; then
echo
echo "Build of ${REPO_NAME}/${APP_NAME}:${TAG} completed OK"
echo
# log build details to builds file
echo "`date` => ${REPO_NAME}/${APP_NAME}:${TAG}" >> builds
# The build exited with an error.
else
echo "Build failed!"
exit 1
fi
EOF
fi
#### END BUILD.SH HEREDOC
#### BEGIN DOCKERFILE HEREDOC
if [[ ! -f Dockerfile ]]; then
cat << EOF > Dockerfile
FROM ubuntu:${UBUNTU_MAJOR_VERSION}.04
MAINTAINER ${EMAIL_ADDRESS}
EOF
cat << 'EOF' >> Dockerfile
ENV DEBIAN_FRONTEND noninteractive
# Update APT repository and install Supervisor
RUN apt-get -q update \
&& apt-get -y install supervisor
# Install Startup script
COPY assets/startup.sh /opt/startup.sh
# Execute Startup script when container starts
ENTRYPOINT [ "/opt/startup.sh" ]
EOF
fi
#### END DOCKERFILE HEREDOC
#### BEGIN RUN.SH HEREDOC
if [[ ! -f run.sh ]]; then
cat << 'EOF' > run.sh
#!/bin/bash
source vars
#If there is a locally built image present, prefer that over the
#one in the registry, we're going to assume you're working on changes
#to the image.
if [[ ! -f builds ]]; then
LATESTIMAGE=${REPO_NAME}/${APP_NAME}:latest
else
LATESTIMAGE=`tail -1 builds | awk '{print $8}'`
fi
echo
echo "Starting $APP_NAME..."
echo
echo -n "Container ID: "
docker run \
--detach=true \
--log-driver=syslog \
--name="${APP_NAME}" \
--restart=always \
${LATESTIMAGE}
# Other useful options
# -p DOCKERHOST_PORT:CONTAINER_PORT \
# -e "ENVIRONMENT_VARIABLE_NAME=VALUE" \
# -v /DOCKERHOST/PATH:/CONTAINER/PATH \
EOF
fi
#### END RUN.SH HEREDOC
#### BEGIN PUSH.SH HEREDOC
if [[ ! -f push.sh ]]; then
cat << 'EOF' > push.sh
#!/bin/bash
source vars
#This will take the latest locally built image and push it to the repository as
#configured in vars and tag it as latest.
if [[ ! -f builds ]]; then
echo
echo "It appears that the Docker image hasn't been built yet, run build.sh first"
echo
exit 1
fi
LATESTIMAGE=`tail -1 builds | awk '{print $8}'`
# Flatten is here as an option and not the default because with the export/import
# process we lose Dockerfile attributes like PORT and VOLUMES. Flattening helps if
# we are concerned about hitting the AUFS 42 layer limit or creating an image that
# other containers source FROM
DockerExport () {
docker export ${APP_NAME} | docker import - ${REPO_NAME}/${APP_NAME}:latest
}
DockerPush () {
docker push ${REPO_NAME}/${APP_NAME}:latest
}
case "$1" in
flatten)
docker inspect ${APP_NAME} > /dev/null 2>&1
if [[ $? -ne 0 ]]; then
echo "The ${APP_NAME} container doesn't appear to exist, exiting"
exit 1
fi
RUNNING=`docker inspect ${APP_NAME} | python3 -c 'import sys, json; print(json.load(sys.stdin)[0]["State"]["Running"])'`
if [[ "${RUNNING}" = "True" ]]; then
echo "Stopping ${APP_NAME} container for export"
docker stop ${APP_NAME}
DockerExport
DockerPush
else
DockerExport
DockerPush
fi
;;
*)
docker tag -f ${LATESTIMAGE} ${REPO_NAME}/${APP_NAME}:latest
DockerPush
esac
EOF
fi
#### END PUSH.SH HEREDOC
#### BEGIN SHELL.SH HEREDOC
if [[ ! -f shell.sh ]]; then
cat << 'EOF' > shell.sh
#!/bin/bash
source vars
docker inspect ${APP_NAME} > /dev/null 2>&1
if [[ $? -ne 0 ]]; then
echo "The ${APP_NAME} container doesn't appear to exist, exiting"
fi
CONTAINER_ID=`docker inspect ${APP_NAME} | python3 -c 'import sys, json; print(json.load(sys.stdin)[0]["Id"])'`
docker exec -it ${CONTAINER_ID} /bin/bash
EOF
fi
#### END SHELL.SH HEREDOC
#### BEGIN STARTUP.SH HEREDOC
mkdir -p assets
if [[ ! -f assets/startup.sh ]]; then
cat << 'EOF' > assets/startup.sh
#! /bin/bash
# Start Supervisor
/usr/bin/supervisord -n -c /etc/supervisor/supervisord.conf
EOF
fi
#### END STARTUP.SH HEREDOC
#### BEGIN README.MD HEREDOC
if [[ ! -f README.md ]]; then
cat << EOF > README.md
docker-${APP_NAME}
==
EOF
cat << 'EOF' >> README.md
brief description of container
>description of software used in the container [project website](http://URLofproject.com)
Quickstart
--
The following command will run mycontainer, if you want to customize or build the container locally, skip to [Building the Container](#building-the-container) below
```
docker run \
--detach=true \
--log-driver=syslog \
--name="mycontainer" \
--restart=always \
--env VARIABLE_NAME=value \
--publish 80:80 \
dockerhubusername/mycontainer:latest
```
### Runtime flags explained
```
--detach=true
```
run the container in the background
```
--log-driver=syslog
```
send logs to syslog on the Docker host (requires Docker 1.6 or higher)
```
--name="mycontainer"
```
name of the container
```
--restart=always
```
automatically start the container when the Docker daemon starts
```
--env VARIABLE_NAME=value
```
a key/value that are available inside the container
```
--publish 80:80
```
Docker host port : mapped port in the container
Additional Steps
--
1. Additional info if applicable
Building the container
--
If you want to make modifications to the image or simply see how things work, check out this repository:
```
git clone https://github.com/username/docker-mycontainer.git
```
### Commands and variables
* ```vars```: Variables for Docker registry, the application, and aptly repository data location
* ```build.sh```: Build the Docker image locally
* ```run.sh```: Starts the Docker container, it the image hasn't been built locally, it is fetched from the repository set in vars
* ```push.sh```: Pushes the latest locally built image to the repository set in vars
* ```shell.sh```: get a shell within the container
### How this image/container works
**Data**
**Networking**
**Security**
### Usage
#### Configure the container
1. Configure application specific variables in ```vars```
#### Build the image
1. Run ```./build.sh```
#### Start the container
1. Run ```./run.sh```
#### Pushing your image to the registry
If you're happy with your container and ready to share with others, push your image up to a [Docker registry](https://docs.docker.com/docker-hub/) and save any other changes you've made so the image can be easily changed or rebuilt in the future.
1. Authenticate to the Docker Registry ```docker login```
2. Run ```./push.sh```
3. Log into your Docker hub account and add a description, etc.
> NOTE: If your image will be used FROM other containers you might want to use ```./push.sh flatten``` to consolidate the AUFS layers into a single layer. Keep in mind, you may lose Dockerfile attributes when your image is flattened.
EOF
fi
#### END README.MD HEREDOC
#### BEGIN .GITIGNORE HEREDOC
if [[ ! -f .gitignore ]]; then
cat << 'EOF' > .gitignore
builds
EOF
fi
#### END .GITIGNORE HEREDOC
chmod 755 build.sh push.sh run.sh shell.sh assets/startup.sh