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

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.

Related

Using different databases for development vs production 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.

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.

Django local development, remote test and production configuration

I'm writing some django apps and I have this setup:
local machine (laptop) that I use for development, with local dev
virtualenv
remote machine VPS (with public address) used for test. I
need to have some end-users testing my app before moving to prod
with test virtualenv
remote machine VPS (with public address, same as
above) used for production with production virtualenv
I use git for versioning.
The idea that I have so far (after reading various tutorials) to manage everything is:
develop on local machine new branch
push branch to git
deploy branch into test virtualenv
test it
test passed, push branch to master and deploy into production
virtualenv
And I have lot of questions about this:
is this a recommended approach?
how can I get the new branch to test virtualenv and not to production? Do I need to have two separate app folders, one for prod and one for test?
How can I then move code from test to prod?
Thanks in advance, I'm a django/git novice so I'm trying to approach it in the best way from start.
It seems almost right to me (but there are many strategies),
I'd make a testing-branch, so you could continue pushing to develop-branch while others are testing the test-branch. Then when it passes the test merge to Master.
(Also, if you want to make your live easier, use fab files to 'pull' on the remote machine.)

Re-build files in Ember-CLI without running server

I am planning on moving from "EmberJS" to the Ember-cli, though I have a small problem. Is it possible only to run file watcher instead of serving/using ember serve that will run local server? As I am running my PHP backend on the Google App Script I have already a local python HTTP server running in localhost:8080 I do not need another one to run in localhost:4200
If I don't run ember serve my local changes in development environment wont get updated. Is there a better way of doing this? Is it possible to use assets in the app folder when running in development environment? and use dist folder for staging/live environments?
As mentioned in the guide, you can use the build command with the --watch flag.
ember build --watch
That will keep rebuilding your changes but not actually run the server.
As for your second question:
Is it possible to use assets in the app folder when running in development environment? and use dist folder for staging/live environments?
I don't believe so. You can change the output-path property in your .ember-cli config file, but you can't have one that's specific to a certain environment. You could always write a quick script to move the files though. :)

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