Docker container allows you to run your development environment completely in the background.
Currently, docker-compose starts three containers:
webthat holds node.js web applicationmongodbthat runs MongoDBredisthat runs Redis service
Internally, docker setup separate network with own DNS so it is possible to use container names as the hostnames, e.g. http://web:3000/ URI is accessible from mongodb and redis containers. The containers expose defined ports outside on the host machine, e.g, web container expose port 9080 so you can open http://localhost:9080/ on your local web browser.
- Mac OS: https://docs.docker.com/docker-for-mac/ (
docker-composeis already included) - Ubuntu:
- First, clone this repository to your computer with
git clone git@github.com:schemadesign/gist.git
Environment-related secrets such as the production password database are not committed to this repository as a security-related best practice.
In order to add them (and to support both local development and production deployment) you need to create two files named ".env.development" and ".env.production" in 'config/env/' of this repository at gist/config/env/.env* and then fill them respectively with the content which you can find in the EXAMPLE.env. It is necessary to fulfil S3 credentials (first four rows) either from the AWS S3 or from the Digital Ocean Space, also Mapbox to make world map working.
- Run
make develop-build
- Open
seed.jsonand make sure it is configured with your local database name - Execute
make develop-seed-db-- the data inseeds/views.jsonwill be saved into your database.
Edit seeds/views.json when you want to edit the views config, then execute make develop-seed-db to save into the database. Commit seeds/views.json to Git so everyone can use your updated views.
- Run
make develop-startto start development server in non-daemon mode with logs.
- Add app.local.arrays.co:
- Run
sudo nano /etc/hosts- You should see some numbers including your local ip address on the left column and host names on the right. - Add a new line
127.0.0.1 app.local.arrays.cofor the frontend - Add another new line
127.0.0.1 local.arrays.cofor the mongodb connection - Save the write changes with "control" + "o"
- Hit "enter"
- Exit with "control" + "x"
After the app is up and running you will want to create a user:
-
Access http://app.local.arrays.co:9080/signup/email?superUser=true (If you don't see a form please make command
make develop-grunt) -
Fill the form in and add a subdomain
- The subdomain must be listed in the hosts file (more details in point IX)
- email must be youremail+superuser@schemadesign.com (if you don't have an email address in the schemadesign.com domain then please update the domain in the code to one of your choices)
-
After confirming you will see an email template in the logs of the backend. Look for an URL with a token.
-
Copy and paste the URL to activate your user.
-
Now you can login in Gist.
- Add your subdomain to hosts
- Run
sudo nano /etc/hostsagain. - Add a new line
127.0.0.1 [your team subdomain].local.arrays.co - Save the write changes with control + "o"
- Hit "enter"
- Exit with "control" + "x"
- You will now be able to navigate to your subdomain at [your team subdomain].local.arrays.co:9080 Anytime you add a new account in Gist, you will have a new subdomain. In order for that subdomain to work locally, you have to add it to your hosts file by repeating step 3.
- Digital Ocean configuration:
- Create a droplet with Docker
- Create or have a domain (Gist uses subdomains and it won't work on the IP address) and add the Digital Ocean Network with DNSs which direct to your Droplet:
<your_domain>app.<your_domain>*.<your_domain>
- Generate new API key in the API tab for the spaces
- Create spaces and add CORS privileges for origin
http(s)://app.<your_domain>for all methods and add Header*.
- Create a Mapbox account. Gist is using Mapbox to render world map.
- Create access key
- Create a basic layout to show a map containing countries only
- Create a roads layout to show a map containing roads only
- Add files and changes in the code
- Find all occurrences of
gist.infoin the code and replace with your domain - To create the first user we need to configure emails in the file
nodemailer.jsto get activation email or we will see this email on docker logs, but we need to change all occurrences of@schemadesign.comemail to your email domain. - Add
env.productionfile in theconfig/envusingExmaple.envas an example and replace:- DO_ACCESS_KEY_ID=(digital ocean key id)
- DO_SECRET_ACCESS_KEY=(digital ocean access key)
- DO_S3_BUCKET=(digital ocean space name)
- DO_S3_ENDPOINT=(digital ocean space endpoint for example
nyc3.digitaloceanspaces.com, also please find this url in the code and replace to your endpoint) - MAPBOX_ACCESS_KEY=(your Mapbox access token)
- MAPBOX_BASIC_LAYOUT=(URL of the basic layout)
- MAPBOX_ROADS_LAYOUT=(URL of the basic layout)
- FONT_CENTRANO_CDN=(URL to the Centra No font, or you can leave it empty and put the font in the folder
public/fonts/centrano2. You can also replace font in thepublic/stylesheets/base/typography/font-faces.cssand later replace all occurrences of the centrano2) - HOST=(your domain)
- SUBDOMAIN=(your main subdomain)
- NODE_ENV=production
- MONGODB_URI=mongodb://login:password@mongodb:27017/arraysdb?authSource=admin&readPreference=primary&appname=MongoDB%20Compass&ssl=false (please replace login and password with you credentials which will be used by the admin user in mongodb)
- USE_SSL=(
trueif your domain has SSL connection,falseif your domain doesn't have SSL) - PORT=(
443if your domain has SSL connection,80if your domain doesn't have SSL)
- Connect to your droplet for example via ssh and deploy code there.
- Build the app by running commands:
make buildmake develop-seed-dbmake start
- Configure MongoDB
- open the terminal and enter
mongodbcontainer with commanddocker-compose exec -e COLUMNS=222 mongodb bash - enter mongo shell with command
mongo - switch to admin db with command
use admin - create admin user with command
db.createUser({user: "your-login", pwd: "your-password", roles: [ { role: "readWrite", db: “admin”} ] })(please replace login and password with your credentials which you put in theMONGODB_URI)
- Restart the app with commands
make stopandmake start
- Enter URL
http://app.<your-domain>/signup/email?superUser=trueand fill the data (if you don't see anything please run the commandmake develop-grunt). Please use as email+superuser@schemadesign.comor if you replaced to your email domain, with your domain+superuser@<your-domain> - In the docker logs you should see an email activation with the URL to activate account. If not you can also activate a user in the mongo shell by changing
activatedtotrue.
Map *.local.arrays.co to localhost, so new teams and subdomains do not have to be manually added to /etc/hosts every time.
Install dnsmasq:
brew install dnsmasq
Add *.local.arrays.co to config file:
echo 'address=/.local.arrays.co/127.0.0.1' > $(brew --prefix)/etc/dnsmasq.conf
Add to resolvers:
sudo bash -c 'echo "nameserver 127.0.0.1" > /etc/resolver/local.arrays.co'
if you do not have /etc/resolver, simply create it by mkdir /etc/resolver
Start dnsmasq and run on boot:
sudo brew services start dnsmasq
- Run
make test
This will run all fronted and backend tests in the container.
-
Gist Integration tests are kept here
-
Run
npm installto prepare all files and then -
Run
npm run test:backendfor backend tests andnpm run test:frontendfor frontend tests.
Make commands in development environment
developRun development servicesdevelop-startRun development services & logsdevelop-statusShow the status of services.develop-logsShow the logs on the terminal from web container.develop-stopStop the containers.develop-restartRestart the containers.develop-buildRebuild web container.develop-build-nocachebuild web container (no cache)develop-restart-noderestart node inside the containerdevelop-seed-dbSeed database (npm run seed).develop-exec-bashRun bash in the web container.
Make commands for testing
testrun tests intestingenviroment
Misc commands
run-debuggerstop the development web container and run again with debug mode (see below)stop-allstop all containerlint-fixfor running JS linter.
make run-debugger
This will stop the web container and run it again, exposing debugger port 9229 and run in non daemon mode (all logs in the terminal) with a single worker.
Keep in mind if you run your app in the debugger mode, you cannot use other make develop-* commands.
You can stop the debug-mode by Ctrl+C;
- Click
Debugbutton in VS code. - Set the
configuration:
{
"type": "node",
"request": "attach",
"name": "Docker: Attach to Node",
"port": 9229,
"address": "localhost",
"localRoot": "${workspaceFolder}",
"remoteRoot": "/src",
"protocol": "inspector"
}This is usually related to the fact that two node instances tries to bind the same port. The simple solution is to stop the command and run it again with Ctrl+C;
You can also check if the web container is running with docker ps command.
-
The Gist app loads AWS credentials from the .env files. There are quite a few ways that AWS credentials can be loaded, and they exist in a provider chain. Keep this in mind if you're running into AWS related issues: you may be unintentionally overriding the credentials.
-
If you are seeing errors related to the
sharpnode package, try this:- Change directory (
cd [the path to]/gist/node_modules/sharp) into thesharpdirectory of your local clone of this repository - Run
npm install
- Change directory (
-
By default the mongodb and redis containers exposes locally the ports (27017 and 6379 respectively). If you try to start again containers, you get the following error:
ERROR: for mongodb Cannot start service mongodb: driver failed programming external connectivity on endpoint arraystesting_mongodb_1 (0d0b754cd4c943ccdc051b14a38cde0a11c65409f9d3916395a1905d55ebd024): Bind for 0.0.0.0:27017 failed: port is already allocatedYou have to kill the containers that already use the ports, e.g.
docker kill $(docker ps -q)to kill all containers.By default the testing containers does not expose ports to mongodb and redis. However, you can add this by editing
docker-compose.test.ymland enabling lines with- ports:. -
Problem with existing container name:
ERROR: for mongodb Cannot create container for service mongodb: Conflict. The container name "/mongodb" is already in use by container "86e6470e1e7dd82e798fa677cfc210c4aac0d749e68f5907123f6c005fea71b2". You have to remove (or rename) that container to be able to reuse that name.Check the containers that runs already by
docker psand kill container with the same name. -
Travis stops because of wrong encryption key
If your travis-ci build returns following error:
$ openssl aes-256-cbc -K $encrypted_29d90a842206_key -iv $encrypted_29d90a842206_iv -in .env.testing.enc -out config/env/.env.testing -d bad decrypt 140444667311776:error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt:evp_enc.c:539: The command "openssl aes-256-cbc -K $encrypted_29d90a842206_key -iv $encrypted_29d90a842206_iv -in .env.testing.enc -out config/env/.env.testing -d"then you have to recreate
.env.testing.incfile that holds the content ofconfig/env/.env.testing1. Run `travis encrypt-file config/env/.env.testing` 2. Edit `.travis.yml` and replace line in `before_install:` which starts of `- openssl` with the line returned by the `travis` command. -
Running or building container cause unexpected errors related to wrong .json files
- Run the build process without cache
make develop-build-nocacheormake test-build-nocache.
- Run the build process without cache
-
Travis fails with a nonsense error - how to live?
This can happen from time to time. If your tests run correctly on your local machine (via
make testcommand) then you have to debug the problem directly in the travis service. To do that you can use Debug build available on the page with the task. Reference: https://docs.travis-ci.com/user/running-build-in-debug-mode/ -
Clean up your local docker environment
You can use script
bin/cleanup-docker.sh. -
Error from trying to seed db:
err = { MongoError: failed to connect to server [undefined:27017] on first connect [MongoError: getaddrinfo ENOTFOUND undefined undefined:27017]include the node environment in run seed command
NODE_ENV=development npm run seed