No description
- JavaScript 51.2%
- Dockerfile 23.6%
- EJS 19.3%
- HTML 5.9%
| nginx/html | ||
| node | ||
| postgres | ||
| .gitignore | ||
| Dockerfile | ||
| README.md | ||
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/htmldirectory:
- in foreground
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
docker build -t osinet/nginx:latest .
- Run the newly built image:
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
- All except intermediates:
Step 2: Node.js app
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
mkdir postgres
cd postgres
# edit Dockerfile
docker build -t voting-pg .
docker run -p 5432:5432 \
--name voting-pg \
--rm \
voting-pg
- Enter the container with a PG client:
# Without the -U, PG will try to use undeclared used root.
docker container exec -it voting-pg psql -U postgres
- In
psqlin the container, list databases, create table, list tables:
\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
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
gatewayvalue in the results ofdocker 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 be172.17.0.1, at least in the current configuration. Will probably have to come from the outside for more flexibility. - Posting data to update:
curl -d"yourVote=sandwiches" http://localhost:8888/vote
curl -d"yourVote=tacos" http://localhost:8888/vote
curl -d"yourVote=invalid" http://localhost:8888/vote
Step 5: persistence
-
Initialize PG as described on the image page, by adding a SQL file to the container from the host into the
docker-entrypoint-initdb.d/directory.COPY seed.sql /docker-entrypoint-initdb.d/ -
Redefine the image-provided volume pointing to the PG data:
VOLUME /var/lib/postgresql/data -
Rebuild container
cd postgres docker container build -t voting-pg . -
Run it. Beware: we can't have a
.gitkeepin thepostgres/datadirectory, which will prevent PG from starting in that directory. But if we don't have it, the directory will have to be created, because git won't save it.
cd postgres
if [ ! -d data ]; then mkdir data fi
docker container run \
--name voting-pg \
-p 9000:5432 \
-v $PWD/data:/var/lig/postgresql/data \
--rm -d \
voting-pg
- Run the app
cd node
docker container run \
--name voting-node \
-p 8888:8888 \
-v $PWD/src:/usr/src/app/src \
--rm -d \
voting-node
- When stopping the PG container, the node app will crash and not restart.
Just touch the
server.jsfile andnodemonin the node container will restart it. This is only good for a development workflow: a production version should handle disconnects.