-
Notifications
You must be signed in to change notification settings - Fork 35
feat: add Devcontainers #2096
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
feat: add Devcontainers #2096
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| # Devcontainers | ||
|
|
||
| Use [Devcontainers](https://code.visualstudio.com/docs/devcontainers/containers) to prepare a fully automated working environment. | ||
|
|
||
| ### Docker | ||
|
|
||
| Docker defaults should work fine therefore there is nothing to do. | ||
|
|
||
| ### Podman | ||
|
|
||
| Start Podman service for a regular user (rootless) and make it listen to a socket: | ||
|
|
||
| ```shell | ||
| systemctl --user enable --now podman.socket | ||
| ``` | ||
|
|
||
| Restart your OS if necessary and verify that podman listens: | ||
|
|
||
| ```shell | ||
| systemctl --user status podman.socket | ||
| ``` | ||
|
|
||
| ## VSCode | ||
|
|
||
| Install the extension https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers | ||
|
|
||
| Only if you use podman, therefore Optional: | ||
|
|
||
| Go to the Extension Settings: | ||
|
|
||
| - `Dev › Containers: Docker Compose Path` set `podman-compose` | ||
| - `Dev › Containers: Docker Path` set `podman` | ||
| - `Dev › Containers: Docker Socket Path` set `/run/podman/podman.sock` | ||
|
|
||
| To open the repository with DevContainers do `Ctrl + Shift + P` and enter `Dev Containers: Rebuild and Reopen in Container` or `Dev Containers: Reopen in Container`. For more options see the Extension documentation. | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| FROM mcr.microsoft.com/devcontainers/base:ubuntu | ||
|
|
||
| RUN sudo apt update && \ | ||
| sudo apt install -y build-essential pkg-config libssl-dev postgresql-client | ||
|
Comment on lines
+3
to
+4
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. suggestion: Using 'sudo' in Dockerfile may be unnecessary. Since Dockerfile commands are executed as root by default, 'sudo' can be removed to streamline the build and prevent complications if the user context changes in the base image. |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| { | ||
| "name": "trustify-full", | ||
| "dockerComposeFile": "./docker-compose.yml", | ||
| "service": "trustify", | ||
| "workspaceFolder": "/workspace", | ||
| "initializeCommand": "bash .devcontainer/full/initializeCommand.sh ${devcontainerId}", | ||
| "postCreateCommand": "bash .devcontainer/full/postCreateCommand.sh ${devcontainerId}", | ||
| "forwardPorts": [ | ||
| 8080, | ||
| 9010 | ||
| ], | ||
| "features": { | ||
| "ghcr.io/devcontainers/features/common-utils:2": {}, | ||
| "ghcr.io/devcontainers/features/rust:1": {} | ||
| }, | ||
| "customizations": { | ||
| "vscode": { | ||
| "extensions": [ | ||
| "vadimcn.vscode-lldb", | ||
| "rust-lang.rust-analyzer", | ||
| "tamasfe.even-better-toml", | ||
| "mtxr.sqltools", | ||
| "mtxr.sqltools-driver-pg" | ||
| ], | ||
| "settings": { | ||
| "git.alwaysSignOff": true, | ||
| "sqltools.connections": [ | ||
| { | ||
| "server": "trustify-db", | ||
| "database": "trustify", | ||
| "username": "postgres", | ||
| "password": "trustify", | ||
| "port": 5432, | ||
| "name": "db", | ||
| "driver": "PostgreSQL" | ||
| } | ||
| ] | ||
| } | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,81 @@ | ||
| networks: | ||
| trustify: | ||
| name: "trustify" | ||
|
|
||
| volumes: | ||
| trustify-postgres-data: | ||
|
|
||
| services: | ||
| trustify: | ||
| image: localhost/devcontainer-trustify:latest | ||
| build: | ||
| dockerfile: ./Dockerfile | ||
| security_opt: | ||
| - "label=disable" | ||
| userns_mode: "keep-id" | ||
| environment: | ||
| TRUSTD_DB_HOST: trustify-db | ||
| HTTP_SERVER_BIND_ADDR: "::" | ||
| UI_ISSUER_URL: http://localhost:9090/realms/trustify | ||
| UI_CLIENT_ID: frontend | ||
| AUTHENTICATOR_OIDC_ISSUER_URL: http://trustify-keycloak:8080/realms/trustify | ||
| AUTHENTICATOR_OIDC_CLIENT_IDS: frontend,cli | ||
| command: /bin/sh -c "while sleep 1000; do :; done" | ||
| volumes: | ||
| - ../..:/workspace:cached | ||
| networks: | ||
| - trustify | ||
| depends_on: | ||
| trustify-db: | ||
| condition: service_started | ||
|
|
||
| trustify-db: | ||
| image: postgres:17 | ||
| restart: unless-stopped | ||
| volumes: | ||
| - trustify-postgres-data:/var/lib/postgresql/data | ||
| environment: | ||
| POSTGRES_USER: postgres | ||
| POSTGRES_PASSWORD: trustify | ||
| POSTGRES_DB: trustify | ||
| POSTGRES_HOSTNAME: localhost | ||
| POSTGRES_PORT: 5432 | ||
| networks: | ||
| - trustify | ||
|
|
||
| trustify-keycloak: | ||
| image: quay.io/keycloak/keycloak:latest | ||
| environment: | ||
| KEYCLOAK_ADMIN: admin | ||
| KEYCLOAK_ADMIN_PASSWORD: admin | ||
| KC_HOSTNAME_BACKCHANNEL_DYNAMIC: true | ||
| KC_HOSTNAME: http://localhost:9090 | ||
| ports: | ||
| - "9090:8080" | ||
| command: [ "start-dev" ] | ||
| networks: | ||
| - trustify | ||
|
|
||
| trustify-keycloak-wait: | ||
| image: docker.io/alpine/curl:latest | ||
| volumes: | ||
| - ./keycloak/kc-wait.sh:/tmp/kc-wait.sh:Z | ||
| entrypoint: [ "/bin/sh" ] | ||
| command: /tmp/kc-wait.sh | ||
| depends_on: | ||
| trustify-keycloak: | ||
| condition: service_started | ||
| networks: | ||
| - trustify | ||
|
|
||
| trustify-keycloak-init: | ||
| image: quay.io/keycloak/keycloak:latest | ||
| volumes: | ||
| - ./keycloak/kc-init.sh:/tmp/kc-init.sh:Z | ||
| entrypoint: [ "/bin/sh" ] | ||
| command: /tmp/kc-init.sh | ||
| depends_on: | ||
| trustify-keycloak-wait: | ||
| condition: service_completed_successfully | ||
| networks: | ||
| - trustify |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| #!/bin/bash | ||
|
|
||
| # custom initialization goes here - runs outside of the dev container | ||
| # just before the container is launched but after the container is created | ||
|
|
||
| echo "devcontainerID ${1}" |
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,117 @@ | ||||||
| SERVER_URL="http://trustify-keycloak:8080" | ||||||
| USERNAME="admin" | ||||||
| PASSWORD="admin" | ||||||
| REALM="master" | ||||||
|
|
||||||
| # Login | ||||||
| /opt/keycloak/bin/kcadm.sh config credentials \ | ||||||
| --server ${SERVER_URL} \ | ||||||
| --user ${USERNAME} \ | ||||||
| --password ${PASSWORD} \ | ||||||
| --realm ${REALM} | ||||||
|
|
||||||
| # Start working on Trustify Realm | ||||||
| TRUSTIFY_REALM="trustify" | ||||||
| TRUSTIFY_ROLE="admin" | ||||||
| TRUSTIFY_USERNAME="admin" | ||||||
|
|
||||||
| # Realm | ||||||
| /opt/keycloak/bin/kcadm.sh create realms -s realm=${TRUSTIFY_REALM} -s enabled=true | ||||||
|
|
||||||
| # Realm roles | ||||||
| /opt/keycloak/bin/kcadm.sh create roles -r ${TRUSTIFY_REALM} -s name=${TRUSTIFY_ROLE} -o | ||||||
| admin_role_id=$(/opt/keycloak/bin/kcadm.sh get roles -r "${TRUSTIFY_REALM}" --fields id,name --format csv --noquotes | grep ",${TRUSTIFY_ROLE}" | sed 's/,.*//') | ||||||
|
|
||||||
| # Scopes | ||||||
| for scope in read:document create:document update:document delete:document; do | ||||||
| /opt/keycloak/bin/kcadm.sh create client-scopes -r "${TRUSTIFY_REALM}" -s "name=$scope" -s protocol=openid-connect | ||||||
| done | ||||||
|
|
||||||
| # Roles scope mappings | ||||||
| for scope in read:document create:document update:document delete:document; do | ||||||
| scope_id=$(/opt/keycloak/bin/kcadm.sh get client-scopes -r "${TRUSTIFY_REALM}" --fields id,name --format csv --noquotes | grep ",${scope}" | sed 's/,.*//') | ||||||
| /opt/keycloak/bin/kcadm.sh create "client-scopes/${scope_id}/scope-mappings/realm" -r "${TRUSTIFY_REALM}" -b '[{"name":"'"${TRUSTIFY_ROLE}"'", "id":"'"${admin_role_id}"'"}]' | ||||||
| done | ||||||
|
|
||||||
| # Users | ||||||
| /opt/keycloak/bin/kcadm.sh create users -r ${TRUSTIFY_REALM} -s username=${TRUSTIFY_USERNAME} -s enabled=true -s firstName="admin" -s lastName="admin" -s email="admin@trustify.org" -o | ||||||
| /opt/keycloak/bin/kcadm.sh set-password -r ${TRUSTIFY_REALM} --username admin --new-password admin | ||||||
|
|
||||||
| /opt/keycloak/bin/kcadm.sh add-roles -r ${TRUSTIFY_REALM} --uusername ${TRUSTIFY_USERNAME} --rolename ${TRUSTIFY_ROLE} | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. issue (typo): Possible typo in kcadm.sh argument '--uusername'. Please update '--uusername' to '--username' to ensure correct role assignment.
Suggested change
|
||||||
|
|
||||||
| # Clients | ||||||
| /opt/keycloak/bin/kcadm.sh create clients -r ${TRUSTIFY_REALM} -f - << EOF | ||||||
| { | ||||||
| "clientId": "frontend", | ||||||
| "publicClient": true, | ||||||
| "webOrigins": [ | ||||||
| "*" | ||||||
| ], | ||||||
| "redirectUris": [ | ||||||
| "*" | ||||||
| ], | ||||||
| "defaultClientScopes": [ | ||||||
| "acr", | ||||||
| "basic", | ||||||
| "email", | ||||||
| "profile", | ||||||
| "roles", | ||||||
| "create:document", | ||||||
| "read:document", | ||||||
| "update:document", | ||||||
| "delete:document" | ||||||
| ], | ||||||
| "optionalClientScopes": [ | ||||||
| "address", | ||||||
| "microprofile-jwt", | ||||||
| "offline_access", | ||||||
| "phone" | ||||||
| ] | ||||||
| } | ||||||
| EOF | ||||||
|
|
||||||
| /opt/keycloak/bin/kcadm.sh create clients -r ${TRUSTIFY_REALM} -f - << EOF | ||||||
| { | ||||||
| "clientId": "cli", | ||||||
| "publicClient": false, | ||||||
| "standardFlowEnabled": false, | ||||||
| "serviceAccountsEnabled": true, | ||||||
| "secret": "secret", | ||||||
| "defaultClientScopes": [ | ||||||
| "acr", | ||||||
| "basic", | ||||||
| "email", | ||||||
| "profile", | ||||||
| "roles", | ||||||
| "create:document", | ||||||
| "read:document", | ||||||
| "update:document", | ||||||
| "delete:document" | ||||||
| ], | ||||||
| "optionalClientScopes": [ | ||||||
| "address", | ||||||
| "microprofile-jwt", | ||||||
| "offline_access", | ||||||
| "phone" | ||||||
| ] | ||||||
| } | ||||||
| EOF | ||||||
|
|
||||||
| # Assign roles to service-account | ||||||
| cli_client="cli" | ||||||
|
|
||||||
| adminRoleId=$(/opt/keycloak/bin/kcadm.sh get roles -r ${TRUSTIFY_REALM} --fields id,name --format csv --noquotes | grep ",${TRUSTIFY_ROLE}" | sed 's/,.*//') | ||||||
|
|
||||||
| cliClientId=$(/opt/keycloak/bin/kcadm.sh get clients -r ${TRUSTIFY_REALM} --fields id,clientId --format csv --noquotes | grep ",${cli_client}" | sed 's/,.*//') | ||||||
| serviceAccountId=$(/opt/keycloak/bin/kcadm.sh get clients/${cliClientId}/service-account-user -r ${TRUSTIFY_REALM} --fields id,username --format csv --noquotes | grep ",service-account-${cli_client}" | sed 's/,.*//') | ||||||
|
|
||||||
| /opt/keycloak/bin/kcadm.sh create users/${serviceAccountId}/role-mappings/realm -r ${TRUSTIFY_REALM} -f - << EOF | ||||||
| [ | ||||||
| { | ||||||
| "id": "${adminRoleId}", | ||||||
| "name": "${TRUSTIFY_ROLE}", | ||||||
| "clientRole": false, | ||||||
| "composite": false | ||||||
| } | ||||||
| ] | ||||||
| EOF | ||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| SERVER_URL="http://trustify-keycloak:8080" | ||
| TIMEOUT=120 | ||
|
|
||
| attempt_counter=0 | ||
| interval=3 | ||
| max_attempts=$(($TIMEOUT/interval)); | ||
|
|
||
| ## Wait until server is ready to continue | ||
| echo "Waiting for $SERVER_URL" | ||
| until (curl --output /dev/null --silent --head --fail $SERVER_URL); do | ||
| if [ ${attempt_counter} -eq ${max_attempts} ];then | ||
| echo "Max attempts reached" | ||
| exit 1 | ||
| fi | ||
|
|
||
| printf '.' | ||
| attempt_counter=$(($attempt_counter+1)) | ||
| sleep $interval | ||
| done | ||
|
|
||
| echo "Server ready to listen" |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| #!/bin/bash | ||
|
|
||
| # Custom initialization goes here if needed. | ||
| # Runs inside the dev container after the container is created | ||
|
|
||
| ################################################################################ | ||
| # When using docker we will not be root inside the container | ||
| # the following steps are then required | ||
| ################################################################################ | ||
|
|
||
| echo "alias start:dev='cargo run --bin trustd db migrate && cargo run --bin trustd api'" >> ~/.bashrc | ||
| echo "alias psql:postgres='env PGPASSWORD=trustify psql -U postgres -d postgres -h trustify-db -p 5432'" >> ~/.bashrc |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| FROM mcr.microsoft.com/devcontainers/base:ubuntu | ||
|
|
||
| RUN sudo apt update && \ | ||
| sudo apt install -y build-essential pkg-config libssl-dev postgresql-client |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| { | ||
| "name": "trustify-minimal", | ||
| "dockerComposeFile": "./docker-compose.yml", | ||
| "service": "trustify-minimal", | ||
| "workspaceFolder": "/workspace", | ||
| "forwardPorts": [ | ||
| 8080, | ||
| 8090, | ||
| 9010 | ||
| ], | ||
| "portsAttributes": { | ||
| "8090": { | ||
| "label": "Embedded OIDC", | ||
| "requireLocalPort": true, | ||
| "onAutoForward": "silent" | ||
| } | ||
| }, | ||
| "features": { | ||
| "ghcr.io/devcontainers/features/common-utils:2": {}, | ||
| "ghcr.io/devcontainers/features/rust:1": {} | ||
| }, | ||
| "customizations": { | ||
| "vscode": { | ||
| "extensions": [ | ||
| "vadimcn.vscode-lldb", | ||
| "rust-lang.rust-analyzer", | ||
| "tamasfe.even-better-toml" | ||
| ] | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| networks: | ||
| trustify: | ||
| name: "trustify" | ||
|
|
||
| services: | ||
| trustify-minimal: | ||
| image: localhost/devcontainer-trustify-minimal:latest | ||
| build: | ||
| dockerfile: ./Dockerfile | ||
| security_opt: | ||
| - "label=disable" | ||
| userns_mode: "keep-id" | ||
| environment: | ||
| HTTP_SERVER_BIND_ADDR: "::" | ||
| command: /bin/sh -c "while sleep 1000; do :; done" | ||
| volumes: | ||
| - ../..:/workspace:cached | ||
| networks: | ||
| - trustify |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be scoped to "Linux", it works differently on Windows and MacOS, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, Windows and MacOS have to use "Podman Machine" if am not wrong.
I have no MacOS neither Windows for me to be able to write accurate instructions. I expect the README to evolve and be enhanced title by title by Windows and MacOS users if they find DevContainer within VSCode useful.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm against having half-done instructions. If we can't come up with a solution which works on all platforms, including documentation, then it might better to not do it. Maybe someone with more Mac OS/Windows experience can amend this PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider this PR as a well intended contribution to a community project.
If we could merge this PR it would help me a lot as it will allow me to save a ton of time as a regular code watcher of this repository.
I guess the majority of contributors of this repository are Windows and MacOS users and very few of them use Linux.
It is not my intention to make the core contributors harder. Unfortunately I have no way of testing things on MacOS nor Windows and be sure that the instructions are accurate.
I was expecting an "evolution" approach, evolve documentation in the same peace as users start using it. There is low risk as it does not affect the code in any way. But if the approach "all or nothing" is the approach advised by the core contributors of this project then I am afraid I cannot anything about it so please feel free to close this PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As a side note. This PR added a README for setting up Devcontainers with good intentions, but it brought more troubles than expected so maybe it is just better to delete the README.md inside the .devcontainer directory. Documenting how to set up podman or docker is something out of the scope of any project.
Here are some examples of relatively big projects that use devcontainers. None of them have docs for setting up Podman/Docker:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I understand, but then I don't want to merge this. If we end up with instructions that only work for part of users, that will cause frustration, because things don't work.
I am sure you can find someone with MacOS and collaborate. What would at least sort out least two out of three.
If that's not possible, then I'm against merging this.