Skip to content
This repository has been archived by the owner on May 8, 2021. It is now read-only.

Commit

Permalink
Dockerize application (#52)
Browse files Browse the repository at this point in the history
* Remove dangling env variables and add Dockerfile

* Main workflow added

* Add checkout to deploy job

* Update deploy and verify command

* Add separate workflows for environments

* Prevent cypress install in CI workflow

* Remove .env.ci

* Remove deploy script
  • Loading branch information
lukebettridge committed Mar 16, 2020
1 parent 7ae6ae5 commit 0492821
Show file tree
Hide file tree
Showing 25 changed files with 394 additions and 142 deletions.
25 changes: 25 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
.DS_Store
.env

# logs
logs
*.log
npm-debug.log.*

# dependencies
node_modules

# test coverage
coverage

# cypress
cypress
cypress.env.json

# git
.git
.gitignore

# docker
Dockerfile
.dockerignore
7 changes: 0 additions & 7 deletions .env.ci

This file was deleted.

17 changes: 12 additions & 5 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
BASE_URL=# server URL
CORS_ORIGIN=# not required if same as BASE_URL
NODE_ENV=# environment (e.g. development)
PORT=# server port (e.g. 5000)
MONGO_URI=# db connection (e.g. mongodb://<username>:<password>@<host>:<port>/<db>
NODE_ENV=# environment (e.g. development)

MONGO_USERNAME=# host username
MONGO_PASSWORD=# host password
MONGO_HOSTNAME=# host name
MONGO_PORT=# host port (e.g. 27017)
MONGO_DB=# db name
MONGO_REPLICASET=# db replica set

SECRET_OR_KEY=# JWT secret
EXPIRE_PASSWORD_RESET_DAYS=# days for password reset requests to expire in
HAS_SSL=# hosted with an SSL certificate

APP_NAME=# used in outgoing email

MAIL_HOST=# smtp host
MAIL_PORT=# smtp port (465)
MAIL_PORT=# smtp port (e.g. 465)
MAIL_FROM=# from email address
MAIL_USERNAME=# smtp host username
MAIL_PASSWORD=# smtp host password
6 changes: 4 additions & 2 deletions .github/workflows/main.yml → .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,15 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1

- name: Use Node.js 8.x
uses: actions/setup-node@v1
with:
node-version: "8.x"
- name: Install dependencies, build, and test

- name: Install dependencies, build and test
run: |
npm ci
CYPRESS_INSTALL_BINARY=0 npm ci
npm run build --if-present
npm test
env:
Expand Down
20 changes: 0 additions & 20 deletions .github/workflows/e2e.yml

This file was deleted.

44 changes: 44 additions & 0 deletions .github/workflows/production.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
name: K8S PROD

on:
release:
types: [published]

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1

- name: Build container image
run: docker build -t registry.paddl.co.uk/mern-auth-boilerplate:$GITHUB_REF .

- name: Registry authentication
env:
REGISTRY_USERNAME: ${{ secrets.REGISTRY_USERNAME }}
REGISTRY_PASSWORD: ${{ secrets.REGISTRY_PASSWORD }}
run: docker login -u $REGISTRY_USERNAME -p $REGISTRY_PASSWORD registry.paddl.co.uk

- name: Push image
run: docker push registry.paddl.co.uk/mern-auth-boilerplate
deploy:
runs-on: ubuntu-latest
needs: build
steps:
- uses: actions/checkout@v1

- name: Update deployment file
run: sed -i 's|<IMAGE>|registry.paddl.co.uk/mern-auth-boilerplate:$GITHUB_REF|' $GITHUB_WORKSPACE/config/deployment.yml

- name: Save DigitalOcean kubeconfig
uses: digitalocean/action-doctl@master
env:
DIGITALOCEAN_ACCESS_TOKEN: ${{ secrets.DO_ACCESS_TOKEN }}
with:
args: kubernetes cluster kubeconfig show k8s-1-16-6-do-0-lon1-1584220776791 > $GITHUB_WORKSPACE/.kubeconfig

- name: Deploy to cluster
run: kubectl --kubeconfig=$GITHUB_WORKSPACE/.kubeconfig apply -f $GITHUB_WORKSPACE/config/deployment.yml -n prod

- name: Verify deployment
run: kubectl --kubeconfig=$GITHUB_WORKSPACE/.kubeconfig rollout status deployment/mern-auth-boilerplate-nodeapp -n prod
45 changes: 45 additions & 0 deletions .github/workflows/staging.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
name: K8S STG

on:
push:
branches:
- staging

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1

- name: Build container image
run: docker build -t registry.paddl.co.uk/mern-auth-boilerplate:$(echo $GITHUB_SHA | head -c7) .

- name: Registry authentication
env:
REGISTRY_USERNAME: ${{ secrets.REGISTRY_USERNAME }}
REGISTRY_PASSWORD: ${{ secrets.REGISTRY_PASSWORD }}
run: docker login -u $REGISTRY_USERNAME -p $REGISTRY_PASSWORD registry.paddl.co.uk

- name: Push image
run: docker push registry.paddl.co.uk/mern-auth-boilerplate
deploy:
runs-on: ubuntu-latest
needs: build
steps:
- uses: actions/checkout@v1

- name: Update deployment file
run: TAG=$(echo $GITHUB_SHA | head -c7) && sed -i 's|<IMAGE>|registry.paddl.co.uk/mern-auth-boilerplate:'${TAG}'|' $GITHUB_WORKSPACE/config/deployment.yml

- name: Save DigitalOcean kubeconfig
uses: digitalocean/action-doctl@master
env:
DIGITALOCEAN_ACCESS_TOKEN: ${{ secrets.DO_ACCESS_TOKEN }}
with:
args: kubernetes cluster kubeconfig show k8s-1-16-6-do-0-lon1-1584220776791 > $GITHUB_WORKSPACE/.kubeconfig

- name: Deploy to cluster
run: kubectl --kubeconfig=$GITHUB_WORKSPACE/.kubeconfig apply -f $GITHUB_WORKSPACE/config/deployment.yml -n stg

- name: Verify deployment
run: kubectl --kubeconfig=$GITHUB_WORKSPACE/.kubeconfig rollout status deployment/mern-auth-boilerplate-nodeapp -n stg
22 changes: 22 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
FROM node:8-alpine

RUN mkdir -p /home/node/app/node_modules && chown -R node:node /home/node/app

# Create app directory
WORKDIR /home/node/app

COPY package*.json ./
USER node

# Install app dependencies
RUN CYPRESS_INSTALL_BINARY=0 npm install

# Bundle app source
COPY --chown=node:node . .

# Test and build
RUN npm run test
RUN npm run build && npm prune --production

EXPOSE 5000
CMD npm start
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ npm run dev
Which can now be viewed in the browser at:

```
http://localhost:3000/
http://localhost:5000/
```

## Testing
Expand Down
5 changes: 0 additions & 5 deletions __tests__/client/components/pages/auth/login/utils.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,6 @@ jest.mock("axios", () => ({
catch: jest.fn()
}));

global.process.env = {
BASE_URL: "foo"
};
const success = jest.fn();
const error = jest.fn();

Expand All @@ -35,7 +32,6 @@ describe("Login utility methods", () => {
"/api/auth/login",
{ email: "[email protected]", password: "password" },
{
baseURL: "foo",
withCredentials: true
}
);
Expand All @@ -51,7 +47,6 @@ describe("Login utility methods", () => {
expect(axios.get).toHaveBeenCalledWith(
"/api/auth/[email protected]",
{
baseURL: "foo",
withCredentials: true
}
);
Expand Down
21 changes: 7 additions & 14 deletions __tests__/client/components/pages/auth/register/utils.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,6 @@ jest.mock("axios", () => ({
catch: jest.fn()
}));

global.process.env = {
BASE_URL: "foo"
};
const success = jest.fn();
const error = jest.fn();

Expand All @@ -35,17 +32,13 @@ describe("Register utility methods", () => {
error
);

expect(axios.post).toHaveBeenCalledWith(
"/api/auth/register",
{
forename: "John",
surname: "Doe",
email: "[email protected]",
password: "password",
password2: "password"
},
{ baseURL: "foo" }
);
expect(axios.post).toHaveBeenCalledWith("/api/auth/register", {
forename: "John",
surname: "Doe",
email: "[email protected]",
password: "password",
password2: "password"
});
expect(axios.then).toHaveBeenCalledWith(success);
expect(axios.catch).toHaveBeenCalledWith(error);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,6 @@ jest.mock("axios", () => ({
catch: jest.fn()
}));

global.process.env = {
BASE_URL: "foo"
};
const success = jest.fn();
const error = jest.fn();

Expand All @@ -33,15 +30,11 @@ describe("ResetPassword utility methods", () => {
error
);

expect(axios.post).toHaveBeenCalledWith(
"/api/auth/reset-password",
{
resetKey: "bar",
newPassword: "password",
newPassword2: "password"
},
{ baseURL: "foo" }
);
expect(axios.post).toHaveBeenCalledWith("/api/auth/reset-password", {
resetKey: "bar",
newPassword: "password",
newPassword2: "password"
});
expect(axios.then).toHaveBeenCalledWith(success);
expect(axios.catch).toHaveBeenCalledWith(error);
});
Expand Down
8 changes: 5 additions & 3 deletions __tests__/server/routes/auth/reset-password.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,7 @@ const oldDate = new Date(0);
const newDate = new Date(1);

global.process.env = {
APP_NAME: "app",
BASE_URL: "http://example.com"
APP_NAME: "app"
};

describe("routes reset password (get)", () => {
Expand All @@ -46,6 +45,7 @@ describe("routes reset password (get)", () => {
res.status.mockReturnValue(res);
baseUser.updateOne.mockReturnValue(baseUser);
baseUser.then.mockReturnValue(baseUser);
req.get.mockReturnValue("example.com");
});

it("request password reset successfully", () => {
Expand Down Expand Up @@ -123,7 +123,9 @@ The app Team`
const req = {
query: {
email: "[email protected]"
}
},
protocol: "http",
get: jest.fn()
};
});

Expand Down
2 changes: 1 addition & 1 deletion client/components/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import { Accounts } from "./pages/admin";
import Home from "./pages/home";

const httpLink = createHttpLink({
uri: `${process.env.BASE_URL}/graphql`,
uri: "/graphql",
credentials: "include"
});

Expand Down
2 changes: 0 additions & 2 deletions client/components/pages/auth/login/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ const login = ({ email, password }, success, error) => {
"/api/auth/login",
{ email, password },
{
baseURL: process.env.BASE_URL,
withCredentials: true
}
)
Expand All @@ -17,7 +16,6 @@ const login = ({ email, password }, success, error) => {
const resetPassword = (email, success, error) => {
axios
.get(`/api/auth/reset-password?email=${email}`, {
baseURL: process.env.BASE_URL,
withCredentials: true
})
.then(success)
Expand Down
12 changes: 7 additions & 5 deletions client/components/pages/auth/register/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@ const register = (
error
) => {
axios
.post(
"/api/auth/register",
{ forename, surname, email, password, password2 },
{ baseURL: process.env.BASE_URL }
)
.post("/api/auth/register", {
forename,
surname,
email,
password,
password2
})
.then(success)
.catch(error);
};
Expand Down
Loading

0 comments on commit 0492821

Please sign in to comment.