Skip to content

Commit

Permalink
Add docker-staging.yml for deploymen to staging
Browse files Browse the repository at this point in the history
SAML fixes based on testing with staging

Use HOSTNAME=http://host.docker.internal:8080 so tests work
  • Loading branch information
humphd committed Mar 14, 2023
1 parent 4453612 commit 1291cf2
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 7 deletions.
5 changes: 2 additions & 3 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,7 @@ NOTIFICATIONS_EMAIL_USER="[email protected]"
SMTP_PORT=1025

# SSO Config
HOSTNAME=http://localhost:8080
# NOTE: we don't use localhost here due to DNS issues between Docker and host
HOSTNAME=http://host.docker.internal:8080
# The SimpleSAML IDP's XML metadata
SAML_IDP_METADATA_PATH=config/idp-metadata-dev.xml
# Our apps's SP Entity ID, which is also the URL to our metadata.
SAML_ENTITY_ID=http://host.docker.internal:8080/sp
4 changes: 3 additions & 1 deletion DEPLOY.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ The following configuration values must be set via environment variables.

| Variable Name | Description |
| ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `HOSTNAME` | The hostname of the server (e.g., `https://mycustomdomain.senecacollege.ca`) |
| `PORT` | The server runs on port `8080` by default |
| `LOG_LEVEL` | The log level to use for log messages. One of `error`, `debug`, `info`, etc. See [Winston docs](https:/winstonjs/winston#logging-levels). Defaults to `info` |
| `ROOT_DOMAIN` | The DNS root domain for the hosted zone (e.g., `starchart.com`) |
Expand All @@ -27,8 +28,9 @@ The following configuration values must be set via environment variables.
| `SMTP_PORT` | The port to use for the SMTP server. Defaults to `587` in production (using `smtp.office365.com`) and `1025` in development (using ([MailHog](https:/mailhog/MailHog)) |
| `LETS_ENCRYPT_ACCOUNT_EMAIL` | The email address to use for the app's [single Let's Encrypt account](https://letsencrypt.org/docs/integration-guide/#one-account-or-many) |
| `REDIS_URL` | The Redis server to use for the worker queues. Defaults to `redis://redis:6379` in production and `localhost:6379` in development. |
| `SAML_IDP_METADATA_PATH` | The file path of the SAML Identify Provider (IdP)'s metadata XML. We store various XML files in `config/` and use `config/idp-metadata-dev.xml` by default. |
| `SAML_IDP_METADATA_PATH` | The file path of the SAML Identify Provider (IdP)'s metadata XML. We store various XML files in `config/` and use `config/idp-metadata-dev.xml` by default in development. |
| `SECRETS_OVERRIDE` | In development, to override the Docker secrets |
| `DATABASE_SETUP` | In order to sync the Prisma schema with MySQL, set `DATABASE_SETUP=1` when running the app |

### Secrets

Expand Down
17 changes: 14 additions & 3 deletions app/lib/saml.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,32 @@ const idp = samlify.IdentityProvider({
metadata: xml,
});

const { NODE_ENV, HOSTNAME } = process.env;

/**
* In production, we require the hostname
*/
if (NODE_ENV === 'production') {
if (!HOSTNAME) {
throw new Error('HOSTNAME environment variable is missing');
}
}

// Here we configure the service provider: https://samlify.js.org/#/sp-configuration
const sp = samlify.ServiceProvider({
entityID: process.env.SAML_ENTITY_ID,
entityID: new URL('/sp', HOSTNAME).href,
nameIDFormat: ['urn:oasis:names:tc:SAML:2.0:nameid-format:persistent'],
wantAssertionsSigned: true,
assertionConsumerService: [
{
Binding: 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST',
Location: process.env.HOSTNAME + '/login/callback',
Location: new URL('/login/callback', HOSTNAME).href,
},
],
singleLogoutService: [
{
Binding: 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST',
Location: process.env.HOSTNAME + '/logout/callback',
Location: new URL('/logout/callback', HOSTNAME).href,
},
],
});
Expand Down
67 changes: 67 additions & 0 deletions docker-staging.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# Stack Definition for Staging
services:
# Redis is used to back our worker queues. It is not exposed.
redis:
image: redis:7.0.9-alpine3.17@sha256:8201775852e31262823ac8da9d76d0c8f36583f1a028b4800c35fc319c75289f
restart: unless-stopped
volumes:
- redis-data:/data
deploy:
placement:
# We run the redis instance on the manager node only
constraints: [node.role == manager]

mycustomdomain-dev:
# Staging runs the most recent commit on the main branch
image: ghcr.io/developingspace/starchart:main
restart: unless-stopped
depends_on:
- redis
ports:
- 8080:8080
environment:
- HOSTNAME=https://mycustomdomain-dev.senecacollege.ca
- AWS_ROUTE53_HOSTED_ZONE_ID=Z0228625ICAL609E0BBT
- [email protected]
- LETS_ENCRYPT_DIRECTORY_URL=https://acme-staging-v02.api.letsencrypt.org/directory
- LOG_LEVEL=info
- NODE_ENV=production
- [email protected]
- PORT=8080
- REDIS_URL=redis://redis:6379
- ROOT_DOMAIN=_stage_.mystudentproject.ca
secrets:
- AWS_ACCESS_KEY_ID
- AWS_SECRET_ACCESS_KEY
- DATABASE_URL
- LETS_ENCRYPT_ACCOUNT_PRIVATE_KEY_PEM
- NOTIFICATIONS_USERNAME
- NOTIFICATIONS_PASSWORD
- SESSION_SECRET
deploy:
mode: replicated
replicas: 2
update_config:
# Only update 1 instance at a time, not all at once (rolling-update)
parallelism: 1
# If the update fails, rollback to last-known-good
failure_action: rollback

secrets:
AWS_ACCESS_KEY_ID:
external: true
AWS_SECRET_ACCESS_KEY:
external: true
DATABASE_URL:
external: true
LETS_ENCRYPT_ACCOUNT_PRIVATE_KEY_PEM:
external: true
NOTIFICATIONS_USERNAME:
external: true
NOTIFICATIONS_PASSWORD:
external: true
SESSION_SECRET:
external: true

volumes:
redis-data:

0 comments on commit 1291cf2

Please sign in to comment.