Skip to content

Commit 5ae37cc

Browse files
committed
adding docs
Signed-off-by: Vanessa Sochat <[email protected]>
1 parent c25babd commit 5ae37cc

File tree

14 files changed

+566
-10
lines changed

14 files changed

+566
-10
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
# Singularity Compose
22

33
This is a simple orchestration library for Singularity containers, akin to
4-
Docker Compose.
4+
Docker Compose. See the [specification]() and the [documentation]() for
5+
details, or more examples below.
56

67
## Examples
78

docs/.nojekyll

Whitespace-only changes.

docs/README.md

Lines changed: 300 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,300 @@
1+
# Singularity Compose
2+
3+
This is a simple orchestration library for Singularity containers, akin to
4+
Docker Compose. It is under development, and working for basic examples.
5+
6+
## Who is this intended for?
7+
8+
Singularity compose is intended to run a small number of container instances
9+
on your host. It is *not* a complicated orchestration tool like Kubernetes,
10+
but rather a controlled way to represent and manage a set of container instances,
11+
or services.
12+
13+
## Getting Started
14+
15+
### singularity-compose.yml
16+
17+
For a singularity-compose project, it's expected to have a `singularity-compose.yml`
18+
in the present working directory. You can look at a simple example here:
19+
20+
```yaml
21+
version: "1.0"
22+
instances:
23+
app:
24+
build:
25+
context: ./app
26+
volumes:
27+
- ./nginx.conf:/etc/nginx/conf.d/default.conf
28+
- ./app:/code
29+
- ./static:/var/www/static
30+
- ./images:/var/www/images
31+
ports:
32+
- 80:80
33+
```
34+
35+
If you are familiar with [docker-compose](https://docs.docker.com/compose/)
36+
the file should look very familiar. A key difference is that instead of
37+
"services" we have "instances." And you guessed correctly - each
38+
section there corresponds to a
39+
[Singularity instance](https://sylabs.io/guides/3.2/user-guide/running_services.html)
40+
that will be created. In this guide, we will walk through each of the sections
41+
in detail.
42+
43+
### Instance folders
44+
45+
Generally, each section in the yaml file corresponds with a container instance to be run,
46+
and each container instance is matched to a folder in the present working directory.
47+
For example, if I give instruction to build an `nginx` instance from
48+
a `nginx/Singularity.nginx` file, I should have the
49+
following in my singularity-compose:
50+
51+
```
52+
nginx:
53+
build:
54+
context: ./nginx
55+
recipe: Singularity.nginx
56+
```
57+
58+
The above says that I want to build a container and corresponding instance
59+
named `nginx`, and use the recipe `Singularity.nginx` in the context
60+
folder `./nginx` in the present working directory. This gives me the following
61+
directory structure:
62+
63+
```bash
64+
singularity-compose-example
65+
├── nginx
66+
...
67+
│   ├── Singularity.nginx
68+
│   └── uwsgi_params.par
69+
└── singularity-compose.yml
70+
71+
```
72+
73+
Notice how I also have other dependency files for the nginx container
74+
in that folder. While the context for starting containers with Singularity
75+
compose is the directory location of the `singularity-compose.yml`,
76+
the build context for this container is inside the nginx folder.
77+
We will talk about the [build command](commands.md) soon. First,
78+
as another option, you can just define a container to pull,
79+
and it will be pulled to the same folder that is created if it doesn't exist.
80+
81+
```
82+
nginx:
83+
image: docker://nginx
84+
```
85+
86+
This will pull a container `nginx.sif` into a `nginx` context folder:
87+
88+
```bash
89+
├── nginx (- created if it doesn't exist
90+
│   └── nginx.sif (- named according to the instance
91+
└── singularity-compose.yml
92+
```
93+
94+
It's less likely that you will be able to pull a container that is ready to
95+
go, as typically you will want to customize the
96+
[startscript](https://sylabs.io/guides/3.2/user-guide/definition_files.html#startscript)
97+
for the instance. Now that we understand the basic organization, let's
98+
bring up some instances.
99+
100+
## Quick Start
101+
102+
For this quick start, we are going to use the
103+
[singularity-compose-simple](https://www.github.com/singularityhub/singularity-compose-simple)
104+
example. Singularity has a networking issue that currently doesn't allow communication
105+
between multiple containers (due to iptables and firewall issues) so for now the most we
106+
can do is show you one container. First, install singularity-compose from pip:
107+
108+
```bash
109+
$ pip install singularity-compose
110+
```
111+
112+
Then, clone the repository:
113+
114+
```bash
115+
$ git clone https://www.github.com/singularityhub/singularity-compose-simple
116+
```
117+
118+
cd inside, and you'll see a `singularity-compose.yml` like we talked about.
119+
120+
```bash
121+
$ cd singularity-compose-simple
122+
$ ls
123+
app images LICENSE nginx.conf README.md singularity-compose.yml static
124+
```
125+
126+
Let's take a look at the `singularity-compose.yml`
127+
128+
```yaml
129+
version: "1.0"
130+
instances:
131+
app:
132+
build:
133+
context: ./app
134+
volumes:
135+
- ./nginx.conf:/etc/nginx/conf.d/default.conf
136+
- ./app/nginx/uwsgi_params.par:/etc/nginx/uwsgi_params.par
137+
- ./app/nginx/cache:/var/cache/nginx
138+
- ./app/nginx/run:/var/run
139+
- ./app:/code
140+
- ./static:/var/www/static
141+
- ./images:/var/www/images
142+
ports:
143+
- 80:80
144+
...
145+
```
146+
147+
It defines a single service, `app`, which has both a Django application and
148+
a nginx server with the [nginx-upload module](https://www.nginx.com/resources/wiki/modules/upload/) enabled.
149+
It tells us right away that the folder `app` is the context folder, and inside we can
150+
see dependency files for nginx and django.
151+
152+
```bash
153+
$ ls app/
154+
manage.py nginx requirements.txt run_uwsgi.sh Singularity upload...
155+
```
156+
157+
What we don't see is a container. We need to build that from the Singularity recipe.
158+
Let's do that.
159+
160+
```bash
161+
$ singularity-compose build
162+
```
163+
164+
Will generate an `app.sif` in the folder:
165+
166+
```bash
167+
$ ls app/
168+
app.sif manage.py nginx requirements.txt run_uwsgi.sh Singularity upload...
169+
```
170+
171+
And now we can bring up our instance!
172+
173+
```bash
174+
$ singularity-compose up
175+
```
176+
177+
Verify it's running:
178+
179+
```bash
180+
$ singularity-compose ps
181+
INSTANCES NAME PID IMAGE
182+
1 app 20023 app.sif
183+
```
184+
185+
And then look at logs, shell inside, or execute a command.
186+
187+
```bash
188+
$ singularity-compose logs app
189+
$ singularity-compose logs app --tail 30
190+
$ singularity-compose shell app
191+
$ singularity-compose exec app uname -a
192+
```
193+
194+
When you open your browser to [http://127.0.0.1](http://127.0.0.1)
195+
you should see the upload interface.
196+
197+
![img/upload.png](img/upload.png)
198+
199+
If you drop a file in the box (or click
200+
to select) we will use the nginx-upload module to send it directly to the
201+
server. Cool!
202+
203+
![img/content.png](img/content.png)
204+
205+
This is just a simple Django application, the database is sqlite3, and it's
206+
now appeared in the app folder:
207+
208+
```bash
209+
$ ls app/
210+
app.sif db.sqlite3 manage.py nginx requirements.txt run_uwsgi.sh Singularity upload uwsgi.ini
211+
```
212+
213+
The images that you upload are stored in `images` at the root:
214+
215+
```bash
216+
$ ls images/
217+
2018-02-20-172617.jpg 40-acos.png _upload
218+
```
219+
220+
And static files are in `static`.
221+
222+
```bash
223+
$ ls static/
224+
admin css js
225+
```
226+
227+
Finally, the volumes that we specified in the `singularity-compose.yml`
228+
tell us exactly where nginx and the application need write. The present
229+
working directory (where the database is written) is bound to the
230+
container at `/code`, and nginx dependencies are bound to locations
231+
in `/etc/nginx`. Notice how the local static and images folder are bound
232+
to locations in the container where we normally wouldn't have write.
233+
234+
```bash
235+
volumes:
236+
- ./nginx.conf:/etc/nginx/conf.d/default.conf
237+
- ./app/nginx/uwsgi_params.par:/etc/nginx/uwsgi_params.par
238+
- ./app/nginx/cache:/var/cache/nginx
239+
- ./app/nginx/run:/var/run
240+
- ./app:/code
241+
- ./static:/var/www/static
242+
- ./images:/var/www/images
243+
```
244+
245+
This is likely a prime different between Singularity and Docker compose - Docker doesn't need
246+
binds for write, but rather to reduce isolation. When you develop an application,
247+
a lot of your debug will come down to figuring out where the services need to write
248+
log and similar files, which you might not have been aware of when using Docker.
249+
250+
Continue below to read about networking, and see these commands in detail.
251+
252+
## Networking
253+
254+
When you bring the container up, you'll see generation of an `etc.hosts` file,
255+
and if you guessed it, this is indeed bound to `/etc/hosts` in the container.
256+
Let's take a look:
257+
258+
```bash
259+
10.22.0.2 app
260+
127.0.0.1 localhost
261+
262+
# The following lines are desirable for IPv6 capable hosts
263+
::1 ip6-localhost ip6-loopback
264+
fe00::0 ip6-localnet
265+
ff00::0 ip6-mcastprefix
266+
ff02::1 ip6-allnodes
267+
ff02::2 ip6-allrouters
268+
```
269+
270+
This file will give each container that you create (in our case, just one)
271+
a name on its local network. Singularity by default creates a bridge for
272+
instance containers, which you can conceptually think of as a router,
273+
This means that, if I were to reference the hostname "app" in a second container,
274+
it would resolve to `10.22.0.2`. Singularity compose does this by generating
275+
these addresses before creating the instances, and then assigning them to it.
276+
If you would like to see the full commands that are generated, run the up
277+
with `--debug` (binds and full paths have been removed to make this easier to read).
278+
279+
```bash
280+
$ singularity instance start \
281+
--bind /home/vanessa/Documents/Dropbox/Code/singularity/singularity-compose-simple/etc.hosts:/etc/hosts \
282+
--net --network-args "portmap=80:80/tcp" --network-args "IP=10.22.0.2" \
283+
--hostname app \
284+
--writable-tmpfs app.sif app
285+
```
286+
287+
Control and customization of these instances is probably the coolest (and not widely
288+
used) feature of Singularity. You can create your own network configurations,
289+
and customie the arguments to the command. Read [here](https://sylabs.io/guides/3.2/user-guide/running_services.html) for more detalis.
290+
291+
## Commands
292+
293+
Read more about the commands shown above [here](commands.md#commands).
294+
295+
## Specification
296+
297+
The [specification](spec) describes in more detail the sections of the singularity-compose.yml.
298+
For example, in the quick start above, we have a post command for the app instance
299+
that creates a series of folders on the host.
300+

docs/_coverpage.md

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
![logo](img/scompose.png)
2+
3+
# Singularity Compose <small>docs</small>
4+
5+
> Singularity Compose for simple container orchestration
6+
7+
- Definition of services
8+
- Interaction with instances
9+
- Logging and Networking
10+
11+
12+
<style>
13+
section.cover .cover-main > p:last-child a:last-child {
14+
background-color: #ffffff;
15+
color: black !important;
16+
}
17+
18+
section.cover .cover-main>p:last-child a {
19+
border: 1px solid #ffffff !important;
20+
color: white !important;
21+
}
22+
23+
.cover {
24+
background: linear-gradient(to left bottom, hsl(352, 88%, 48%) 0%,hsl(331, 100%, 19%) 100%) !important;;
25+
color: white;
26+
}
27+
28+
.cover-main span {
29+
color: whitesmoke !important;
30+
}
31+
</style>
32+
33+
[GitHub](https://github.com/singularityhub/singularity-compose)
34+
[Get Started](#singularity-compose)

0 commit comments

Comments
 (0)