Skip to content

Commit

Permalink
Merge pull request #78 from create-go-app/dev
Browse files Browse the repository at this point in the history
Add Postgres and Redis roles; Fix proxy 'none' case
  • Loading branch information
Vic Shóstak committed May 5, 2021
2 parents 798a461 + 4201b7c commit 24f9023
Show file tree
Hide file tree
Showing 11 changed files with 254 additions and 83 deletions.
12 changes: 11 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
</h1>
<p align="center">Create a new production-ready project with <b>backend</b> (Golang), <b>frontend</b> (JavaScript, TypeScript)<br/>and <b>deploy automation</b> (Ansible, Docker) by running one CLI command.<br/><br/>Focus on <b>writing</b> code and <b>thinking</b> of business-logic! The CLI will take care of the rest.</p>

<p align="center"><a href="https://github.com/create-go-app/cli/releases" target="_blank"><img src="https://img.shields.io/badge/version-v2.0.0-blue?style=for-the-badge&logo=none" alt="cli version" /></a>&nbsp;<a href="https://pkg.go.dev/github.com/create-go-app/cli?tab=doc" target="_blank"><img src="https://img.shields.io/badge/Go-1.16+-00ADD8?style=for-the-badge&logo=go" alt="go version" /></a>&nbsp;<a href="https://gocover.io/github.com/create-go-app/cli/pkg/cgapp" target="_blank"><img src="https://img.shields.io/badge/Go_Cover-89%25-success?style=for-the-badge&logo=none" alt="go cover" /></a>&nbsp;<a href="https://goreportcard.com/report/github.com/create-go-app/cli" target="_blank"><img src="https://img.shields.io/badge/Go_report-A+-success?style=for-the-badge&logo=none" alt="go report" /></a>&nbsp;<img src="https://img.shields.io/badge/license-apache_2.0-red?style=for-the-badge&logo=none" alt="license" /></p>
<p align="center"><a href="https://github.com/create-go-app/cli/releases" target="_blank"><img src="https://img.shields.io/badge/version-v2.1.0-blue?style=for-the-badge&logo=none" alt="cli version" /></a>&nbsp;<a href="https://pkg.go.dev/github.com/create-go-app/cli?tab=doc" target="_blank"><img src="https://img.shields.io/badge/Go-1.16+-00ADD8?style=for-the-badge&logo=go" alt="go version" /></a>&nbsp;<a href="https://gocover.io/github.com/create-go-app/cli/pkg/cgapp" target="_blank"><img src="https://img.shields.io/badge/Go_Cover-89%25-success?style=for-the-badge&logo=none" alt="go cover" /></a>&nbsp;<a href="https://goreportcard.com/report/github.com/create-go-app/cli" target="_blank"><img src="https://img.shields.io/badge/Go_report-A+-success?style=for-the-badge&logo=none" alt="go report" /></a>&nbsp;<img src="https://img.shields.io/badge/license-apache_2.0-red?style=for-the-badge&logo=none" alt="license" /></p>

## ⚡️ Quick start

Expand Down Expand Up @@ -132,6 +132,16 @@ cgapp deploy [OPTION]

> ✌️ Since Create Go App CLI `v2.0.0`, we're recommend to use **Traefik Proxy** as default proxy server for your projects. The main reason: this proxy provides _automatic_ SSL certificates from Let's Encrypt out of the box. Also, Traefik was built on the Docker ecosystem and has a _really good looking_ and _useful_ Web UI.
### Database

