1# Deploying Capsul on a server
2
3Capsul has a ["hub and spoke" architecture](./architecture.md). The "Hub" runs the web application and talks to the Postgres database, while the "Spoke"s are responsible for creating/managing virtual machines. One instance of the capsul-flask application can run in both hub mode and spoke mode at the same time, however there must only be one instance of the app running in "Hub" mode at any given time.
4
5## <a name="spoke_mode_prerequisites"></a>Installing prerequisites for Spoke Mode
6
7On your spoke (see [Architecture](./architecture.md) You'll need `libvirtd`, `dnsmasq`, and `qemu-kvm`, plus a `/tank` diectory with some operating system images in it:
8
9```
10sudo apt install git dnsmasq qemu-system-x86 libvirt-clients libvirt-daemon-system virtinst cloud-image-utils
11sudo mkdir -p /var/www /tank/{vm,img,config}
12sudo mkdir -p /tank/img/debian/10
13cd !$
14sudo wget https://cloud.debian.org/images/cloud/buster/20201023-432/debian-10-genericcloud-amd64-20201023-432.qcow2 -O root.img.qcow2
15```
16
17TODO: network set-up
18
19
20## cyberia-cloudinit.yml
21
22The create vm shell script depends on this file. I think right now its file path is hard-coded to `/tank/config/cyberia-cloudinit.yml`
23
24```
25#cloud-config
26preserve_hostname: true
27packages:
28 - qemu-guest-agent
29 - acpid
30runcmd:
31 - [ 'systemctl', 'daemon-reload' ]
32 - [ 'systemctl', 'enable', 'qemu-guest-agent' ]
33 - [ 'systemctl', 'enable', 'acpid' ]
34 - [ 'systemctl', 'start', '--no-block', 'qemu-guest-agent' ]
35 - [ 'systemctl', 'start', '--no-block', 'acpid' ]
36users:
37 - name: cyberian
38 groups: wheel
39 lock_passwd: true
40 shell: /bin/bash
41 sudo: ['ALL=(ALL) NOPASSWD:ALL']
42 ssh-authorized_keys:
43```
44
45### Metrics
46
47Capsul integrates with Prometheus to grab the data for the capsul metric graphs.
48
49The code that generates those metrics is here: https://github.com/kumina/libvirt_exporter
50
51### autonomic / servers.coop version for ipv6 support
52
53```
54#cloud-config
55package_upgrade: true
56packages:
57 - curl
58 - wget
59 - git
60 - vim
61bootcmd:
62 - echo 'iface ens3 inet6 dhcp' >> /etc/network/interfaces.d/50-cloud-init
63 - ifdown ens3; ifup ens3
64final_message: "The system is finally up, after $UPTIME seconds"
65users:
66 - name: user
67 groups: sudo
68 sudo: ['ALL=(ALL) NOPASSWD:ALL']
69 ssh-authorized-keys:
70```
71
72
73## Deploying capsul-flask
74
75### <a name="deploy_manually"></a>Manually
76
77Follow the [local set-up instructions](./local-set-up.md) on your server.
78
79Make sure to set `BASE_URL` correctly, generate your own secret tokens, and
80configure your own daemon management for the capsul-flask server (e.g. writing
81init scripts, or SystemD unit files).
82
83Use the suggested `gunicorn` command (with appropriately-set address and port),
84instead of `flask run`, to launch the server.
85
86For example, here is the SystemD service unit file we use in production for `capsul.org`:
87
88```
89[Unit]
90Description=capsul-flask virtual machines as a service
91After=network.target
92
93[Service]
94ExecStart=/usr/local/bin/pipenv run gunicorn --bind 127.0.0.1:5000 -k gevent --worker-connections 1000 app:app
95Restart=on-failure
96WorkingDirectory=/opt/capsul-flask
97
98[Install]
99WantedBy=multi-user.target
100
101```
102
103TODO: cron runner is required to run maintenance tasks for now, but in the future we want to build this into the python based task scheduler.
104
105### <a name="coop_cloud_docker"></a> Using Co-op Cloud's vanilla Docker Swarm configuration
106
107Download the Co-op Cloud swarm `compose.yml`:
108
109```sh
110wget https://git.autonomic.zone/coop-cloud/capsul/src/branch/main/compose.yml
111```
112
113Optionally, download add-on compose files for Stripe, BTCPay, and Spoke Mode:
114
115```sh
116wget https://git.autonomic.zone/coop-cloud/capsul/src/branch/main/compose.{stripe,btcpay,spoke}.yml
117```
118
119Then, create a `.env` file and configure appropriately -- you probably want to
120define most settings in [the Co-op Cloud `.envrc.sample`
121file](https://git.autonomic.zone/coop-cloud/capsul/src/branch/main/.envrc.sample).
122
123Load the environment variables (using Python `direnv`, or a manual `set -a && source .env && set +a`), insert any necessary secrets, then run the deployment:
124
125```sh
126docker stack deploy -c compose.yml -c compose.stripe.yml your_capsul
127```
128
129(where you'd add an extra `-c compose.btcpay.yml` for each optional compose file
130you want, and set `your_capsul` to the "stack name" you want).
131
132TODO: cron runner
133
134### <a name="coop_cloud_abra"></a> Using Co-op Cloud's `abra` deployment tool
135
136Follow [the guide in the README for the Co-op Cloud capsul package](https://git.autonomic.zone/coop-cloud/capsul/).
137
138### Using docker-compose
139
140TODO