Skip to content

Commit 3b419d0

Browse files
committed
Add license and readme
1 parent fe60a70 commit 3b419d0

File tree

2 files changed

+304
-0
lines changed

2 files changed

+304
-0
lines changed

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2020 Codeacious Pty Ltd
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 283 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,283 @@
1+
# dev-compose
2+
3+
dev-compose is a command-line tool for managing portable development environments using Docker.
4+
It's built on top of [docker-compose](https://docs.docker.com/compose/).
5+
6+
7+
### Installation
8+
9+
1. Download the version of the tool built for your OS.
10+
2. Unzip it
11+
3. Place the executable file somewhere within your system path (so your shell or command interpreter
12+
can find it). For example:
13+
* Mac or Linux: `/usr/local/bin`
14+
* Windows 10: `C:\Windows\System32`
15+
16+
### Requirements
17+
18+
dev-compose requires Docker to be running, and for the docker-compose binary to be present in your
19+
execution path.
20+
21+
### Usage
22+
23+
dev-compose is configured using a devSpec. This is a YAML file, usually named `dev.yml` and located
24+
in the top-level directory of your software project. It defines the containers that are required,
25+
and the commands to run within them to accomplish tasks such as recompiling the application or
26+
bringing up a new instance from scratch on your local machine.
27+
28+
dev-compose is invoked by the command `dev`. By default it looks for a `dev.yml` file in the current
29+
working directory and parses it.
30+
31+
To see what commands are available:
32+
```
33+
dev commands
34+
```
35+
36+
To run a single command:
37+
```
38+
dev <command> [args...]
39+
```
40+
41+
To start an interactive shell:
42+
```
43+
dev
44+
```
45+
46+
#### Commands
47+
48+
You can define custom commands specific to your project by adding handlers to your `dev.yml` file.
49+
In addition, these built-in commands are always available:
50+
51+
* `status` - Show the status (running/stopped) of the containers defined in your devSpec
52+
* `start` - Start the containers defined in your devSpec (creating them first, if necessary).
53+
You can specify `start <service_name>` to start a specific container only.
54+
* `stop` - Stop the containers defined in your devSpec
55+
You can specify `stop <service_name>` to stop a specific container only.
56+
* `restart` - Restart the containers defined in your devSpec.
57+
You can specify `restart <service_name>` to restart a specific container only.
58+
* `init` - (Re-)initialise the dev environment. Ideally, this is the only command a developer needs
59+
to type to get a fully working development version of your application up and running.
60+
`init` performs the following sequence of actions:
61+
1. If containers already exist for this project, stop and remove them.
62+
1. Pull the latest versions of any referenced Docker images.
63+
1. Create and start the containers defined in your devSpec.
64+
1. If an `init` handler is defined in your devSpec, run its actions. This might perform tasks
65+
like installing dependencies, and creating database tables.
66+
* `destroy` - Stop and remove any containers that exist for this project. If a `destroy` handler
67+
is defined in your devSpec, its actions run first.
68+
* `sync` - Bring the dev environment up to date. Ideally, this is the only command a developer
69+
needs to type after pulling changes to the source code, to get their instance of the application
70+
working again. `sync` performs the following sequence of actions:
71+
1. Pull the latest versions of any referenced Docker images. Re-create containers, if necessary,
72+
to use the new images.
73+
1. Rebuild any auto-built container images
74+
1. If a `sync` handler is defined in your devSpec, run its actions. This might perform tasks
75+
like installing new dependencies, and modifying the schema of a database.
76+
* `exec` - Execute a program inside a container. The syntax is
77+
`exec [-c <service_name>] <program> [args...]`.
78+
The program can be followed by space-separated arguments. _Note:_ Shell syntax and argument
79+
escaping are not currently supported. If you don't specify a service name, the default container
80+
will be used. Interactive commands are supported (so `exec bash` could launch a shell
81+
inside your container, for example).
82+
* `logs` - Print the recent log output from a container, then follow and continue to print any new
83+
log messages that arrive until Ctrl-C is pressed. The syntax is
84+
`logs [-c <service_name>]`. If you don't specify a service name, the default container will be used.
85+
* `commands` - Lists the commands that are applicable to the current devSpec, including any custom commands.
86+
87+
88+
* * *
89+
90+
### Why use Docker containers in development?
91+
Containerised dev environments are a great way of making sure everyone in your development team
92+
has access to the correct build, test and runtime dependencies. This is especially true when developing
93+
web applications, where there is an overwhelming choice of build systems, package managers and
94+
frameworks. These applications can also be complicated to configure and bring up. When onboarding a
95+
new developer, significant time can be spent just trying to get an instance of the product running
96+
on their machine.
97+
98+
Using container images and scripts, the process for preparing and running the application on a
99+
developer's laptop can be fully automated.
100+
101+
The general approach is:
102+
103+
1. Check out the project source code as normal in the host OS
104+
2. Create the container and mount your source code directory into it
105+
3. Modify the code in the host OS, but execute all build tools (and the application itself) inside
106+
the container
107+
108+
Each developer can use their IDE of choice on their platform of choice (Mac/Win/Linux) without
109+
taking any special steps to set up their machine for building and running each application they work
110+
on. The only tool they need to install is Docker.
111+
112+
113+
### Why not just use docker-compose?
114+
115+
docker-compose, distributed with Docker, is a convenient way of starting a set
116+
of containers needed for development (such as an app container and a database). You define the
117+
containers in a `docker-compose.yml` file (which can be committed with your project) and then type
118+
`docker-compose up` to start them all.
119+
120+
But there are a few minor annoyances when using docker-compose for development, which this tool aims
121+
to address:
122+
123+
1. In development you may need to run some commands frequently inside your running containers. Sometimes you
124+
even need to run a sequence of commands across multiple containers (execute a build in container
125+
A, then a restart in container B). docker-compose just starts the containers, it doesn't help
126+
you script these operations. If you script them yourself (eg. a bash script that calls docker-compose)
127+
you break the platform independence that the containerised dev environment promised.
128+
1. Running commands in a container is verbose (you get pretty sick of typing `docker-compose exec
129+
container_name`)
130+
1. You can't configure different default environment variables or run-as-user for command-line
131+
actions. The configuration used to start the main container process will be applied to all
132+
command-line actions, unless you specify overrides every time you call `docker-compose exec`.
133+
1. If you also use docker-compose in production, you may want `docker-compose.yml` to contain
134+
your deployment configuration, which is probably quite different to your development configuration.
135+
If you see a `docker-compose.yml` file in a project, you can't easily tell if it's meant for
136+
development or deployment purposes.
137+
1. It would be nice if docker-compose could automatically load environment variable overrides from
138+
a `local.env` file if it happens to be present in your working copy, without _requiring_ that it be
139+
present (so you can exclude it from source control).
140+
141+
142+
* * *
143+
144+
### devSpec reference
145+
146+
dev-compose is configured using a YAML file, usually named `dev.yml`, which is intended to live in
147+
the top-level directory of your software project and be committed with the project. Its syntax is
148+
a superset of `docker-compose.yml`. You can define `services`, `networks` and `volumes`
149+
[as you normally would](https://docs.docker.com/compose/compose-file/), plus these top-level keys:
150+
151+
* `handlers`: Define named command sequences
152+
* `command_defaults`: Override the settings used when executing a command in a running container
153+
(either ad-hoc on the command line, or via a handler)
154+
* `buildkit`: A flag specifying whether to enable the next-gen Docker image builder. Relevant only if
155+
some of your service definitions include a `build` section.
156+
157+
#### handlers
158+
```yaml
159+
# This example defines a handler called 'init', containing a sequence of 3 actions
160+
handlers:
161+
init:
162+
- service: app
163+
command: npm install
164+
- service: app
165+
command: gulp
166+
- service: db
167+
command: migrate-schema
168+
```
169+
Each named handler consists of an array of actions. Each action can contain the following keys:
170+
* `service` - Specifies which container this action applies to. A default can be set under
171+
`command_defaults`. Otherwise it defaults to the first one defined in the `services` section.
172+
* `action` - The name of a special action to perform. Currently the only supported value is `restart`,
173+
which restarts the container.
174+
* `command` - A program to execute inside the container. This can include space-separated arguments,
175+
or you can specify the arguments separately with `args`. _Note:_ Shell syntax and escaping rules do not work here.
176+
* `handler` - The name of another handler to execute. Allows you to include all the actions of one
177+
handler within another.
178+
* `args` - An array of command-line arguments. If used with `handler`, these arguments will be
179+
_appended_ to each command that handler executes.
180+
* `user` - The username or UID (inside the container) to use when executing the command.
181+
* `working_dir` - The path (inside the container) to set as the working directory when executing the command.
182+
* `environment` - Key-value pairs to append to the program's environment.
183+
184+
Each action must specify exactly one of `action`, `command` or `handler`.
185+
186+
All the other keys are optional. Defaults are inherited in this order of priority:
187+
1. From the `command_defaults` section
188+
1. From the services section
189+
1. From the container image
190+
191+
#### command_defaults
192+
The command_defaults section can contain the following keys:
193+
* `service` - Specifies the default container that commands should run within.
194+
* `user` - The default username or UID (inside the container) to use when executing a command.
195+
* `working_dir` - The default path (inside the container) to set as the working directory when
196+
executing a command.
197+
* `environment` - Key-value pairs to append to the program's environment when executing a command.
198+
199+
#### buildkit
200+
This is a boolean value. When true, it's equivalent to running the Docker CLI with the
201+
`DOCKER_BUILDKIT` environment variable set, so it will
202+
[use BuildKit to build Docker images](https://docs.docker.com/develop/develop-images/build_enhancements/).
203+
When absent, *this property is true by default*, since BuildKit provides some features
204+
that are super useful in development scenarios.
205+
206+
207+
* * *
208+
209+
### Example
210+
211+
```yaml
212+
# This example is for a Node.JS server project. The Gulp build system is in use.
213+
# Build actions are performed in a 'build' container, which is kept running by setting its
214+
# initial command to 'bash'. The built daemon runs in the 'app' container.
215+
216+
version: '3.6'
217+
218+
services:
219+
build:
220+
image: node:12-buster
221+
restart: on-failure
222+
volumes:
223+
- ./:/srv/app:cached
224+
working_dir: /srv/app
225+
command: bash
226+
tty: true
227+
ports:
228+
- "9230:9230"
229+
env_file:
230+
- dev.env
231+
environment:
232+
PATH: "$PATH:/srv/app/bin:/srv/app/node_modules/.bin"
233+
234+
app:
235+
image: node:12-buster
236+
restart: no
237+
volumes:
238+
- ./:/srv/app:cached
239+
working_dir: /srv/app
240+
command: node --inspect=0.0.0.0:9229 bin/server
241+
ports:
242+
- "8080:8080"
243+
- "9229:9229"
244+
env_file:
245+
- dev.env
246+
247+
db:
248+
image: mysql:5.6
249+
restart: on-failure
250+
command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
251+
ports:
252+
- "127.0.0.1:33060:3306"
253+
environment:
254+
MYSQL_DATABASE: app
255+
MYSQL_PASSWORD: devdb
256+
MYSQL_ROOT_PASSWORD: devdb
257+
MYSQL_USER: app
258+
259+
handlers:
260+
build:
261+
- command: gulp
262+
- service: app
263+
action: restart
264+
sync:
265+
- command: npm install
266+
- handler: build
267+
- handler: migrate
268+
init:
269+
- command: rm -Rf node_modules
270+
- command: npm install
271+
- handler: build
272+
args:
273+
- clean
274+
- handler: build
275+
- handler: migrate
276+
- command: cli setup
277+
cli:
278+
- command: node --inspect=0.0.0.0:9230 bin/cli
279+
sql:
280+
- command: cli orm generate
281+
migrate:
282+
- command: cli orm migrate
283+
```

0 commit comments

Comments
 (0)