diff --git a/{{cookiecutter.django_project_name}}/deployment/README.md b/{{cookiecutter.django_project_name}}/deployment/README.md index ab47198..91fda30 100644 --- a/{{cookiecutter.django_project_name}}/deployment/README.md +++ b/{{cookiecutter.django_project_name}}/deployment/README.md @@ -1,8 +1,139 @@ # Deployment +> NOTE: This text is a working in progress. + +Deployment is always a complex subject to cover, it shouldn't be.. but it is. The approach we'll take here +it's not the easiest or a definitive guide on how to deploy your Django with Docker. + +If you run a "simple" Django app you may be better off starting things as simple as possible and from there +you can expand as much as you like. + +I won't cover the topics in-depth. If you're not familiar with some subject covered here, you should do some +research about it. + +- [Deployment](#deployment) + - [Provisioning](#provisioning) + - [Terraform](#terraform) + - [Digital Ocean](#digital-ocean) + - [Configuration Management](#configuration-management) + - [Ansible](#ansible) + - [Docker](#docker) + - [Docker Swarm](#docker-swarm) + - [Secrets](#secrets) + - [Databases](#databases) + - [Postgres](#postgres) + - [Redis](#redis) + - [Object Storage (File/Media)](#object-storage-filemedia) + - [Django](#django) + - [CI/CD](#cicd) + - [GitlabCI](#gitlabci) + - [GitHub Actions](#github-actions) + +## Provisioning + +Provisioning can be many things in I.T. but here we're talking about provision a server/instance with the +appropriated operational system. Let's be specific, we're talking about creating a server with Debian Stretch, +so you can ssh into it and do the things you want. + +I'm going to use a tool called Terraform to create our Debian instance on Digital Ocean and/or Linode. + +The steps are so similar for Digital Ocean and Linode, that I could just show you how to do this in only one +of them. Maybe in the future I'll add an example for AWS too. + +> Create a [Digital Ocean](https://m.do.co/c/6c759c705865) account. + +OR + +> Create a [Linode](https://www.linode.com/?r=f89d7040a73d83627bd6e7490244b280015354d9) account. + +**NOTE:** If you find this subject new/complicated/unnecessary for you, just go to your favorite provider +and manually create an instance with Debian Stretch and jump to [Configuration Management](#configuration-management) section. + +Basically we need a instance more or less like this: + +- Debian Stretch (You can go with Ubuntu, Alpine, whatever, as long as you know your way around the distro) +- Basic resources like 1GB RAM, 1CPU... +- Open ports: + - SSH + - HTTP/HTTPS + - Docker Remote (2376) +- SSH connection with ssh key (always better than user/password) + +### Terraform + +> Familiarize yourself with [Terraform](https://www.terraform.io). + +If you know the basics of Terraform, you can just go to [provisioning/terraform](provisioning/terraform) and +do your thing. + +> [Terraform Providers](https://www.terraform.io/docs/providers/index.html) + +> [Some of my Terraform snippets](https://github.com/douglasmiranda/lab/tree/master/terraform) + +> [My notes on Terraform](https://gist.github.com/douglasmiranda/ec2baf28d8cb7215d4033de3aad17025) + +After you learn Terraform and read the documentation of Digital Ocean provider, you can adapt the file +I provided to fit your plans. + +#### Digital Ocean + +> [provisioning/terraform/digitalocean](provisioning/terraform/digitalocean) + +> [How To Use Terraform with DigitalOcean](https://www.digitalocean.com/community/tutorials/how-to-use-terraform-with-digitalocean) + +> [Digital Ocean Provider](https://www.terraform.io/docs/providers/do/index.html) + +In order to create our instance/droplet with the files I provided you'll need a API token and the name of +your SSH key available in your Digital Ocean dashboard. + +## Configuration Management + TODO -Before You Deploy Things -Before you start deploying you'll probably need to create some secrets. -For example: openssl rand -base64 20 | docker secret create POSTGRES_PASSWORD - -or: openssl rand -base64 50 | docker secret create DJANGO_SECRET_KEY - +### Ansible + +TODO + +## Docker + +TODO + +### Docker Swarm + +TODO + +### Secrets + +TODO + +## Databases + +TODO + +### Postgres + +TODO + +### Redis + +TODO + +## Object Storage (File/Media) + +TODO + +## Django + +TODO + +## CI/CD + +TODO + +### GitlabCI + +TODO + +### GitHub Actions + +TODO diff --git a/{{cookiecutter.django_project_name}}/deployment/provisioning/terraform/digitalocean/ddpt.tf b/{{cookiecutter.django_project_name}}/deployment/provisioning/terraform/digitalocean/ddpt.tf new file mode 100644 index 0000000..0f4003f --- /dev/null +++ b/{{cookiecutter.django_project_name}}/deployment/provisioning/terraform/digitalocean/ddpt.tf @@ -0,0 +1,76 @@ +# We sill: +# - create a simple droplet +# - allow ssh access to our user with sshkey +# - configure firewall to allow the desired connections + +provider "digitalocean" { + token = "${var.digitalocean_token}" +} + +data "digitalocean_ssh_key" "me" { + name = "${var.digitalocean_sshkey_name}" +} + +resource "digitalocean_droplet" "ddpt" { + image = "debian-9-x64" + name = "ddpt-web-1" + region = "nyc3" + size = "s-1vcpu-1gb" + monitoring = true + private_networking = true + tags = ["ddpt", "web"] + + ssh_keys = ["${data.digitalocean_ssh_key.me.fingerprint}"] +} + +resource "digitalocean_firewall" "web" { + name = "ssh-docker-http-https" + + droplet_ids = ["${digitalocean_droplet.ddpt.id}"] + + # Allow incoming ssh, http, https, icmp and Docker remote connection + inbound_rule = [ + { + protocol = "tcp" + port_range = "22" + source_addresses = ["0.0.0.0/0", "::/0"] + }, + # Docker remote connection + { + protocol = "tcp" + port_range = "2376" + source_addresses = ["0.0.0.0/0", "::/0"] + }, + { + protocol = "tcp" + port_range = "80" + source_addresses = ["0.0.0.0/0", "::/0"] + }, + { + protocol = "tcp" + port_range = "443" + source_addresses = ["0.0.0.0/0", "::/0"] + }, + { + protocol = "icmp" + source_addresses = ["0.0.0.0/0", "::/0"] + }, + ] + + outbound_rule = [ + { + protocol = "tcp" + port_range = "1-6553" + destination_addresses = ["0.0.0.0/0", "::/0"] + }, + { + protocol = "udp" + port_range = "1-6553" + destination_addresses = ["0.0.0.0/0", "::/0"] + }, + { + protocol = "icmp" + destination_addresses = ["0.0.0.0/0", "::/0"] + } + ] +} diff --git a/{{cookiecutter.django_project_name}}/deployment/provisioning/terraform/digitalocean/variables.tf b/{{cookiecutter.django_project_name}}/deployment/provisioning/terraform/digitalocean/variables.tf new file mode 100644 index 0000000..b161bd5 --- /dev/null +++ b/{{cookiecutter.django_project_name}}/deployment/provisioning/terraform/digitalocean/variables.tf @@ -0,0 +1,2 @@ +variable "digitalocean_token" {} +variable "digitalocean_sshkey_name" {}