- Roles for run Docker container with [PostgreSQL](https://postgresql.org/):
- `postgres` — configured PostgreSQL container with apply migrations for backend.

### Cache (key-value storage)

- Roles for run Docker container with [Redis](https://redis.io/):
- `redis` — configured Redis container for backend.

## ⭐️ Project assistance

If you want to say **thank you** or/and support active development of `Create Go App CLI`:
Expand Down
130 changes: 68 additions & 62 deletions cmd/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,6 @@ func runCreateCmd(cmd *cobra.Command, args []string) error {
return cgapp.ShowError(err.Error())
}

// Cleanup project.
cgapp.RemoveFolders("backend", []string{".git", ".github"})

// Show success report.
cgapp.ShowMessage(
"success",
Expand Down Expand Up @@ -96,66 +93,60 @@ func runCreateCmd(cmd *cobra.Command, args []string) error {
The project's webserver part creation.
*/

if proxy != "none" {
// Copy Ansible roles from embedded file system.
if err := cgapp.CopyFromEmbeddedFS(
&cgapp.EmbeddedFileSystem{
Name: registry.EmbedRoles,
RootFolder: "roles",
SkipDir: false,
},
); err != nil {
return cgapp.ShowError(err.Error())
}

// Copy Ansible playbook, inventory and roles from embedded file system.
if err := cgapp.CopyFromEmbeddedFS(
&cgapp.EmbeddedFileSystem{
Name: registry.EmbedTemplates,
RootFolder: "templates",
SkipDir: true,
},
); err != nil {
return cgapp.ShowError(err.Error())
}
// Copy Ansible playbook, inventory and roles from embedded file system.
if err := cgapp.CopyFromEmbeddedFS(
&cgapp.EmbeddedFileSystem{
Name: registry.EmbedTemplates,
RootFolder: "templates",
SkipDir: true,
},
); err != nil {
return cgapp.ShowError(err.Error())
}

// Set template variables for Ansible playbook and inventory files.
inventory = registry.AnsibleInventoryVariables[proxy].List
playbook = registry.AnsiblePlaybookVariables[proxy].List
// Set template variables for Ansible playbook and inventory files.
inventory = registry.AnsibleInventoryVariables[proxy].List
playbook = registry.AnsiblePlaybookVariables[proxy].List

// Generate Ansible inventory file.
if err := cgapp.GenerateFileFromTemplate("hosts.ini.tmpl", inventory); err != nil {
return cgapp.ShowError(err.Error())
}
// Generate Ansible inventory file.
if err := cgapp.GenerateFileFromTemplate("hosts.ini.tmpl", inventory); err != nil {
return cgapp.ShowError(err.Error())
}

// Generate Ansible playbook file.
if err := cgapp.GenerateFileFromTemplate("playbook.yml.tmpl", playbook); err != nil {
return cgapp.ShowError(err.Error())
}
// Generate Ansible playbook file.
if err := cgapp.GenerateFileFromTemplate("playbook.yml.tmpl", playbook); err != nil {
return cgapp.ShowError(err.Error())
}

// Set unused proxy roles.
if proxy == "traefik" || proxy == "traefik-acme-dns" {
proxyList = []string{"nginx"}
} else if proxy == "nginx" {
proxyList = []string{"traefik"}
}
// Show success report.
cgapp.ShowMessage(
"success",
fmt.Sprintf("Web/Proxy server configuration for `%v` was created!", proxy),
false, false,
)

// Delete unused proxy and/or frontend roles.
cgapp.RemoveFolders("roles", proxyList)
/*
The project's Ansible roles part creation.
*/

// Success messages.
cgapp.ShowMessage(
"success",
fmt.Sprintf("Web/Proxy server configuration for `%v` was created!", proxy),
false, false,
)
cgapp.ShowMessage(
"success",
"Ansible inventory, playbook and roles for deploying was created!",
false, false,
)
// Copy Ansible roles from embedded file system.
if err := cgapp.CopyFromEmbeddedFS(
&cgapp.EmbeddedFileSystem{
Name: registry.EmbedRoles,
RootFolder: "roles",
SkipDir: false,
},
); err != nil {
return cgapp.ShowError(err.Error())
}

// Show success report.
cgapp.ShowMessage(
"success",
"Ansible inventory, playbook and roles for deploying was created!",
false, false,
)

/*
The project's misc files part creation.
*/
Expand All @@ -171,6 +162,23 @@ func runCreateCmd(cmd *cobra.Command, args []string) error {
return cgapp.ShowError(err.Error())
}

/*
Cleanup project.
*/

// Set unused proxy roles.
if proxy == "traefik" || proxy == "traefik-acme-dns" {
proxyList = []string{"nginx"}
} else if proxy == "nginx" {
proxyList = []string{"traefik"}
} else {
proxyList = []string{"traefik", "nginx"}
}

// Delete unused roles and backend files.
cgapp.RemoveFolders("roles", proxyList)
cgapp.RemoveFolders("backend", []string{".git", ".github"})

// Stop timer.
stopTimer := cgapp.CalculateDurationTime(startTimer)
cgapp.ShowMessage(
Expand All @@ -180,13 +188,11 @@ func runCreateCmd(cmd *cobra.Command, args []string) error {
)

// Ending messages.
if proxy != "none" {
cgapp.ShowMessage(
"",
"* Please put credentials into the Ansible inventory file (`hosts.ini`) before you start deploying a project!",
false, false,
)
}
cgapp.ShowMessage(
"",
"* Please put credentials into the Ansible inventory file (`hosts.ini`) before you start deploying a project!",
false, false,
)
if frontend != "none" {
cgapp.ShowMessage(
"",
Expand Down
12 changes: 11 additions & 1 deletion pkg/registry/defaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
)

// CLIVersion version of Create Go App CLI.
const CLIVersion string = "2.0.0"
const CLIVersion string = "2.1.0"

// Variables struct for Ansible variables (inventory, hosts).
type Variables struct {
Expand Down Expand Up @@ -103,6 +103,11 @@ var (

// AnsibleInventoryVariables list of variables for inventory.
AnsibleInventoryVariables = map[string]*Variables{
"none": {
List: map[string]interface{}{
"Proxy": "none",
},
},
"traefik": {
List: map[string]interface{}{
"Proxy": "traefik",
Expand All @@ -124,6 +129,11 @@ var (

// AnsiblePlaybookVariables list of variables for playbook.
AnsiblePlaybookVariables = map[string]*Variables{
"none": {
List: map[string]interface{}{
"Proxy": "none",
},
},
"traefik": {
List: map[string]interface{}{
"Proxy": "traefik",
Expand Down
6 changes: 3 additions & 3 deletions pkg/registry/roles/backend/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
# Build backend Docker container.
#
- name: Build Docker image for backend
docker_image:
community.docker.docker_image:
name: cgapp_backend # name of the backend image
build:
path: "{{ server_dir }}/backend" # folder with Dockerfile
Expand All @@ -36,7 +36,7 @@
# Run backend container (for Traefik Proxy).
#
- name: Run Docker container with backend (for Traefik Proxy)
docker_container:
community.docker.docker_container:
name: cgapp-backend # name of the backend container
image: cgapp_backend:latest
restart_policy: unless-stopped
Expand All @@ -55,7 +55,7 @@
# Run backend container (for Nginx).
#
- name: Run Docker container with backend (for Nginx)
docker_container:
community.docker.docker_container:
name: cgapp-backend # name of the backend container
image: cgapp_backend:latest
restart_policy: unless-stopped
Expand Down
2 changes: 1 addition & 1 deletion pkg/registry/roles/docker/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,5 +53,5 @@
# Create a new Docker network for connect all project elements into one network.
#
- name: Create a new Docker network
docker_network:
community.docker.docker_network:
name: "{{ docker_network }}"
28 changes: 24 additions & 4 deletions pkg/registry/roles/nginx/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,18 +40,38 @@
mode: 0600

#
# Run official Nginx Docker container with specified version.
# Run official Nginx Docker container (for HTTP only) with specified version.
#
- name: Run Nginx container
docker_container:
- name: Run Nginx container (for HTTP)
community.docker.docker_container:
name: cgapp-nginx
image: "nginx:{{ nginx_version }}"
restart_policy: unless-stopped
recreate: true
networks:
- name: "{{ docker_network }}"
ports:
- ["80:80", "{{ '443:443' if nginx_use_only_https == 'yes' }}"]
- "80:80"
volumes:
- "{{ server_dir }}/webserver/nginx.conf:/etc/nginx/nginx.conf:ro"
- "{{ server_dir }}/webserver/default.conf:/etc/nginx/conf.d/default.conf:ro"
when: nginx_use_only_https == 'no'

#
# Run official Nginx Docker container (for HTTPS only) with specified version.
#
- name: Run Nginx container (for HTTPS only)
community.docker.docker_container:
name: cgapp-nginx
image: "nginx:{{ nginx_version }}"
restart_policy: unless-stopped
recreate: true
networks:
- name: "{{ docker_network }}"
ports:
- "80:80"
- "443:443"
volumes:
- "{{ server_dir }}/webserver/nginx.conf:/etc/nginx/nginx.conf:ro"
- "{{ server_dir }}/webserver/default.conf:/etc/nginx/conf.d/default.conf:ro"
when: nginx_use_only_https == 'yes'
52 changes: 52 additions & 0 deletions pkg/registry/roles/postgres/tasks/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Ansible role for deploy the PostgreSQL for the Create Go App project.
# Author: Vic Shóstak <vic@shostak.dev> (https://shostak.dev)
# For more information, please visit https://create-go.app/

---
#
# Create folder for PostgreSQL database.
#
- name: Ensures PostgreSQL dir exists
file:
state: directory
path: "{{ server_dir }}/database"
owner: "{{ server_user }}"
group: "{{ server_group }}"

#
# Run official PostgreSQL Docker container with specified version.
#
- name: Run PostgreSQL container
community.docker.docker_container:
name: cgapp-postgres
image: "postgres:{{ postgres_version }}"
restart_policy: unless-stopped
recreate: true
networks:
- name: "{{ docker_network }}"
ports:
- "{{ postgres_port }}:{{ postgres_port }}"
volumes:
- "{{ server_dir }}/database/data/:/var/lib/postgresql/data"

#
# Make DB migration.
#
- name: Make DB migration
community.docker.docker_container:
name: cgapp-db-migration
image: "migrate/migrate"
recreate: true
networks:
- name: "{{ docker_network }}"
command:
[
"-path",
"/migrations",
"-database",
"postgres://{{ postgres_user }}:{{ postgres_password }}@localhost:{{ postgres_port }}/{{ postgres_db }}?sslmode={{ postgres_ssl_mode }}",
"up",
"{{ migrate_number }}",
]
volumes:
- "{{ server_dir }}/backend/platform/migrations/:/migrations"
30 changes: 30 additions & 0 deletions pkg/registry/roles/redis/tasks/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Ansible role for deploy the Redis for the Create Go App project.
# Author: Vic Shóstak <vic@shostak.dev> (https://shostak.dev)
# For more information, please visit https://create-go.app/

---
#
# Create folder for Redis cache.
#
- name: Ensures Redis dir exists
file:
state: directory
path: "{{ server_dir }}/cache"
owner: "{{ server_user }}"
group: "{{ server_group }}"

#
# Run official Redis Docker container with specified version.
#
- name: Run Redis container
community.docker.docker_container:
name: cgapp-redis
image: "redis:{{ redis_version }}"
restart_policy: unless-stopped
recreate: true
networks:
- name: "{{ docker_network }}"
ports:
- "{{ redis_port }}:{{ redis_port }}"
volumes:
- "{{ server_dir }}/cache/data/:/data"
Loading

0 comments on commit 24f9023

Please sign in to comment.