Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature: Added generate-compose script. #295

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Mandatory settings to set
EXTERNAL_HOST = localhost.localdomain
ZULIP_ADMINISTRATOR_EMAIL = [email protected]

# Optional secrets to set
POSTGRES_PASSWORD = REPLACE_WITH_SECURE_POSTGRES_PASSWORD
MEMCACHED_PASSWORD = REPLACE_WITH_SECURE_MEMCACHED_PASSWORD
RABBITMQ_PASSWORD = REPLACE_WITH_SECURE_RABBITMQ_PASSWORD
REDIS_PASSWORD = REPLACE_WITH_SECURE_REDIS_PASSWORD
secret_key = REPLACE_WITH_SECURE_SECRET_KEY
22 changes: 11 additions & 11 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ services:
# Note that you need to do a manual `ALTER ROLE` query if you
# change this on a system after booting the postgres container
# the first time on a host. Instructions are available in README.md.
POSTGRES_PASSWORD: 'REPLACE_WITH_SECURE_POSTGRES_PASSWORD'
POSTGRES_PASSWORD: '${POSTGRES_PASSWORD}'
volumes:
- '/opt/docker/zulip/postgresql/data:/var/lib/postgresql/data:rw'
memcached:
Expand All @@ -24,15 +24,15 @@ services:
environment:
SASL_CONF_PATH: '/home/memcache/memcached.conf'
MEMCACHED_SASL_PWDB: '/home/memcache/memcached-sasl-db'
MEMCACHED_PASSWORD: 'REPLACE_WITH_SECURE_MEMCACHED_PASSWORD'
MEMCACHED_PASSWORD: '${MEMCACHED_PASSWORD}'
restart: always
rabbitmq:
image: 'rabbitmq:3.7.7'
hostname: zulip-rabbit
restart: always
environment:
RABBITMQ_DEFAULT_USER: 'zulip'
RABBITMQ_DEFAULT_PASS: 'REPLACE_WITH_SECURE_RABBITMQ_PASSWORD'
RABBITMQ_DEFAULT_PASS: '${RABBITMQ_PASSWORD}'
volumes:
- '/opt/docker/zulip/rabbitmq:/var/lib/rabbitmq:rw'
redis:
Expand All @@ -44,7 +44,7 @@ services:
echo "requirepass '$$REDIS_PASSWORD'" > /etc/redis.conf
exec redis-server /etc/redis.conf
environment:
REDIS_PASSWORD: 'REPLACE_WITH_SECURE_REDIS_PASSWORD'
REDIS_PASSWORD: '${REDIS_PASSWORD}'
volumes:
- '/opt/docker/zulip/redis:/data:rw'
zulip:
Expand All @@ -71,13 +71,13 @@ services:
SECRETS_email_password: '123456789'
# These should match RABBITMQ_DEFAULT_PASS, POSTGRES_PASSWORD,
# MEMCACHED_PASSWORD, and REDIS_PASSWORD above.
SECRETS_rabbitmq_password: 'REPLACE_WITH_SECURE_RABBITMQ_PASSWORD'
SECRETS_postgres_password: 'REPLACE_WITH_SECURE_POSTGRES_PASSWORD'
SECRETS_memcached_password: 'REPLACE_WITH_SECURE_MEMCACHED_PASSWORD'
SECRETS_redis_password: 'REPLACE_WITH_SECURE_REDIS_PASSWORD'
SECRETS_secret_key: 'REPLACE_WITH_SECURE_SECRET_KEY'
SETTING_EXTERNAL_HOST: 'localhost.localdomain'
SETTING_ZULIP_ADMINISTRATOR: '[email protected]'
SECRETS_rabbitmq_password: '${RABBITMQ_PASSWORD}'
SECRETS_postgres_password: '${POSTGRES_PASSWORD}'
SECRETS_memcached_password: '${MEMCACHED_PASSWORD}'
SECRETS_redis_password: '${REDIS_PASSWORD}'
SECRETS_secret_key: '${secret_key}'
SETTING_EXTERNAL_HOST: '${EXTERNAL_HOST}'
SETTING_ZULIP_ADMINISTRATOR: '${ZULIP_ADMINISTRATOR_EMAIL}'
SETTING_EMAIL_HOST: '' # e.g. smtp.example.com
SETTING_EMAIL_HOST_USER: '[email protected]'
SETTING_EMAIL_PORT: '587'
Expand Down
44 changes: 44 additions & 0 deletions scripts/generate_env_file.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
from io import StringIO
import os
import configparser
import secrets

def read_example_env():
file_to_read = None
if os.path.isfile('.env'):
file_to_read = '.env'
else:
file_to_read = '.env.example'

dummy_config = StringIO()
dummy_config.write('[dummy]\n')
dummy_config.write(open(file_to_read).read())
dummy_config.seek(0, os.SEEK_SET)

cp = configparser.ConfigParser()
cp.read_file(dummy_config)
return cp['dummy']

def set_if_expected(env, key, expected, value):
if env[key] == expected:
env[key] = value

def generate_and_set_secrets(env):
set_if_expected(env, 'POSTGRES_PASSWORD', 'REPLACE_WITH_SECURE_POSTGRES_PASSWORD', secrets.token_hex(32))
set_if_expected(env, 'MEMCACHED_PASSWORD', 'REPLACE_WITH_SECURE_MEMCACHED_PASSWORD', secrets.token_hex(32))
set_if_expected(env, 'RABBITMQ_PASSWORD', 'REPLACE_WITH_SECURE_RABBITMQ_PASSWORD', secrets.token_hex(32))
set_if_expected(env, 'REDIS_PASSWORD', 'REPLACE_WITH_SECURE_REDIS_PASSWORD', secrets.token_hex(32))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do these entropy amounts match what's used in generate_secrets.py? If so, we should have a comment saying so.

set_if_expected(env, 'secret_key', 'REPLACE_WITH_SECURE_SECRET_KEY', ''.join(secrets.choice('abcdefghijklmnopqrstuvwxyz0123456789!@#$^&*(-_=+)') for i in range(50)))

def write_env(env):
env_file = ''
for key in env:
env_file = f'{env_file}{key}={env[key]}\n'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is probably cleaner written using a more natural append code; I found this hard to read.


f = open('.env', 'w')
f.write(env_file)
f.close()

env = read_example_env()
generate_and_set_secrets(env)
write_env(env)