From https://www.codeschool.com/screencasts/build-a-node-app-with-postgres-and-docker # Step 1: Nginx * Run nginx * in foreground * `docker run -p 81:80 --name web nginx` * in foreground and removing it when stopped * `docker run -p 81:80 --name web --rm nginx` * in background * `docker run -p 81:80 --name web -d nginx` * foreground, mounting the `nginx/html` directory: ```bash docker run --rm \ -p 81:80 \ --name web \ --mount type=bind,source="$PWD"/nginx/html,target=/usr/share/nginx/html \ nginx # or... docker run --rm \ -p 81:80 \ --name web \ -v "$PWD"/nginx/html,/usr/share/nginx/html \ nginx ``` * Enter the container: `docker exec -it web /bin/bash` * Build a local image from the `Dockerfile` ```bash docker build -t osinet/nginx:latest . ``` * Run the newly built image: ```bash docker run --rm \ -p 81:80 \ --name web \ --mount type=bind,source=$PWD/nginx/html,target=/usr/share/nginx/html \ osinet/nginx ``` * List images * All except intermediates: `docker images` * All including intermediates: `docker images -a` * Images with this name: `docker images osinet/nginx` # Step 2: Node.js app ```bash mkdir node cd node # edit Dockerfile docker build -t node-app . docker run -p 8888:8888 \ -v $PWD/node/src:/usr/src/app/src \ --name voting-node \ --rm \ node-app ``` # Step 3: PostgreSQL * Build and run the container ```bash mkdir postgres cd postgres # edit Dockerfile docker build -t node-pg . docker run -p 5432:5432 \ --name voting-pg \ --rm \ node-pg ``` * Enter the container with a PG client: ```bash # Without the -U, PG will try to use undeclared used root. docker container exec -it voting-pg psql -U postgres ``` * In `psql` in the container, list databases, create table, list tables: ```postgresql \l CREATE TABLE votes ( id INTEGER PRIMARY KEY, number_of_votes INTEGER, option_name VARCHAR(20) ); \dt ``` * Now we have a table: ``` List of relations Schema | Name | Type | Owner --------+-------+-------+---------- public | votes | table | postgres (1 row) ``` * Insert initial data ```postgresql INSERT INTO votes (id, number_of_votes, option_name) VALUES (1, 13, 'sandwiches'); INSERT INTO votes (id, number_of_votes, option_name) VALUES (2, 21, 'tacos'); SELECT * FROM votes; ``` * Results: ``` id | number_of_votes | option_name ----+-----------------+------------- 1 | 0 | sandwiches 2 | 0 | tacos (2 rows) ``` # Step 4: PG in Node app * To reach PG, the app needs to know the address. To get to it from inside the container where the app runs, look for the `gateway` value in the results of `docker bridge`: ``` [...snip...] "IPAM": { "Driver": "default", "Options": null, "Config": [ { "Subnet": "172.17.0.0/16", "Gateway": "172.17.0.1" } ] }, [...snip...] ``` * We then know that the IP to use in `client.connect()` will be `172.17.0.1`, at least in the current configuration. Will probably have to come from the outside for more flexibility. * Posting data to update: ```bash curl -d"yourVote=sandwiches" http://localhost:8888/vote curl -d"yourVote=tacos" http://localhost:8888/vote curl -d"yourVote=invalid" http://localhost:8888/vote ```