├── ssh-encryption
├── example
│ ├── test.txt
│ └── docker-compose.yml
├── info.json
├── image
│ ├── Dockerfile
│ ├── ssh-decrypt
│ └── ssh-encrypt
├── push_image.sh
└── README.md
├── .gitignore
├── node-app
├── dockerfile-builder
│ ├── example
│ │ ├── output
│ │ │ └── touch.txt
│ │ ├── shared
│ │ │ ├── capitalize-array
│ │ │ │ ├── index.js
│ │ │ │ └── package.json
│ │ │ └── user-store
│ │ │ │ ├── index.js
│ │ │ │ └── package.json
│ │ ├── app
│ │ │ ├── index.js
│ │ │ └── package.json
│ │ └── docker-compose.yml
│ ├── code
│ │ ├── app
│ │ │ ├── template
│ │ │ ├── package.json
│ │ │ ├── getCopyCmd.js
│ │ │ ├── getCopySharedCmd.js
│ │ │ └── index.js
│ │ └── dockerfile
│ ├── templates
│ │ └── docker-compose.yml
│ └── README.md
├── base-image
│ ├── example2
│ │ ├── dockerfile
│ │ ├── docker-compose.yml
│ │ └── app
│ │ │ ├── package.json
│ │ │ └── index.js
│ ├── example
│ │ ├── shared
│ │ │ ├── capitalize-array
│ │ │ │ ├── index.js
│ │ │ │ └── package.json
│ │ │ └── user-store
│ │ │ │ ├── index.js
│ │ │ │ └── package.json
│ │ ├── dockerfile
│ │ ├── dockerfile-slim
│ │ └── app
│ │ │ ├── index.js
│ │ │ └── package.json
│ ├── example3
│ │ ├── shared
│ │ │ ├── array
│ │ │ │ ├── capitalize-array
│ │ │ │ │ ├── index.js
│ │ │ │ │ └── package.json
│ │ │ │ └── sort-array
│ │ │ │ │ ├── index.js
│ │ │ │ │ └── package.json
│ │ │ └── user-store
│ │ │ │ ├── index.js
│ │ │ │ └── package.json
│ │ ├── app
│ │ │ ├── index.js
│ │ │ └── package.json
│ │ └── dockerfile
│ ├── example5
│ │ ├── dockerfile
│ │ ├── dockerfile-slim
│ │ ├── shared
│ │ │ ├── package.json
│ │ │ └── index.js
│ │ └── app
│ │ │ ├── package.json
│ │ │ └── test
│ │ │ └── index.js
│ ├── example4
│ │ ├── shared
│ │ │ ├── module1
│ │ │ │ ├── index.js
│ │ │ │ └── package.json
│ │ │ └── module2
│ │ │ │ ├── index.js
│ │ │ │ └── package.json
│ │ ├── app
│ │ │ ├── index.js
│ │ │ └── package.json
│ │ └── dockerfile
│ ├── code
│ │ ├── finalize.sh
│ │ ├── dockerfile
│ │ ├── dockerfile-slim
│ │ └── resolve_dependencies.js
│ ├── templates
│ │ ├── dockerfile-template
│ │ └── dockerfile-template-slim
│ └── README.md
├── image-builder
│ ├── code
│ │ ├── app
│ │ │ ├── template
│ │ │ ├── package.json
│ │ │ ├── compileDependencies.js
│ │ │ ├── wgetDirCmd.js
│ │ │ └── index.js
│ │ ├── server
│ │ │ ├── package.json
│ │ │ └── index.js
│ │ └── dockerfile
│ ├── example
│ │ ├── shared
│ │ │ ├── capitalize-array
│ │ │ │ ├── index.js
│ │ │ │ └── package.json
│ │ │ └── user-store
│ │ │ │ ├── index.js
│ │ │ │ └── package.json
│ │ ├── app
│ │ │ ├── index.js
│ │ │ └── package.json
│ │ ├── docker-compose.yml
│ │ └── docker-compose-slim.yml
│ ├── example2
│ │ ├── shared
│ │ │ ├── package.json
│ │ │ └── index.js
│ │ ├── app
│ │ │ ├── package.json
│ │ │ └── test
│ │ │ │ └── index.js
│ │ ├── docker-compose.yml
│ │ └── docker-compose-slim.yml
│ ├── templates
│ │ └── docker-compose.yml
│ └── README.md
├── base-dev-image
│ ├── example
│ │ ├── shared
│ │ │ ├── module1
│ │ │ │ ├── index.js
│ │ │ │ └── package.json
│ │ │ └── module2
│ │ │ │ ├── index.js
│ │ │ │ └── package.json
│ │ ├── app
│ │ │ ├── index.js
│ │ │ └── package.json
│ │ └── docker-compose.yml
│ ├── code
│ │ ├── finalize.sh
│ │ ├── dockerfile
│ │ └── resolve_dependencies.js
│ └── README.md
└── README.md
├── headless-factorio-server
├── requirements.txt
├── templates
│ ├── server-adminlist.json.j2
│ ├── server-whitelist.json.j2
│ ├── map-gen-settings.json.j2
│ └── server-settings.json.j2
├── docker-compose.yml
├── Dockerfile
├── code
│ ├── game.py
│ └── entrypoint.py
└── README.md
├── certificate
├── example
│ ├── ca-signed-with-password
│ │ ├── password.txt
│ │ ├── ca-password.txt
│ │ └── docker-compose.yml
│ ├── self-signed-with-password
│ │ ├── password.txt
│ │ └── docker-compose.yml
│ ├── self-signed
│ │ └── docker-compose.yml
│ └── ca-signed
│ │ └── docker-compose.yml
├── Dockerfile
└── test
│ └── run.py
├── remote-terraform
├── ansible_scripts
│ ├── roles
│ │ ├── deploy_scripts
│ │ │ ├── files
│ │ │ │ └── placeholder
│ │ │ └── tasks
│ │ │ │ └── main.yml
│ │ ├── cleanup_scripts
│ │ │ └── tasks
│ │ │ │ └── main.yml
│ │ ├── terraform_plan
│ │ │ └── tasks
│ │ │ │ └── main.yml
│ │ └── terraform_apply
│ │ │ └── tasks
│ │ │ └── main.yml
│ ├── plan.yml
│ └── apply.yml
├── info.json
├── push_image.sh
├── binaries
│ ├── plan
│ └── apply
└── Dockerfile
├── ansible
├── README.md
├── info.json
├── Dockerfile
└── push_image.sh
├── automated-tests
├── run.sh
├── user-store
│ ├── node-0.10.df
│ ├── node-4.1.df
│ ├── build.sh
│ └── run.sh
├── user-properties
│ ├── node-0.10.df
│ ├── node-4.1.df
│ ├── run.sh
│ └── build.sh
├── express-access-control
│ ├── node-0.10.df
│ ├── node-4.1.df
│ ├── run.sh
│ └── build.sh
├── node-4.1-base.df
├── node-0.10-base.df
├── build.sh
└── build-base.sh
├── pulsar-orchestration
├── cleanup.sh
├── README.md
├── zookeeper-conf
│ └── zoo.cfg
├── configure_zookeeper.sh
├── launch.sh
├── docker-compose.yml
└── bookkeeper-conf
│ └── bookkeeper.conf
├── react-build
├── code
│ ├── dockerfile-onbuild
│ ├── dockerfile-onbuild-slim
│ ├── dockerfile
│ ├── dockerfile-slim
│ └── app
│ │ ├── package.json
│ │ └── index.js
├── example-onbuild
│ ├── dockerfile
│ ├── docker-compose.yml
│ ├── app
│ │ └── javascript
│ │ │ ├── header.jsx
│ │ │ ├── index.jsx
│ │ │ ├── draw-section.jsx
│ │ │ ├── registration-feedback.jsx
│ │ │ ├── draw-feedback.jsx
│ │ │ ├── register-section.jsx
│ │ │ └── app.jsx
│ ├── build.json
│ └── lib
│ │ ├── draw.js
│ │ ├── participants.js
│ │ └── pot.js
├── example
│ ├── docker-compose.yml
│ ├── app
│ │ └── javascript
│ │ │ ├── header.jsx
│ │ │ ├── index.jsx
│ │ │ ├── draw-section.jsx
│ │ │ ├── registration-feedback.jsx
│ │ │ ├── draw-feedback.jsx
│ │ │ ├── register-section.jsx
│ │ │ └── app.jsx
│ ├── build.json
│ └── lib
│ │ ├── draw.js
│ │ ├── participants.js
│ │ └── pot.js
└── README.md
├── electron-app
├── app
│ ├── package.json
│ ├── index.html
│ └── main.js
├── docker-compose.yml
├── dockerfile
├── entryScript.sh
└── README.md
├── cfssl
├── example
│ ├── ca-csr.json
│ ├── client.json
│ └── ca-config.json
├── amd64
│ └── Dockerfile
├── arm64
│ └── Dockerfile
└── README.md
├── chrony
├── Dockerfile
└── README.md
├── pyspark
├── run.sh
├── README.md
└── Dockerfile
├── chrome
├── dockerfile
├── entryScript.sh
├── docker-compose.yml
└── README.md
├── hapi-service
├── hello-world
│ ├── dockerfile
│ ├── package.json
│ └── index.js
└── README.md
├── jedit
├── entryScript.sh
├── docker-compose.yml
├── dockerfile
└── README.md
├── network-setup
├── image
│ ├── dns.conf.j2
│ ├── zonefile.j2
│ ├── Dockerfile
│ └── dhcp.conf.j2
├── docker-compose.yml
├── conf
└── README.md
├── isc-dhcp-server
├── example
│ ├── docker-compose.yml
│ └── dhcpd.conf
├── entrypoint.sh
├── Dockerfile-amd64
├── Dockerfile-arm64
└── README.md
├── .github
└── workflows
│ ├── build_ansible.yml
│ ├── build_ssh_encryption.yml
│ ├── build_remote_terraform.yml
│ ├── publish_ansible.yml
│ ├── publish_ssh_encryption.yml
│ └── publish_remote_terraform.yml
├── sbt
├── Dockerfile
└── README.md
└── License.txt
/ssh-encryption/example/test.txt:
--------------------------------------------------------------------------------
1 | Hello world!
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | #editor generated backup files
2 | *~
3 |
--------------------------------------------------------------------------------
/node-app/dockerfile-builder/example/output/touch.txt:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/headless-factorio-server/requirements.txt:
--------------------------------------------------------------------------------
1 | jinja2 == 2.11.1
--------------------------------------------------------------------------------
/certificate/example/ca-signed-with-password/password.txt:
--------------------------------------------------------------------------------
1 | foobar
2 |
--------------------------------------------------------------------------------
/certificate/example/ca-signed-with-password/ca-password.txt:
--------------------------------------------------------------------------------
1 | cafoobar
2 |
--------------------------------------------------------------------------------
/certificate/example/self-signed-with-password/password.txt:
--------------------------------------------------------------------------------
1 | foobar
2 |
--------------------------------------------------------------------------------
/remote-terraform/ansible_scripts/roles/deploy_scripts/files/placeholder:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/ansible/README.md:
--------------------------------------------------------------------------------
1 | # About
2 |
3 | Simple image to troubleshoot ansible playbooks locally
--------------------------------------------------------------------------------
/automated-tests/run.sh:
--------------------------------------------------------------------------------
1 | for dir in */ ; do
2 | (cd "$dir"; ./run.sh);
3 | done
4 |
--------------------------------------------------------------------------------
/ansible/info.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "1.0.0",
3 | "image_repo": "magnitus/ansible"
4 | }
--------------------------------------------------------------------------------
/headless-factorio-server/templates/server-adminlist.json.j2:
--------------------------------------------------------------------------------
1 | [
2 | {{ players|join(', ') }}
3 | ]
--------------------------------------------------------------------------------
/headless-factorio-server/templates/server-whitelist.json.j2:
--------------------------------------------------------------------------------
1 | [
2 | {{ players|join(', ') }}
3 | ]
--------------------------------------------------------------------------------
/pulsar-orchestration/cleanup.sh:
--------------------------------------------------------------------------------
1 | docker-compose down;
2 | rm -r zookeeper;
3 | sudo rm -r bookie;
--------------------------------------------------------------------------------
/react-build/code/dockerfile-onbuild:
--------------------------------------------------------------------------------
1 | FROM magnitus/node-app:4
2 |
3 | COPY "app/*" ${APP_DIR}/
4 |
--------------------------------------------------------------------------------
/ansible/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM python:3.9-slim-bullseye
2 |
3 | RUN python3 -m pip install ansible-core==2.12.3
--------------------------------------------------------------------------------
/react-build/code/dockerfile-onbuild-slim:
--------------------------------------------------------------------------------
1 | FROM magnitus/node-app:4-slim
2 |
3 | COPY "app/*" ${APP_DIR}/
4 |
--------------------------------------------------------------------------------
/ssh-encryption/info.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "1.0.0",
3 | "image_repo": "magnitus/ssh-encryption"
4 | }
--------------------------------------------------------------------------------
/remote-terraform/info.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "1.0.0",
3 | "image_repo": "magnitus/remote-terraform"
4 | }
--------------------------------------------------------------------------------
/electron-app/app/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name" : "hello-world",
3 | "version" : "0.1.0",
4 | "main" : "main.js"
5 | }
6 |
--------------------------------------------------------------------------------
/cfssl/example/ca-csr.json:
--------------------------------------------------------------------------------
1 | {
2 | "CN": "etcd",
3 | "key": {
4 | "algo": "rsa",
5 | "size": 2048
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/chrony/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM debian:stretch
2 |
3 | RUN apt-get update && apt-get install -y chrony
4 |
5 | CMD ["/usr/sbin/chronyd", "-d"]
--------------------------------------------------------------------------------
/automated-tests/user-store/node-0.10.df:
--------------------------------------------------------------------------------
1 | FROM magnitus/automated-tests:node-0.10-base
2 | ENV PROJECT="UserStore"
3 | RUN /opt/build-base.sh
4 |
--------------------------------------------------------------------------------
/automated-tests/user-store/node-4.1.df:
--------------------------------------------------------------------------------
1 | FROM magnitus/automated-tests:node-4.1-base
2 | ENV PROJECT="UserStore"
3 | RUN /opt/build-base.sh
4 |
--------------------------------------------------------------------------------
/cfssl/example/client.json:
--------------------------------------------------------------------------------
1 | {
2 | "CN": "client",
3 | "key": {
4 | "algo": "ecdsa",
5 | "size": 256
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/react-build/example-onbuild/dockerfile:
--------------------------------------------------------------------------------
1 | FROM magnitus/react-compiler:onbuild
2 |
3 | ENV UID="1000"
4 |
5 | RUN finalize.sh
6 |
7 | USER $UID
8 |
--------------------------------------------------------------------------------
/automated-tests/user-properties/node-0.10.df:
--------------------------------------------------------------------------------
1 | FROM magnitus/automated-tests:node-0.10-base
2 | ENV PROJECT="UserProperties"
3 | RUN /opt/build-base.sh
4 |
--------------------------------------------------------------------------------
/automated-tests/user-properties/node-4.1.df:
--------------------------------------------------------------------------------
1 | FROM magnitus/automated-tests:node-4.1-base
2 | ENV PROJECT="UserProperties"
3 | RUN /opt/build-base.sh
4 |
--------------------------------------------------------------------------------
/automated-tests/express-access-control/node-0.10.df:
--------------------------------------------------------------------------------
1 | FROM magnitus/automated-tests:node-0.10-base
2 | ENV PROJECT="ExpressAccessControl"
3 | RUN /opt/build-base.sh
4 |
--------------------------------------------------------------------------------
/automated-tests/express-access-control/node-4.1.df:
--------------------------------------------------------------------------------
1 | FROM magnitus/automated-tests:node-4.1-base
2 | ENV PROJECT="ExpressAccessControl"
3 | RUN /opt/build-base.sh
4 |
--------------------------------------------------------------------------------
/pyspark/run.sh:
--------------------------------------------------------------------------------
1 | docker build -t pyspark-jupyter-notebook:latest .;
2 | docker run -d --rm -p "8888:8888" --name pyspark-jupyter-notebook pyspark-jupyter-notebook:latest;
--------------------------------------------------------------------------------
/react-build/code/dockerfile:
--------------------------------------------------------------------------------
1 | FROM magnitus/node-app:4
2 |
3 | COPY "app/*" ${APP_DIR}/
4 |
5 | ENV UID="0"
6 |
7 | RUN finalize.sh
8 |
9 | USER $UID
10 |
--------------------------------------------------------------------------------
/react-build/code/dockerfile-slim:
--------------------------------------------------------------------------------
1 | FROM magnitus/node-app:4-slim
2 |
3 | COPY "app/*" ${APP_DIR}/
4 |
5 | ENV UID="0"
6 |
7 | RUN finalize.sh
8 |
9 | USER $UID
10 |
--------------------------------------------------------------------------------
/node-app/base-image/example2/dockerfile:
--------------------------------------------------------------------------------
1 | FROM magnitus/node-app:4
2 |
3 | ENV UID="1000"
4 |
5 | COPY "app/* ${APP_DIR}/
6 |
7 | RUN finalize.sh
8 |
9 | USER $UID
10 |
--------------------------------------------------------------------------------
/node-app/image-builder/code/app/template:
--------------------------------------------------------------------------------
1 | FROM {{SOURCE}}
2 |
3 | ENV UID="{{UID}}"
4 | {{NPM_COMMAND}}
5 |
6 | {{COPY_ALL}}
7 |
8 | RUN finalize.sh
9 |
10 | USER $UID
11 |
--------------------------------------------------------------------------------
/automated-tests/user-properties/run.sh:
--------------------------------------------------------------------------------
1 | docker run -it --rm magnitus/automated-tests:0.10-node-user-properties;
2 | docker run -it --rm magnitus/automated-tests:4.1-node-user-properties;
3 |
--------------------------------------------------------------------------------
/ssh-encryption/image/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM ubuntu:20.04
2 |
3 | RUN apt-get update && apt-get install -y openssl openssh-client
4 |
5 | COPY ssh-decrypt ssh-encrypt /usr/bin/
6 |
7 | WORKDIR /opt
--------------------------------------------------------------------------------
/node-app/base-image/example2/docker-compose.yml:
--------------------------------------------------------------------------------
1 | app:
2 | container_name: node-app-hapi-example
3 | image: magnitus/node-app:example-hapi
4 | restart: always
5 | ports:
6 | - "8080:8080"
--------------------------------------------------------------------------------
/automated-tests/user-store/build.sh:
--------------------------------------------------------------------------------
1 | docker build -t magnitus/automated-tests:0.10-node-user-store -f node-0.10.df .;
2 | docker build -t magnitus/automated-tests:4.1-node-user-store -f node-4.1.df .;
3 |
--------------------------------------------------------------------------------
/chrome/dockerfile:
--------------------------------------------------------------------------------
1 | FROM jess/chrome:stable
2 | COPY ["./entryScript.sh", "/opt/entryScript.sh"]
3 | RUN chmod +x /opt/entryScript.sh
4 | ENTRYPOINT ["/bin/bash", "/opt/entryScript.sh"]
5 | CMD [ "" ]
6 |
--------------------------------------------------------------------------------
/node-app/dockerfile-builder/code/app/template:
--------------------------------------------------------------------------------
1 | FROM magnitus/node-app:4
2 |
3 | ENV UID="{{UID}}"
4 |
5 | {{COPY_APP}}
6 |
7 | {{COPY_SHARED}}
8 |
9 | RUN finalize.sh
10 |
11 | USER $UID
12 |
--------------------------------------------------------------------------------
/remote-terraform/ansible_scripts/roles/cleanup_scripts/tasks/main.yml:
--------------------------------------------------------------------------------
1 | - name: Remove terraform configuration from bastion
2 | file:
3 | path: "{{ remote_terraform_config_dir }}"
4 | state: absent
--------------------------------------------------------------------------------
/automated-tests/express-access-control/run.sh:
--------------------------------------------------------------------------------
1 | docker run -it --rm magnitus/automated-tests:0.10-node-express-access-control;
2 | docker run -it --rm magnitus/automated-tests:4.1-node-express-access-control;
3 |
--------------------------------------------------------------------------------
/remote-terraform/ansible_scripts/roles/deploy_scripts/tasks/main.yml:
--------------------------------------------------------------------------------
1 | - name: Copy terraform configuration to bastion
2 | copy:
3 | src: "terraform/"
4 | dest: "{{ remote_terraform_config_dir }}/"
5 |
--------------------------------------------------------------------------------
/automated-tests/user-properties/build.sh:
--------------------------------------------------------------------------------
1 | docker build -t magnitus/automated-tests:0.10-node-user-properties -f node-0.10.df .;
2 | docker build -t magnitus/automated-tests:4.1-node-user-properties -f node-4.1.df .;
3 |
--------------------------------------------------------------------------------
/cfssl/amd64/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM golang:1.14
2 |
3 | RUN go get -u github.com/cloudflare/cfssl/cmd/cfssl && go get -u github.com/cloudflare/cfssl/cmd/cfssljson
4 |
5 | WORKDIR /opt
6 |
7 | ENTRYPOINT [""]
8 | CMD ["sh"]
--------------------------------------------------------------------------------
/cfssl/arm64/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM arm64v8/golang:1.14
2 |
3 | RUN go get -u github.com/cloudflare/cfssl/cmd/cfssl && go get -u github.com/cloudflare/cfssl/cmd/cfssljson
4 |
5 | WORKDIR /opt
6 |
7 | ENTRYPOINT [""]
8 | CMD ["sh"]
--------------------------------------------------------------------------------
/hapi-service/hello-world/dockerfile:
--------------------------------------------------------------------------------
1 | FROM magnitus/node-app:4-slim
2 |
3 | ENV UID="1000"
4 |
5 | COPY ["index.js", "package.json", "${APP_DIR}/"]
6 |
7 | RUN finalize.sh
8 |
9 | USER $UID
10 |
11 | EXPOSE 8080
12 |
--------------------------------------------------------------------------------
/node-app/base-image/example/shared/capitalize-array/index.js:
--------------------------------------------------------------------------------
1 | module.exports = function(array) {
2 | return array.map(function(value) {
3 | return value.charAt(0).toUpperCase() + value.slice(1);
4 | });
5 | }
6 |
7 |
--------------------------------------------------------------------------------
/ansible/push_image.sh:
--------------------------------------------------------------------------------
1 | export IMAGE_REPO=$(cat ./info.json | jq -r ".image_repo")
2 | export VERSION=$(cat ./info.json | jq -r ".version")
3 | export IMAGE=$IMAGE_REPO:$VERSION
4 |
5 | docker build -t $IMAGE .
6 |
7 | docker push $IMAGE
--------------------------------------------------------------------------------
/jedit/entryScript.sh:
--------------------------------------------------------------------------------
1 | echo "${_USER}:x:${_UID}:${_UID}:${_USER},,,:/home/${_USER}:/bin/bash" >> /etc/passwd && \
2 | echo "${_USER}:x:${_UID}:" >> /etc/group && \
3 | chown $_UID:$_UID -R /home/$_USER && \
4 | su - $_USER -c "jedit"
5 |
--------------------------------------------------------------------------------
/node-app/image-builder/example/shared/capitalize-array/index.js:
--------------------------------------------------------------------------------
1 | module.exports = function(array) {
2 | return array.map(function(value) {
3 | return value.charAt(0).toUpperCase() + value.slice(1);
4 | });
5 | }
6 |
7 |
--------------------------------------------------------------------------------
/automated-tests/express-access-control/build.sh:
--------------------------------------------------------------------------------
1 | docker build -t magnitus/automated-tests:0.10-node-express-access-control -f node-0.10.df .;
2 | docker build -t magnitus/automated-tests:4.1-node-express-access-control -f node-4.1.df .;
3 |
--------------------------------------------------------------------------------
/automated-tests/node-4.1-base.df:
--------------------------------------------------------------------------------
1 | FROM node:4.1
2 | RUN apt-get update
3 | RUN apt-get install unzip
4 | COPY ["./build-base.sh", "/opt/build-base.sh"]
5 | RUN chmod +x /opt/build-base.sh
6 | ENTRYPOINT ["/bin/bash"]
7 | CMD ["runtest.sh"]
8 |
--------------------------------------------------------------------------------
/node-app/base-image/example3/shared/array/capitalize-array/index.js:
--------------------------------------------------------------------------------
1 | module.exports = function(array) {
2 | return array.map(function(value) {
3 | return value.charAt(0).toUpperCase() + value.slice(1);
4 | });
5 | }
6 |
7 |
--------------------------------------------------------------------------------
/node-app/dockerfile-builder/example/shared/capitalize-array/index.js:
--------------------------------------------------------------------------------
1 | module.exports = function(array) {
2 | return array.map(function(value) {
3 | return value.charAt(0).toUpperCase() + value.slice(1);
4 | });
5 | }
6 |
7 |
--------------------------------------------------------------------------------
/automated-tests/node-0.10-base.df:
--------------------------------------------------------------------------------
1 | FROM node:0.10
2 | RUN apt-get update
3 | RUN apt-get install unzip
4 | COPY ["./build-base.sh", "/opt/build-base.sh"]
5 | RUN chmod +x /opt/build-base.sh
6 | ENTRYPOINT ["/bin/bash"]
7 | CMD ["runtest.sh"]
8 |
--------------------------------------------------------------------------------
/remote-terraform/push_image.sh:
--------------------------------------------------------------------------------
1 | export IMAGE_REPO=$(cat ./info.json | jq -r ".image_repo")
2 | export VERSION=$(cat ./info.json | jq -r ".version")
3 | export IMAGE=$IMAGE_REPO:$VERSION
4 |
5 | docker build -t $IMAGE .
6 |
7 | docker push $IMAGE
--------------------------------------------------------------------------------
/automated-tests/build.sh:
--------------------------------------------------------------------------------
1 | docker build -t magnitus/automated-tests:node-0.10-base -f node-0.10-base.df .;
2 | docker build -t magnitus/automated-tests:node-4.1-base -f node-4.1-base.df .;
3 | for dir in */ ; do
4 | (cd "$dir"; ./build.sh);
5 | done
6 |
--------------------------------------------------------------------------------
/node-app/base-image/example/shared/user-store/index.js:
--------------------------------------------------------------------------------
1 | const CapitalizeArray = require('capitalize-array');
2 |
3 | module.exports = {
4 | 'getUsers': function() {
5 | return CapitalizeArray(['sally','craigs','chris','tom']);
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/node-app/image-builder/example/shared/user-store/index.js:
--------------------------------------------------------------------------------
1 | const CapitalizeArray = require('capitalize-array');
2 |
3 | module.exports = {
4 | 'getUsers': function() {
5 | return CapitalizeArray(['sally','craigs','chris','tom']);
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/node-app/dockerfile-builder/example/shared/user-store/index.js:
--------------------------------------------------------------------------------
1 | const CapitalizeArray = require('capitalize-array');
2 |
3 | module.exports = {
4 | 'getUsers': function() {
5 | return CapitalizeArray(['sally','craigs','chris','tom']);
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/chrony/README.md:
--------------------------------------------------------------------------------
1 | # Purpose
2 |
3 | Pretty simple image to run Chrony in a container.
4 |
5 | A configuration file needs to be mapped at **/etc/chrony.conf** in the container and you probably want to give the container the **CAP_SYS_TIME** permission as well.
6 |
7 |
--------------------------------------------------------------------------------
/electron-app/app/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Hello World!
6 |
7 |
8 | Hello world from example app!
9 |
10 |
11 |
--------------------------------------------------------------------------------
/hapi-service/README.md:
--------------------------------------------------------------------------------
1 | # hapi-service
2 |
3 | Per-container standalone hapi services that can be bolted to an app behind a reverse-proxy.
4 |
5 | Atm, there is only an hello-world service to test the latest iteration of the letsencrypt reverse-proxy I implemented.
6 |
--------------------------------------------------------------------------------
/network-setup/image/dns.conf.j2:
--------------------------------------------------------------------------------
1 | {% for network in networks %}
2 | {{ network.domain }} {
3 | file /etc/network-setup/zonefile.{{ network.domain }}
4 | log
5 | }
6 | {% endfor %}
7 |
8 | . {
9 | forward . {{ fallback_dns_server }}
10 | log
11 | }
--------------------------------------------------------------------------------
/ssh-encryption/push_image.sh:
--------------------------------------------------------------------------------
1 | export IMAGE_REPO=$(cat ./info.json | jq -r ".image_repo")
2 | export VERSION=$(cat ./info.json | jq -r ".version")
3 | export IMAGE=$IMAGE_REPO:$VERSION
4 |
5 | (
6 | cd image;
7 | docker build -t $IMAGE .;
8 | docker push $IMAGE;
9 | )
--------------------------------------------------------------------------------
/node-app/base-image/example5/dockerfile:
--------------------------------------------------------------------------------
1 | FROM magnitus/node-app:4
2 |
3 | ENV UID="1000"
4 | ENV NPM_COMMAND test
5 |
6 | COPY "app/*" ${APP_DIR}/
7 | COPY "app/test/* ${APP_DIR}/test/
8 | COPY shared/* ${SHARED_DIR}/
9 |
10 | RUN finalize.sh
11 |
12 | USER $UID
13 |
--------------------------------------------------------------------------------
/node-app/base-dev-image/example/shared/module1/index.js:
--------------------------------------------------------------------------------
1 | const Xregexp = require('xregexp');
2 |
3 | module.exports = function() {
4 | console.log('console log from module1, xregexp version should be 3.1.1');
5 | console.log('xregexp version is: '+Xregexp.version);
6 | }
7 |
8 |
--------------------------------------------------------------------------------
/node-app/base-image/example4/shared/module1/index.js:
--------------------------------------------------------------------------------
1 | const Xregexp = require('xregexp');
2 |
3 | module.exports = function() {
4 | console.log('console log from module1, xregexp version should be 3.1.1');
5 | console.log('xregexp version is: '+Xregexp.version);
6 | }
7 |
8 |
--------------------------------------------------------------------------------
/node-app/base-dev-image/example/shared/module2/index.js:
--------------------------------------------------------------------------------
1 | const Xregexp = require('xregexp');
2 |
3 | module.exports = function() {
4 | console.log('console log from module2, xregexp version should be undefined');
5 | console.log('xregexp version is: '+Xregexp.version);
6 | }
7 |
8 |
--------------------------------------------------------------------------------
/node-app/base-image/example4/shared/module2/index.js:
--------------------------------------------------------------------------------
1 | const Xregexp = require('xregexp');
2 |
3 | module.exports = function() {
4 | console.log('console log from module2, xregexp version should be undefined');
5 | console.log('xregexp version is: '+Xregexp.version);
6 | }
7 |
8 |
--------------------------------------------------------------------------------
/node-app/base-image/example5/dockerfile-slim:
--------------------------------------------------------------------------------
1 | FROM magnitus/node-app:4-slim
2 |
3 | ENV UID="1000"
4 | ENV NPM_COMMAND test
5 |
6 | COPY "app/*" ${APP_DIR}/
7 | COPY "app/test/* ${APP_DIR}/test/
8 | COPY shared/* ${SHARED_DIR}/
9 |
10 | RUN finalize.sh
11 |
12 | USER $UID
13 |
--------------------------------------------------------------------------------
/node-app/base-image/example/dockerfile:
--------------------------------------------------------------------------------
1 | FROM magnitus/node-app:4
2 |
3 | ENV UID="1000"
4 |
5 | COPY "app/*" ${APP_DIR}/
6 | COPY "shared/user-store" ${SHARED_DIR}/user-store
7 | COPY "shared/capitalize-array" ${SHARED_DIR}/capitalize-array
8 |
9 | RUN finalize.sh
10 |
11 | USER $UID
12 |
--------------------------------------------------------------------------------
/node-app/base-image/code/finalize.sh:
--------------------------------------------------------------------------------
1 | echo "node-app:x:${UID}:${UID}:node-app,,,:/home/node-app:/bin/bash" >> /etc/passwd;
2 | echo "node-app:x:${UID}:" >> /etc/group;
3 |
4 | /opt/app-setup/resolve_dependencies.js;
5 |
6 | chown -R ${UID}:${UID} /home/node-app;
7 | chown -R ${UID}:${UID} ${SHARED_DIR};
8 |
--------------------------------------------------------------------------------
/node-app/base-image/example/dockerfile-slim:
--------------------------------------------------------------------------------
1 | FROM magnitus/node-app:4-slim
2 |
3 | ENV UID="1000"
4 |
5 | COPY "app/*" ${APP_DIR}/
6 | COPY "shared/user-store" ${SHARED_DIR}/user-store
7 | COPY "shared/capitalize-array" ${SHARED_DIR}/capitalize-array
8 |
9 | RUN finalize.sh
10 |
11 | USER $UID
12 |
--------------------------------------------------------------------------------
/node-app/base-image/example3/shared/user-store/index.js:
--------------------------------------------------------------------------------
1 | const CapitalizeArray = require('capitalize-array');
2 | const SortArray = require('sort-array');
3 |
4 | module.exports = {
5 | 'getUsers': function() {
6 | return SortArray(CapitalizeArray(['sally','craigs','chris','tom']));
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/remote-terraform/binaries/plan:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | mkdir -p /opt/bastion_terraform/roles/deploy_scripts/files
4 | cp -r $TERRAFORM_DIR /opt/bastion_terraform/roles/deploy_scripts/files/terraform
5 | ansible-playbook /opt/bastion_terraform/plan.yml --private-key=$PRIVATE_SSH_KEY -u $ANSIBLE_USER -i $INVENTORY
--------------------------------------------------------------------------------
/jedit/docker-compose.yml:
--------------------------------------------------------------------------------
1 | jedit:
2 | image: magnitus/jedit:latest
3 | environment:
4 | - DISPLAY=$DISPLAY
5 | - _USER=eric
6 | - _UID=1000
7 | volumes:
8 | - /tmp/.X11-unix:/tmp/.X11-unix
9 | - /home/eric
10 | - /home/eric/Projects:/home/eric/files
11 |
--------------------------------------------------------------------------------
/network-setup/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: '3'
2 | services:
3 | setup:
4 | image: magnitus/network-setup:latest
5 | volumes:
6 | - "./conf:/opt/conf"
7 | - "/var/run/docker.sock:/var/run/docker.sock"
8 | - "network-config:/etc/network-setup"
9 |
10 | volumes:
11 | network-config:
--------------------------------------------------------------------------------
/node-app/base-image/example4/app/index.js:
--------------------------------------------------------------------------------
1 | const Xregexp = require('xregexp');
2 | const Bluebird = require('bluebird');
3 |
4 | (require('module1')());
5 | (require('module2')());
6 |
7 | console.log('console log from main, xregexp version should be 3.1.1');
8 | console.log('xregexp version is: '+Xregexp.version);
9 |
--------------------------------------------------------------------------------
/remote-terraform/binaries/apply:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | mkdir -p /opt/bastion_terraform/roles/deploy_scripts/files
4 | cp -r $TERRAFORM_DIR /opt/bastion_terraform/roles/deploy_scripts/files/terraform
5 | ansible-playbook /opt/bastion_terraform/apply.yml --private-key=$PRIVATE_SSH_KEY -u $ANSIBLE_USER -i $INVENTORY
--------------------------------------------------------------------------------
/electron-app/docker-compose.yml:
--------------------------------------------------------------------------------
1 | electron:
2 | image: magnitus/electron-app:dev-beta
3 | environment:
4 | - DISPLAY=$DISPLAY
5 | - _USER=eric
6 | - _UID=1000
7 | volumes:
8 | - /tmp/.X11-unix:/tmp/.X11-unix
9 | - /home/eric
10 | - ./app:/home/eric/app
11 |
--------------------------------------------------------------------------------
/node-app/base-dev-image/example/app/index.js:
--------------------------------------------------------------------------------
1 | const Xregexp = require('xregexp');
2 | const Bluebird = require('bluebird');
3 |
4 | (require('module1')());
5 | (require('module2')());
6 |
7 | console.log('console log from main, xregexp version should be 3.1.1');
8 | console.log('xregexp version is: '+Xregexp.version);
9 |
--------------------------------------------------------------------------------
/chrome/entryScript.sh:
--------------------------------------------------------------------------------
1 | echo "chrome:x:${_UID}:${_UID}:chrome,,,:/home/chrome:/bin/bash" >> /etc/passwd && \
2 | echo "chrome:x:${_UID}:" >> /etc/group && \
3 | chown ${_UID}:${_UID} /home/chrome && \
4 | chown ${_UID}:${_UID} /data && \
5 | usermod -a -G audio chrome && \
6 | su - chrome -c "google-chrome --user-data-dir=/data"
7 |
--------------------------------------------------------------------------------
/node-app/base-dev-image/example/docker-compose.yml:
--------------------------------------------------------------------------------
1 | app:
2 | image: magnitus/node-app:4-dev
3 | container_name: node-app-dev-example
4 | environment:
5 | - UID=1000
6 | - NPM_MODULES=bluebird@3;xregexp@3.1.1
7 | volumes:
8 | - ./app:/home/node-app/app
9 | - ./shared:/home/node-app/shared_modules
10 |
--------------------------------------------------------------------------------
/node-app/base-image/example4/dockerfile:
--------------------------------------------------------------------------------
1 | FROM magnitus/node-app:4
2 |
3 | ENV UID="1000"
4 |
5 | COPY "app/*" ${APP_DIR}/
6 | COPY "shared/module1" ${SHARED_DIR}/module1
7 | COPY "shared/module2" ${SHARED_DIR}/module2
8 |
9 | ENV NPM_MODULES="bluebird@3;xregexp@3.1.1"
10 |
11 | RUN finalize.sh
12 |
13 | USER $UID
14 |
--------------------------------------------------------------------------------
/isc-dhcp-server/example/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: "3"
2 | services:
3 | dhcp-server:
4 | image: magnitus/isc-dhcp-server:latest
5 | restart: always
6 | network_mode: host
7 | environment:
8 | INTERFACE: eth0
9 | volumes:
10 | - ./dhcpd.conf:/opt/dhcp/dhcpd.conf
--------------------------------------------------------------------------------
/node-app/base-image/example/app/index.js:
--------------------------------------------------------------------------------
1 | //Sample app that prints all the users in a mock database
2 | //The database entrypoints would be shared modules accross apps
3 | var UserStore = require('user-store');
4 |
5 | var users = UserStore.getUsers();
6 |
7 | users.forEach(function(user) {
8 | console.log(user);
9 | });
10 |
--------------------------------------------------------------------------------
/node-app/base-image/example3/app/index.js:
--------------------------------------------------------------------------------
1 | //Sample app that prints all the users in a mock database
2 | //The database entrypoints would be shared modules accross apps
3 | var UserStore = require('user-store');
4 |
5 | var users = UserStore.getUsers();
6 |
7 | users.forEach(function(user) {
8 | console.log(user);
9 | });
10 |
--------------------------------------------------------------------------------
/node-app/image-builder/example/app/index.js:
--------------------------------------------------------------------------------
1 | //Sample app that prints all the users in a mock database
2 | //The database entrypoints would be shared modules accross apps
3 | var UserStore = require('user-store');
4 |
5 | var users = UserStore.getUsers();
6 |
7 | users.forEach(function(user) {
8 | console.log(user);
9 | });
10 |
--------------------------------------------------------------------------------
/react-build/example-onbuild/docker-compose.yml:
--------------------------------------------------------------------------------
1 | app:
2 | container_name: react-compiler-onbuild-example
3 | build: .
4 | environment:
5 | - BUILD_FILE=/opt/build.json
6 | volumes:
7 | - ./build.json:/opt/build.json
8 | - ./app/javascript:/opt/app/javascript
9 | - ./lib:/opt/lib
10 | - ./app/dist:/opt/dist
11 |
--------------------------------------------------------------------------------
/node-app/dockerfile-builder/example/app/index.js:
--------------------------------------------------------------------------------
1 | //Sample app that prints all the users in a mock database
2 | //The database entrypoints would be shared modules accross apps
3 | var UserStore = require('user-store');
4 |
5 | var users = UserStore.getUsers();
6 |
7 | users.forEach(function(user) {
8 | console.log(user);
9 | });
10 |
--------------------------------------------------------------------------------
/automated-tests/build-base.sh:
--------------------------------------------------------------------------------
1 | wget --output-document="/opt/master.zip" https://github.com/Magnitus-/$PROJECT/archive/master.zip;
2 | (cd /opt; unzip master.zip);
3 | (cd /opt/"$PROJECT"-master; npm install);
4 | touch /bin/runtest.sh;
5 | echo "(cd /opt/$PROJECT-master; npm test)" > /bin/runtest.sh;
6 | chmod +x /bin/runtest.sh;
7 | rm /opt/master.zip;
8 |
--------------------------------------------------------------------------------
/isc-dhcp-server/entrypoint.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | cp $SOURCE_CONF_PATH $CONF_PATH;
4 | touch $LEASE_PATH;
5 |
6 | chown $RUNTIME_USER:$RUNTIME_USER $CONF_PATH;
7 | chown $RUNTIME_USER:$RUNTIME_USER $LEASE_PATH;
8 |
9 | exec /usr/sbin/dhcpd -$IP_VERSION -d -f --no-pid -user $RUNTIME_USER -group $RUNTIME_USER -cf $CONF_PATH -lf $LEASE_PATH $INTERFACE
--------------------------------------------------------------------------------
/.github/workflows/build_ansible.yml:
--------------------------------------------------------------------------------
1 | name: Build Ansible Image
2 |
3 | on:
4 | push:
5 | paths:
6 | - 'ansible/**'
7 |
8 | jobs:
9 | publish:
10 | name: Build Image
11 | runs-on: ubuntu-18.04
12 | steps:
13 | - uses: actions/checkout@v2
14 | - name: Build the image
15 | run: cd ansible && docker build -t test:test .
--------------------------------------------------------------------------------
/automated-tests/user-store/run.sh:
--------------------------------------------------------------------------------
1 | docker run -d --net none --name user-store-db mongo:3.1;
2 | docker run -it --rm --net container:user-store-db magnitus/automated-tests:4.1-node-user-store;
3 | docker run -it --rm --net container:user-store-db magnitus/automated-tests:0.10-node-user-store;
4 | docker stop user-store-db;
5 | docker rm user-store-db;
6 |
7 |
8 |
--------------------------------------------------------------------------------
/electron-app/dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:latest
2 | RUN apt-get update -y && \
3 | apt-get install -y libgtk2.0-0 && \
4 | apt-get install -y libnotify-dev && \
5 | apt-get install -y libgconf-2-4 && \
6 | apt-get install -y libnss3
7 | COPY ["./entryScript.sh", "/opt/entryScript.sh"]
8 | RUN chmod +x /opt/entryScript.sh
9 | ENTRYPOINT ["/bin/bash", "/opt/entryScript.sh"]
--------------------------------------------------------------------------------
/node-app/base-image/example3/dockerfile:
--------------------------------------------------------------------------------
1 | FROM magnitus/node-app:4
2 |
3 | ENV UID="1000"
4 |
5 | COPY "app/*" ${APP_DIR}/
6 | COPY "shared/user-store" ${SHARED_DIR}/user-store
7 | COPY "shared/array/capitalize-array" ${SHARED_DIR}/array/capitalize-array
8 | COPY "shared/array/sort-array" ${SHARED_DIR}/array/sort-array
9 |
10 | RUN finalize.sh
11 |
12 | USER $UID
13 |
--------------------------------------------------------------------------------
/node-app/base-image/example3/shared/array/sort-array/index.js:
--------------------------------------------------------------------------------
1 | function compare(a, b)
2 | {
3 | if(a.length < b.length)
4 | {
5 | return -1;
6 | }
7 |
8 | if(a.length > b.length)
9 | {
10 | return 1;
11 | }
12 |
13 | return 0;
14 | }
15 |
16 | module.exports = function(array) {
17 | return array.sort(compare);
18 | }
19 |
20 |
--------------------------------------------------------------------------------
/react-build/example/docker-compose.yml:
--------------------------------------------------------------------------------
1 | app:
2 | container_name: react-compiler-example
3 | image: magnitus/react-compiler:latest-slim
4 | environment:
5 | - BUILD_FILE=/opt/build.json
6 | - OUTPUT_UID=1000
7 | volumes:
8 | - ./build.json:/opt/build.json
9 | - ./app/javascript:/opt/app/javascript
10 | - ./lib:/opt/lib
11 | - ./app/dist:/opt/dist
12 |
--------------------------------------------------------------------------------
/sbt/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM openjdk:14-jdk-buster
2 |
3 | RUN apt-get update && apt-get install -y curl gnupg
4 | RUN echo "deb https://dl.bintray.com/sbt/debian/ /" > /etc/apt/sources.list.d/sbt.list
5 | RUN curl -sL "https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x2EE0EA64E40A89B84B2DF73499E82A75642AC823" | apt-key add
6 | RUN apt-get update && apt-get install -y sbt
7 | RUN sbt --version
--------------------------------------------------------------------------------
/.github/workflows/build_ssh_encryption.yml:
--------------------------------------------------------------------------------
1 | name: Build Ssh Encryption Image
2 |
3 | on:
4 | push:
5 | paths:
6 | - 'ssh-encryption/**'
7 |
8 | jobs:
9 | publish:
10 | name: Build Image
11 | runs-on: ubuntu-18.04
12 | steps:
13 | - uses: actions/checkout@v2
14 | - name: Build the image
15 | run: cd ssh-encryption/image && docker build -t test:test .
--------------------------------------------------------------------------------
/.github/workflows/build_remote_terraform.yml:
--------------------------------------------------------------------------------
1 | name: Build Remote Terraform Image
2 |
3 | on:
4 | push:
5 | paths:
6 | - 'remote-terraform/**'
7 |
8 | jobs:
9 | publish:
10 | name: Build Image
11 | runs-on: ubuntu-18.04
12 | steps:
13 | - uses: actions/checkout@v2
14 | - name: Build the image
15 | run: cd remote-terraform && docker build -t test:test .
--------------------------------------------------------------------------------
/node-app/dockerfile-builder/code/dockerfile:
--------------------------------------------------------------------------------
1 | FROM docker:1.11
2 |
3 | ENV TEMPLATE_PATH /opt/build/template
4 | ENV APP_DIR /opt/app
5 | ENV SHARED_DIR /opt/shared
6 | ENV OUTPUT_DIR /opt/output
7 |
8 | RUN apk add --no-cache nodejs
9 | COPY ["app/", "/opt/build/"]
10 | RUN (cd /opt/build; npm install)
11 |
12 | WORKDIR /opt/build
13 |
14 | ENTRYPOINT ["/usr/bin/npm"]
15 | CMD ["start"]
16 |
17 |
--------------------------------------------------------------------------------
/node-app/base-image/example5/shared/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "is-prime",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "licenses": [
6 | {
7 | "type": "MIT License",
8 | "url": "http://mit-license.org/"
9 | }
10 | ],
11 | "dependencies": {
12 | },
13 | "devDependencies": {
14 | },
15 | "license": "MIT",
16 | "directories": {
17 | },
18 | "scripts": {
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/node-app/base-image/example4/shared/module1/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "module1",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "licenses": [
6 | {
7 | "type": "MIT License",
8 | "url": "http://mit-license.org/"
9 | }
10 | ],
11 | "dependencies": {
12 | },
13 | "devDependencies": {
14 | },
15 | "license": "MIT",
16 | "directories": {
17 | },
18 | "scripts": {
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/node-app/image-builder/example2/shared/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "is-prime",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "licenses": [
6 | {
7 | "type": "MIT License",
8 | "url": "http://mit-license.org/"
9 | }
10 | ],
11 | "dependencies": {
12 | },
13 | "devDependencies": {
14 | },
15 | "license": "MIT",
16 | "directories": {
17 | },
18 | "scripts": {
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/certificate/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM debian:stretch
2 |
3 | ENV KEY_FILE domain.key
4 | ENV CSR_FILE domain.csr
5 | ENV CERTIFICATE_FILE domain.crt
6 | ENV OUTPUT_DIR /opt/output
7 | ENV KEY_BITS 2048
8 | ENV CERTIFICATE_DURATION 365
9 |
10 | RUN apt-get update && apt-get install -y openssl && apt-get install -y python
11 |
12 | COPY generateCertificate.py /opt/scripts/
13 |
14 | CMD ["python", "/opt/scripts/generateCertificate.py"]
15 |
--------------------------------------------------------------------------------
/node-app/base-dev-image/example/shared/module1/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "module1",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "licenses": [
6 | {
7 | "type": "MIT License",
8 | "url": "http://mit-license.org/"
9 | }
10 | ],
11 | "dependencies": {
12 | },
13 | "devDependencies": {
14 | },
15 | "license": "MIT",
16 | "directories": {
17 | },
18 | "scripts": {
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/node-app/base-image/example3/shared/array/sort-array/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "sort-array",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "licenses": [
6 | {
7 | "type": "MIT License",
8 | "url": "http://mit-license.org/"
9 | }
10 | ],
11 | "dependencies": {
12 | },
13 | "devDependencies": {
14 | },
15 | "license": "MIT",
16 | "directories": {
17 | },
18 | "scripts": {
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/node-app/base-image/example/shared/capitalize-array/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "capitalize-array",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "licenses": [
6 | {
7 | "type": "MIT License",
8 | "url": "http://mit-license.org/"
9 | }
10 | ],
11 | "dependencies": {
12 | },
13 | "devDependencies": {
14 | },
15 | "license": "MIT",
16 | "directories": {
17 | },
18 | "scripts": {
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/node-app/image-builder/example/shared/capitalize-array/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "capitalize-array",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "licenses": [
6 | {
7 | "type": "MIT License",
8 | "url": "http://mit-license.org/"
9 | }
10 | ],
11 | "dependencies": {
12 | },
13 | "devDependencies": {
14 | },
15 | "license": "MIT",
16 | "directories": {
17 | },
18 | "scripts": {
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/network-setup/image/zonefile.j2:
--------------------------------------------------------------------------------
1 | $TTL {{ ttl.default }}
2 | $ORIGIN {{ domain }}.
3 | @ IN SOA nameserver.{{ domain }}. email.{{ domain }}. (
4 | {{ timestamp }};
5 | 7200;
6 | 3600;
7 | 1209600;
8 | 3600;
9 |
10 | )
11 | IN NS nameserver.{{ domain }}.
12 | nameserver {{ ttl.default }} IN A {{ ip }}
13 | {% for static_host in network.static_hosts %}
14 | {{ static_host.name }} {{ ttl.short }} IN A {{ static_host.ip }}
15 | {% endfor %}
--------------------------------------------------------------------------------
/node-app/base-image/example3/shared/array/capitalize-array/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "capitalize-array",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "licenses": [
6 | {
7 | "type": "MIT License",
8 | "url": "http://mit-license.org/"
9 | }
10 | ],
11 | "dependencies": {
12 | },
13 | "devDependencies": {
14 | },
15 | "license": "MIT",
16 | "directories": {
17 | },
18 | "scripts": {
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/node-app/dockerfile-builder/example/shared/capitalize-array/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "capitalize-array",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "licenses": [
6 | {
7 | "type": "MIT License",
8 | "url": "http://mit-license.org/"
9 | }
10 | ],
11 | "dependencies": {
12 | },
13 | "devDependencies": {
14 | },
15 | "license": "MIT",
16 | "directories": {
17 | },
18 | "scripts": {
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/node-app/base-image/example4/shared/module2/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "module2",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "licenses": [
6 | {
7 | "type": "MIT License",
8 | "url": "http://mit-license.org/"
9 | }
10 | ],
11 | "dependencies": {
12 | "xregexp": "2.x"
13 | },
14 | "devDependencies": {
15 | },
16 | "license": "MIT",
17 | "directories": {
18 | },
19 | "scripts": {
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/node-app/base-image/example5/shared/index.js:
--------------------------------------------------------------------------------
1 | module.exports = function(candidate) {
2 | var max = Math.floor(Math.sqrt(candidate));
3 | var index = 3;
4 | if(candidate % 2 == 0 && candidate != 2)
5 | {
6 | return false;
7 | }
8 | while(index <= max)
9 | {
10 | if(candidate % index == 0)
11 | {
12 | return false;
13 | }
14 | index += 2;
15 | }
16 | return true;
17 | }
18 |
--------------------------------------------------------------------------------
/node-app/dockerfile-builder/example/docker-compose.yml:
--------------------------------------------------------------------------------
1 | app:
2 | container_name: build-example
3 | image: magnitus/node-app:dockerfile-builder
4 | environment:
5 | - UID=1000
6 | - OUTPUT_UID=1000
7 | - OUTPUT_IMAGE=magnitus/node-app:dockerfile-builder-example
8 | - IGNORE=.+~$$
9 | volumes:
10 | - ./app:/opt/app
11 | - ./shared:/opt/shared
12 | - ./output:/opt/output
13 | - /var/run/docker.sock:/var/run/docker.sock
14 |
--------------------------------------------------------------------------------
/node-app/base-dev-image/example/shared/module2/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "module2",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "licenses": [
6 | {
7 | "type": "MIT License",
8 | "url": "http://mit-license.org/"
9 | }
10 | ],
11 | "dependencies": {
12 | "xregexp": "2.x"
13 | },
14 | "devDependencies": {
15 | },
16 | "license": "MIT",
17 | "directories": {
18 | },
19 | "scripts": {
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/node-app/image-builder/example2/shared/index.js:
--------------------------------------------------------------------------------
1 | module.exports = function(candidate) {
2 | var max = Math.floor(Math.sqrt(candidate));
3 | var index = 3;
4 | if(candidate % 2 == 0 && candidate != 2)
5 | {
6 | return false;
7 | }
8 | while(index <= max)
9 | {
10 | if(candidate % index == 0)
11 | {
12 | return false;
13 | }
14 | index += 2;
15 | }
16 | return true;
17 | }
18 |
--------------------------------------------------------------------------------
/pulsar-orchestration/README.md:
--------------------------------------------------------------------------------
1 | # About
2 |
3 | This is a "high availability" local orchestration for Apache Pulsar (yes, **high availability** and **local** are somewhat of an oxymoron, hence the quotes)
4 |
5 | This not meant to be used in production. There is an official Helm chart for that: http://pulsar.apache.org/docs/en/helm-install/
6 |
7 | This is more of a personal exercise to get some hands on practice on how the different components of a Pulsar cluster fit together.
--------------------------------------------------------------------------------
/react-build/example/app/javascript/header.jsx:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 | var ReactDOM = require('react-dom');
3 |
4 | module.exports = React.createClass({
5 | render: function() {
6 | return (
7 |
8 | Welcome to React Lotto!
9 | The lotto where you dream less, but the mathematical expectation of your gains is much higher!
10 |
11 | );
12 | }
13 | });
14 |
--------------------------------------------------------------------------------
/hapi-service/hello-world/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "geev-hello-word",
3 | "version": "0.1.0",
4 | "description": "Tractr private app.",
5 | "author": "Eric Vallee ",
6 | "main": "./index.js",
7 | "repository": {
8 | "type": "git",
9 | "url": "git@bitbucket.org:tractrs/geev-api.git"
10 | },
11 | "dependencies": {
12 | "hapi": "13.x"
13 | },
14 | "scripts": {
15 | "start": "node ./index.js"
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/node-app/base-image/example/shared/user-store/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "user-store",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "licenses": [
6 | {
7 | "type": "MIT License",
8 | "url": "http://mit-license.org/"
9 | }
10 | ],
11 | "dependencies": {
12 | },
13 | "devDependencies": {
14 | },
15 | "localDependencies": ["capitalize-array"],
16 | "license": "MIT",
17 | "directories": {
18 | },
19 | "scripts": {
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/node-app/base-image/example2/app/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "sample-hapi-app",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "licenses": [
6 | {
7 | "type": "MIT License",
8 | "url": "http://mit-license.org/"
9 | }
10 | ],
11 | "dependencies": {
12 | "hapi": "13.x"
13 | },
14 | "devDependencies": {
15 | },
16 | "license": "MIT",
17 | "directories": {
18 | },
19 | "scripts": {
20 | "start": "node index.js"
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/node-app/dockerfile-builder/templates/docker-compose.yml:
--------------------------------------------------------------------------------
1 | app:
2 | container_name: <>
3 | image: magnitus/node-app:dockerfile-builder
4 | environment:
5 | - UID=<<1000>>
6 | - OUTPUT_UID=<<1000>>
7 | - OUTPUT_IMAGE=<>
8 | - IGNORE=.+~$$
9 | volumes:
10 | - <<./app>>:/opt/app
11 | - <<./shared>>:/opt/shared
12 | - <<./output>>:/opt/output
13 | - /var/run/docker.sock:/var/run/docker.sock
14 |
--------------------------------------------------------------------------------
/node-app/image-builder/example/shared/user-store/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "user-store",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "licenses": [
6 | {
7 | "type": "MIT License",
8 | "url": "http://mit-license.org/"
9 | }
10 | ],
11 | "dependencies": {
12 | },
13 | "devDependencies": {
14 | },
15 | "localDependencies": ["capitalize-array"],
16 | "license": "MIT",
17 | "directories": {
18 | },
19 | "scripts": {
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/react-build/example-onbuild/app/javascript/header.jsx:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 | var ReactDOM = require('react-dom');
3 |
4 | module.exports = React.createClass({
5 | render: function() {
6 | return (
7 |
8 | Welcome to React Lotto!
9 | The lotto where you dream less, but the mathematical expectation of your gains is much higher!
10 |
11 | );
12 | }
13 | });
14 |
--------------------------------------------------------------------------------
/node-app/dockerfile-builder/example/shared/user-store/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "user-store",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "licenses": [
6 | {
7 | "type": "MIT License",
8 | "url": "http://mit-license.org/"
9 | }
10 | ],
11 | "dependencies": {
12 | },
13 | "devDependencies": {
14 | },
15 | "localDependencies": ["capitalize-array"],
16 | "license": "MIT",
17 | "directories": {
18 | },
19 | "scripts": {
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/node-app/image-builder/code/app/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "builder-app",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "licenses": [
6 | {
7 | "type": "MIT License",
8 | "url": "http://mit-license.org/"
9 | }
10 | ],
11 | "dependencies": {
12 | "act-on-modules": "0.1.0"
13 | },
14 | "devDependencies": {
15 | },
16 | "license": "MIT",
17 | "directories": {
18 | },
19 | "scripts": {
20 | "start": "node index.js"
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/node-app/base-image/example3/shared/user-store/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "user-store",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "licenses": [
6 | {
7 | "type": "MIT License",
8 | "url": "http://mit-license.org/"
9 | }
10 | ],
11 | "dependencies": {
12 | },
13 | "devDependencies": {
14 | },
15 | "localDependencies": ["capitalize-array", "sort-array"],
16 | "license": "MIT",
17 | "directories": {
18 | },
19 | "scripts": {
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/pulsar-orchestration/zookeeper-conf/zoo.cfg:
--------------------------------------------------------------------------------
1 | #Taken from recommended zookeeper configuration file with minimal adjustments
2 | tickTime=2000
3 | initLimit=10
4 | syncLimit=5
5 | dataDir=/data
6 | dataLogDir=/datalog
7 | clientPort=2181
8 | admin.enableServer=true
9 | admin.serverPort=9990
10 | autopurge.snapRetainCount=3
11 | autopurge.purgeInterval=1
12 | forceSync=yes
13 | server.1=zookeeper-one:2888:3888;2181
14 | server.2=zookeeper-two:2888:3888;2181
15 | server.3=zookeeper-three:2888:3888;2181
--------------------------------------------------------------------------------
/electron-app/app/main.js:
--------------------------------------------------------------------------------
1 | const electron = require('electron');
2 |
3 | electron.crashReporter.start();
4 |
5 | var mainWindow = null;
6 |
7 | electron.app.on('window-all-closed', function() {
8 | electron.app.quit();
9 | });
10 |
11 | electron.app.on('ready', function() {
12 | mainWindow = new electron.BrowserWindow();
13 | mainWindow.loadURL('file://' + __dirname + '/index.html');
14 | mainWindow.on('closed', function() {
15 | mainWindow = null;
16 | });
17 | });
18 |
--------------------------------------------------------------------------------
/network-setup/image/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM python:3-stretch
2 |
3 | ENV CONFIG_DIRECTORY /etc/network-setup
4 | ENV TEMPLATE_DIRECTORY /opt/templates
5 | ENV SCRIPT_DIRECTORY /opt/scripts
6 |
7 | RUN pip install Jinja2 pyyaml docker && mkdir -p $SCRIPT_DIRECTORY && mkdir -p $TEMPLATE_DIRECTORY
8 |
9 | ENV DNS_IMAGE=coredns/coredns:latest
10 | ENV DHCP_IMAGE=magnitus/isc-dhcp-server:latest
11 |
12 | COPY setup.py $SCRIPT_DIRECTORY/
13 | COPY *.j2 $TEMPLATE_DIRECTORY/
14 |
15 | CMD ["/opt/scripts/setup.py"]
--------------------------------------------------------------------------------
/node-app/base-image/example/app/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "sample-app",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "licenses": [
6 | {
7 | "type": "MIT License",
8 | "url": "http://mit-license.org/"
9 | }
10 | ],
11 | "dependencies": {
12 | },
13 | "devDependencies": {
14 | },
15 | "localDependencies": ["user-store"],
16 | "license": "MIT",
17 | "directories": {
18 | },
19 | "scripts": {
20 | "start": "node index.js"
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/node-app/base-image/example3/app/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "sample-app",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "licenses": [
6 | {
7 | "type": "MIT License",
8 | "url": "http://mit-license.org/"
9 | }
10 | ],
11 | "dependencies": {
12 | },
13 | "devDependencies": {
14 | },
15 | "localDependencies": ["user-store"],
16 | "license": "MIT",
17 | "directories": {
18 | },
19 | "scripts": {
20 | "start": "node index.js"
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/node-app/image-builder/example/app/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "sample-app",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "licenses": [
6 | {
7 | "type": "MIT License",
8 | "url": "http://mit-license.org/"
9 | }
10 | ],
11 | "dependencies": {
12 | },
13 | "devDependencies": {
14 | },
15 | "localDependencies": ["user-store"],
16 | "license": "MIT",
17 | "directories": {
18 | },
19 | "scripts": {
20 | "start": "node index.js"
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/node-app/base-image/example4/app/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "sample-app",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "licenses": [
6 | {
7 | "type": "MIT License",
8 | "url": "http://mit-license.org/"
9 | }
10 | ],
11 | "dependencies": {
12 | },
13 | "devDependencies": {
14 | },
15 | "localDependencies": ["module1","module2"],
16 | "license": "MIT",
17 | "directories": {
18 | },
19 | "scripts": {
20 | "start": "node index.js"
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/node-app/dockerfile-builder/example/app/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "sample-app",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "licenses": [
6 | {
7 | "type": "MIT License",
8 | "url": "http://mit-license.org/"
9 | }
10 | ],
11 | "dependencies": {
12 | },
13 | "devDependencies": {
14 | },
15 | "localDependencies": ["user-store"],
16 | "license": "MIT",
17 | "directories": {
18 | },
19 | "scripts": {
20 | "start": "node index.js"
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/node-app/base-dev-image/example/app/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "sample-app",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "licenses": [
6 | {
7 | "type": "MIT License",
8 | "url": "http://mit-license.org/"
9 | }
10 | ],
11 | "dependencies": {
12 | },
13 | "devDependencies": {
14 | },
15 | "localDependencies": ["module1","module2"],
16 | "license": "MIT",
17 | "directories": {
18 | },
19 | "scripts": {
20 | "start": "node index.js"
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/node-app/dockerfile-builder/code/app/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "builder-app",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "licenses": [
6 | {
7 | "type": "MIT License",
8 | "url": "http://mit-license.org/"
9 | }
10 | ],
11 | "dependencies": {
12 | "chownr": "1.x",
13 | "cpr": "1.x"
14 | },
15 | "devDependencies": {
16 | },
17 | "license": "MIT",
18 | "directories": {
19 | },
20 | "scripts": {
21 | "start": "node index.js"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/react-build/example/app/javascript/index.jsx:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 | var ReactDOM = require('react-dom');
3 | var App = require('app');
4 |
5 | var reactElement = React.createElement(App, {'balls': 50,
6 | 'draws': 3,
7 | 'initPot': 200,
8 | 'winRatios': [0.375, 0.075, 0.05]});
9 | ReactDOM.render(reactElement, document.getElementById('app'));
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.github/workflows/publish_ansible.yml:
--------------------------------------------------------------------------------
1 | name: Publish Ansible Image
2 |
3 | on:
4 | push:
5 | branches:
6 | - master
7 | paths:
8 | - 'ansible/**'
9 |
10 | jobs:
11 | publish:
12 | name: Publish Image
13 | runs-on: ubuntu-18.04
14 | steps:
15 | - uses: actions/checkout@v2
16 | - name: Log into registry
17 | run: echo "${{ secrets.DOCKER_HUB_TOKEN }}" | docker login -u magnitus --password-stdin
18 | - name: Publish the image
19 | run: cd ansible && ./push_image.sh
--------------------------------------------------------------------------------
/node-app/image-builder/code/server/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "builder-app-server",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "licenses": [
6 | {
7 | "type": "MIT License",
8 | "url": "http://mit-license.org/"
9 | }
10 | ],
11 | "dependencies": {
12 | "hapi": "13.x",
13 | "inert": ""
14 | },
15 | "devDependencies": {
16 | },
17 | "license": "MIT",
18 | "directories": {
19 | },
20 | "scripts": {
21 | "start": "node index.js"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/node-app/image-builder/example/docker-compose.yml:
--------------------------------------------------------------------------------
1 | app:
2 | container_name: build-image-example
3 | image: magnitus/node-app:image-builder
4 | environment:
5 | - UID=1000
6 | - OUTPUT_IMAGE=magnitus/node-app:image-builder-example
7 | - IGNORE=.+~$$
8 | - EXTERNAL_PORT=8080
9 | - DOCKER_LOCALHOST=172.17.0.1
10 | - CACHE=no
11 | volumes:
12 | - ./app:/opt/app
13 | - ./shared:/opt/shared
14 | - /var/run/docker.sock:/var/run/docker.sock
15 | ports:
16 | - "8080:8080"
17 |
--------------------------------------------------------------------------------
/react-build/example-onbuild/app/javascript/index.jsx:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 | var ReactDOM = require('react-dom');
3 | var App = require('app');
4 |
5 | var reactElement = React.createElement(App, {'balls': 50,
6 | 'draws': 3,
7 | 'initPot': 200,
8 | 'winRatios': [0.375, 0.075, 0.05]});
9 | ReactDOM.render(reactElement, document.getElementById('app'));
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/node-app/base-image/example5/app/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "sample-test",
3 | "version": "1.0.0",
4 | "licenses": [
5 | {
6 | "type": "MIT License",
7 | "url": "http://mit-license.org/"
8 | }
9 | ],
10 | "dependencies": {
11 | "nodeunit": "^0.9.1"
12 | },
13 | "devDependencies": {
14 | },
15 | "localDependencies": ["is-prime"],
16 | "license": "MIT",
17 | "directories": {
18 | },
19 | "scripts": {
20 | "test": "./node_modules/nodeunit/bin/nodeunit test"
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/node-app/image-builder/example2/app/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "sample-test",
3 | "version": "1.0.0",
4 | "licenses": [
5 | {
6 | "type": "MIT License",
7 | "url": "http://mit-license.org/"
8 | }
9 | ],
10 | "dependencies": {
11 | "nodeunit": "^0.9.1"
12 | },
13 | "devDependencies": {
14 | },
15 | "localDependencies": ["is-prime"],
16 | "license": "MIT",
17 | "directories": {
18 | },
19 | "scripts": {
20 | "test": "./node_modules/nodeunit/bin/nodeunit test"
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/isc-dhcp-server/Dockerfile-amd64:
--------------------------------------------------------------------------------
1 | FROM debian:stretch-slim
2 |
3 | RUN apt-get update -y && \
4 | apt-get install -y isc-dhcp-server && \
5 | apt-get autoremove -y && \
6 | apt-get clean -y
7 |
8 | ENV RUNTIME_USER=www-data
9 | ENV SOURCE_CONF_PATH=/opt/dhcp/dhcpd.conf
10 | ENV IP_VERSION=4
11 | ENV INTERFACE=eth0
12 |
13 | ENV CONF_PATH=/etc/dhcp/dhcp.conf
14 | ENV LEASE_PATH=/var/lib/dhcp/dhcp.lease
15 |
16 | COPY entrypoint.sh /opt/entrypoint.sh
17 | RUN chmod +x /opt/entrypoint.sh
18 |
19 | CMD ["/opt/entrypoint.sh"]
--------------------------------------------------------------------------------
/electron-app/entryScript.sh:
--------------------------------------------------------------------------------
1 | echo "${_USER}:x:${_UID}:${_UID}:${_USER},,,:/home/${_USER}:/bin/bash" >> /etc/passwd && \
2 | echo "${_USER}:x:${_UID}:" >> /etc/group && \
3 | chown $_UID:$_UID -R /home/$_USER
4 | su $_USER <<'EOF'
5 | if [ ! -d "/home/${_USER}/app/node_modules" ]; then
6 | (cd /home/$_USER/app; npm install; npm install electron-rebuild; /home/$_USER/app/node_modules/.bin/electron-rebuild; npm install electron-prebuilt)
7 | fi
8 | /home/$_USER/app/node_modules/electron-prebuilt/dist/electron /home/$_USER/app;
9 | EOF
10 |
--------------------------------------------------------------------------------
/isc-dhcp-server/Dockerfile-arm64:
--------------------------------------------------------------------------------
1 | FROM arm64v8/debian:stretch-slim
2 |
3 | RUN apt-get update -y && \
4 | apt-get install -y isc-dhcp-server && \
5 | apt-get autoremove -y && \
6 | apt-get clean -y
7 |
8 | ENV RUNTIME_USER=www-data
9 | ENV SOURCE_CONF_PATH=/opt/dhcp/dhcpd.conf
10 | ENV IP_VERSION=4
11 | ENV INTERFACE=eth0
12 |
13 | ENV CONF_PATH=/etc/dhcp/dhcp.conf
14 | ENV LEASE_PATH=/var/lib/dhcp/dhcp.lease
15 |
16 | COPY entrypoint.sh /opt/entrypoint.sh
17 | RUN chmod +x /opt/entrypoint.sh
18 |
19 | CMD ["/opt/entrypoint.sh"]
--------------------------------------------------------------------------------
/.github/workflows/publish_ssh_encryption.yml:
--------------------------------------------------------------------------------
1 | name: Publish Ssh Encryption Image
2 |
3 | on:
4 | push:
5 | branches:
6 | - master
7 | paths:
8 | - 'ssh-encryption/**'
9 |
10 | jobs:
11 | publish:
12 | name: Publish Image
13 | runs-on: ubuntu-18.04
14 | steps:
15 | - uses: actions/checkout@v2
16 | - name: Log into registry
17 | run: echo "${{ secrets.DOCKER_HUB_TOKEN }}" | docker login -u magnitus --password-stdin
18 | - name: Publish the image
19 | run: cd ssh-encryption && ./push_image.sh
--------------------------------------------------------------------------------
/node-app/image-builder/example2/docker-compose.yml:
--------------------------------------------------------------------------------
1 | app:
2 | container_name: build-image-example2
3 | image: magnitus/node-app:image-builder
4 | environment:
5 | - UID=1000
6 | - OUTPUT_IMAGE=magnitus/node-app:image-builder-example2
7 | - IGNORE=.+~$$
8 | - EXTERNAL_PORT=8080
9 | - DOCKER_LOCALHOST=172.17.0.1
10 | - CACHE=no
11 | - NPM_COMMAND=test
12 | volumes:
13 | - ./app:/opt/app
14 | - ./shared:/opt/shared
15 | - /var/run/docker.sock:/var/run/docker.sock
16 | ports:
17 | - "8080:8080"
18 |
--------------------------------------------------------------------------------
/.github/workflows/publish_remote_terraform.yml:
--------------------------------------------------------------------------------
1 | name: Publish Remote Terraform Image
2 |
3 | on:
4 | push:
5 | branches:
6 | - master
7 | paths:
8 | - 'remote-terraform/**'
9 |
10 | jobs:
11 | publish:
12 | name: Publish Image
13 | runs-on: ubuntu-18.04
14 | steps:
15 | - uses: actions/checkout@v2
16 | - name: Log into registry
17 | run: echo "${{ secrets.DOCKER_HUB_TOKEN }}" | docker login -u magnitus --password-stdin
18 | - name: Publish the image
19 | run: cd remote-terraform && ./push_image.sh
--------------------------------------------------------------------------------
/node-app/image-builder/templates/docker-compose.yml:
--------------------------------------------------------------------------------
1 | app:
2 | container_name: <>
3 | image: magnitus/node-app:image-builder
4 | environment:
5 | - UID=<<1000>>
6 | - OUTPUT_IMAGE=<>
7 | - IGNORE=<<.+~$$>>
8 | - EXTERNAL_PORT=<<8080>>
9 | - DOCKER_LOCALHOST=<<172.17.0.1>>
10 | - CACHE=<>
11 | volumes:
12 | - <<./app>>:/opt/app
13 | - <<./shared>>:/opt/shared
14 | - /var/run/docker.sock:/var/run/docker.sock
15 | ports:
16 | - "<<8080>>:8080"
17 |
--------------------------------------------------------------------------------
/ssh-encryption/example/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: '3.7'
2 | services:
3 | encrypt:
4 | build: ../image
5 | command: ssh-encrypt
6 | environment:
7 | FILE: /opt/target/test.txt
8 | PUBLIC_KEY: /opt/.ssh/id_rsa.pub
9 | volumes:
10 | - ./:/opt/target
11 | - ~/.ssh:/opt/.ssh
12 | decrypt:
13 | build: ../image
14 | command: ssh-decrypt
15 | environment:
16 | FILE: /opt/target/test.txt
17 | PRIVATE_KEY: /opt/.ssh/id_rsa
18 | volumes:
19 | - ./:/opt/target
20 | - ~/.ssh:/opt/.ssh
--------------------------------------------------------------------------------
/chrome/docker-compose.yml:
--------------------------------------------------------------------------------
1 | chrome:
2 | image: magnitus/chrome:stable
3 | net: host
4 | cpuset: 0,1
5 | mem_limit: 1G
6 | devices:
7 | - /dev/snd:/dev/snd
8 | volumes:
9 | - /tmp/.X11-unix:/tmp/.X11-unix
10 | - /dev/shm:/dev/shm
11 | - /run/dbus:/run/dbus
12 | - /var/run/dbus/system_bus_socket:/var/run/dbus/system_bus_socket
13 | - $HOME/Downloads:/home/chrome/Downloads
14 | - $HOME/.config/google-chrome:/data
15 | environment:
16 | - DISPLAY=$DISPLAY
17 | - _UID=1000
18 |
--------------------------------------------------------------------------------
/node-app/image-builder/code/dockerfile:
--------------------------------------------------------------------------------
1 | FROM docker:1.11
2 |
3 | ENV TEMPLATE_PATH /opt/build/template
4 | ENV APP_DIR /opt/app
5 | ENV SHARED_DIR /opt/shared
6 |
7 | ENV SERVER_DIR /opt/server
8 |
9 | ENV DEFAULT_SOURCE_IMAGE magnitus/node-app:4
10 |
11 | RUN apk add --no-cache nodejs && apk add --no-cache wget
12 |
13 | COPY ["app/", "/opt/build/"]
14 | RUN (cd /opt/build; npm install)
15 |
16 | COPY ["server/", "${SERVER_DIR}"]
17 | RUN (cd ${SERVER_DIR}; npm install)
18 |
19 | WORKDIR /opt/build
20 |
21 | ENTRYPOINT ["/usr/bin/npm"]
22 | CMD ["start"]
23 |
24 |
--------------------------------------------------------------------------------
/node-app/image-builder/example/docker-compose-slim.yml:
--------------------------------------------------------------------------------
1 | app:
2 | container_name: build-image-example-slim
3 | image: magnitus/node-app:image-builder
4 | environment:
5 | - SOURCE_IMAGE=magnitus/node-app:4-slim
6 | - UID=1000
7 | - OUTPUT_IMAGE=magnitus/node-app:image-builder-example-slim
8 | - IGNORE=.+~$$
9 | - EXTERNAL_PORT=8080
10 | - DOCKER_LOCALHOST=172.17.0.1
11 | - CACHE=no
12 | volumes:
13 | - ./app:/opt/app
14 | - ./shared:/opt/shared
15 | - /var/run/docker.sock:/var/run/docker.sock
16 | ports:
17 | - "8080:8080"
18 |
--------------------------------------------------------------------------------
/pyspark/README.md:
--------------------------------------------------------------------------------
1 | # About
2 |
3 | Just a dockerfile I wrote to try out the code of a pyspark course locally.
4 |
5 | I followed the installation instructions from the course (tailored for an ubuntu vm) and made a few adjustments where needed.
6 |
7 | I will make adjustments to this image as needed to follow the course.
8 |
9 | # Usage
10 |
11 | Launch the container by running:
12 |
13 | ```
14 | ./run.sh
15 | ```
16 |
17 | Find out the connection string by typing:
18 |
19 | ```
20 | docker logs pyspark-jupyter-notebook
21 | ```
22 |
23 | Plug the connection string in your browser.
--------------------------------------------------------------------------------
/jedit/dockerfile:
--------------------------------------------------------------------------------
1 | FROM ubuntu:14.04
2 | RUN apt-get update && \
3 | apt-get install -y openjdk-7-jdk && \
4 | apt-get install -y wget && \
5 | wget 'http://sourceforge.net/projects/jedit/files/jedit-devel/5.2pre1/jedit_5.2pre1_all.deb/download' --output-document=/opt/jedit_5.2pre1_all.deb && \
6 | dpkg -i /opt/jedit_5.2pre1_all.deb && \
7 | apt-get purge -y wget && \
8 | apt-get clean && \
9 | rm /opt/jedit_5.2pre1_all.deb
10 | COPY ["./entryScript.sh", "/opt/entryScript.sh"]
11 | RUN chmod +x /opt/entryScript.sh
12 | ENTRYPOINT ["/bin/bash", "/opt/entryScript.sh"]
13 |
--------------------------------------------------------------------------------
/headless-factorio-server/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: '3.4'
2 | services:
3 | factorio-headless-server:
4 | image: magnitus/factorio-headless-server:0.17.79
5 | build: .
6 | network_mode: "host"
7 | environment:
8 | GAME_NAME: "Friendly Game"
9 | GAME_DESCRIPTION: "Friendly Game"
10 | GAME_PASSWORD: "MyPasswordIsMighty"
11 | ADMIN_PLAYERS: "me,you"
12 | WHITELISTED_PLAYERS: "me,you"
13 | BIND_PORT: 8080
14 | BIND_IP: "0.0.0.0"
15 | volumes:
16 | - "factorio-data:/opt/data"
17 | restart: always
18 |
19 | volumes:
20 | factorio-data: {}
--------------------------------------------------------------------------------
/node-app/image-builder/example2/docker-compose-slim.yml:
--------------------------------------------------------------------------------
1 | app:
2 | container_name: build-image-example2-slim
3 | image: magnitus/node-app:image-builder
4 | environment:
5 | - SOURCE_IMAGE=magnitus/node-app:4-slim
6 | - UID=1000
7 | - OUTPUT_IMAGE=magnitus/node-app:image-builder-example2-slim
8 | - IGNORE=.+~$$
9 | - EXTERNAL_PORT=8080
10 | - DOCKER_LOCALHOST=172.17.0.1
11 | - CACHE=no
12 | - NPM_COMMAND=test
13 | volumes:
14 | - ./app:/opt/app
15 | - ./shared:/opt/shared
16 | - /var/run/docker.sock:/var/run/docker.sock
17 | ports:
18 | - "8080:8080"
19 |
--------------------------------------------------------------------------------
/node-app/base-image/example5/app/test/index.js:
--------------------------------------------------------------------------------
1 | const isPrime = require('is-prime');
2 |
3 | exports.main = {
4 | main: function(test) {
5 | test.expect(2);
6 | test.ok(isPrime(1) && isPrime(2) && isPrime(3) && isPrime(5) && isPrime(7) && isPrime(11) && isPrime(13) && isPrime(17) && isPrime(19) && isPrime(23), "Assert that library can detect primes.");
7 | test.ok((!isPrime(4)) && (!isPrime(6)) && (!isPrime(8)) && (!isPrime(9)) && (!isPrime(10)) && (!isPrime(12)) && (!isPrime(14)) && (!isPrime(15)), "Assert that library can identify non-primes.");
8 | test.done();
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/node-app/image-builder/example2/app/test/index.js:
--------------------------------------------------------------------------------
1 | const isPrime = require('is-prime');
2 |
3 | exports.main = {
4 | main: function(test) {
5 | test.expect(2);
6 | test.ok(isPrime(1) && isPrime(2) && isPrime(3) && isPrime(5) && isPrime(7) && isPrime(11) && isPrime(13) && isPrime(17) && isPrime(19) && isPrime(23), "Assert that library can detect primes.");
7 | test.ok((!isPrime(4)) && (!isPrime(6)) && (!isPrime(8)) && (!isPrime(9)) && (!isPrime(10)) && (!isPrime(12)) && (!isPrime(14)) && (!isPrime(15)), "Assert that library can identify non-primes.");
8 | test.done();
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/pulsar-orchestration/configure_zookeeper.sh:
--------------------------------------------------------------------------------
1 | docker run --rm \
2 | --network pulsar-internal \
3 | --entrypoint="" \
4 | apachepulsar/pulsar:2.5.1 bin/pulsar initialize-cluster-metadata \
5 | --cluster pulsar-cluster-1 \
6 | --zookeeper zookeeper-one:2181 \
7 | --configuration-store zookeeper-one:2181 \
8 | --web-service-url http://pulsar-broker:8080 \
9 | --web-service-url-tls https://pulsar-broker:8443 \
10 | --broker-service-url pulsar://pulsar-broker:6650 \
11 | --broker-service-url-tls pulsar+ssl://pulsar-broker:6651
--------------------------------------------------------------------------------
/certificate/example/self-signed/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: "3"
2 | services:
3 | self-signed-certificate-generator:
4 | image: magnitus/certificate-generator:latest
5 | environment:
6 | COUNTRY: CA
7 | STATE: Quebec
8 | CITY: Montreal
9 | ORGANIZATION: Any
10 | DEPARTMENT: IT
11 | EMAIL: email@mydomain.com
12 | DOMAINS: dev.mydomain.com;test.mydomain.com
13 | CERTIFICATE_DURATION: 1095
14 | KEY_FILE: ""
15 | CSR_FILE: ""
16 | CERTIFICATE_FILE: ""
17 | OUTPUT_CERTIFICATE_INFO: "true"
18 | volumes:
19 | - .:/opt/output
20 |
--------------------------------------------------------------------------------
/node-app/dockerfile-builder/code/app/getCopyCmd.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs');
2 | const path = require('path');
3 |
4 | var ignoreRegex = process.env.IGNORE ? new RegExp(process.env.IGNORE) : null;
5 |
6 | module.exports = function (rootPath, destination)
7 | {
8 | //Plug app copy in template
9 | var copyAppCmd = "COPY [";
10 |
11 | fs.readdirSync(rootPath).forEach((filename) => {
12 | if(filename != "node_modules" && (ignoreRegex && (!ignoreRegex.test(filename))))
13 | {
14 | copyAppCmd += ("\""+path.join(rootPath, filename).replace('/opt', '.')+"\", ");
15 | }
16 | });
17 |
18 | copyAppCmd += ("\""+destination+"/\"]");
19 | return copyAppCmd;
20 | }
21 |
--------------------------------------------------------------------------------
/react-build/code/app/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-build",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "author": "Eric Vallee ",
6 | "licenses": [
7 | {
8 | "type": "MIT License",
9 | "url": "http://mit-license.org/"
10 | }
11 | ],
12 | "dependencies": {
13 | "browserify": "13.x",
14 | "watchify": "3.x",
15 | "babelify": "7.x",
16 | "babel-preset-es2015": "6.x",
17 | "babel-preset-react": "6.x",
18 | "uglifyify": "3.x",
19 | "react": "15.x",
20 | "react-dom": "15.x",
21 | "redux": "3.x"
22 | },
23 | "license": "MIT",
24 | "scripts": {
25 | "start": "node index.js"
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/hapi-service/hello-world/index.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const Hapi = require('hapi');
4 |
5 | const server = new Hapi.Server();
6 | server.connection({ port: 8080 });
7 |
8 | server.route([
9 | {
10 | method: 'GET',
11 | path: '/hello_world',
12 | handler: function (request, reply) {
13 | reply('Hello World');
14 | }
15 | }
16 | ]);
17 |
18 | server.start((err) => {
19 | if (err) {
20 | throw err;
21 | }
22 | console.log('Server running at:', server.info.uri);
23 | });
24 |
25 | process.on('SIGTERM', () => {
26 | console.log('Sigterm received. Terminating hello world module...');
27 | server.stop((err) => {
28 | process.exit(0);
29 | });
30 | });
31 |
--------------------------------------------------------------------------------
/node-app/base-image/example2/app/index.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const Hapi = require('hapi');
4 |
5 | const server = new Hapi.Server();
6 | server.connection({ port: 8080 });
7 |
8 | server.route([
9 | {
10 | method: 'GET',
11 | path: '/hello_world',
12 | handler: function (request, reply) {
13 | reply('Hello, world!');
14 | }
15 | }
16 | ]);
17 |
18 | server.start((err) => {
19 | if (err) {
20 | throw err;
21 | }
22 | console.log('Server running at:', server.info.uri);
23 | });
24 |
25 | process.on('SIGTERM', () => {
26 | console.log('Sigterm received. Terminating process...');
27 | server.stop((err) => {
28 | process.exit(0);
29 | });
30 | });
31 |
--------------------------------------------------------------------------------
/network-setup/image/dhcp.conf.j2:
--------------------------------------------------------------------------------
1 | default-lease-time {{ lease_time.default }};
2 | max-lease-time {{ lease_time.max }};
3 |
4 | subnet {{ network.subnet }} netmask {{ network.mask }} {
5 | {% if network.router %}
6 | option routers {{ network.router }};
7 | {% endif %}
8 | option broadcast-address {{ network.broadcast }};
9 | option subnet-mask {{ network.mask }};
10 | option domain-name-servers {{ ip }};
11 | range {{ network.range }};
12 | }
13 |
14 | {% for static_host in network.static_hosts %}
15 | host {{ static_host.name }} {
16 | option host-name "{{ static_host.name }}";
17 | hardware ethernet {{ static_host.mac }};
18 | fixed-address {{ static_host.ip }};
19 | }
20 | {% endfor %}
--------------------------------------------------------------------------------
/react-build/example/build.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": 1,
3 | "modules": {
4 | "*": ["/opt/lib"],
5 | "app": "/opt/app/javascript/app.jsx",
6 | "header": "/opt/app/javascript/header.jsx",
7 | "register-section": "/opt//app/javascript/register-section.jsx",
8 | "draw-section": "/opt/app/javascript/draw-section.jsx",
9 | "registration-feedback": "/opt/app/javascript/registration-feedback.jsx",
10 | "draw-feedback": "/opt/app/javascript/draw-feedback.jsx"
11 | },
12 | "entrypoints": ["/opt/app/javascript/index.jsx"],
13 | "extensions": ["js", "jsx"],
14 | "watch": true,
15 | "minify": true,
16 | "dependencies": ["react", "react-dom"],
17 | "destination": "/opt/dist/bundle.js"
18 | }
--------------------------------------------------------------------------------
/node-app/base-image/templates/dockerfile-template:
--------------------------------------------------------------------------------
1 | FROM magnitus/node-app:4
2 |
3 | #TODO: Set UID to whichever values makes sense
4 | ENV UID="1000"
5 |
6 | #TODO: your app content in /home/node-app/app
7 | COPY "app/*" ${APP_DIR}/
8 |
9 | #TODO: Copy shared modules in shared modules directory
10 | # You can also simply omit the statement if you do not use shared modules
11 | COPY ["shared_modules/users", ${SHARED_DIR}/users]
12 |
13 | #TODO: Copy list of semi-colon separated npm module names that should be availabe by default everywhere in your project
14 | # You can also simply omit the declaration of this environment variable if you don't want to use any
15 | ENV NPM_MODULES="bluebird@3;xregexp@3"
16 |
17 | RUN finalize.sh
18 |
19 | USER $UID
20 |
--------------------------------------------------------------------------------
/remote-terraform/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM python:3.8-slim-buster
2 |
3 | RUN apt-get update && apt-get install -y openssh-client sshpass
4 | RUN pip install ansible==2.9.6
5 |
6 | ENV ANSIBLE_STDOUT_CALLBACK=debug
7 |
8 | ENV ANSIBLE_USER=admin
9 | ENV PRIVATE_SSH_KEY=/opt/keys/id_rsa
10 | ENV INVENTORY=/opt/inventory
11 | ENV TERRAFORM_DIR=/opt/terraform
12 |
13 | ENV REMOTE_TERRAFORM_CONFIG_DIR=/opt/terraform_config
14 | ENV REMOTE_TERRAFORM_STATE_DIR=/opt/terraform_state
15 | ENV REMOTE_TERRAFORM_IMAGE=hashicorp/terraform:latest
16 | ENV REMOTE_CONTAINER_NAME=terraform
17 |
18 | WORKDIR /opt
19 |
20 | COPY ansible_scripts /opt/bastion_terraform
21 | COPY binaries/apply /bin/terraform_apply
22 | COPY binaries/plan /bin/terraform_plan
23 |
24 | CMD ["terraform_plan"]
--------------------------------------------------------------------------------
/jedit/README.md:
--------------------------------------------------------------------------------
1 | # jEdit
2 |
3 | **NOTICE:** This image is not longer maintained as I no longer use jEdit as my primary editor.
4 |
5 | This is a dockerfile for the jEdit text editor.
6 |
7 | # Usage
8 |
9 | 1) Edit the docker-compose.yml file to convey your particular settings:
10 |
11 | - Change the _USER and _UID environment variables to reflect your particular executiong context
12 | - Change the /home/eric directory in the volumes to reflect your user
13 | - Change the /home/eric/Projects directory in the volumes to reflext the directory containing the files you want to edit with jEdit
14 |
15 | 2) Run docker-compose up
16 | 3) By differienciating the configuration and placement of the docker-compose.yml file, you can seperate your file editing environments.
17 |
--------------------------------------------------------------------------------
/node-app/base-dev-image/code/finalize.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | if ! id "node-app" >/dev/null 2>&1; then
3 | echo "node-app:x:${UID}:${UID}:node-app,,,:/home/node-app:/bin/bash" >> /etc/passwd;
4 | echo "node-app:x:${UID}:" >> /etc/group;
5 | pwconv;
6 | grpconv;
7 | fi
8 |
9 | if [ ! -z "$ALWAYS_INSTALL" ] || [ ! -f "${HOME_DIR}/installation_done" ] ; then
10 | /opt/app-setup/resolve_dependencies.js;
11 | if [ -z "$ALWAYS_INSTALL" ] ; then
12 | touch ${HOME_DIR}/installation_done;
13 | fi
14 | fi
15 |
16 | chown -R ${UID}:${UID} /home/node-app;
17 | chown -R ${UID}:${UID} ${SHARED_DIR};
18 |
19 | if [ -z "$NPM_COMMAND" ]; then
20 | NPM_COMMAND="start";
21 | fi
22 |
23 | (cd ${APP_DIR}; su -c "${TOOL} run ${NPM_COMMAND}" node-app);
24 |
--------------------------------------------------------------------------------
/react-build/example-onbuild/build.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": 1,
3 | "modules": {
4 | "*": ["/opt/lib"],
5 | "app": "/opt/app/javascript/app.jsx",
6 | "header": "/opt/app/javascript/header.jsx",
7 | "register-section": "/opt//app/javascript/register-section.jsx",
8 | "draw-section": "/opt/app/javascript/draw-section.jsx",
9 | "registration-feedback": "/opt/app/javascript/registration-feedback.jsx",
10 | "draw-feedback": "/opt/app/javascript/draw-feedback.jsx"
11 | },
12 | "entrypoints": ["/opt/app/javascript/index.jsx"],
13 | "extensions": ["js", "jsx"],
14 | "watch": true,
15 | "minify": true,
16 | "dependencies": ["react", "react-dom"],
17 | "destination": "/opt/dist/bundle.js"
18 | }
--------------------------------------------------------------------------------
/node-app/base-image/templates/dockerfile-template-slim:
--------------------------------------------------------------------------------
1 | FROM magnitus/node-app:4-slim
2 |
3 | #TODO: Set UID to whichever values makes sense
4 | ENV UID="1000"
5 |
6 | #TODO: your app content in /home/node-app/app
7 | COPY "app/*" ${APP_DIR}/
8 |
9 | #TODO: Copy shared modules in shared modules directory
10 | # You can also simply omit the statement if you do not use shared modules
11 | COPY ["shared_modules/users", ${SHARED_DIR}/users]
12 |
13 | #TODO: Copy list of semi-colon separated npm module names that should be availabe by default everywhere in your project
14 | # You can also simply omit the declaration of this environment variable if you don't want to use any
15 | ENV NPM_MODULES="bluebird@3;xregexp@3"
16 |
17 | RUN finalize.sh
18 |
19 | USER $UID
20 |
--------------------------------------------------------------------------------
/pulsar-orchestration/launch.sh:
--------------------------------------------------------------------------------
1 | ZOOKEEPER_SET="yes"
2 | if [ ! -d "./zookeeper" ]; then
3 | ZOOKEEPER_SET="no"
4 | mkdir -p zookeeper/one/data;
5 | mkdir -p zookeeper/one/datalog;
6 | mkdir -p zookeeper/two/data;
7 | mkdir -p zookeeper/two/datalog;
8 | mkdir -p zookeeper/three/data;
9 | mkdir -p zookeeper/three/datalog;
10 | fi
11 | docker-compose up -d zookeeper-one zookeeper-two zookeeper-three;
12 | sleep 10;
13 | if [ "$ZOOKEEPER_SET" = "no" ]; then
14 | ./configure_zookeeper.sh;
15 | fi
16 |
17 | if [ ! -d "./bookie" ]; then
18 | mkdir -p bookie/one/data;
19 | mkdir -p bookie/two/data;
20 | mkdir -p bookie/three/data;
21 | fi
22 | docker-compose up -d bookie-one bookie-two bookie-three;
23 | sleep 10;
24 |
25 | docker-compose up -d broker;
--------------------------------------------------------------------------------
/headless-factorio-server/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM python:3-slim
2 |
3 | ARG FACTORIO_VERSION=0.17.79
4 | ENV FACTORIO_VERSION=$FACTORIO_VERSION
5 | LABEL "factorio.version"=$FACTORIO_VERSION
6 |
7 | ENV TEMPLATES_PATH=/opt/templates
8 | ENV CONFIGS_PATH=/opt/data/configs
9 | ENV GAME_PATH=/opt/data/games
10 |
11 | RUN apt-get update && apt-get install -y wget xz-utils
12 |
13 | WORKDIR /opt
14 |
15 | RUN wget --output-document factorio.tar.xz https://factorio.com/get-download/$FACTORIO_VERSION/headless/linux64 && \
16 | tar -xJf factorio.tar.xz && \
17 | rm factorio.tar.xz
18 |
19 | COPY requirements.txt /opt
20 |
21 | RUN pip install -r requirements.txt
22 |
23 | COPY code /opt/code
24 | COPY templates /opt/templates
25 |
26 | WORKDIR /opt/code
27 |
28 | ENTRYPOINT ["python", "/opt/code/entrypoint.py"]
--------------------------------------------------------------------------------
/ssh-encryption/image/ssh-decrypt:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | if [ -z "$PRIVATE_KEY" ]; then
4 | echo "Private ssh key need to be defined with the PUBLIC_KEY environment variable";
5 | exit 1;
6 | fi
7 |
8 | if [ -z "$FILE" ]; then
9 | echo "Target file need to be defined with the FILE environment variable";
10 | exit 1;
11 | fi
12 |
13 | FILE_DIR=$(dirname $FILE)
14 |
15 | #Decrypt symmetric key with private key
16 | openssl rsautl -decrypt -inkey $PRIVATE_KEY -in $FILE_DIR/symmetric_key.encrypted -out symmetric_key;
17 | #Decrypt secret with symmetric key
18 | openssl aes-256-cbc -md sha512 -pbkdf2 -iter 100000 -salt -d -in ${FILE}.encrypted -out $FILE -pass file:symmetric_key
19 |
20 | #Cleanup decryption artifacts
21 | rm symmetric_key;
22 | rm $FILE_DIR/symmetric_key.encrypted;
23 | rm ${FILE}.encrypted;
--------------------------------------------------------------------------------
/network-setup/conf:
--------------------------------------------------------------------------------
1 | fallback_dns_server: 8.8.8.8
2 | networks:
3 | test:
4 | subnet: 192.168.10.0
5 | mask: 255.255.255.0
6 | range: "192.168.10.100 192.168.10.254"
7 | router: 192.168.10.1
8 | broadcast: 192.168.10.255
9 | interface: eth0
10 | static_hosts:
11 | - mac: "00:00:00:00:00:00"
12 | ip: 192.168.10.3
13 | name: dummy_one
14 | - mac: "11:11:11:11:11:11"
15 | ip: 192.168.10.4
16 | name: dummy_two
17 |
18 | admin:
19 | subnet: 192.168.11.0
20 | mask: 255.255.255.0
21 | range: "192.168.11.100 192.168.11.254"
22 | broadcast: 192.168.11.255
23 | interface: eth1
24 | static_hosts:
25 | - mac: "00:00:00:00:00:00"
26 | ip: 192.168.11.2
27 | name: dummy_one
28 | - mac: "11:11:11:11:11:11"
29 | ip: 192.168.11.3
30 | name: dummy_two
31 |
--------------------------------------------------------------------------------
/node-app/base-dev-image/code/dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:4
2 |
3 | ENV HOME_DIR /home/node-app
4 | ENV SHARED_DIR ${HOME_DIR}/shared_modules
5 | ENV APP_DIR ${HOME_DIR}/app
6 | ENV TOOL npm
7 |
8 | COPY ["finalize.sh", "/usr/local/bin/"]
9 | COPY ["resolve_dependencies.js", "/opt/app-setup/"]
10 | RUN (cd /opt/app-setup; npm install bluebird; npm install module-linker; npm install recursive-installer; npm install -g yarn) && \
11 | chmod +x /usr/local/bin/finalize.sh && chmod +x /opt/app-setup/resolve_dependencies.js && \
12 | mkdir ${HOME_DIR} && mkdir ${APP_DIR} && mkdir ${SHARED_DIR} && \
13 | wget -O /usr/local/bin/dumb-init https://github.com/Yelp/dumb-init/releases/download/v1.0.2/dumb-init_1.0.2_amd64 && \
14 | chmod +x /usr/local/bin/dumb-init
15 |
16 | WORKDIR ${APP_DIR}
17 |
18 | ENTRYPOINT ["dumb-init"]
19 | CMD ["finalize.sh"]
20 |
--------------------------------------------------------------------------------
/certificate/example/self-signed-with-password/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: "3"
2 | services:
3 | self-signed-certificate-generator:
4 | image: magnitus/certificate-generator:latest
5 | environment:
6 | COUNTRY: CA
7 | STATE: Quebec
8 | CITY: Montreal
9 | ORGANIZATION: Any
10 | DEPARTMENT: IT
11 | EMAIL: email@mydomain.com
12 | DOMAINS: dev.mydomain.com;test.mydomain.com
13 | CERTIFICATE_DURATION: 1095
14 | KEY_FILE: ""
15 | CSR_FILE: ""
16 | CERTIFICATE_FILE: ""
17 | KEY_PASSWORD_FILE: "/opt/password.txt"
18 | KEY_ENCRYPTION_CYPHER: aes256
19 | OUTPUT_CERTIFICATE_INFO: "true"
20 | volumes:
21 | - .:/opt/output
22 | - ./password.txt:/opt/password.txt
23 |
--------------------------------------------------------------------------------
/headless-factorio-server/code/game.py:
--------------------------------------------------------------------------------
1 | import os
2 |
3 | CONFIGS_PATH = os.environ['CONFIGS_PATH']
4 | GAME_PATH = os.environ['GAME_PATH']
5 |
6 | def game_defined():
7 | return os.path.isdir(GAME_PATH)
8 |
9 | def generate_game():
10 | os.makedirs(GAME_PATH)
11 | code = os.system(
12 | "/opt/factorio/bin/x64/factorio --create {game_path} --server-settings {server_settings_path} --map-gen-settings {map_gen_settings_path} --map-settings {map_settings_path}".format(
13 | game_path=os.path.join(GAME_PATH, 'game.zip'),
14 | server_settings_path=os.path.join(CONFIGS_PATH, 'server-settings.json'),
15 | map_gen_settings_path=os.path.join(CONFIGS_PATH, 'map-gen-settings.json'),
16 | map_settings_path=os.path.join(CONFIGS_PATH, 'map-settings.json'),
17 | )
18 | )
19 | if code != 0:
20 | exit(code)
--------------------------------------------------------------------------------
/node-app/base-image/code/dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:4
2 |
3 | ENV HOME_DIR /home/node-app
4 | ENV SHARED_DIR ${HOME_DIR}/shared_modules
5 | ENV APP_DIR ${HOME_DIR}/app
6 | ENV NPM_COMMAND start
7 | ENV TOOL npm
8 |
9 | COPY ["finalize.sh", "/usr/local/bin/"]
10 | COPY ["resolve_dependencies.js", "/opt/app-setup/"]
11 | RUN (cd /opt/app-setup; npm install bluebird; npm install module-linker; npm install recursive-installer; npm install -g yarn) && \
12 | chmod +x /usr/local/bin/finalize.sh && chmod +x /opt/app-setup/resolve_dependencies.js && \
13 | mkdir ${HOME_DIR} && mkdir ${APP_DIR} && mkdir ${SHARED_DIR} && \
14 | wget -O /usr/local/bin/dumb-init https://github.com/Yelp/dumb-init/releases/download/v1.0.2/dumb-init_1.0.2_amd64 && \
15 | chmod +x /usr/local/bin/dumb-init
16 |
17 | WORKDIR ${APP_DIR}
18 |
19 | ENTRYPOINT ["dumb-init"]
20 | CMD ["bash", "-c", "${TOOL} run ${NPM_COMMAND}"]
21 |
--------------------------------------------------------------------------------
/node-app/base-image/code/dockerfile-slim:
--------------------------------------------------------------------------------
1 | FROM node:4-slim
2 |
3 | ENV HOME_DIR /home/node-app
4 | ENV SHARED_DIR ${HOME_DIR}/shared_modules
5 | ENV APP_DIR ${HOME_DIR}/app
6 | ENV NPM_COMMAND start
7 | ENV TOOL npm
8 |
9 | COPY ["finalize.sh", "/usr/local/bin/"]
10 | COPY ["resolve_dependencies.js", "/opt/app-setup/"]
11 | RUN (cd /opt/app-setup; npm install bluebird; npm install module-linker; npm install recursive-installer; npm install -g yarn) && \
12 | chmod +x /usr/local/bin/finalize.sh && chmod +x /opt/app-setup/resolve_dependencies.js && \
13 | mkdir ${HOME_DIR} && mkdir ${APP_DIR} && mkdir ${SHARED_DIR} && \
14 | wget -O /usr/local/bin/dumb-init https://github.com/Yelp/dumb-init/releases/download/v1.0.2/dumb-init_1.0.2_amd64 && \
15 | chmod +x /usr/local/bin/dumb-init
16 |
17 | WORKDIR ${APP_DIR}
18 |
19 | ENTRYPOINT ["dumb-init"]
20 | CMD ["sh", "-c", "${TOOL} run ${NPM_COMMAND}"]
21 |
--------------------------------------------------------------------------------
/sbt/README.md:
--------------------------------------------------------------------------------
1 | # Purpose
2 |
3 | This is a development image to develop scala code.
4 |
5 | I consider it a work in progress so I won't push an image for it on the foreseeable future, but you can build it on your machine.
6 |
7 | # Usage
8 |
9 | From this directory, run the following to build the image:
10 |
11 | ```
12 | docker build -t sbt:latest .
13 | ```
14 |
15 | Then, type the following to open an interactive shell in the containers:
16 |
17 | ```
18 | docker run -it --rm sbt:latest bash
19 | ```
20 |
21 | If you want to test the image with an hello world example, type the following inside the containers:
22 |
23 | ```
24 | cd /opt
25 | sbt new scala/hello-world.g8
26 | ```
27 |
28 | Press enter when prompted and then type the following to open an sbt console:
29 |
30 | ```
31 | cd hello-world-template
32 | sbt
33 | ```
34 |
35 | Then, press the following to run your hello-world example:
36 |
37 | ```
38 | run
39 | ```
--------------------------------------------------------------------------------
/node-app/base-dev-image/code/resolve_dependencies.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | const path = require('path');
4 | const childProcess = require('child_process');
5 | const moduleLinker = require('module-linker');
6 | const recursiveInstaller = require('recursive-installer');
7 | Promise = require('bluebird');
8 |
9 | if(process.env.NPM_MODULES)
10 | {
11 | var modules = process.env.NPM_MODULES.replace(' ','').split(';');
12 | if(modules.length > 0)
13 | {
14 | process.chdir(process.env.HOME_DIR);
15 | modules.forEach(function(module) {
16 | childProcess.execSync("npm install "+module);
17 | });
18 | }
19 |
20 | }
21 |
22 | Promise.all([recursiveInstaller([process.env.APP_DIR, process.env.SHARED_DIR], {'maxBuffer': 5 * 1024 * 1024, 'tool': process.env.TOOL, 'lock': false}),
23 | moduleLinker([process.env.APP_DIR, process.env.SHARED_DIR], [process.env.SHARED_DIR], process.env.TOOL)]).catch((err) => {
24 | console.log(err);
25 | })
26 |
--------------------------------------------------------------------------------
/ssh-encryption/image/ssh-encrypt:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | if [ -z "$PUBLIC_KEY" ]; then
4 | echo "Public ssh key need to be defined with the PUBLIC_KEY environment variable";
5 | exit 1;
6 | fi
7 |
8 | if [ -z "$FILE" ]; then
9 | echo "Target file need to be defined with the FILE environment variable";
10 | exit 1;
11 | fi
12 |
13 | FILE_DIR=$(dirname $FILE)
14 |
15 | #Change public ssh key to pem format
16 | ssh-keygen -f $PUBLIC_KEY -e -m PKCS8 > id_rsa.pem.pub;
17 | #Generate symmetric key
18 | openssl rand -out symmetric_key 32;
19 | #Encrypt file with symmetric key
20 | openssl aes-256-cbc -md sha512 -pbkdf2 -iter 100000 -salt -in $FILE -out ${FILE}.encrypted -pass file:symmetric_key;
21 | #Encrypt symmetric key with public key
22 | openssl rsautl -encrypt -pubin -inkey id_rsa.pem.pub -ssl -in symmetric_key -out $FILE_DIR/symmetric_key.encrypted;
23 |
24 | #Cleanup unencrypted secrets
25 | rm $FILE;
26 | rm symmetric_key;
27 |
28 | #Cleanup encryption artifacts
29 | rm id_rsa.pem.pub;
--------------------------------------------------------------------------------
/node-app/base-image/code/resolve_dependencies.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | const path = require('path');
4 | const childProcess = require('child_process');
5 | const moduleLinker = require('module-linker');
6 | const recursiveInstaller = require('recursive-installer');
7 | Promise = require('bluebird');
8 |
9 | if(process.env.NPM_MODULES)
10 | {
11 | var modules = process.env.NPM_MODULES.replace(' ','').split(';');
12 | if(modules.length > 0)
13 | {
14 | process.chdir(process.env.HOME_DIR);
15 | modules.forEach(function(module) {
16 | childProcess.execSync("npm install "+module);
17 | });
18 | }
19 |
20 | }
21 |
22 | Promise.all([recursiveInstaller([process.env.APP_DIR, process.env.SHARED_DIR], {'arguments': '--production --no-lockfile', 'maxBuffer': 5 * 1024 * 1024, 'tool': process.env.TOOL}),
23 | moduleLinker([process.env.APP_DIR, process.env.SHARED_DIR], [process.env.SHARED_DIR], process.env.TOOL)]).catch((err) => {
24 | console.log(err);
25 | })
26 |
--------------------------------------------------------------------------------
/cfssl/example/ca-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "signing": {
3 | "default": {
4 | "expiry": "43800h"
5 | },
6 | "profiles": {
7 | "server": {
8 | "expiry": "43800h",
9 | "usages": [
10 | "signing",
11 | "key encipherment",
12 | "server auth",
13 | "client auth"
14 | ]
15 | },
16 | "client": {
17 | "expiry": "43800h",
18 | "usages": [
19 | "signing",
20 | "key encipherment",
21 | "client auth"
22 | ]
23 | },
24 | "peer": {
25 | "expiry": "43800h",
26 | "usages": [
27 | "signing",
28 | "key encipherment",
29 | "server auth",
30 | "client auth"
31 | ]
32 | }
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/node-app/image-builder/code/server/index.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const Hapi = require('hapi');
4 | const Inert = require('inert');
5 |
6 | const server = new Hapi.Server();
7 | server.connection({ port: 8080 });
8 |
9 | server.register(Inert, () => {});
10 |
11 | server.route([
12 | {
13 | method: 'GET',
14 | path: (process.env.APP_DIR+'/{param*}'),
15 | handler: {
16 | directory: {
17 | path: process.env.APP_DIR
18 | }
19 | }
20 | },
21 | {
22 | method: 'GET',
23 | path: (process.env.SHARED_DIR+'/{param*}'),
24 | handler: {
25 | directory: {
26 | path: process.env.SHARED_DIR
27 | }
28 | }
29 | }
30 | ]);
31 |
32 | server.start((err) => {
33 | if (err) {
34 | throw err;
35 | }
36 | console.log('Server running at:', server.info.uri);
37 | });
38 |
39 | process.on('SIGTERM', () => {
40 | console.log('Sigterm received. Terminating process...');
41 | server.stop((err) => {
42 | process.exit(0);
43 | });
44 | });
45 |
--------------------------------------------------------------------------------
/isc-dhcp-server/example/dhcpd.conf:
--------------------------------------------------------------------------------
1 | #In this example, we have the following setup:
2 |
3 | #We have a router on ip 192.168.2.1
4 |
5 | #The dhcp server is already running on ip 192.168.2.2
6 |
7 | #Additionally, we are running a dns server on the same host as the dhcp server
8 |
9 | #We are reserving ip range 192.168.2.3-192.168.2.19 as buffer for static ip addresses
10 |
11 | #We defined that the host whose network inteface has the mac address 00:00:00:00:00:00:00 should have the static ip 192.168.2.3
12 |
13 | #Up to 234 hosts joining the network will get an ip dynamically assigned in the 192.168.2.20-192.168.2.254 range
14 |
15 | default-lease-time 600;
16 | max-lease-time 7200;
17 |
18 | subnet 192.168.2.0 netmask 255.255.255.0 {
19 | option routers 192.168.2.1;
20 | option broadcast-address 192.168.2.255;
21 | option subnet-mask 255.255.255.0;
22 | option domain-name-servers 192.168.2.2;
23 | range 192.168.2.20 192.168.2.254;
24 | }
25 |
26 | host hera {
27 | option host-name "hera";
28 | hardware ethernet 00:00:00:00:00:00;
29 | fixed-address 192.168.2.3;
30 | }
--------------------------------------------------------------------------------
/License.txt:
--------------------------------------------------------------------------------
1 | Copyright (c) 2018 Eric Vallee
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to deal
5 | in the Software without restriction, including without limitation the rights
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | copies of the Software, and to permit persons to whom the Software is
8 | furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in
11 | all copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | THE SOFTWARE.
20 |
--------------------------------------------------------------------------------
/remote-terraform/ansible_scripts/plan.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Set directory to upload terraform scripts
3 | hosts: all
4 | tasks:
5 | - set_fact: remote_terraform_config_dir="{{ lookup('env','REMOTE_TERRAFORM_CONFIG_DIR') }}"
6 |
7 | - name: Set file to store terraform state
8 | hosts: all
9 | tasks:
10 | - set_fact: remote_terraform_state_dir="{{ lookup('env','REMOTE_TERRAFORM_STATE_DIR') }}"
11 |
12 | - name: Set image to execute terraform configuration from
13 | hosts: all
14 | tasks:
15 | - set_fact: remote_terraform_image="{{ lookup('env','REMOTE_TERRAFORM_IMAGE') }}"
16 |
17 | - name: Set remote container name to run terraform operation in
18 | hosts: all
19 | tasks:
20 | - set_fact: remote_container_name="{{ lookup('env','REMOTE_CONTAINER_NAME') }}"
21 |
22 | - name: Upload terraform configuration
23 | hosts: all
24 | roles:
25 | - { role: ./roles/deploy_scripts, become: true }
26 |
27 | - name: Run terraform plan
28 | hosts: all
29 | roles:
30 | - { role: ./roles/terraform_plan, become: true }
31 |
32 | - name: Cleanup terraform configuration
33 | hosts: all
34 | roles:
35 | - { role: ./roles/cleanup_scripts, become: true }
--------------------------------------------------------------------------------
/remote-terraform/ansible_scripts/apply.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Set directory to upload terraform scripts
3 | hosts: all
4 | tasks:
5 | - set_fact: remote_terraform_config_dir="{{ lookup('env','REMOTE_TERRAFORM_CONFIG_DIR') }}"
6 |
7 | - name: Set file to store terraform state
8 | hosts: all
9 | tasks:
10 | - set_fact: remote_terraform_state_dir="{{ lookup('env','REMOTE_TERRAFORM_STATE_DIR') }}"
11 |
12 | - name: Set image to execute terraform configuration from
13 | hosts: all
14 | tasks:
15 | - set_fact: remote_terraform_image="{{ lookup('env','REMOTE_TERRAFORM_IMAGE') }}"
16 |
17 | - name: Set remote container name to run terraform operation in
18 | hosts: all
19 | tasks:
20 | - set_fact: remote_container_name="{{ lookup('env','REMOTE_CONTAINER_NAME') }}"
21 |
22 | - name: Upload terraform configuration
23 | hosts: all
24 | roles:
25 | - { role: ./roles/deploy_scripts, become: true }
26 |
27 | - name: Run terraform apply
28 | hosts: all
29 | roles:
30 | - { role: ./roles/terraform_apply, become: true }
31 |
32 | - name: Cleanup terraform configuration
33 | hosts: all
34 | roles:
35 | - { role: ./roles/cleanup_scripts, become: true }
--------------------------------------------------------------------------------
/ssh-encryption/README.md:
--------------------------------------------------------------------------------
1 | # About
2 |
3 | This image is used to encrypt and decrypt a file using an ssh key.
4 |
5 | Sometimes, you just want to pass something encrypted over the internet and don't have an obvious secure channel to pass a secret.
6 |
7 | However, given that most developpers will already have an ssh key setup on their computer and that it is asymmetric, it can be used to encrypt data with minimum fuss without having to exchange some bootstrap secret over a potentially insecure network.
8 |
9 | One dev needs to send the other his public ssh key. If particularly paranoid, some checksum could potentially be done on the provided public ssh key.
10 |
11 | # Usage
12 |
13 | See the **example** directory for an example encrypting and decrypting a small text file.
14 |
15 | It outlines the orchestration contract (ie, expected commands and environment variables) expected by the image.
16 |
17 | Note that the encryption command will delete the source file and replace it with an encrypted file and an encrypted symmetric key. The decryption command will need both of these files. Also, for this to work, you need to map the entire directory of the plaintext file as a mapped volume for the container, not just the plaintext file.
18 |
19 |
--------------------------------------------------------------------------------
/chrome/README.md:
--------------------------------------------------------------------------------
1 | # Chrome
2 |
3 | **NOTICE:** While it worked for a bit, this image has always been flacky for me. I'll work on it as time allows if I find that the image by jessfraz still fails me, but truth be told, a dockerized Chrome has always been more of a nice-to-have expiment than a priority for me.
4 |
5 | This is an adaptation of a [popular](https://github.com/jessfraz/dockerfiles/tree/master/chrome) Chrome dockerfile that was needed to make it work on my machine.
6 |
7 | I abstracted necessary runtime arguments in a docker-compose file.
8 |
9 | # Usage
10 |
11 | 1) Edit the docker-compose.yml file to convey your particular settings:
12 |
13 | - Change the _UID environment variable to reflect your particular executiong context
14 | - Change the $HOME/Downloads directory in the volumes to reflect where you want your downloads to go
15 | - Change the $HOME/.config/google-chrome directory in the volumes to reflect where you want the rest of your Chrome data (bookmarks & al.) to go
16 | - Change the mem_limit and cpuset settings to reflect the amount of memory and CPU cores you wish the Chrome container to use
17 |
18 | 2) Run 'docker-compose up' to launch Chrome
19 |
20 | 3) Run 'docker-compose rm' to cleanup your environment when done
21 |
--------------------------------------------------------------------------------
/isc-dhcp-server/README.md:
--------------------------------------------------------------------------------
1 | # Overview
2 |
3 | This is just a dockerfile to run the isc dhcp server.
4 |
5 | Basically, you can plugin your configuration file, start the container on the host network and you should be set.
6 |
7 | # Usage
8 |
9 | The container can be composed with the following environment variables:
10 |
11 | - IP_VERSION: Version of the IP protocol to use (ie, 4 or 6). Note that my use case if for ip 4 so 6 has not been validated.
12 | - INTERFACE: Interface the dhcp server should bind to on the host. Defaults to eth0.
13 | - SOURCE_CONF_PATH: Path the entrypoint will expect the configuration file to be at. Defaults to /opt/dhcp/dhcpd.conf.
14 | - RUNTIME_USER: The dhcp server will be running as this user. Defaults to www-data. Note that because the dhcp daemon expects this user to exist, you'll have to extent the image if the pre-existing users in the image are unsuitable for your purpose.
15 |
16 | # Example
17 |
18 | There is an example complete with a sample configuration and docker-compose file that can easily be adapted for simple needs.
19 |
20 | # Manual Push for Arm64
21 |
22 | The image comes in both amd64 and arm64 flavors.
23 |
24 | However, to the best of my knowledge, docker hub doesn't have a builder for arm64 images currently so the arm64 version has to be pushed manually.
25 |
--------------------------------------------------------------------------------
/pyspark/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM openjdk:8-slim-buster
2 |
3 | RUN apt-get update && \
4 | apt-get install -y build-essential libssl-dev libffi-dev python3-dev && \
5 | ln -s /usr/bin/python3 /usr/bin/python
6 |
7 | RUN apt-get install -y python3-pip && \
8 | ln -s /usr/bin/pip3 /usr/bin/pip
9 |
10 | RUN pip install jupyter
11 |
12 | RUN apt-get update && apt-get install -y curl gnupg && \
13 | echo "deb https://dl.bintray.com/sbt/debian/ /" > /etc/apt/sources.list.d/sbt.list && \
14 | curl -sL "https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x2EE0EA64E40A89B84B2DF73499E82A75642AC823" | apt-key add && \
15 | apt-get update && apt-get install -y sbt
16 |
17 | RUN pip install py4j
18 |
19 | WORKDIR /opt
20 |
21 | RUN curl http://muug.ca/mirror/apache-dist/spark/spark-2.4.5/spark-2.4.5-bin-hadoop2.7.tgz --output spark-2.4.5-bin-hadoop2.7.tgz && \
22 | tar zxvf spark-2.4.5-bin-hadoop2.7.tgz && \
23 | rm spark-2.4.5-bin-hadoop2.7.tgz
24 |
25 | ENV SPARK_HOME=/opt/spark-2.4.5-bin-hadoop2.7
26 | ENV PATH="/opt/spark-2.4.5-bin-hadoop2.7/bin:${PATH}"
27 | ENV PYSPARK_DRIVER_PYTHON=jupyter
28 | ENV PYSPARK_DRIVER_PYTHON_OPTS=notebook
29 |
30 | RUN cd /opt/spark-2.4.5-bin-hadoop2.7/python && python setup.py install
31 |
32 | CMD ["jupyter", "notebook", "--no-browser", "--allow-root", "--ip", "0.0.0.0"]
--------------------------------------------------------------------------------
/electron-app/README.md:
--------------------------------------------------------------------------------
1 | # electron-app
2 |
3 | This is a dockerfile to launch an electron gui within a docker container.
4 |
5 | Currently, the sole image is oriented toward a dev environment where the the source code changes a lot (and is therefore in a bound volume), because it's where I'm at.
6 |
7 | I'm merely beginning my electron(ic) journey and so far this image only ran an "hello world" example, so I can't really vouch about its correctness yet, except that it can run an hello world example :).
8 |
9 | ## Usage
10 |
11 | The 'dockerfile' and 'entryScript.sh' files that I used to build the image that was pushed in the docker hub are included for completeness, but not necessary to run the image.
12 |
13 | You just need to use docker-compose to make use of the prescribed settings to launch the container.
14 |
15 | You'll want to tweak the settings (user name and id and corresponding home folder) in the docker-compose.yml file to reflect your environment and change the content of the 'app' directory with your electron app.
16 |
17 | ## Name Change Notice
18 |
19 | Changed the name (including the image) for this project from atom-electron to electron-app as I found the previous name confusing (given the existence of the Atom text editor) when revisiting the project after a prolonged absence. I'll keep the old atom-electron image on my docker hub for compatibility reason in the unlikely event that someone out there is depending on it.
20 |
--------------------------------------------------------------------------------
/certificate/example/ca-signed/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: "3"
2 | services:
3 | ca-certificate-generator:
4 | image: magnitus/certificate-generator:latest
5 | environment:
6 | COUNTRY: CA
7 | STATE: Quebec
8 | CITY: Montreal
9 | ORGANIZATION: Any
10 | DEPARTMENT: IT
11 | EMAIL: email@cadomain.com
12 | DOMAINS: dev.cadomain.com;test.cadomain.com
13 | CERTIFICATE_DURATION: 1095
14 | KEY_FILE: "ca.key"
15 | CSR_FILE: "ca.csr"
16 | CERTIFICATE_FILE: "ca.crt"
17 | OUTPUT_CERTIFICATE_INFO: "true"
18 | volumes:
19 | - .:/opt/output
20 | certificate-generator:
21 | image: magnitus/certificate-generator:latest
22 | environment:
23 | COUNTRY: CA
24 | STATE: Quebec
25 | CITY: Montreal
26 | ORGANIZATION: Any
27 | DEPARTMENT: IT
28 | EMAIL: email@mydomain.com
29 | DOMAINS: dev.mydomain.com;test.mydomain.com
30 | CERTIFICATE_DURATION: 1095
31 | KEY_FILE: "certificate.key"
32 | CSR_FILE: "certificate.csr"
33 | CERTIFICATE_FILE: "certificate.crt"
34 | CA_KEY_FILE: "/opt/output/ca.key"
35 | CA_CERTIFICATE_FILE: "/opt/output/ca.crt"
36 | OUTPUT_CERTIFICATE_INFO: "true"
37 | volumes:
38 | - .:/opt/output
39 |
--------------------------------------------------------------------------------
/react-build/example/app/javascript/draw-section.jsx:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 | var ReactDOM = require('react-dom');
3 |
4 | var DrawFeedback = require('draw-feedback');
5 |
6 | module.exports = React.createClass({
7 | handleSubmit: function(event) {
8 | //Sometimes, it's extra work to prevent built-in browser defaults (in this case, reloading the page), but
9 | //I think using the right semantic html tags to describe gui structure makes the application easier to understand
10 | event.preventDefault();
11 | this.props.initiateDraw();
12 | },
13 | render: function() {
14 | var self = this;
15 | return (
16 |
17 | {function() {
18 | if(this.props.winners === null)
19 | {
20 | return (
21 |
26 | );
27 | }
28 | else
29 | {
30 | return ();
31 | }
32 | }.call(this)}
33 |
34 | );
35 | }
36 | });
--------------------------------------------------------------------------------
/react-build/example-onbuild/app/javascript/draw-section.jsx:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 | var ReactDOM = require('react-dom');
3 |
4 | var DrawFeedback = require('draw-feedback');
5 |
6 | module.exports = React.createClass({
7 | handleSubmit: function(event) {
8 | //Sometimes, it's extra work to prevent built-in browser defaults (in this case, reloading the page), but
9 | //I think using the right semantic html tags to describe gui structure makes the application easier to understand
10 | event.preventDefault();
11 | this.props.initiateDraw();
12 | },
13 | render: function() {
14 | var self = this;
15 | return (
16 |
17 | {function() {
18 | if(this.props.winners === null)
19 | {
20 | return (
21 |
26 | );
27 | }
28 | else
29 | {
30 | return ();
31 | }
32 | }.call(this)}
33 |
34 | );
35 | }
36 | });
--------------------------------------------------------------------------------
/react-build/example/app/javascript/registration-feedback.jsx:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 | var ReactDOM = require('react-dom');
3 |
4 | module.exports = React.createClass({
5 | handleInfoClick: function() {
6 | this.props.hideRegistrant();
7 | },
8 | render: function() {
9 | if(this.props.lastRegistrant.number != -1)
10 | {
11 | var title = "Successful Registration";
12 | }
13 | else
14 | {
15 | var title = "Unsuccessful Registration";
16 | }
17 | return (
18 |
19 | {title}
20 | {function() {
21 | if(this.props.lastRegistrant.number != -1)
22 | {
23 | return (
24 |
25 |
26 | - Name:
27 | - {this.props.lastRegistrant.name}
28 | - Number:
29 | - {this.props.lastRegistrant.number}
30 |
31 | );
32 | }
33 | else
34 | {
35 | return (
36 |
37 | Registrant already exists!
38 | );
39 | }
40 | }.call(this)}
41 |
42 | );
43 | }
44 | });
--------------------------------------------------------------------------------
/react-build/example-onbuild/app/javascript/registration-feedback.jsx:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 | var ReactDOM = require('react-dom');
3 |
4 | module.exports = React.createClass({
5 | handleInfoClick: function() {
6 | this.props.hideRegistrant();
7 | },
8 | render: function() {
9 | if(this.props.lastRegistrant.number != -1)
10 | {
11 | var title = "Successful Registration";
12 | }
13 | else
14 | {
15 | var title = "Unsuccessful Registration";
16 | }
17 | return (
18 |
19 | {title}
20 | {function() {
21 | if(this.props.lastRegistrant.number != -1)
22 | {
23 | return (
24 |
25 |
26 | - Name:
27 | - {this.props.lastRegistrant.name}
28 | - Number:
29 | - {this.props.lastRegistrant.number}
30 |
31 | );
32 | }
33 | else
34 | {
35 | return (
36 |
37 | Registrant already exists!
38 | );
39 | }
40 | }.call(this)}
41 |
42 | );
43 | }
44 | });
--------------------------------------------------------------------------------
/node-app/dockerfile-builder/README.md:
--------------------------------------------------------------------------------
1 | ##Automated Dockerfile Creation Using the dockerfile-builder Image and a Customized docker-compose.yml File Derived From the Template
2 |
3 | Take the docker-compose.yml template file and customize is for your needs (any parts between <<...>> should be customised).
4 |
5 | ###Customizations
6 |
7 | * container-name: Name of the container that builds the dockerfile (mostly useful to avoid name clashed with already running containers)
8 | * environment
9 | * UID: Running user ID of the image that will be created from the generated dockerfile
10 | * OUTPUT_UID: User ID of the outputed dockerfile and other dependent files
11 | * OUTPUT_IMAGE: Full image name of the image that will be created from the generated dockerfile
12 | * IGNORE: Regex pattern identifiying files that the dockerfile should not copy (for example, my text editor always creates backup files ending with ~ that I don't want included in a production image)
13 | * volume mapping
14 | * App directory: Change the LHS of the volume mapping to map to the directory where your app is contained
15 | * Shared directory: Change the LHS of the volume mapping to map to the directory where your local shared modules are located
16 | * Ouput directory: Change the LHS of the volume mapping to map to the directory where you would like your dockerfile, build script and other dependencies generated
17 |
18 | ###Output
19 |
20 | The dockerfile should appear in the specified output directory along with a build.sh bash script to build it.
21 |
22 | ###Examples
23 |
24 | The 'dockerfile-builder-image-example' directory contain an example, adapted to have its dockerfile automatically generated.
25 |
--------------------------------------------------------------------------------
/node-app/image-builder/code/app/compileDependencies.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs');
2 | const path = require('path');
3 | const actOnModules = require('act-on-modules');
4 |
5 | var mainKey = '!APP!';
6 |
7 | var info = {
8 | pathsByModule: {},
9 | dependenciesByModule: {},
10 | resolvedDependencies: {},
11 | dependencies: {}
12 | };
13 |
14 | function compileInfo(directory)
15 | {
16 | var package = JSON.parse(fs.readFileSync(path.join(directory, 'package.json'), 'utf8'));
17 | var packageName = this.mainModule ? mainKey : package.name;
18 | this.pathsByModule[packageName] = directory;
19 | if(package.localDependencies)
20 | {
21 | this.dependenciesByModule[packageName] = package.localDependencies;
22 | }
23 | }
24 |
25 | function compileDependencies(currentModule, info)
26 | {
27 | if(info.resolvedDependencies[currentModule])
28 | {
29 | return;
30 | }
31 |
32 | info.resolvedDependencies[currentModule] = true;
33 | if(info.dependenciesByModule[currentModule])
34 | {
35 | info.dependenciesByModule[currentModule].forEach((dependency) => {
36 | info.dependencies[dependency] = true;
37 | compileDependencies(dependency, info);
38 | });
39 | }
40 | }
41 |
42 | module.exports = function() {
43 | var compileInfoBound = compileInfo.bind(info);
44 | info.mainModule = true;
45 | actOnModules.sync(process.env.APP_DIR, compileInfoBound);
46 | info.mainModule = false;
47 | actOnModules.sync(process.env.SHARED_DIR, compileInfoBound);
48 |
49 | compileDependencies(mainKey, info);
50 |
51 | delete info['mainModule'];
52 |
53 | return info;
54 | };
55 |
56 |
--------------------------------------------------------------------------------
/node-app/dockerfile-builder/code/app/getCopySharedCmd.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs');
2 | const path = require('path');
3 | const getCopyCmd = require('./getCopyCmd');
4 |
5 | var namesToPaths = {};
6 | var namesToDependencies = {};
7 | var resolvedDependencies = {};
8 |
9 | function mapNames(rootPath)
10 | {
11 | fs.readdirSync(rootPath).forEach(function(directory) {
12 | var package = JSON.parse(fs.readFileSync(path.join(rootPath, directory, 'package.json'), 'utf8'));
13 | namesToPaths[package.name] = path.join(rootPath, directory);
14 | namesToDependencies[package.name] = package.localDependencies;
15 | });
16 | }
17 |
18 | function dependenciesToCmds(name, destination)
19 | {
20 | if(namesToDependencies[name])
21 | {
22 | return namesToDependencies[name].reduce((cmds, currentDep) => {
23 | if(!resolvedDependencies[currentDep])
24 | {
25 | resolvedDependencies[currentDep] = true;
26 | var _path = namesToPaths[currentDep];
27 | var _destination = path.join(destination, path.basename(namesToPaths[currentDep]));
28 | return cmds + "\n" + getCopyCmd(_path, _destination) + dependenciesToCmds(currentDep, destination);
29 | }
30 | }, "");
31 | }
32 | else
33 | {
34 | return "\n";
35 | }
36 | }
37 |
38 | module.exports = function (appDir, sharedAppDir, destinationDir)
39 | {
40 | resolvedDependencies = {};
41 | namesToPaths = {};
42 | namesToDependencies = {};
43 |
44 | var package = JSON.parse(fs.readFileSync(path.join(appDir, 'package.json'), 'utf8'));
45 | namesToDependencies['[APP]'] = package.localDependencies;
46 |
47 | mapNames(sharedAppDir);
48 | return dependenciesToCmds('[APP]', destinationDir);
49 | }
50 |
--------------------------------------------------------------------------------
/node-app/base-dev-image/README.md:
--------------------------------------------------------------------------------
1 | ##Development Base Image
2 |
3 | Unlike the production-oriented base image, the development image can be used as is with a joining docker-compose file without customization.
4 |
5 | Of course, customizations are possible by inheriting from the image (to add environment variable and other customizations).
6 |
7 | ###Customizations
8 |
9 | The docker-compose file should have the following settings:
10 |
11 | - UID Environment variable: Determines the user and group ID that the node app will run under in the container
12 | - NPM_COMMAND Environment Variable: Determines the command that will be passed as to "npm run" when the container launches. Defaults to "start".
13 | - NPM_MODULES environment variable: npm modules that should be globally available to code in your app (see base image documentation for greater details).
14 | - ALWAYS_INSTALL variable: Set this environment variable if you want npm install & shared module linking each time you start your container. Leaving it unset will greatly speed up re-starting the container, but will also force you to destroy and re-create the container if you change your dependencies in package.json files.
15 | - TOOL Environment Variable: Tool that you want to use to install your dependencies, link your shared modules and launch your program. Defaults to "npm". Can be set to "yarn" instead.
16 | - /home/node-app/app volume mapping: Map your main application to this path in the image (see base image documentation for greater details).
17 | - /home/node-app/shared_modules: Map your local shared modules to this path in the image (see base image documentation for greater details).
18 |
19 | ###Examples
20 |
21 | The 'example' directory contain an example with the docker-compose file already prepared. Its the same example as example 4 for the base-image, but adapted to the development image.
22 |
23 |
24 |
--------------------------------------------------------------------------------
/certificate/example/ca-signed-with-password/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: "3"
2 | services:
3 | ca-certificate-generator:
4 | image: magnitus/certificate-generator:latest
5 | environment:
6 | COUNTRY: CA
7 | STATE: Quebec
8 | CITY: Montreal
9 | ORGANIZATION: Any
10 | DEPARTMENT: IT
11 | EMAIL: email@cadomain.com
12 | DOMAINS: dev.cadomain.com;test.cadomain.com
13 | CERTIFICATE_DURATION: 1095
14 | KEY_FILE: "ca.key"
15 | CSR_FILE: "ca.csr"
16 | CERTIFICATE_FILE: "ca.crt"
17 | OUTPUT_CERTIFICATE_INFO: "true"
18 | KEY_PASSWORD_FILE: "/opt/ca-password.txt"
19 | KEY_ENCRYPTION_CYPHER: aes256
20 | volumes:
21 | - .:/opt/output
22 | - ./ca-password.txt:/opt/ca-password.txt
23 | certificate-generator:
24 | image: magnitus/certificate-generator:latest
25 | environment:
26 | COUNTRY: CA
27 | STATE: Quebec
28 | CITY: Montreal
29 | ORGANIZATION: Any
30 | DEPARTMENT: IT
31 | EMAIL: email@mydomain.com
32 | DOMAINS: dev.mydomain.com;test.mydomain.com
33 | CERTIFICATE_DURATION: 1095
34 | KEY_FILE: "certificate.key"
35 | CSR_FILE: "certificate.csr"
36 | CERTIFICATE_FILE: "certificate.crt"
37 | CA_KEY_FILE: "/opt/output/ca.key"
38 | CA_CERTIFICATE_FILE: "/opt/output/ca.crt"
39 | OUTPUT_CERTIFICATE_INFO: "true"
40 | KEY_PASSWORD_FILE: "/opt/password.txt"
41 | KEY_ENCRYPTION_CYPHER: aes256
42 | CA_KEY_PASSWORD_FILE: "/opt/ca-password.txt"
43 | volumes:
44 | - .:/opt/output
45 | - ./password.txt:/opt/password.txt
46 | - ./ca-password.txt:/opt/ca-password.txt
47 |
--------------------------------------------------------------------------------
/react-build/example/lib/draw.js:
--------------------------------------------------------------------------------
1 | /*
2 | Performance note:
3 |
4 | This algorithm yields acceptable performance when the number of draws is small compared to the number of balls (ie, small number of collisions in generated results)
5 |
6 | If the number of draws is a significant proportion of the number of balls (ex: 40 picks out of 50), it may be worthwhile to consider sorting an array of balls instead.
7 |
8 | Alternatively, you could calculate the number of possible permutations, generate a result at random from 1 to that number and find out the permutation is maps to, but this may not yield a significant performance improvement (generating a random number is pretty fast) and potentially lead to ridiculously large numbers (ex:, 250 ordered balls out of 300 is a lot of permutations)
9 |
10 | A final way, that could generate the fastest performances at the cost of memory, if you want to crunch a lot of results with the same set, is to pre-compute a matrix of conditional probabilites.
11 |
12 | Again, while exploring all those possibilities would make an interesting engineering exercise, quickly finding a simple solution with acceptable performance characteristics for the kind of problems we are trying to solve is paramount.
13 | */
14 |
15 | module.exports = function(balls, draws) {
16 | if((!balls) || balls <= 0)
17 | {
18 | throw new Error("draw:ballsBadValue");
19 | }
20 |
21 | if((!draws) || draws <= 0 || draws > balls)
22 | {
23 | throw new Error("draw:drawsBadValue");
24 | }
25 |
26 | var results = [];
27 |
28 | while(draws > 0)
29 | {
30 | var result = Math.floor((Math.random() * balls) + 1);
31 | if(!results.some(function(element) {
32 | return element == result;
33 | }))
34 | {
35 | results.push(result);
36 | draws--;
37 | }
38 | }
39 |
40 | return results;
41 | }
--------------------------------------------------------------------------------
/react-build/example-onbuild/lib/draw.js:
--------------------------------------------------------------------------------
1 | /*
2 | Performance note:
3 |
4 | This algorithm yields acceptable performance when the number of draws is small compared to the number of balls (ie, small number of collisions in generated results)
5 |
6 | If the number of draws is a significant proportion of the number of balls (ex: 40 picks out of 50), it may be worthwhile to consider sorting an array of balls instead.
7 |
8 | Alternatively, you could calculate the number of possible permutations, generate a result at random from 1 to that number and find out the permutation is maps to, but this may not yield a significant performance improvement (generating a random number is pretty fast) and potentially lead to ridiculously large numbers (ex:, 250 ordered balls out of 300 is a lot of permutations)
9 |
10 | A final way, that could generate the fastest performances at the cost of memory, if you want to crunch a lot of results with the same set, is to pre-compute a matrix of conditional probabilites.
11 |
12 | Again, while exploring all those possibilities would make an interesting engineering exercise, quickly finding a simple solution with acceptable performance characteristics for the kind of problems we are trying to solve is paramount.
13 | */
14 |
15 | module.exports = function(balls, draws) {
16 | if((!balls) || balls <= 0)
17 | {
18 | throw new Error("draw:ballsBadValue");
19 | }
20 |
21 | if((!draws) || draws <= 0 || draws > balls)
22 | {
23 | throw new Error("draw:drawsBadValue");
24 | }
25 |
26 | var results = [];
27 |
28 | while(draws > 0)
29 | {
30 | var result = Math.floor((Math.random() * balls) + 1);
31 | if(!results.some(function(element) {
32 | return element == result;
33 | }))
34 | {
35 | results.push(result);
36 | draws--;
37 | }
38 | }
39 |
40 | return results;
41 | }
--------------------------------------------------------------------------------
/node-app/dockerfile-builder/code/app/index.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | const fs = require('fs');
4 | const path = require('path');
5 | const childProcess = require('child_process');
6 | const chownr = require('chownr');
7 | const cpr = require('cpr');
8 |
9 | const getCopyCmd = require('./getCopyCmd');
10 | const getCopySharedCmd = require('./getCopySharedCmd');
11 |
12 | //Read template in memory
13 | var output = fs.readFileSync(process.env.TEMPLATE_PATH, 'utf8');
14 |
15 | //Plug values in template
16 | output = output.replace(/{{UID}}/, process.env.UID);
17 | output = output.replace(/{{COPY_APP}}/, getCopyCmd(process.env.APP_DIR, "${APP_DIR}"));
18 | output = output.replace(/{{COPY_SHARED}}/, getCopySharedCmd(process.env.APP_DIR, process.env.SHARED_DIR, "${SHARED_DIR}"));
19 |
20 |
21 | fs.writeFileSync(path.join(process.env.OUTPUT_DIR, 'dockerfile'), output);
22 | fs.writeFileSync(path.join(process.env.OUTPUT_DIR, 'build.sh'), "docker build -t "+process.env.OUTPUT_IMAGE+" -f dockerfile .");
23 |
24 | cpr(process.env.APP_DIR, path.join(process.env.OUTPUT_DIR, 'app'), {
25 | deleteFirst: true, //Delete "to" before
26 | overwrite: true, //If the file exists, overwrite it
27 | confirm: true //After the copy, stat all the copied files to make sure they are there
28 | }, function(err, files) {
29 | if(err)
30 | {
31 | process.exit(1);
32 | }
33 | else
34 | {
35 | cpr(process.env.SHARED_DIR, path.join(process.env.OUTPUT_DIR, 'shared'), {
36 | deleteFirst: true, //Delete "to" before
37 | overwrite: true, //If the file exists, overwrite it
38 | confirm: true //After the copy, stat all the copied files to make sure they are there
39 | }, function(err, files) {
40 | if(err)
41 | {
42 | process.exit(1);
43 | }
44 | chownr.sync(process.env.OUTPUT_DIR, parseInt(process.env.OUTPUT_UID), parseInt(process.env.OUTPUT_UID));
45 | });
46 | }
47 | });
48 |
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/node-app/image-builder/code/app/wgetDirCmd.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs');
2 | const path = require('path');
3 |
4 | var ignoreRegex = process.env.IGNORE ? new RegExp(process.env.IGNORE) : null;
5 |
6 | function wgetDirCmd(rootPath, destination , trimToDestination, prefix)
7 | {
8 | //Plug app copy in template
9 | var cmd = prefix ? prefix : "";
10 | var addedOne = false;
11 | var acceptExtensionFlag = "";
12 |
13 | fs.readdirSync(rootPath).forEach((filename) => {
14 | if(filename != "node_modules" && (ignoreRegex && (!ignoreRegex.test(filename))))
15 | {
16 | if(fs.lstatSync(path.join(rootPath, filename)).isDirectory())
17 | {
18 | var cmdForDir = wgetDirCmd(path.join(rootPath, filename), destination, trimToDestination, "");
19 | if(cmdForDir != "")
20 | {
21 | if((!addedOne))
22 | {
23 | addedOne = true;
24 | cmd += " ";
25 | }
26 | else
27 | {
28 | cmd += " && ";
29 | }
30 | cmd += cmdForDir;
31 | }
32 | }
33 | else
34 | {
35 | if(!addedOne)
36 | {
37 | addedOne = true;
38 |
39 | }
40 | else
41 | {
42 | cmd += " && ";
43 | }
44 |
45 | acceptExtensionFlag = path.extname(filename) != '' ? '-A'+path.extname(filename) : '';
46 |
47 | cmd += ("mkdir -p "+rootPath.replace(trimToDestination, destination)+" && wget 'http://"+process.env.DOCKER_LOCALHOST+":"+process.env.EXTERNAL_PORT+path.join(rootPath, filename) + "' --output-document=\"" + path.join(destination, path.join(rootPath, filename).replace(trimToDestination+"/", ""))+"\"");
48 | }
49 | }
50 | });
51 |
52 | return cmd;
53 | }
54 |
55 | module.exports = wgetDirCmd;
56 |
--------------------------------------------------------------------------------
/cfssl/README.md:
--------------------------------------------------------------------------------
1 | # Purpose
2 |
3 | Docker images for the cfssl project: https://github.com/cloudflare/cfssl
4 |
5 | As I need cfssl to run on arm64 machines and the official binary are not (at the time of this writing) running properly on Scaleway arm64 machines, I opted to create my own arm64 image and also decided to make an amd64 version while I was at it.
6 |
7 | # Usage
8 |
9 | ## Images Names
10 |
11 | The image for adm64 is **magnitus/cfssl:latest**. The image for arm64 is **magnitus/cfssl:arm64-latest**
12 |
13 | ## Included Binaries
14 |
15 | The **cfssl** and **cfssljson** were built into the images
16 |
17 | ## Running It
18 |
19 | By default, the execution directory is **/opt** and the command is **sh** (no entrypoint).
20 |
21 | You can override the command, setting it run either **cfssl** or **cfssljson** with whatever arguments you need. You can also map whichever directory should provide files input or receive files output to the container.
22 |
23 | Take the following command as an example:
24 |
25 | ```
26 | cfssl gencert -initca ca-csr.json | cfssljson -bare ca -
27 | cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=client client.json | cfssljson -bare client
28 | ```
29 |
30 | You would run it this way with the docker images:
31 |
32 | ```
33 | IMAGE=magnitus/cfssl:latest
34 | docker run --rm -v $(pwd):/opt $IMAGE cfssl gencert -initca ca-csr.json \
35 | | docker run --rm -i -v $(pwd):/opt $IMAGE cfssljson -bare ca -
36 | docker run --rm -v $(pwd):/opt $IMAGE cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=client client.json \
37 | | docker run --rm -i -v $(pwd):/opt $IMAGE cfssljson -bare client -
38 | ```
39 |
40 | All the dependent files for the example can be found in the **example** directory.
41 |
42 | # Manual Push
43 |
44 | Because I don't think Docker Hub supports arm64 automated builds at this time, the arm64 images have to be pushed manually (ie, no automated build). If you want to use the images, but don't really trust the source (I totally get it), feel free to clone the repo and build your own from the project's Dockerfiles (keeping in mind that you'll need an arm64 machine to build the arm64 images).
--------------------------------------------------------------------------------
/react-build/example/app/javascript/draw-feedback.jsx:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 | var ReactDOM = require('react-dom');
3 |
4 | function getRankingSuffix(rank)
5 | {
6 | if(rank == 1)
7 | {
8 | return 'rst';
9 | }
10 | else if(rank == 2)
11 | {
12 | return 'nd';
13 | }
14 | else if(rank == 3)
15 | {
16 | return 'rd';
17 | }
18 | else
19 | {
20 | return 'th';
21 | }
22 | }
23 |
24 | var WinnersList = React.createClass({
25 | render: function() {
26 | return (
27 |
28 | {this.props.winners.map(function(winner, index){
29 | if(winner === null)
30 | {
31 | return (
32 | -
33 | {(index+1)+getRankingSuffix(index+1)+' ball'}
34 | {'no winner'}
35 |
36 | );
37 | }
38 | else
39 | {
40 | return (
41 | -
42 | {(index+1)+getRankingSuffix(index+1)+' ball'}
43 | {winner['name']+': '+winner['award']+ '$'}
44 |
45 | );
46 | }
47 | })}
48 |
49 | );
50 | }
51 | });
52 |
53 |
54 | module.exports = React.createClass({
55 | handleClick: function(event) {
56 | this.props.clearParticipants();
57 | },
58 | render: function() {
59 | var allNull = this.props.winners.every(function(elem) {return elem === null});
60 | var content = [];
61 | content.push(Winners
);
62 | if(allNull)
63 | {
64 | content.push(No winners this round. Better luck next time...
);
65 | }
66 | else
67 | {
68 | content.push();
69 | }
70 | return (
71 |
72 |
73 | );
74 | }
75 | });
--------------------------------------------------------------------------------
/react-build/example-onbuild/app/javascript/draw-feedback.jsx:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 | var ReactDOM = require('react-dom');
3 |
4 | function getRankingSuffix(rank)
5 | {
6 | if(rank == 1)
7 | {
8 | return 'rst';
9 | }
10 | else if(rank == 2)
11 | {
12 | return 'nd';
13 | }
14 | else if(rank == 3)
15 | {
16 | return 'rd';
17 | }
18 | else
19 | {
20 | return 'th';
21 | }
22 | }
23 |
24 | var WinnersList = React.createClass({
25 | render: function() {
26 | return (
27 |
28 | {this.props.winners.map(function(winner, index){
29 | if(winner === null)
30 | {
31 | return (
32 | -
33 | {(index+1)+getRankingSuffix(index+1)+' ball'}
34 | {'no winner'}
35 |
36 | );
37 | }
38 | else
39 | {
40 | return (
41 | -
42 | {(index+1)+getRankingSuffix(index+1)+' ball'}
43 | {winner['name']+': '+winner['award']+ '$'}
44 |
45 | );
46 | }
47 | })}
48 |
49 | );
50 | }
51 | });
52 |
53 |
54 | module.exports = React.createClass({
55 | handleClick: function(event) {
56 | this.props.clearParticipants();
57 | },
58 | render: function() {
59 | var allNull = this.props.winners.every(function(elem) {return elem === null});
60 | var content = [];
61 | content.push(Winners
);
62 | if(allNull)
63 | {
64 | content.push(No winners this round. Better luck next time...
);
65 | }
66 | else
67 | {
68 | content.push();
69 | }
70 | return (
71 |
72 |
73 | );
74 | }
75 | });
--------------------------------------------------------------------------------
/node-app/image-builder/code/app/index.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | const fs = require('fs');
4 | const path = require('path');
5 | const childProcess = require('child_process');
6 |
7 | const dependencies = (require('./compileDependencies')());
8 | const wgetDirCmd = require('./wgetDirCmd');
9 |
10 | var exitCode = 0;
11 |
12 | var source_image = process.env.SOURCE_IMAGE ? process.env.SOURCE_IMAGE : process.env.DEFAULT_SOURCE_IMAGE;
13 |
14 | //Read template in memory
15 | var output = fs.readFileSync(process.env.TEMPLATE_PATH, 'utf8');
16 |
17 | output = output.replace(/{{SOURCE}}/, source_image);
18 |
19 | //Plug values in template
20 | output = output.replace(/{{UID}}/, process.env.UID);
21 |
22 | output = process.env.NPM_COMMAND ? output.replace(/{{NPM_COMMAND}}/, "ENV NPM_COMMAND "+process.env.NPM_COMMAND) : output.replace(/{{NPM_COMMAND}}/, "");
23 |
24 | var wgetFilesCmd = wgetDirCmd(process.env.APP_DIR, "${APP_DIR}", process.env.APP_DIR, "RUN ");
25 |
26 | try
27 | {
28 | fs.accessSync(process.env.SHARED_DIR, fs.F_OK);
29 | Object.keys(dependencies['dependencies']).forEach((module) => {
30 | wgetFilesCmd = wgetFilesCmd + wgetDirCmd(dependencies['pathsByModule'][module], "${SHARED_DIR}", process.env.SHARED_DIR, " && ");
31 | });
32 | }
33 | catch(err)
34 | {
35 | }
36 |
37 | output = output.replace(/{{COPY_ALL}}/, wgetFilesCmd);
38 |
39 | console.log("Building image \""+process.env.OUTPUT_IMAGE+"\" with the following dockerfile: ")
40 | console.log("*********************************");
41 | console.log(output);
42 | console.log("*********************************");
43 |
44 | const serverProcess = childProcess.spawn('npm', ['start'], {'cwd': process.env.SERVER_DIR});
45 |
46 | serverProcess.on('exit', (code) => {
47 | process.exit(exitCode);
48 | });
49 |
50 | if(process.env.CACHE == 'yes')
51 | {
52 | var buildArgs = ['build', '-t', process.env.OUTPUT_IMAGE, '-'];
53 | }
54 | else
55 | {
56 | var buildArgs = ['build', '--no-cache', '-t', process.env.OUTPUT_IMAGE, '-']
57 | }
58 |
59 |
60 | const buildProcess = childProcess.spawn('docker', buildArgs, {'cwd': '/opt'});
61 |
62 | buildProcess.stdout.pipe(process.stdout);
63 | buildProcess.stderr.pipe(process.stderr);
64 |
65 | buildProcess.on('exit', (code) => {
66 | exitCode = code;
67 | serverProcess.kill('SIGTERM');
68 | });
69 |
70 | buildProcess.stdin.write(output);
71 | buildProcess.stdin.end();
72 |
--------------------------------------------------------------------------------
/network-setup/README.md:
--------------------------------------------------------------------------------
1 | # Purpose
2 |
3 | This container sets up dockerized dhcp and dns servers on a networked machine based on a configuration file.
4 |
5 | The following manual tasks still needs to be done before running this container:
6 | - Setup the routing
7 | - Setup a static ip on the network interfaces of the machine hosting the dhcp/dns containers
8 | - Potentially disable existing services that are already listening on port 53 on the machine (https://askubuntu.com/questions/907246/how-to-disable-systemd-resolved-in-ubuntu)
9 | - As a result of the above step, you might have to add your local hostname to the **/etc/hosts** file and add your localhost to **/etc/resolv.conf** (other machines on the network should not require those steps)
10 |
11 | From there, assuming your configuration is comprehensive, ip and name assignment will be handled from a centralized configuration file on the machine running the dhcp/dns servers.
12 |
13 | This should work well in a network where the number of machines that need to have a fixed ip and known name is limited to at most ~20 machines (ex: home lab, small company, etc).
14 |
15 | In a larger setup, a dynamic system where machines requiring a fixed ip and a known name register themselves probably makes more sense.
16 |
17 | # Usage
18 |
19 | Change the content of the "conf" file for something that makes sense for your network.
20 |
21 | The top-level entries under "networks" are the various networks the dhcp/dns server will server. The name of each entry represents the domain name that will be used on the network.
22 |
23 | For example, if the entry is test, then a host with the name **hosta** will actually be have the name **hosta.test**.
24 |
25 | The machines list is optional. If set, it will make sure that for each mac address specifie, the given machine will have to given ip and name (remember that the network domain name will be appended to that name to form the machine name).
26 |
27 | Then, run:
28 |
29 | ```
30 | docker-compose run setup
31 | ```
32 | # Idempotency of the scripts
33 |
34 | You can regenerate the containers with configuration file changes by re-executing the docker-compose command.
35 |
36 | There will be brief moment where the services will be unresponsive if you do this however.
37 |
38 | While I know that CoreDNS supports graceful restart with new configurations, I'm less certain the isc dhcp supports it making the point of a gracefully restart moot.
39 |
40 | The most graceful solution to conteract this may be to setup failover dhcp servers (https://kb.isc.org/docs/aa-00502).
--------------------------------------------------------------------------------
/remote-terraform/ansible_scripts/roles/terraform_plan/tasks/main.yml:
--------------------------------------------------------------------------------
1 | - name: Run terraform init on the remote machine
2 | docker_container:
3 | image: "{{ remote_terraform_image }}"
4 | name: "{{ remote_container_name }}"
5 | network_mode: host
6 | volumes:
7 | - "{{ remote_terraform_config_dir }}:/opt/terraform_config"
8 | - "{{ remote_terraform_state_dir }}:/opt/terraform_state"
9 | working_dir: "/opt/terraform_config"
10 | detach: false
11 | recreate: true
12 | state: started
13 | entrypoint: ""
14 | command: "terraform init"
15 | register: init_output
16 |
17 | - name: Get init output
18 | debug:
19 | msg: "{{ init_output.ansible_facts.docker_container.Output }}"
20 |
21 | - name: Cleanup terraform init on the remote machine
22 | docker_container:
23 | image: "{{ remote_terraform_image }}"
24 | name: "{{ remote_container_name }}"
25 | network_mode: host
26 | volumes:
27 | - "{{ remote_terraform_config_dir }}:/opt/terraform_config"
28 | - "{{ remote_terraform_state_dir }}:/opt/terraform_state"
29 | working_dir: "/opt/terraform_config"
30 | detach: false
31 | recreate: true
32 | state: started
33 | entrypoint: ""
34 | command: "terraform init"
35 | state: absent
36 |
37 | - name: Run terraform plan on the remote machine
38 | docker_container:
39 | image: "{{ remote_terraform_image }}"
40 | name: "{{ remote_container_name }}"
41 | network_mode: host
42 | volumes:
43 | - "{{ remote_terraform_config_dir }}:/opt/terraform_config"
44 | - "{{ remote_terraform_state_dir }}:/opt/terraform_state"
45 | working_dir: "/opt/terraform_config"
46 | detach: false
47 | recreate: true
48 | state: started
49 | entrypoint: ""
50 | command: "terraform plan -state /opt/terraform_state/terraform.tfstate"
51 | register: plan_output
52 |
53 | - name: Get plan output
54 | debug:
55 | msg: "{{ plan_output.ansible_facts.docker_container.Output }}"
56 |
57 | - name: Cleanup terraform plan on the remote machine
58 | docker_container:
59 | image: "{{ remote_terraform_image }}"
60 | name: "{{ remote_container_name }}"
61 | network_mode: host
62 | volumes:
63 | - "{{ remote_terraform_config_dir }}:/opt/terraform_config"
64 | - "{{ remote_terraform_state_dir }}:/opt/terraform_state"
65 | working_dir: "/opt/terraform_config"
66 | detach: false
67 | recreate: true
68 | state: started
69 | entrypoint: ""
70 | command: "terraform plan -state /opt/terraform_state/terraform.tfstate"
71 | state: absent
--------------------------------------------------------------------------------
/remote-terraform/ansible_scripts/roles/terraform_apply/tasks/main.yml:
--------------------------------------------------------------------------------
1 | - name: Run terraform init on the remote machine
2 | docker_container:
3 | image: "{{ remote_terraform_image }}"
4 | name: "{{ remote_container_name }}"
5 | network_mode: host
6 | volumes:
7 | - "{{ remote_terraform_config_dir }}:/opt/terraform_config"
8 | - "{{ remote_terraform_state_dir }}:/opt/terraform_state"
9 | working_dir: "/opt/terraform_config"
10 | detach: false
11 | recreate: true
12 | state: started
13 | entrypoint: ""
14 | command: "terraform init"
15 | register: init_output
16 |
17 | - name: Get init output
18 | debug:
19 | msg: "{{ init_output.ansible_facts.docker_container.Output }}"
20 |
21 | - name: Cleanup terraform init on the remote machine
22 | docker_container:
23 | image: "{{ remote_terraform_image }}"
24 | name: "{{ remote_container_name }}"
25 | network_mode: host
26 | volumes:
27 | - "{{ remote_terraform_config_dir }}:/opt/terraform_config"
28 | - "{{ remote_terraform_state_dir }}:/opt/terraform_state"
29 | working_dir: "/opt/terraform_config"
30 | detach: false
31 | recreate: true
32 | state: started
33 | entrypoint: ""
34 | command: "terraform init"
35 | state: absent
36 |
37 | - name: Run terraform apply on the remote machine
38 | docker_container:
39 | image: "{{ remote_terraform_image }}"
40 | name: "{{ remote_container_name }}"
41 | network_mode: host
42 | volumes:
43 | - "{{ remote_terraform_config_dir }}:/opt/terraform_config"
44 | - "{{ remote_terraform_state_dir }}:/opt/terraform_state"
45 | working_dir: "/opt/terraform_config"
46 | detach: false
47 | recreate: true
48 | state: started
49 | entrypoint: ""
50 | command: "terraform apply -auto-approve -state /opt/terraform_state/terraform.tfstate"
51 | register: apply_output
52 |
53 | - name: Get apply output
54 | debug:
55 | msg: "{{ apply_output.ansible_facts.docker_container.Output }}"
56 |
57 | - name: Cleanup terraform apply on the remote machine
58 | docker_container:
59 | image: "{{ remote_terraform_image }}"
60 | name: "{{ remote_container_name }}"
61 | network_mode: host
62 | volumes:
63 | - "{{ remote_terraform_config_dir }}:/opt/terraform_config"
64 | - "{{ remote_terraform_state_dir }}:/opt/terraform_state"
65 | working_dir: "/opt/terraform_config"
66 | detach: false
67 | recreate: true
68 | state: started
69 | entrypoint: ""
70 | command: "terraform apply -auto-approve -state /opt/terraform_state/terraform.tfstate"
71 | state: absent
--------------------------------------------------------------------------------
/react-build/example/app/javascript/register-section.jsx:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 | var ReactDOM = require('react-dom');
3 |
4 | var RegistrationFeedback = require('registration-feedback');
5 |
6 | module.exports = React.createClass({
7 | handleNameChange: function(event) {
8 | this.name = event.target.value;
9 | },
10 | handleSubmit: function(event) {
11 | //Sometimes, it's extra work to prevent built-in browser defaults (in this case, reloading the page), but
12 | //I think using the right semantic html tags to describe gui structure makes the application easier to understand
13 | event.preventDefault();
14 | if(this.name != "")
15 | {
16 | this.props.addRegistrant(this.name);
17 | document.getElementById('registrationForm').reset();
18 | this.name = "";
19 | }
20 | },
21 | render: function() {
22 | if(this.props.winners === null)
23 | {
24 | return (
25 |
26 | {function() {
27 | if(this.props.participants.length < this.props.balls)
28 | {
29 | return (
30 |
36 | );
37 |
38 | }
39 | else
40 | {
41 | return (Fully booked. No more registrations!
);
42 | }
43 | }.call(this)}
44 | {function() {
45 | if(this.props.lastRegistrant && this.props.lastRegistrant.visible)
46 | {
47 | return (
48 |
49 | );
50 | }
51 | }.call(this)}
52 |
53 | );
54 | }
55 | else
56 | {
57 | return false;
58 | }
59 | }
60 | });
--------------------------------------------------------------------------------
/react-build/example-onbuild/app/javascript/register-section.jsx:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 | var ReactDOM = require('react-dom');
3 |
4 | var RegistrationFeedback = require('registration-feedback');
5 |
6 | module.exports = React.createClass({
7 | handleNameChange: function(event) {
8 | this.name = event.target.value;
9 | },
10 | handleSubmit: function(event) {
11 | //Sometimes, it's extra work to prevent built-in browser defaults (in this case, reloading the page), but
12 | //I think using the right semantic html tags to describe gui structure makes the application easier to understand
13 | event.preventDefault();
14 | if(this.name != "")
15 | {
16 | this.props.addRegistrant(this.name);
17 | document.getElementById('registrationForm').reset();
18 | this.name = "";
19 | }
20 | },
21 | render: function() {
22 | if(this.props.winners === null)
23 | {
24 | return (
25 |
26 | {function() {
27 | if(this.props.participants.length < this.props.balls)
28 | {
29 | return (
30 |
36 | );
37 |
38 | }
39 | else
40 | {
41 | return (Fully booked. No more registrations!
);
42 | }
43 | }.call(this)}
44 | {function() {
45 | if(this.props.lastRegistrant && this.props.lastRegistrant.visible)
46 | {
47 | return (
48 |
49 | );
50 | }
51 | }.call(this)}
52 |
53 | );
54 | }
55 | else
56 | {
57 | return false;
58 | }
59 | }
60 | });
--------------------------------------------------------------------------------
/pulsar-orchestration/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: '3.5'
2 | services:
3 | zookeeper-one:
4 | image: zookeeper:3.6
5 | restart: always
6 | hostname: zookeeper-one
7 | volumes:
8 | - "./zookeeper/one/data:/data"
9 | - "./zookeeper/one/datalog:/datalog"
10 | - "./zookeeper-conf/zoo.cfg:/conf/zoo.cfg"
11 | environment:
12 | ZOO_CONF_DIR: /conf
13 | ZOO_MY_ID: 1
14 | networks:
15 | - pulsar-internal
16 | zookeeper-two:
17 | image: zookeeper:3.6
18 | restart: always
19 | hostname: zookeeper-two
20 | volumes:
21 | - "./zookeeper/two/data:/data"
22 | - "./zookeeper/two/datalog:/datalog"
23 | - "./zookeeper-conf/zoo.cfg:/conf/zoo.cfg"
24 | environment:
25 | ZOO_CONF_DIR: /conf
26 | ZOO_MY_ID: 2
27 | networks:
28 | - pulsar-internal
29 | zookeeper-three:
30 | image: zookeeper:3.6
31 | restart: always
32 | hostname: zookeeper-three
33 | volumes:
34 | - "./zookeeper/three/data:/data"
35 | - "./zookeeper/three/datalog:/datalog"
36 | - "./zookeeper-conf/zoo.cfg:/conf/zoo.cfg"
37 | environment:
38 | ZOO_CONF_DIR: /conf
39 | ZOO_MY_ID: 3
40 | networks:
41 | - pulsar-internal
42 | bookie-one:
43 | image: apachepulsar/pulsar:2.5.1
44 | restart: always
45 | volumes:
46 | - "./bookkeeper-conf/bookkeeper.conf:/pulsar/conf/bookkeeper.conf"
47 | - "./bookie/one/data:/pulsar/data"
48 | command: ["bin/bookkeeper", "bookie"]
49 | networks:
50 | - pulsar-internal
51 | bookie-two:
52 | image: apachepulsar/pulsar:2.5.1
53 | restart: always
54 | volumes:
55 | - "./bookkeeper-conf/bookkeeper.conf:/pulsar/conf/bookkeeper.conf"
56 | - "./bookie/two/data:/pulsar/data"
57 | command: ["bin/bookkeeper", "bookie"]
58 | networks:
59 | - pulsar-internal
60 | bookie-three:
61 | image: apachepulsar/pulsar:2.5.1
62 | restart: always
63 | volumes:
64 | - "./bookkeeper-conf/bookkeeper.conf:/pulsar/conf/bookkeeper.conf"
65 | - "./bookie/three/data:/pulsar/data"
66 | command: ["bin/bookkeeper", "bookie"]
67 | networks:
68 | - pulsar-internal
69 | broker:
70 | image: apachepulsar/pulsar:2.5.1
71 | #Will technically be ignored with scripts in non-swarm mode, but this conveys the idea.
72 | #This is cattle.
73 | deploy:
74 | replicas: 3
75 | restart: always
76 | volumes:
77 | - "./broker-conf/broker.conf:/pulsar/conf/broker.conf"
78 | command: ["bin/pulsar", "broker"]
79 | networks:
80 | - pulsar
81 | - pulsar-internal
82 |
83 | networks:
84 | pulsar:
85 | name: pulsar
86 | pulsar-internal:
87 | name: pulsar-internal
--------------------------------------------------------------------------------
/headless-factorio-server/code/entrypoint.py:
--------------------------------------------------------------------------------
1 | import os
2 | import subprocess
3 | import time
4 | import signal
5 | from configs import configs_defined, generate_configs
6 | from game import game_defined, generate_game
7 |
8 | CONFIGS_PATH = os.environ['CONFIGS_PATH']
9 | GAME_PATH = os.environ['GAME_PATH']
10 |
11 | ADMIN_PLAYERS_CONFIG = os.path.join(CONFIGS_PATH, 'server-adminlist.json')
12 | WHITELISTED_PLAYERS_CONFIG = os.path.join(CONFIGS_PATH, 'server-whitelist.json')
13 |
14 |
15 | class ProcessSignals:
16 | exiting = False
17 | def __init__(self):
18 | signal.signal(signal.SIGINT, self.exit)
19 | signal.signal(signal.SIGTERM, self.exit)
20 |
21 | def exit(self, *args, **kwargs):
22 | self.exiting = True
23 |
24 | if __name__ == '__main__':
25 | if not configs_defined():
26 | generate_configs()
27 | if not game_defined():
28 | generate_game()
29 |
30 | game_path=os.path.join(GAME_PATH, 'game.zip')
31 | server_settings_path=os.path.join(CONFIGS_PATH, 'server-settings.json')
32 | map_gen_settings_path=os.path.join(CONFIGS_PATH, 'map-gen-settings.json')
33 | map_settings_path=os.path.join(CONFIGS_PATH, 'map-settings.json')
34 | command = [
35 | "/opt/factorio/bin/x64/factorio",
36 | "--start-server",
37 | "{game_path}".format(game_path=game_path),
38 | "--server-settings",
39 | "{server_settings_path}".format(server_settings_path=server_settings_path),
40 | "--map-gen-settings",
41 | "{map_gen_settings_path}".format(map_gen_settings_path=map_gen_settings_path),
42 | "--map-settings",
43 | "{map_settings_path}".format(map_settings_path=map_settings_path),
44 | "--port",
45 | "{bind_port}".format(bind_port=os.environ['BIND_PORT']),
46 | "--bind",
47 | "{bind_ip}".format(bind_ip=os.environ['BIND_IP'])
48 | ]
49 | if os.path.isfile(WHITELISTED_PLAYERS_CONFIG):
50 | command = command + ["--use-server-whitelist", "--server-whitelist", "{whitelist_path}".format(whitelist_path=WHITELISTED_PLAYERS_CONFIG)]
51 | if os.path.isfile(ADMIN_PLAYERS_CONFIG):
52 | command = command + ["--server-adminlist", "{admin_path}".format(admin_path=ADMIN_PLAYERS_CONFIG)]
53 |
54 | process = subprocess.Popen(
55 | command,
56 | stdin=subprocess.PIPE
57 | )
58 | process_pid = process.pid
59 |
60 | #Working around the fact that the Factorio server doesn't handle EOF on input well
61 | signal_handler = ProcessSignals()
62 | while not signal_handler.exiting:
63 | time.sleep(1)
64 | os.killpg(os.getpgid(process.pid), signal.SIGTERM)
65 |
66 | while True:
67 | try:
68 | os.kill(process_pid, 0)
69 | except OSError:
70 | break
--------------------------------------------------------------------------------
/pulsar-orchestration/bookkeeper-conf/bookkeeper.conf:
--------------------------------------------------------------------------------
1 | #Taken from recommended bookkeeper configuration file with minimal adjustments
2 | bookiePort=3181
3 | journalDirectory=data/bookkeeper/journal
4 | minUsableSizeForIndexFileCreation=1073741824
5 | advertisedAddress=
6 | allowLoopback=false
7 | bookieDeathWatchInterval=1000
8 | flushInterval=60000
9 | useHostNameAsBookieID=false
10 | gcWaitTime=900000
11 | gcOverreplicatedLedgerWaitTime=86400000
12 | numAddWorkerThreads=0
13 | numReadWorkerThreads=8
14 | numHighPriorityWorkerThreads=8
15 | maxPendingReadRequestsPerThread=2500
16 | maxPendingAddRequestsPerThread=10000
17 | auditorPeriodicBookieCheckInterval=86400
18 | rereplicationEntryBatchSize=100
19 | openLedgerRereplicationGracePeriod=30
20 | autoRecoveryDaemonEnabled=true
21 | lostBookieRecoveryDelay=0
22 | serverTcpNoDelay=true
23 | journalFormatVersionToWrite=5
24 | journalMaxSizeMB=2048
25 | journalMaxBackups=5
26 | journalPreAllocSizeMB=16
27 | journalWriteBufferSizeKB=64
28 | journalRemoveFromPageCache=true
29 | journalSyncData=true
30 | journalAdaptiveGroupWrites=true
31 | journalMaxGroupWaitMSec=1
32 | journalBufferedWritesThreshold=524288
33 | numJournalCallbackThreads=8
34 | journalAlignmentSize=4096
35 | journalFlushWhenQueueEmpty=false
36 | ledgerStorageClass=org.apache.bookkeeper.bookie.storage.ldb.DbLedgerStorage
37 | ledgerDirectories=data/bookkeeper/ledgers
38 | auditorPeriodicCheckInterval=604800
39 | openFileLimit=0
40 | fileInfoFormatVersionToWrite=0
41 | pageLimit=0
42 | zkLedgersRootPath=/ledgers
43 | logSizeLimit=1073741824
44 | entryLogFilePreallocationEnabled=true
45 | readBufferSizeBytes=4096
46 | writeBufferSizeBytes=65536
47 | compactionRate=1000
48 | minorCompactionThreshold=0.2
49 | minorCompactionInterval=3600
50 | compactionMaxOutstandingRequests=100000
51 | majorCompactionThreshold=0.5
52 | majorCompactionInterval=86400
53 | isThrottleByBytes=false
54 | compactionRateByEntries=1000
55 | compactionRateByBytes=1000000
56 | statsProviderClass=org.apache.bookkeeper.stats.prometheus.PrometheusMetricsProvider
57 | prometheusStatsHttpPort=8000
58 | readOnlyModeEnabled=true
59 | diskUsageThreshold=0.95
60 | diskCheckInterval=10000
61 | zkServers=zookeeper-one:2181,zookeeper-two:2181,zookeeper-three:2181
62 | zkTimeout=30000
63 | zkEnableSecurity=false
64 | httpServerEnabled=false
65 | httpServerPort=8000
66 | httpServerClass=org.apache.bookkeeper.http.vertx.VertxHttpServer
67 | dbStorage_writeCacheMaxSizeMb=512
68 | dbStorage_readAheadCacheMaxSizeMb=256
69 | dbStorage_readAheadCacheBatchSize=1000
70 | dbStorage_rocksDB_blockCacheSize=268435456
71 | dbStorage_rocksDB_writeBufferSizeMB=64
72 | dbStorage_rocksDB_sstSizeInMB=64
73 | dbStorage_rocksDB_blockSize=65536
74 | dbStorage_rocksDB_bloomFilterBitsPerKey=10
75 | dbStorage_rocksDB_numLevels=-1
76 | dbStorage_rocksDB_numFilesInLevel0=4
77 | dbStorage_rocksDB_maxSizeInLevel1MB=256
78 | extraServerComponents=org.apache.bookkeeper.stream.server.StreamStorageLifecycleComponent
--------------------------------------------------------------------------------
/certificate/test/run.py:
--------------------------------------------------------------------------------
1 | import unittest, shutil, os, subprocess, hashlib, re
2 |
3 | class TestCAWithPassword(unittest.TestCase):
4 | def setUp(self):
5 | shutil.copytree(os.path.join('..', 'example', 'ca-signed-with-password'), os.path.join('.', 'certificate'))
6 | subprocess.check_call("docker-compose up ca-certificate-generator", shell=True, cwd=os.path.join('.', 'certificate'))
7 | subprocess.check_call("docker-compose up certificate-generator", shell=True, cwd=os.path.join('.', 'certificate'))
8 |
9 | def tearDown(self):
10 | subprocess.check_call("docker-compose down", shell=True, cwd=os.path.join('.', 'certificate'))
11 | shutil.rmtree(os.path.join('.', 'certificate'))
12 |
13 | def test_generated_files_present(self):
14 | self.assertTrue(os.path.isfile(os.path.join('.', 'certificate', 'ca.crt')))
15 | self.assertTrue(os.path.isfile(os.path.join('.', 'certificate', 'ca.csr')))
16 | self.assertTrue(os.path.isfile(os.path.join('.', 'certificate', 'ca.key')))
17 | self.assertTrue(os.path.isfile(os.path.join('.', 'certificate', 'ca.srl')))
18 | self.assertTrue(os.path.isfile(os.path.join('.', 'certificate', 'certificate.crt')))
19 | self.assertTrue(os.path.isfile(os.path.join('.', 'certificate', 'certificate.csr')))
20 | self.assertTrue(os.path.isfile(os.path.join('.', 'certificate', 'certificate.key')))
21 |
22 | #Technically not a memory efficient test for md5 checksum, but who cares in a test scenario
23 | #when the file is small?
24 | def test_certificate_regeneration_works(self):
25 | previousSrlHash = hashlib.md5(open(os.path.join('.', 'certificate', 'ca.srl'), 'rb').read()).hexdigest()
26 | subprocess.check_call("docker-compose up certificate-generator", shell=True, cwd=os.path.join('.', 'certificate'))
27 | currentSrlHash = hashlib.md5(open(os.path.join('.', 'certificate', 'ca.srl'), 'rb').read()).hexdigest()
28 | self.assertNotEqual(previousSrlHash, currentSrlHash)
29 |
30 | def test_certificate_is_valid(self):
31 | output = subprocess.check_output("openssl verify -CAfile ca.crt certificate.crt", shell=True, cwd=os.path.join('.', 'certificate'))
32 | self.assertEqual(output.strip(), "certificate.crt: OK")
33 |
34 | def test_certificate_has_correct_values(self):
35 | output = subprocess.check_output("openssl x509 -in certificate.crt -text -noout", shell=True, cwd=os.path.join('.', 'certificate'))
36 | self.assertIsNotNone(re.search('Issuer: C=CA, ST=Quebec, L=Montreal, O=Any, OU=IT, CN=dev.cadomain.com/emailAddress=email@cadomain.com', output))
37 | self.assertIsNotNone(re.search('Subject: C=CA, ST=Quebec, L=Montreal, O=Any, OU=IT, CN=dev.mydomain.com/emailAddress=email@mydomain.com', output))
38 | self.assertIsNotNone(re.search('Public-Key: \(2048 bit\)', output))
39 | self.assertIsNotNone(re.search('Subject Alternative Name:', output))
40 | self.assertIsNotNone(re.search('DNS:dev.mydomain.com, DNS:test.mydomain.com', output))
41 |
42 | if __name__ == '__main__':
43 | unittest.main()
44 |
--------------------------------------------------------------------------------
/headless-factorio-server/templates/map-gen-settings.json.j2:
--------------------------------------------------------------------------------
1 | {
2 | "_terrain_segmentation_comment": "Inverse of map scale",
3 | "terrain_segmentation": 1,
4 |
5 | "_water_comment":
6 | [
7 | "Multiplier for water 'coverage' - higher increases the water level.",
8 | "Water level = 10 * log2(this value)"
9 | ],
10 | "water": {{ water_elevation }},
11 |
12 | "_comment_width+height": "Width and height of map, in tiles; 0 means infinite",
13 | "width": {{ map_width }},
14 | "height": {{ map_height }},
15 |
16 | "_starting_area_comment": "Multiplier for 'biter free zone radius'",
17 | "starting_area": {{ biter_free_starting_area }},
18 |
19 | "peaceful_mode": {{ peaceful_mode }},
20 |
21 | "autoplace_controls":
22 | {
23 | "coal": {"frequency": {{ coal['frequency'] }}, "size": {{ coal['size'] }}, "richness": {{ coal['richness'] }}},
24 | "stone": {"frequency": {{ stone['frequency'] }}, "size": {{ stone['size'] }}, "richness": {{ stone['richness'] }}},
25 | "copper-ore": {"frequency": {{ copper_ore['frequency'] }}, "size": {{ copper_ore['size'] }}, "richness": {{ copper_ore['richness'] }}},
26 | "iron-ore": {"frequency": {{ iron_ore['frequency'] }}, "size": {{ iron_ore['size'] }}, "richness": {{ iron_ore['richness'] }}},
27 | "uranium-ore": {"frequency": {{ uranium_ore['frequency'] }}, "size": {{ uranium_ore['size'] }}, "richness": {{ uranium_ore['richness'] }}},
28 | "crude-oil": {"frequency": {{ crude_oil['frequency'] }}, "size": {{ crude_oil['size'] }}, "richness": {{ crude_oil['richness'] }}},
29 | "trees": {"frequency": {{ trees['frequency'] }}, "size": {{ trees['size'] }}, "richness": {{ trees['richness'] }}},
30 | "enemy-base": {"frequency": {{ enemy_base['frequency'] }}, "size": {{ enemy_base['size'] }}, "richness": {{ enemy_base['richness'] }}}
31 | },
32 |
33 | "cliff_settings":
34 | {
35 | "_name_comment": "Name of the cliff prototype",
36 | "name": "cliff",
37 |
38 | "_cliff_elevation_0_comment": "Elevation of first row of cliffs",
39 | "cliff_elevation_0": 10,
40 |
41 | "_cliff_elevation_interval_comment": "Elevation difference between successive rows of cliffs",
42 | "cliff_elevation_interval": 10,
43 |
44 | "_richness_comment": "Multiplier for cliff continuity; 0 will result in no cliffs, 10 will make all cliff rows completely solid",
45 | "richness": 1
46 | },
47 |
48 | "_property_expression_names_comment":
49 | [
50 | "Overrides for property value generators",
51 | "Elevation influences water and cliff placement.",
52 | "Leave it blank to get 'normal' terrain.",
53 | "Use '0_16-elevation' to reproduce terrain from 0.16.",
54 | "Use '0_17-island' to get an island."
55 | ],
56 | "property_expression_names":
57 | {
58 | "elevation": "0_17-island",
59 |
60 | "control-setting:aux:bias": "0.300000",
61 | "control-setting:aux:frequency:multiplier": "1.333333",
62 | "control-setting:moisture:bias": "0.100000",
63 | "control-setting:moisture:frequency:multiplier": "0.500000"
64 | },
65 |
66 | "starting_points":
67 | [
68 | {"x": 1000, "y": 2000}
69 | ],
70 |
71 | "_seed_comment": "Use null for a random seed, number for a specific seed.",
72 | "seed": {{ seed }}
73 | }
74 |
--------------------------------------------------------------------------------
/node-app/image-builder/README.md:
--------------------------------------------------------------------------------
1 | ##Automated Image Creation Using the image-builder Image and Customized docker-compose.yml File Derived From the Template
2 |
3 | Take the docker-compose.yml template file and customize is for your needs (any parts between <<...>> should be customised).
4 |
5 | ###Build Note
6 |
7 | Because the docker client runs in a container and the docker daemon that actually builds the image runs on the local machine outside the container the client runs on, I had to do a work-around to make the app files available to the daemon.
8 |
9 | Basically, the client runs an http file server and passes in the dockerfile wget commands to the daemon to fetch the files from the server. This means that the build container must map a port to the local machine.
10 |
11 | Furthermore, it implies an additional delay at build time, but it also makes the resulting image more efficient (all files are imported in a single RUN statement resulting in a single layer).
12 |
13 | ###Customizations
14 |
15 | * container-name: Name of the container that builds the image (mostly useful to avoid name clashed with already running containers)
16 | * environment
17 | * UID: Running user ID of the image
18 | * SOURCE_IMAGE: This optional environment variable allows you to use a source image other than the default (magnitus/node-app:4 at the time of this writing). Useful if you want to use the slim version (magnitus/node-app:4-slim), node 6 (magnitus/node-app:6 or magnitus/node-app:6-slim) or an image that adds extra stuff to the default image (extra environment variables, global modules, etc)
19 | * OUTPUT_IMAGE: Full image name of the resulting image
20 | * IGNORE: Regex pattern identifiying files that the dockerfile should not copy (for example, my text editor always creates backup files ending with ~ that I don't want included in a production image)
21 | * EXTERNAL_PORT: Port on your local machine that your container maps to. It's extremely important that this value corresponds to the mapping that you give in the "ports" section.
22 | * DOCKER_LOCALHOST: Address if your localhost machine on the docker networking interface (in Linux, run ifconfig to find it, you should have a 'docker0' interface by default with an 'inet addr' entry)
23 | * CACHE: Whether to use cached intermediate images or not when building anew (should be yes or no)
24 | * NPM_COMMAND: This optional environment variable allows you to specify which npm command is used to launch the app when a container boots from the generated image. Defaults to 'start' (ie, npm run start).
25 | * volume mapping
26 | * App directory: Change the LHS of the volume mapping to map to the directory where your app is contained
27 | * Shared directory: Change the LHS of the volume mapping to map to the directory where your local shared modules are located
28 | * ports: Change the LHS entry to a free port on your host. Don't forget to give the same value to the EXTERNAL_PORT environment variable.
29 |
30 | ###Output
31 |
32 | The corresponding image should have been built by the docker-daemon on your machine.
33 |
34 | ###Examples
35 |
36 | The 'image-builder-image-example' directory contain an example, adapted to have its image automatically generated (port 8080 will need to be free on your machine for the example to work).
37 |
--------------------------------------------------------------------------------
/react-build/example/lib/participants.js:
--------------------------------------------------------------------------------
1 | /*
2 | Design notes: Idem what was written in pot for class design
3 |
4 | Also, while it would have been more intuitive to map the participants as a {'name': number, ...} structure,
5 | the {'number': 'name', ...} structure fits the access pattern of the class better.
6 | */
7 |
8 | function participants(balls)
9 | {
10 | if((!balls) || balls <= 0)
11 | {
12 | throw new Error("participants.constructor:ballsBadValue");
13 | }
14 |
15 | //Classical pattern to save end-user of the api from having to use the new operator
16 | if(this instanceof participants)
17 | {
18 | this.balls = balls;
19 | this.participants = {};
20 | this.names = []; //Member to efficiently test new names against existing ones
21 | }
22 | else
23 | {
24 | return new participants(balls);
25 | }
26 | }
27 |
28 | participants.prototype.add = function(name) {
29 | if(Object.keys(this.participants).length == this.balls)
30 | {
31 | throw new Error("participants.add:full");
32 | }
33 |
34 | if(name === "" || name === undefined || name === null)
35 | {
36 | throw new Error("participants.add:badName");
37 | }
38 |
39 | if(this.names.some(function(_name) {
40 | return _name == name;
41 | }))
42 | {
43 | throw new Error("participants.add:nameExists");
44 | }
45 | else
46 | {
47 | this.names.push(name);
48 | }
49 |
50 | /*Map the available values left to a range.
51 | Makes traversal slower when almost no values are taken, but greatly improves performance
52 | when all balls are almost taken (ex: 45 balls out of 50). Performance could be improved further
53 | by keeping track of the mapping and updating it as we insert values. */
54 | var range = this.balls - Object.keys(this.participants).length;
55 | var result = Math.floor((Math.random() * range) + 1);
56 |
57 | var index = 1;
58 | while(true)
59 | {
60 | if(this.participants[index] === undefined)
61 | {
62 | if(result == 1)
63 | {
64 | this.participants[index] = name;
65 | break;
66 | }
67 | else
68 | {
69 | result--;
70 | }
71 | }
72 | index++;
73 | }
74 |
75 | return index;
76 | }
77 |
78 | participants.prototype.getNames = function() {
79 | return this.names;
80 | }
81 |
82 | participants.prototype.getRanks = function(draws) {
83 | var result = [];
84 | draws.forEach((function(draw) {
85 | var participant = this.participants[draw];
86 | participant = participant === undefined ? null : participant;
87 | result.push(participant);
88 | }).bind(this));
89 | return result;
90 | }
91 |
92 | participants.prototype.getWinnings = function(ratios) {
93 | var result = {};
94 | for(key in ratios)
95 | {
96 | if(this.participants[key] !== undefined)
97 | {
98 | result[this.participants[key]] = ratios[key];
99 | }
100 | }
101 |
102 | return result;
103 | }
104 |
105 | module.exports = participants;
--------------------------------------------------------------------------------
/react-build/example-onbuild/lib/participants.js:
--------------------------------------------------------------------------------
1 | /*
2 | Design notes: Idem what was written in pot for class design
3 |
4 | Also, while it would have been more intuitive to map the participants as a {'name': number, ...} structure,
5 | the {'number': 'name', ...} structure fits the access pattern of the class better.
6 | */
7 |
8 | function participants(balls)
9 | {
10 | if((!balls) || balls <= 0)
11 | {
12 | throw new Error("participants.constructor:ballsBadValue");
13 | }
14 |
15 | //Classical pattern to save end-user of the api from having to use the new operator
16 | if(this instanceof participants)
17 | {
18 | this.balls = balls;
19 | this.participants = {};
20 | this.names = []; //Member to efficiently test new names against existing ones
21 | }
22 | else
23 | {
24 | return new participants(balls);
25 | }
26 | }
27 |
28 | participants.prototype.add = function(name) {
29 | if(Object.keys(this.participants).length == this.balls)
30 | {
31 | throw new Error("participants.add:full");
32 | }
33 |
34 | if(name === "" || name === undefined || name === null)
35 | {
36 | throw new Error("participants.add:badName");
37 | }
38 |
39 | if(this.names.some(function(_name) {
40 | return _name == name;
41 | }))
42 | {
43 | throw new Error("participants.add:nameExists");
44 | }
45 | else
46 | {
47 | this.names.push(name);
48 | }
49 |
50 | /*Map the available values left to a range.
51 | Makes traversal slower when almost no values are taken, but greatly improves performance
52 | when all balls are almost taken (ex: 45 balls out of 50). Performance could be improved further
53 | by keeping track of the mapping and updating it as we insert values. */
54 | var range = this.balls - Object.keys(this.participants).length;
55 | var result = Math.floor((Math.random() * range) + 1);
56 |
57 | var index = 1;
58 | while(true)
59 | {
60 | if(this.participants[index] === undefined)
61 | {
62 | if(result == 1)
63 | {
64 | this.participants[index] = name;
65 | break;
66 | }
67 | else
68 | {
69 | result--;
70 | }
71 | }
72 | index++;
73 | }
74 |
75 | return index;
76 | }
77 |
78 | participants.prototype.getNames = function() {
79 | return this.names;
80 | }
81 |
82 | participants.prototype.getRanks = function(draws) {
83 | var result = [];
84 | draws.forEach((function(draw) {
85 | var participant = this.participants[draw];
86 | participant = participant === undefined ? null : participant;
87 | result.push(participant);
88 | }).bind(this));
89 | return result;
90 | }
91 |
92 | participants.prototype.getWinnings = function(ratios) {
93 | var result = {};
94 | for(key in ratios)
95 | {
96 | if(this.participants[key] !== undefined)
97 | {
98 | result[this.participants[key]] = ratios[key];
99 | }
100 | }
101 |
102 | return result;
103 | }
104 |
105 | module.exports = participants;
--------------------------------------------------------------------------------
/node-app/base-image/README.md:
--------------------------------------------------------------------------------
1 | ##Manual Dockerfile Creation From Base Image and Customization of 'dockerfile-template'
2 |
3 | Take the dockerfile-template file (or the dockerfile-template-slim file if your prefer more barebone small images) and customize it to your needs. Once that is done, use the modified dockerfile to build your production image.
4 |
5 | ###Customizations
6 |
7 | - UID Environment Variable: Determines the user and group ID that the node app will run under in the container
8 | - NPM_COMMAND Environment Variable: Determines the command that will be passed as to "npm run" when the container launches. Defaults to "start".
9 | - TOOL Environment Variable: Tool that you want to use to install your dependencies, link your shared modules and launch your program. Defaults to "npm". Can be set to "yarn" instead.
10 | - app content: This should contain your node application (location of package.json file and app-specific entrypoint and dependencies)
11 | - shared modules content:
12 |
13 | This should contain any recurring private modules that tend to be used accross apps (or accross containers in the same application if you split it into several containers which is admitedly my primary use-case).
14 |
15 | Those modules can be expressed as a dependency elsewhere by adding their name to the 'localDependencies' entry in the package.json file of the dependent (which is an array of shared module names, as named in their respectif package.json files, see the example).
16 |
17 | Afterwards, they can be required by the dependend by their module name (as defined in their package.json file).
18 |
19 | - npm modules:
20 |
21 | This should contain a semi-colon separated list of npm modules that you want installed and accessible everywhere in your app.
22 |
23 | Note that these "global" npm modules are fallbacks will only be used by your app and shared modules if they are absent from the dependencies in package.json files or if the greater version number matches that of the package.json dependency.
24 |
25 | In the context of application-specific containers with a lot of in-house modules, I think it's a decent compromise between global hell and DRY.
26 |
27 | This allows you to do something like this: say that your app and all shared modules but one use version 3 of bluebird and one shared module use version 2 of bluebird, you can put 'bluebird@3' in the NPM_MODULES environment variable and then put a version 2 dependency in the package.json file of the shared module that uses version 2.
28 |
29 | ###Tag Convention
30 |
31 | The first number appearing in tag names refers to the version of node the image uses.
32 |
33 | The second number appearing in tag names after the 'v' refers to the revision of the image (which increments as improvements are made).
34 |
35 | ###Examples
36 |
37 | The 'example' directory contain an example of a manually generated dockerfile for a project with shared dependencies.
38 |
39 | The 'example2' directory contain an example for a basic 'hello-world' hapi app.
40 |
41 | The 'example3' directory contains a modified version of the 'example' with shared dependencies layered more deedply into the directory structure and one shared dependency requiring another.
42 |
43 | The 'example4' directory contains an example that illustrates the use of the NPM_MODULE environment variable for a global npm module combined with a package.json version override for a shared module.
44 |
--------------------------------------------------------------------------------
/react-build/example/app/javascript/app.jsx:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 | var ReactDOM = require('react-dom');
3 |
4 | var pot = require('pot');
5 | var participants = require('participants');
6 | var draw = require('draw');
7 |
8 | var Header = require('header');
9 | var RegisterSection = require('register-section');
10 | var DrawSection = require('draw-section');
11 |
12 | module.exports = React.createClass({
13 | addRegistrant: function(name) {
14 | var hasName = this.participants.getNames().some(function(_name) {
15 | return _name == name;
16 | });
17 | var number = hasName ? -1 : this.participants.add(name);
18 | var lastRegistrant = {
19 | 'name': name,
20 | 'number': number,
21 | 'visible': true
22 | };
23 | if(!hasName)
24 | {
25 | this.pot.add(10);
26 | }
27 | this.setState({
28 | 'lastRegistrant': lastRegistrant,
29 | 'potAmount': this.pot.get()
30 | });
31 | },
32 | hideRegistrant: function() {
33 | var lastRegistrant = this.state.lastRegistrant;
34 | lastRegistrant.visible = false;
35 | this.setState({
36 | 'lastRegistrant': lastRegistrant
37 | });
38 | },
39 | initiateDraw: function() {
40 | var drawResult = this.draw();
41 | var ranks = this.participants.getRanks(drawResult);
42 | var winners = ranks.map((function(name, index) {
43 | if(name === null)
44 | {
45 | return null;
46 | }
47 | else
48 | {
49 | return {'name': name, 'ratio': this.props.winRatios[index]};
50 | }
51 | }).bind(this));
52 | winners = this.pot.award(winners);
53 | this.setState({
54 | 'winners': winners,
55 | 'potAmount': this.pot.get()
56 | });
57 | },
58 | clearParticipants: function() {
59 | this.participants = participants(this.props.balls);
60 | this.setState({
61 | 'lastRegistrant': null,
62 | 'potAmount': this.pot.get(),
63 | 'participants': [],
64 | 'winners': null
65 | });
66 | },
67 | getInitialState: function () {
68 | this.pot = pot(this.props.initPot);
69 | this.participants = participants(this.props.balls);
70 | this.draw = function() {
71 | return draw(this.props.balls, this.props.draws);
72 | }
73 | return {
74 | 'lastRegistrant': null,
75 | 'potAmount': this.pot.get(),
76 | 'participants': [],
77 | 'winners': null
78 | };
79 | },
80 | render: function () {
81 | return (
82 |
87 | );
88 | }
89 | });
90 |
--------------------------------------------------------------------------------
/react-build/example-onbuild/app/javascript/app.jsx:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 | var ReactDOM = require('react-dom');
3 |
4 | var pot = require('pot');
5 | var participants = require('participants');
6 | var draw = require('draw');
7 |
8 | var Header = require('header');
9 | var RegisterSection = require('register-section');
10 | var DrawSection = require('draw-section');
11 |
12 | module.exports = React.createClass({
13 | addRegistrant: function(name) {
14 | var hasName = this.participants.getNames().some(function(_name) {
15 | return _name == name;
16 | });
17 | var number = hasName ? -1 : this.participants.add(name);
18 | var lastRegistrant = {
19 | 'name': name,
20 | 'number': number,
21 | 'visible': true
22 | };
23 | if(!hasName)
24 | {
25 | this.pot.add(10);
26 | }
27 | this.setState({
28 | 'lastRegistrant': lastRegistrant,
29 | 'potAmount': this.pot.get()
30 | });
31 | },
32 | hideRegistrant: function() {
33 | var lastRegistrant = this.state.lastRegistrant;
34 | lastRegistrant.visible = false;
35 | this.setState({
36 | 'lastRegistrant': lastRegistrant
37 | });
38 | },
39 | initiateDraw: function() {
40 | var drawResult = this.draw();
41 | var ranks = this.participants.getRanks(drawResult);
42 | var winners = ranks.map((function(name, index) {
43 | if(name === null)
44 | {
45 | return null;
46 | }
47 | else
48 | {
49 | return {'name': name, 'ratio': this.props.winRatios[index]};
50 | }
51 | }).bind(this));
52 | winners = this.pot.award(winners);
53 | this.setState({
54 | 'winners': winners,
55 | 'potAmount': this.pot.get()
56 | });
57 | },
58 | clearParticipants: function() {
59 | this.participants = participants(this.props.balls);
60 | this.setState({
61 | 'lastRegistrant': null,
62 | 'potAmount': this.pot.get(),
63 | 'participants': [],
64 | 'winners': null
65 | });
66 | },
67 | getInitialState: function () {
68 | this.pot = pot(this.props.initPot);
69 | this.participants = participants(this.props.balls);
70 | this.draw = function() {
71 | return draw(this.props.balls, this.props.draws);
72 | }
73 | return {
74 | 'lastRegistrant': null,
75 | 'potAmount': this.pot.get(),
76 | 'participants': [],
77 | 'winners': null
78 | };
79 | },
80 | render: function () {
81 | return (
82 |
87 | );
88 | }
89 | });
90 |
--------------------------------------------------------------------------------
/node-app/README.md:
--------------------------------------------------------------------------------
1 | # node-app
2 |
3 | ## Disclaimer
4 |
5 | While nice, the in-project pathless "modules" feature of this image slowed to a crawl during the building phase for me when concurrently building 10+ service images with 20+ shared local dependencies (live and learn).
6 |
7 | It was a nice experiment and it could probably be perfected to actually work well, but I'll tell the interested reader a hard-learned lesson:
8 |
9 | In this day and age, if you need private modules, just pay ~10$/month to npm for a private registry or otherwise work on setting up your own on-prem registry if you have particular privacy/uptime requirements or a shoestring budget or just a cheap employer (seriously, the effort to setup your own on-prem npm registry if you need it is a better investment).
10 |
11 | ## Purpose
12 |
13 | Collection of images to build custom production node application images.
14 |
15 | ## Images
16 |
17 | The Project has 4 main images. Read the documentation provided in the directory of each image for more details about their usage.
18 |
19 | ### base-image
20 |
21 | Base image to build node applications. It can be used on its own by manually building a production dockerfile from the provided template.
22 |
23 | Tags: 4, latest, 4-slim, 6, 6-slim
24 |
25 | ### base-dev-image
26 |
27 | Development image, meant to be used for code that changes often in a mapped volume outside the image.
28 |
29 | Tags: 4-dev, 6-dev
30 |
31 | ### dockerfile-builder
32 |
33 | Image that automatically builds a production dockerfile of a custom node-app with all dependent files packaged with the dockerfile.
34 |
35 | Tag: dockerfile-builder
36 |
37 | ### image-builder
38 |
39 | Image that automatically builds a production image of a custom node-app.
40 |
41 | Tag: image-builder
42 |
43 | ## Assumptions on app structure
44 |
45 | The images provided here assume that your app is broken down in two components:
46 |
47 | - Main App (required): Main app that contains code specialized for the application.
48 | - Shared modules (optional): Re-usable modules that are not published in a registry (and thus cannot be resolved by npm install), but that may be shared by several apps (or perhaps various parts of your main app if it is split in sub-apps)
49 |
50 | ### package.json requirements
51 |
52 | The shared modules and your main app should all contain a package.json file (and in the case of the shared modules, they should have a valid unique name)
53 |
54 | Also, all parts that use shared modules (your main app or other shared modules) should list the shared modules that they use (by name) in the "localDependencies" entry (see the examples)
55 |
56 | ### Degree of support
57 |
58 | - Base Image: The base image, during image construction, will recursively traverse directories in the shared modules, find all modules (it will stop recursing in directories containing a package.json file and will skip over directories named "node_modules") and resolve depencencies (in the main app and other shared modules) via linking.
59 | - Dockerfile Builder: Currently, the dockerfile builder will create dockerfiles and selectively package all dependencies by looking at the top level directories of the shared modules directory only (it does not traverse sub-directories). I plan to make it recursive soon.
60 | - Image Builder: The image build will only copy shared dependencies used by the app in the image. It will recursively traverse the dependencies to make sure that dependencies of dependencies are properly copied.
61 |
--------------------------------------------------------------------------------
/react-build/README.md:
--------------------------------------------------------------------------------
1 | # react-build
2 |
3 | ## Notice
4 |
5 | While functional, the tooling for this image, with browserify, is dated by 2017 standards. Most frontend projects would now use es6 modules with webpack.
6 |
7 | As I'm now in a more backend phase of my workflow, I'll revisit this image when the need for it is felt.
8 |
9 | ## Purpose
10 |
11 | Images to build single-file react bundles with commonjs modules as well as (optional) es-2015, jsx, minification and file watch support.
12 |
13 | Makes use of browserify and babel.
14 |
15 | ## Images
16 |
17 | The are two main images:
18 |
19 | - the onbuild image (onbuild tag) that needs to be the parent of a child image, but that has the final image execute with reduced privilege
20 | - the regular image (latest tag) that can be used directly, but has to run as root
21 | - Additionally, both images have a slim variant that is based on the slim node image
22 |
23 | ## Usage
24 |
25 | ### Environment Variables
26 |
27 | Both the onbuild and regular image need to be executed with the BUILD_FILE environment variable set to the path in the container's file system where the build file can be found.
28 |
29 | Additionally, because the regular image executes as root, it needs an OUTPUT_UID environment variable that sets which user will be the owner of the final bundled file.
30 |
31 | ### Mapped Volumes
32 |
33 | Both images should be executed in a container where all the source code files (js and jsx) to compile, the build file (json) and the distribution directory are mapped between the host filesystem and the container filesystem (see exemples).
34 |
35 | Alternatively, if you have a more strict containers-only build flow, shared docker-managed volumes might also do the work, though such considerations are beyond the scope of this documentation.
36 |
37 | ### dockerfile
38 |
39 | If you use the onbuild image, you need to finalize the image you'll use in a dockerfile.
40 |
41 | You need to perform the following tasks in the dockerfile:
42 |
43 | - Set the UID environment variable to the user ID who should own the files you'll operate on on your host
44 | - Run the finalize.sh script
45 | - Set the container user to UID
46 |
47 | See the onbuild exemple for an implementation of this.
48 |
49 | ### build file
50 |
51 | The build file is a json file that directs how your source files are processed and bundled into the final file.
52 |
53 | Here are the entries:
54 |
55 | - destination: Path of the final bundled file in the container
56 | - dependencies: Array of external dependencies you'll use. Possible values are: react, react-dom, redux. Those external dependencies can be required under those names in your code
57 | - watch: Boolean that sets whether the container should compile your code once or whether it should compile it and re-compile it each time any of the source files are changed
58 | - minify: Boolean that specifies if the result code should be minifed. If set to true, the code will be minified with uglify.
59 | - modules: Object having your module names as keys and the path of their corresponding source file as values. The '*' entry is a special entry. It's an array of folders containing files which should also be bundled and whose module name is their file name, without the extension.
60 | - entrypoints: List of files (or folders containing the files) that should be executed directly when the bundled file is loaded (module code only executes when first required)
61 | - extensions: Array of file extensions that should be included during folder traversals. If this property is not defined, all files will be processed in entries specifying folders, no matter the extension.
62 |
--------------------------------------------------------------------------------
/headless-factorio-server/templates/server-settings.json.j2:
--------------------------------------------------------------------------------
1 | {
2 | "name": "{{ game_name }}",
3 | "description": "{{ game_description }}",
4 | "tags": ["game", "tags"],
5 |
6 | "_comment_max_players": "Maximum number of players allowed, admins can join even a full server. 0 means unlimited.",
7 | "max_players": {{ max_players }},
8 |
9 | "_comment_visibility": ["public: Game will be published on the official Factorio matching server",
10 | "lan: Game will be broadcast on LAN"],
11 | "visibility":
12 | {
13 | "public": false,
14 | "lan": false
15 | },
16 |
17 | "_comment_credentials": "Your factorio.com login credentials. Required for games with visibility public",
18 | "username": "",
19 | "password": "",
20 |
21 | "_comment_token": "Authentication token. May be used instead of 'password' above.",
22 | "token": "",
23 |
24 | "game_password": "{{ game_password }}",
25 |
26 | "_comment_require_user_verification": "When set to true, the server will only allow clients that have a valid Factorio.com account",
27 | "require_user_verification": false,
28 |
29 | "_comment_max_upload_in_kilobytes_per_second" : "optional, default value is 0. 0 means unlimited.",
30 | "max_upload_in_kilobytes_per_second": 0,
31 |
32 | "_comment_max_upload_slots" : "optional, default value is 5. 0 means unlimited.",
33 | "max_upload_slots": 5,
34 |
35 | "_comment_minimum_latency_in_ticks": "optional one tick is 16ms in default speed, default value is 0. 0 means no minimum.",
36 | "minimum_latency_in_ticks": 0,
37 |
38 | "_comment_ignore_player_limit_for_returning_players": "Players that played on this map already can join even when the max player limit was reached.",
39 | "ignore_player_limit_for_returning_players": false,
40 |
41 | "_comment_allow_commands": "possible values are, true, false and admins-only",
42 | "allow_commands": "admins-only",
43 |
44 | "_comment_autosave_interval": "Autosave interval in minutes",
45 | "autosave_interval": {{ auto_save_interval }},
46 |
47 | "_comment_autosave_slots": "server autosave slots, it is cycled through when the server autosaves.",
48 | "autosave_slots": {{ auto_save_slots }},
49 |
50 | "_comment_afk_autokick_interval": "How many minutes until someone is kicked when doing nothing, 0 for never.",
51 | "afk_autokick_interval": 0,
52 |
53 | "_comment_auto_pause": "Whether should the server be paused when no players are present.",
54 | "auto_pause": true,
55 |
56 | "only_admins_can_pause_the_game": true,
57 |
58 | "_comment_autosave_only_on_server": "Whether autosaves should be saved only on server or also on all connected clients. Default is true.",
59 | "autosave_only_on_server": true,
60 |
61 | "_comment_non_blocking_saving": "Highly experimental feature, enable only at your own risk of losing your saves. On UNIX systems, server will fork itself to create an autosave. Autosaving on connected Windows clients will be disabled regardless of autosave_only_on_server option.",
62 | "non_blocking_saving": false,
63 |
64 | "_comment_segment_sizes": "Long network messages are split into segments that are sent over multiple ticks. Their size depends on the number of peers currently connected. Increasing the segment size will increase upload bandwidth requirement for the server and download bandwidth requirement for clients. This setting only affects server outbound messages. Changing these settings can have a negative impact on connection stability for some clients.",
65 | "minimum_segment_size": 25,
66 | "minimum_segment_size_peer_count": 20,
67 | "maximum_segment_size": 100,
68 | "maximum_segment_size_peer_count": 10
69 | }
70 |
--------------------------------------------------------------------------------
/react-build/code/app/index.js:
--------------------------------------------------------------------------------
1 | const browserify = require('browserify');
2 | const babelify = require('babelify');
3 | const watchify = require('watchify');
4 | const uglifyify = require('uglifyify');
5 | const fs = require('fs');
6 | const path = require('path');
7 |
8 | var es2015 = require('babel-preset-es2015');
9 | var jsx = require('babel-preset-react');
10 |
11 | const settings = JSON.parse(fs.readFileSync(process.env.BUILD_FILE, 'utf8'));
12 |
13 | var b = browserify().transform(babelify, {presets: [es2015, jsx]});
14 |
15 | if(settings.watch)
16 | {
17 | b.plugin(watchify);
18 | }
19 |
20 | if(settings.minify)
21 | {
22 | b.transform(uglifyify);
23 | }
24 |
25 | function recursivelyAddModules(_path)
26 | {
27 | if(fs.lstatSync(_path).isDirectory())
28 | {
29 | var files = fs.readdirSync(_path);
30 | files.forEach((file) => {
31 | recursivelyAddModules(path.join(_path, file));
32 | });
33 | }
34 | else
35 | {
36 | if((!settings.extensions) || settings.extensions.some((extention) => {return ('.'+extention) == path.extname(_path);}))
37 | {
38 | b.require(_path, {'expose': path.basename(_path, path.extname(_path))});
39 | }
40 | }
41 | }
42 |
43 | function recursivelyAddEntrypoints(_path)
44 | {
45 | if(fs.lstatSync(_path).isDirectory())
46 | {
47 | var files = fs.readdirSync(_path);
48 | files.forEach((file) => {
49 | recursivelyAddEntrypoints(path.join(_path, file));
50 | });
51 | }
52 | else
53 | {
54 | if((!settings.extensions) || settings.extensions.some((extention) => {return ('.'+extention) == path.extname(_path);}))
55 | {
56 | b.add(_path);
57 | }
58 | }
59 | }
60 |
61 | if(settings.modules)
62 | {
63 | Object.keys(settings['modules']).forEach((key) => {
64 | if(key != '*')
65 | {
66 | b.require(settings['modules'][key], {'expose': key});
67 | }
68 | else
69 | {
70 | settings['modules'][key].forEach((path) => {
71 | recursivelyAddModules(path);
72 | });
73 | }
74 | });
75 | }
76 |
77 | if(settings.entrypoints && settings.entrypoints.length)
78 | {
79 | settings.entrypoints.forEach((entrypoint) => {
80 | recursivelyAddEntrypoints(entrypoint);
81 | });
82 | }
83 |
84 | if(settings.dependencies && settings.dependencies.length)
85 | {
86 | settings.dependencies.forEach((dependency) => {
87 | switch(dependency)
88 | {
89 | case 'react':
90 | b.require(path.join(process.env.APP_DIR, 'node_modules', 'react', 'dist', 'react.min.js'), {'expose': 'react'});
91 | break;
92 | case 'react-dom':
93 | b.require(path.join(process.env.APP_DIR, 'node_modules', 'react-dom', 'dist', 'react-dom.min.js'), {'expose': 'react-dom'});
94 | break;
95 | case 'redux':
96 | b.require(path.join(process.env.APP_DIR, 'node_modules', 'redux', 'dist', 'redux.min.js'), {'expose': 'redux'});
97 | break;
98 | }
99 | });
100 | }
101 |
102 | function bundle()
103 | {
104 | b.bundle().pipe(fs.createWriteStream(settings.destination));
105 | if(process.env.OUTPUT_UID)
106 | {
107 | fs.chownSync(settings.destination, Number(process.env.OUTPUT_UID), Number(process.env.OUTPUT_UID));
108 | }
109 | }
110 |
111 | if(settings.watch)
112 | {
113 | b.on('update', bundle);
114 | }
115 |
116 | bundle();
117 |
118 |
119 |
120 |
--------------------------------------------------------------------------------
/react-build/example/lib/pot.js:
--------------------------------------------------------------------------------
1 | /*
2 | Design note 1:
3 | I first thought about implementing the whole pot state directly inside the module...
4 | ie: var pot = 0; ; module.exports = {'add': add, 'award': award};
5 | But then, it occured to me that the module would be more extensible if the pot was not a singleton.,
6 |
7 | Design note 2:
8 | At first, I though about returning all the methods in the constructor with the pot amount as a shared closure.
9 | In the interest of a slight increase in memory efficiency, I opted for making them prototype properties instead and manipulate the object state.
10 | */
11 |
12 | function properRatio(ratio)
13 | {
14 | return ratio >= 0 && ratio <= 1.0;
15 | }
16 |
17 | function pot(startingAmount)
18 | {
19 | if(startingAmount < 0)
20 | {
21 | throw new Error("pot.constructor:startingAmountNegative");
22 | }
23 |
24 | //Classical pattern to save end-user of the api from having to use the new operator
25 | if(this instanceof pot)
26 | {
27 | this.amount = startingAmount;
28 | }
29 | else
30 | {
31 | return new pot(startingAmount);
32 | }
33 | }
34 |
35 | pot.prototype.add = function(amount) {
36 | if(amount < 0)
37 | {
38 | throw new Error("pot.add:amountNegative");
39 | }
40 |
41 | this.amount += amount;
42 | };
43 |
44 | pot.prototype.award = function(ratios) {
45 | //temporarily copy amount locality to easily void the entire operation if argument is bad and exception is thrown
46 | var amount = this.amount;
47 |
48 | if(typeof(ratios) == typeof({}) && ratios !== null) //mapping of users with ratios
49 | {
50 | //Variable to verify that the sum of passed ratios is <= 1.0
51 | var ratioSum = 0;
52 |
53 | if(Array.isArray(ratios))
54 | { //Array of ordered {'name: .., 'ratio': ..} objects
55 | var result = ratios.map((function(user, index) {
56 | if(user !== null)
57 | {
58 | ratioSum += user['ratio'];
59 | var userAward = Math.floor(user['ratio'] * this.amount); //I use this.amount because each ratio is against the full amount, not the remainders :P
60 | amount -= userAward;
61 | return {'name': user['name'], 'award': userAward};
62 | }
63 | else
64 | {
65 | return null;
66 | }
67 | }).bind(this));
68 | }
69 | else
70 | { //object of unordered user:ratio mappings
71 | var result = {};
72 |
73 | for(user in ratios)
74 | {
75 | if(!properRatio(ratios[user]))
76 | {
77 | throw new Error("pot.award:ratioOutOfBound");
78 | }
79 |
80 | ratioSum += ratios[user];
81 | result[user] = Math.floor(ratios[user] * this.amount); //I use this.amount because each ratio is against the full amount, not the remainders :P
82 | amount -= result[user];
83 | }
84 | }
85 |
86 | if(ratioSum > 1.0)
87 | {
88 | throw new Error("pot.award:ratiosSumGreaterThan1");
89 | }
90 |
91 | this.amount = amount; //Everything is ok, now we can permanently finalize the operation
92 |
93 | return result;
94 | }
95 |
96 | throw new Error("pot.award:ratiosNotObjectOrNull");
97 | };
98 |
99 | pot.prototype.get = function() {
100 | return this.amount;
101 | };
102 |
103 | module.exports = pot;
--------------------------------------------------------------------------------
/react-build/example-onbuild/lib/pot.js:
--------------------------------------------------------------------------------
1 | /*
2 | Design note 1:
3 | I first thought about implementing the whole pot state directly inside the module...
4 | ie: var pot = 0; ; module.exports = {'add': add, 'award': award};
5 | But then, it occured to me that the module would be more extensible if the pot was not a singleton.,
6 |
7 | Design note 2:
8 | At first, I though about returning all the methods in the constructor with the pot amount as a shared closure.
9 | In the interest of a slight increase in memory efficiency, I opted for making them prototype properties instead and manipulate the object state.
10 | */
11 |
12 | function properRatio(ratio)
13 | {
14 | return ratio >= 0 && ratio <= 1.0;
15 | }
16 |
17 | function pot(startingAmount)
18 | {
19 | if(startingAmount < 0)
20 | {
21 | throw new Error("pot.constructor:startingAmountNegative");
22 | }
23 |
24 | //Classical pattern to save end-user of the api from having to use the new operator
25 | if(this instanceof pot)
26 | {
27 | this.amount = startingAmount;
28 | }
29 | else
30 | {
31 | return new pot(startingAmount);
32 | }
33 | }
34 |
35 | pot.prototype.add = function(amount) {
36 | if(amount < 0)
37 | {
38 | throw new Error("pot.add:amountNegative");
39 | }
40 |
41 | this.amount += amount;
42 | };
43 |
44 | pot.prototype.award = function(ratios) {
45 | //temporarily copy amount locality to easily void the entire operation if argument is bad and exception is thrown
46 | var amount = this.amount;
47 |
48 | if(typeof(ratios) == typeof({}) && ratios !== null) //mapping of users with ratios
49 | {
50 | //Variable to verify that the sum of passed ratios is <= 1.0
51 | var ratioSum = 0;
52 |
53 | if(Array.isArray(ratios))
54 | { //Array of ordered {'name: .., 'ratio': ..} objects
55 | var result = ratios.map((function(user, index) {
56 | if(user !== null)
57 | {
58 | ratioSum += user['ratio'];
59 | var userAward = Math.floor(user['ratio'] * this.amount); //I use this.amount because each ratio is against the full amount, not the remainders :P
60 | amount -= userAward;
61 | return {'name': user['name'], 'award': userAward};
62 | }
63 | else
64 | {
65 | return null;
66 | }
67 | }).bind(this));
68 | }
69 | else
70 | { //object of unordered user:ratio mappings
71 | var result = {};
72 |
73 | for(user in ratios)
74 | {
75 | if(!properRatio(ratios[user]))
76 | {
77 | throw new Error("pot.award:ratioOutOfBound");
78 | }
79 |
80 | ratioSum += ratios[user];
81 | result[user] = Math.floor(ratios[user] * this.amount); //I use this.amount because each ratio is against the full amount, not the remainders :P
82 | amount -= result[user];
83 | }
84 | }
85 |
86 | if(ratioSum > 1.0)
87 | {
88 | throw new Error("pot.award:ratiosSumGreaterThan1");
89 | }
90 |
91 | this.amount = amount; //Everything is ok, now we can permanently finalize the operation
92 |
93 | return result;
94 | }
95 |
96 | throw new Error("pot.award:ratiosNotObjectOrNull");
97 | };
98 |
99 | pot.prototype.get = function() {
100 | return this.amount;
101 | };
102 |
103 | module.exports = pot;
--------------------------------------------------------------------------------
/headless-factorio-server/README.md:
--------------------------------------------------------------------------------
1 | # Overview
2 |
3 | This image facilitates the operation of a headless Factorio server by wrapping the headless server factorio binary with some python scripts.
4 |
5 | Given that the binary is not MIT, I won't publish the image on Docker Hub, but you can build it yourself from the Dockerfile here.
6 |
7 | # Running Demo Environment
8 |
9 | To run the server on your local machine, follow the steps below.
10 |
11 | 1. Edit the docker-compose file to change the whitelist adminlist and any other settings you want to change (see environment variables below)
12 | 2. Make sure you have docker and docker-compose installed
13 | 3. Run: **docker-compose up -d**
14 | 4. Open Factorio, click on: Play > Multiplayer > Connect to a Server (enter 127.0.0.1:8080 in the box)
15 |
16 | # Environment Variables
17 |
18 | The behavior of the server is customizable with the following environment variables:
19 |
20 | - GAME_NAME: Name to give your game
21 | - GAME_DESCRIPTION: Description to give your game
22 | - GAME_PASSWORD: Password users will need to supply to join your game
23 | - MAX_PLAYERS: Integer specifying the max number of players who can join. Defaults to unlimited
24 | - AUTO_SAVE_INTERVAL: Interval of time in minutes between automated saves (defaults to 10)
25 | - AUTO_SAVE_SLOTS: Number of save slots that are kept (defaults to 5)
26 | - POLLUTION_ENABLED: Whether pollution exists in the game. Game be 'true' or 'false'. Defaults to 'true'.
27 | - EVOLUTION_ENABLED: Whether enemies evolve. Game be 'true' or 'false'. Defaults to 'true'.
28 | - EXPANSION_ENABLED: Whether enemies build new bases. Game be 'true' or 'false'. Defaults to 'true'.
29 | - MIN_EXPANSION_COOLDOWN: Minimum period of time in minutes before enemies try to build a new base. Defaults to 4.
30 | - MAX_EXPANSION_COOLDOWN: Maximum period of time in minutes before enemies try to build a new base. Defaults to 60.
31 | - MIN_SETTLER_GROUP_SIZE: Minimum size of the group enemies send to build a new base. Defaults to 5.
32 | - MAX_SETTLER_GROUP_SIZE: Maximum size of the group enemies send to build a new base. Defaults to 20.
33 | - TECHNOLOGY_PRICE_MULTIPLIER: Cost multiplier on normal costs to research technologies as an integer. Defaults to 1.
34 | - EVOLUTION_TIME_FACTOR: How much enemies evolve over time as a real number. Defaults to 0.000004.
35 | - EVOLUTION_DESTROY_FACTOR: How much enemies evolve when you destroy their buildings as a real number. Defaults to 0.002.
36 | - EVOLUTION_POLLUTION_FACTOR: How enemies evolve given the amount of pollution you generate as a real number. Defaults to 0.0000009.
37 | - SEED: Provide a seed to generate a game identical to a past game you generated. Defaults to null for a random game.
38 | - MAP_WIDTH: Width of the map in tiles. Defaults to 0 for maximum (a very large map)
39 | - MAP_HEIGHT: Height of the map in tiles. Defaults to 0 for maximum (a very large map)
40 | - BITER_FREE_STARTING_AREA: Multiplier of the normal enemy free radius in the early game as an integer. Defaults to 1.
41 | - WATER_ELEVATION: Multiplier on the normal water levels (to have more water, less land), with a log applied to it before multiplying. Defaults to 1.
42 | - PEACEFUL_MODE: Whether you have enemies or not as 'true' or 'false'. Defaults to 'false' (ie, you have enemies)
43 | - ADMIN_PLAYERS: Comma separated list of players that you want to be admin. If missing, the will be no admin.
44 | - WHITELISTED_PLAYERS: Comma separated list of players to allow. If missing, anyone who can supply the game's password is allowed.
45 |
46 | There are also various environment variables to set the amount (frequency, size, richness) of various starting resources, but I'm getting lazy. Please, look at the configs.py code file for their names.
47 |
48 | Note that the headless server binary supplied by the makers of Factorio is highly configurable. This is just a subset of possible configurations that I found interesting to play with.
49 |
50 | # Requisite volumes
51 |
52 | You should mount a bind a volume on your machine to the following path in the container to persist data: /opt/data
53 |
54 | # Caveats
55 |
56 | Currently, only non-public mode with no centralized account and no LAN broadcast is supported because that was my use-case which I could troubleshoot.
57 |
58 | Also, I could not make it work inside a docker network with port fowarding so right now, it only works if you run the container on the host network.
--------------------------------------------------------------------------------