mirror of https://github.com/doccano/doccano.git
Browse Source
Merge pull request #72 from CatalystCode/feature/azure
Merge pull request #72 from CatalystCode/feature/azure
Feature/Add Azure deployment automationpull/77/head
committed by
GitHub
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 321 additions and 0 deletions
Unified View
Diff Options
-
9README.md
-
27app/server/management/commands/create_admin.py
-
35app/server/management/commands/wait_for_db.py
-
240azuredeploy.json
-
9tools/create-admin.sh
-
1tools/run.sh
@ -0,0 +1,27 @@ |
|||||
|
from django.contrib.auth.management.commands import createsuperuser |
||||
|
from django.core.management import CommandError |
||||
|
|
||||
|
|
||||
|
class Command(createsuperuser.Command): |
||||
|
help = 'Non-interactively create an admin user' |
||||
|
|
||||
|
def add_arguments(self, parser): |
||||
|
super(Command, self).add_arguments(parser) |
||||
|
parser.add_argument('--password', default=None, |
||||
|
help='The password for the admin.') |
||||
|
|
||||
|
def handle(self, *args, **options): |
||||
|
password = options.get('password') |
||||
|
username = options.get('username') |
||||
|
|
||||
|
if password and not username: |
||||
|
raise CommandError('--username is required if specifying --password') |
||||
|
|
||||
|
super(Command, self).handle(*args, **options) |
||||
|
|
||||
|
if password: |
||||
|
database = options.get('database') |
||||
|
db = self.UserModel._default_manager.db_manager(database) |
||||
|
user = db.get(username=username) |
||||
|
user.set_password(password) |
||||
|
user.save() |
@ -0,0 +1,35 @@ |
|||||
|
import sys |
||||
|
import time |
||||
|
|
||||
|
from django.db import connection |
||||
|
from django.db.utils import OperationalError |
||||
|
from django.core.management.base import BaseCommand |
||||
|
|
||||
|
|
||||
|
class Command(BaseCommand): |
||||
|
help = 'Blocks until the database is available' |
||||
|
|
||||
|
def add_arguments(self, parser): |
||||
|
parser.add_argument('--poll_seconds', type=float, default=3) |
||||
|
parser.add_argument('--max_retries', type=int, default=60) |
||||
|
|
||||
|
def handle(self, *args, **options): |
||||
|
max_retries = options['max_retries'] |
||||
|
poll_seconds = options['poll_seconds'] |
||||
|
|
||||
|
for retry in range(max_retries): |
||||
|
try: |
||||
|
connection.ensure_connection() |
||||
|
except OperationalError as ex: |
||||
|
self.stdout.write( |
||||
|
'Database unavailable on attempt {attempt}/{max_retries}:' |
||||
|
' {error}'.format( |
||||
|
attempt=retry + 1, |
||||
|
max_retries=max_retries, |
||||
|
error=ex)) |
||||
|
time.sleep(poll_seconds) |
||||
|
else: |
||||
|
break |
||||
|
else: |
||||
|
self.stdout.write(self.style.ERROR('Database unavailable')) |
||||
|
sys.exit(1) |
@ -0,0 +1,240 @@ |
|||||
|
{ |
||||
|
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", |
||||
|
"contentVersion": "1.0.0.0", |
||||
|
"parameters": { |
||||
|
"appName":{ |
||||
|
"type": "string", |
||||
|
"minLength": 1, |
||||
|
"metadata": { |
||||
|
"description": "The name for the webapp. Must be globally unique." |
||||
|
} |
||||
|
}, |
||||
|
"secretKey":{ |
||||
|
"type": "securestring", |
||||
|
"minLength": 16, |
||||
|
"metadata": { |
||||
|
"description": "The value to use as the Django secret key." |
||||
|
} |
||||
|
}, |
||||
|
"adminUserName":{ |
||||
|
"type": "string", |
||||
|
"minLength": 1, |
||||
|
"metadata": { |
||||
|
"description": "The user name for the admin account." |
||||
|
} |
||||
|
}, |
||||
|
"adminContactEmail":{ |
||||
|
"type": "string", |
||||
|
"minLength": 1, |
||||
|
"metadata": { |
||||
|
"description": "The contact email address for the admin account." |
||||
|
} |
||||
|
}, |
||||
|
"adminPassword":{ |
||||
|
"type": "securestring", |
||||
|
"minLength": 16, |
||||
|
"metadata": { |
||||
|
"description": "The password for the admin account." |
||||
|
} |
||||
|
}, |
||||
|
"appServiceSku": { |
||||
|
"type": "string", |
||||
|
"defaultValue": "B2", |
||||
|
"allowedValues": [ |
||||
|
"B1", |
||||
|
"B2", |
||||
|
"B3", |
||||
|
"S1", |
||||
|
"S2", |
||||
|
"S3" |
||||
|
], |
||||
|
"metadata": { |
||||
|
"description": "The SKU of the webapp hosting tier." |
||||
|
} |
||||
|
}, |
||||
|
"databaseCores": { |
||||
|
"type": "int", |
||||
|
"defaultValue": 2, |
||||
|
"allowedValues": [ |
||||
|
2, |
||||
|
4, |
||||
|
8, |
||||
|
16, |
||||
|
32, |
||||
|
64 |
||||
|
], |
||||
|
"metadata": { |
||||
|
"description": "The number of vCores to provision for the PostgreSQL server." |
||||
|
} |
||||
|
}, |
||||
|
"databaseSize": { |
||||
|
"type": "int", |
||||
|
"minValue": 51200, |
||||
|
"defaultValue": 51200, |
||||
|
"metadata": { |
||||
|
"description": "The storage capacity to provision for the PostgreSQL server." |
||||
|
} |
||||
|
}, |
||||
|
"databaseName": { |
||||
|
"type": "string", |
||||
|
"minLength": 1, |
||||
|
"defaultValue": "doccano", |
||||
|
"metadata": { |
||||
|
"description": "The name of the database to provision on the PostgreSQL server." |
||||
|
} |
||||
|
}, |
||||
|
"dockerImageName": { |
||||
|
"type": "string", |
||||
|
"minLength": 1, |
||||
|
"defaultValue": "cwolff/doccano:latest", |
||||
|
"metadata": { |
||||
|
"description": "The Docker image to deploy." |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
"variables": { |
||||
|
"location": "[resourceGroup().location]", |
||||
|
"databaseSkuTier": "GeneralPurpose", |
||||
|
"databaseSkuFamily": "Gen5", |
||||
|
"databaseSkuName": "[concat('GP_', variables('databaseSkuFamily'), '_', parameters('databaseCores'))]", |
||||
|
"databaseConnectionString": "[concat('pgsql://', parameters('adminUserName'), '@', variables('databaseServerName'), ':', parameters('adminPassword'), '@', variables('databaseServerName'), '.postgres.database.azure.com:5432/', parameters('databaseName'))]", |
||||
|
"databaseVersion": "9.6", |
||||
|
"databaseServerName": "[concat(parameters('appName'),'-state')]", |
||||
|
"setupScriptName": "[concat(parameters('appName'),'-setup')]", |
||||
|
"appServicePlanName": "[concat(parameters('appName'),'-hosting')]", |
||||
|
"env": [ |
||||
|
{ |
||||
|
"name": "WEBSITES_ENABLE_APP_SERVICE_STORAGE", |
||||
|
"value": "false" |
||||
|
}, |
||||
|
{ |
||||
|
"name": "DEBUG", |
||||
|
"value": "False" |
||||
|
}, |
||||
|
{ |
||||
|
"name": "SECRET_KEY", |
||||
|
"value": "[parameters('secretKey')]" |
||||
|
}, |
||||
|
{ |
||||
|
"name": "DATABASE_URL", |
||||
|
"value": "[variables('databaseConnectionString')]" |
||||
|
} |
||||
|
] |
||||
|
}, |
||||
|
"resources": [ |
||||
|
{ |
||||
|
"apiVersion": "2017-08-01", |
||||
|
"type": "Microsoft.Web/serverfarms", |
||||
|
"kind": "linux", |
||||
|
"name": "[variables('appServicePlanName')]", |
||||
|
"location": "[variables('location')]", |
||||
|
"properties": { |
||||
|
"reserved": true |
||||
|
}, |
||||
|
"dependsOn": [], |
||||
|
"sku": { |
||||
|
"name": "[parameters('appServiceSku')]" |
||||
|
} |
||||
|
}, |
||||
|
{ |
||||
|
"apiVersion": "2017-12-01", |
||||
|
"type": "Microsoft.DBforPostgreSQL/servers", |
||||
|
"location": "[variables('location')]", |
||||
|
"name": "[variables('databaseServerName')]", |
||||
|
"sku": { |
||||
|
"name": "[variables('databaseSkuName')]", |
||||
|
"tier": "[variables('databaseSkuTier')]", |
||||
|
"family": "[variables('databaseSkuFamily')]", |
||||
|
"capacity": "[parameters('databaseCores')]", |
||||
|
"size": "[parameters('databaseSize')]" |
||||
|
}, |
||||
|
"properties": { |
||||
|
"version": "[variables('databaseVersion')]", |
||||
|
"administratorLogin": "[parameters('adminUserName')]", |
||||
|
"administratorLoginPassword": "[parameters('adminPassword')]", |
||||
|
"storageMB": "[parameters('databaseSize')]" |
||||
|
}, |
||||
|
"resources": [ |
||||
|
{ |
||||
|
"name": "allowAzure", |
||||
|
"type": "firewallrules", |
||||
|
"apiVersion": "2017-12-01", |
||||
|
"location": "[variables('location')]", |
||||
|
"properties": { |
||||
|
"startIpAddress": "0.0.0.0", |
||||
|
"endIpAddress": "0.0.0.0" |
||||
|
}, |
||||
|
"dependsOn": [ |
||||
|
"[resourceId('Microsoft.DBforPostgreSQL/servers/', variables('databaseServerName'))]" |
||||
|
] |
||||
|
}, |
||||
|
{ |
||||
|
"name": "[parameters('databaseName')]", |
||||
|
"type": "databases", |
||||
|
"apiVersion": "2017-12-01", |
||||
|
"properties": { |
||||
|
"charset": "utf8", |
||||
|
"collation": "English_United States.1252" |
||||
|
}, |
||||
|
"dependsOn": [ |
||||
|
"[resourceId('Microsoft.DBforPostgreSQL/servers/', variables('databaseServerName'))]" |
||||
|
] |
||||
|
} |
||||
|
] |
||||
|
}, |
||||
|
{ |
||||
|
"name": "[variables('setupScriptName')]", |
||||
|
"type": "Microsoft.ContainerInstance/containerGroups", |
||||
|
"apiVersion": "2018-10-01", |
||||
|
"location": "[variables('location')]", |
||||
|
"properties": { |
||||
|
"containers": [ |
||||
|
{ |
||||
|
"name": "createadmin", |
||||
|
"properties": { |
||||
|
"image": "[parameters('dockerImageName')]", |
||||
|
"command": [ |
||||
|
"tools/create-admin.sh", |
||||
|
"[parameters('adminUserName')]", |
||||
|
"[parameters('adminContactEmail')]", |
||||
|
"[parameters('adminPassword')]" |
||||
|
], |
||||
|
"environmentVariables": "[variables('env')]", |
||||
|
"resources": { |
||||
|
"requests": { |
||||
|
"cpu": "1", |
||||
|
"memoryInGb": "1.5" |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
], |
||||
|
"osType": "Linux", |
||||
|
"restartPolicy": "Never" |
||||
|
}, |
||||
|
"dependsOn": [ |
||||
|
"[resourceId('Microsoft.DBforPostgreSQL/servers/', variables('databaseServerName'))]" |
||||
|
] |
||||
|
}, |
||||
|
{ |
||||
|
"type": "Microsoft.Web/sites", |
||||
|
"apiVersion": "2016-08-01", |
||||
|
"name": "[parameters('appName')]", |
||||
|
"kind": "app,linux,container", |
||||
|
"location": "[variables('location')]", |
||||
|
"dependsOn": [ |
||||
|
"[resourceId('Microsoft.DBforPostgreSQL/servers/', variables('databaseServerName'))]", |
||||
|
"[resourceId('Microsoft.Web/serverfarms', variables('appServicePlanName'))]" |
||||
|
], |
||||
|
"properties": { |
||||
|
"name": "[parameters('appName')]", |
||||
|
"siteConfig": { |
||||
|
"linuxFxVersion": "[concat('DOCKER|', parameters('dockerImageName'))]", |
||||
|
"alwaysOn": true, |
||||
|
"appSettings": "[variables('env')]" |
||||
|
}, |
||||
|
"serverFarmId": "[resourceId('Microsoft.Web/serverfarms', variables('appServicePlanName'))]" |
||||
|
} |
||||
|
} |
||||
|
] |
||||
|
} |
@ -0,0 +1,9 @@ |
|||||
|
#!/usr/bin/env bash |
||||
|
|
||||
|
if [[ "$#" -ne 3 ]]; then echo "Usage: $0 <username> <email> <password>" >&2; exit 1; fi |
||||
|
|
||||
|
set -o errexit |
||||
|
|
||||
|
python app/manage.py wait_for_db |
||||
|
python app/manage.py migrate |
||||
|
python app/manage.py create_admin --noinput --username="$1" --email="$2" --password="$3" |
Write
Preview
Loading…
Cancel
Save