Using different databases for development vs production Flask - flask

I have a flask app that uses a different database based on production vs development environment variables. I am worried about a developer forgetting to set FLASK_ENV=development before running their local flask app, and suddenly they are making updates to a production database.
My only easy solution I have thought of is restricting the production DB to only accept requests from the production server IP so that way everything will error out if the developer forgets to set the environment variable, but I was wondering if there are better solutions for this issue.

First of all, it is a good practice to limit access to your production database to trusted IPs only.
As you can read in Configuration Handling: Development/Production (Flask Docs), you can have multiple configurations and use inheritance.
class Config(object):
DATABASE_URI = 'sqlite:///:memory:'
class ProductionConfig(Config):
DATABASE_URI = 'mysql://user#localhost/foo'
class DevelopmentConfig(Config):
pass
You can load, all the time, the default configuration that is safe. Only if the production environment variable is set, the real database configuration will be loaded.
Another solution is to use the instance folder (Flask Docs) that mustn't be a part of your git repository.
The instance folder is designed to not be under version control and be deployment-specific.
So, when you deploy your app, just add your production configuration to this instance folder, and nobody would have the prod configuration on their local machine.
They have a few examples and explain very well how to use it in the link that I gave you above.

You can prewrite the environment variables in .flaskenv:
FLASK_ENV=development
Then install python-dotenv:
pip install python-dotenv
Now if you run your application locally with flask run, Flask will automatically read the .flaskenv and set the environment variables in it.

Related

Env vars and Docker differences between dev, staging, and prod

Although my specific example involves Django, Docker, and Heroku, I believe these are pretty general testing/QA questions.
I have a dockerized Django app tested in dev with Selenium confirming that my static files are being served correctly from my local folder (EXPECTED_ROOT = '/staticfiles/'). This app is deployed to Heroku and I can see (visually and in the dev tools) that the static files are being pulled in from CloudFront correctly as well. I want to formalize this with the same test I'm using in dev. My first question is related to if/how environment variables are used for tests:
Do I add for example EXPECTED_ROOT = 'https://<somehash>.cloudfront.net/' as an env var to Heroku and use it in the Selenium test?
Also, to run this test in staging I would need to install Firefox in my Docker image like I do in dev. Perhaps this is ok in staging, but in prod I believe I should be aiming for the the smallest image possible. So the question is about differences between staging and prod:
Do I keep Firefox in my staging image, run the tests, and then send
to production a replica of that Dockerfile, but now without firefox?
Any help is appreciated.
The idea of Config Var is to setup configuration variables that differ from environment to environment. Having said that you are in control of the environment and can define what you need.
I personally would use a different approach: create a test that is independent of the environment (for example instead of testing the expected root I would confirm a given DIV ID is found, or some other element).
This would be enough to confirm the test is successful and the functionality works as expected.
The production Dockerfile indeed does not need Selenium and can be different from the one from staging.

Elastic Beanstalk with development and production environment?

I made a Django project and have successfully deployed it to an Elastic Beanstalk environment, let's say it's called app_name. However, I realized I needed 2 environments: development and production. The purpose of this is so I can try things out in development, and when I know it's fully working, I can deploy it in production for the public to use.
I tried looking around their documentations and found Managing multiple Elastic Beanstalk environments as a group with the EB CLI . It basically says you can create a group of environments in one project with the command:
~/workspace/project-name$ eb create --modules component-a component-b --env-group-suffix group-name
However, I'm not sure what a group means. I mean, I just need a development and production environment.
I'm fairly new at this. How do I create and manage development and production environments for this purpose? I would ever be so grateful if someone were to shed some light to my problem.
Running a group of environments is more for different services doing different things. You would have an environment that handles Service One, and an environment that handles Service Two etc. This isn't really what you want.
You just need an environment in the same application as your production environment. It doesn't have to be in the same application but I like it that way because its useful for deploying an app version to dev, and then deploy the app version to prod once it's tested.
An easy way to do this is run
eb clone app_name (where app_name is the name of your production environment)
This will clone your production environment and prompt you to give it a name, which you might set to app_name_dev. From there you can edit your dev environment to make it more suitable for dev (maybe you'd make the instances smaller, change software variables like MAIL_DRIVER=mailgun to MAIL_DRIVER=mailtrap, connect it to a dev database instead of your prod database, etc)
The downside of doing this would be if your production environment is currently running jobs or doing anything meaningful, you may not want to clone it right away since the new dev environment could start doing these things too, before you manage to update its config to point to a dev DB etc! If this is the case, you would just run eb create my_app_dev and configure it from scratch.

Creating a virtualenv with already created django app

I am trying to deploy my django app in to production on a centos server. I have an app running on my computer(not server) with a code repository that doesn't utilize a virtual environment, and i wish i had set that up to begin with. I would like the production stage of the django app be run with a virtual environment, and was wondering what was the best way to go about this.
I am very cloudy on how this would work out. Would i need to set up the django app on my computer with a virtual environment, and then move the code repository to the server and go about it that way?
My understanding is the purpose of the virtual environment is to keep tabs and easily install any dependecies and software updates need to run the django app.
So the question is: Should i not worry about setting up a virtual environment on my computer, but start one on my server and start from there? Or would i run into problems when i try to git clone my project to the server because there isnt a virtualenv setup from the repository.
And if i should have it setup up on my local django app on my computer, how to i go about setting it up on an existing webapp?
The app doesn't care whether it's running in a virtualenv or not. You can simply create a new virtualenv on the server and redeploy the app inside it, reinstall the dependencies, then point your web server at the new app.

What do I need to do in preparation for cloning a django repository?

Assuming the django project repository is on github and I have had no interaction with it previously.
So: I cd to a new directory on my computer.
I clone the repository.
If the django project is using postgresql, do I have to have postgresql installed on my local machine?
Do I have to be running in a virtual environment to use a specific interpreter?
Thanks Peter
Database
You can actually use another database on your local copy if you choose, although in general it's a good idea to use the same database locally.
If you're going to be using postgres locally, yes you'll need to install it and then create your local database. Once you have your local database setup, you'll need to change some config values of your DATABASES property in settings.
Packages
Your project will also have some dependencies which should be listed in a requirements.txt file at the root directory. If it is not, you'll need to find out which packages need to be installed via pip freeze in the production console.
Virtual Env
You should use a virtual environment, but it's not completely necessary to get your project up and running. Virtualenvs allow you to have different installs and runtimes for different projects.
Other
Every project is different, and there will most likely be some other things that pop up. However, this should get you going in the right direction.

Setting up the environment for django development and deployment(nginx/gunicorn/git/south/fabric)

Let's imagine I have nginx+gunicorn set up and running already. How do I set up git for deployment from local testing to remote production server?
I need instructions like these, but a bit more detailed and with some possible advice about using this with gunicron and nginx
Here you are..https://github.com/jacobian/django-deployment-workshop