187 lines
4.8 KiB
Markdown
187 lines
4.8 KiB
Markdown
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 voting-pg .
|
|
docker run -p 5432:5432 \
|
|
--name voting-pg \
|
|
--rm \
|
|
voting-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
|
|
```
|
|
|
|
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 `.gitkeep` in the `postgres/data` directory, 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.
|
|
|
|
```bash
|
|
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
|
|
```bash
|
|
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.js` file and `nodemon` in the node container will
|
|
restart it. This is only good for a development workflow: a production version
|
|
should handle disconnects.
|