This post will combine that last three posts on [Packer](/blog/snapshotswithpacker/), [Terraform](/blog/autodeployterraform/), and their [configuration](/blog/sharedpackerterraformconfig/) to show an entire example of how to deploy a docker-compose application. We will specifically look at deploying a game called [`minetest`](https://www.minetest.net/) on DigitalOcean, but these principles can be adjusted to deploy your application as well. The entire setup is [documented on Github](https://github.com/Brandon-Rozek/minetest-deploy).
We're going to use a shared configuration between Packer and Terraform. The template goes like this:
```
base_system_image = "ubuntu-20-04-x64"
region = "nyc3"
size = "512mb"
domain = "brandonrozek.com" # Replace
subdomain = "minetest"
# Secrets
do_token = "DO-TOKEN-HERE" # Replace
key_name = "SSH-NAME-ON-DO-HERE" # Replace
```
We'll also need to define the types of these variables in `variables.hcl`
```
variable "do_token" {
type = string
}
variable "base_system_image" {
type = string
}
variable "domain" {
type = string
}
variable "key_name" {
type = string
}
variable "subdomain" {
type = string
}
variable "region" {
type = string
}
variable "size" {
type = string
}
```
## Packer
Create a packer directory and setup some symbolic links to the share configuration
```bash
mkdir packer && cd packer
ln -s ../config variables.auto.pkrvars.hcl
ln -s ../variables.hcl variables.pkr.hcl
```
Now let's create a script named `setup.sh` that will run on top of our base image. This will install Docker and setup the firewall to allow SSH and Minetest traffic through.
```bash
#!/bin/bash
apt update
apt upgrade -y
apt install -y docker.io docker-compose
systemctl enable docker-compose
systemctl start docker-compose
ufw allow OpenSSH
# Add any firewall rules you need
# for your application here
ufw allow 30000/udp
ufw --force enable
```
The image that we'll use for Minetest comes from [linuxserverio](https://fleet.linuxserver.io/image?name=linuxserver/minetest). To configure docker-compose we'll need a file named `docker-compose.yml`. Its contents will be highly similar to what is listed on their [Github](https://github.com/linuxserver/docker-minetest/blob/466cde1f2fd38278fe69d33ea3b2f42df50e6b16/README.md).
We'll need to create a `systemd` script called `docker-compose.service` for systemd to [enable docker-compose on startup](https://brandonrozek.com/blog/composesystemd/).
```ini
[Unit]
Description=Docker Compose Application Service
Requires=docker.service
After=docker.service
[Service]
Type=oneshot
RemainAfterExit=yes
WorkingDirectory=/root
ExecStart=/usr/bin/docker-compose up -d
ExecStop=/usr/bin/docker-compose down
TimeoutStartSec=0
[Install]
WantedBy=multi-user.target
```
Finally we'll need to write a packer configuration file `do.pkr.hcl` to create our snapshot.
value = "${digitalocean_record.www.name}.${digitalocean_record.www.domain}"
}
```
To deploy run
```bash
terraform apply
```
To later take down the minetest server, run
```bash
terraform destroy
```
## Conclusion
This method can be easily configured to run whichever docker services you'd like. All you have to do is edit the `packer/docker.compose.yml` file and `packer/setup.sh` to setup the firewall rules.