mirror of https://github.com/coder/coder.git
docs: explain JFrog integration 🐸 (#8682)
This commit is contained in:
parent
29963433ee
commit
8686b7a499
|
@ -85,6 +85,18 @@
|
|||
"path": "./platforms/aws.md",
|
||||
"icon_path": "./images/aws.svg"
|
||||
},
|
||||
{
|
||||
"title": "Azure",
|
||||
"description": "Set up Coder on an Azure VM",
|
||||
"path": "./platforms/azure.md",
|
||||
"icon_path": "./images/azure.svg"
|
||||
},
|
||||
{
|
||||
"title": "Docker",
|
||||
"description": "Set up Coder with Docker",
|
||||
"path": "./platforms/docker.md",
|
||||
"icon_path": "./images/icons/docker.svg"
|
||||
},
|
||||
{
|
||||
"title": "GCP",
|
||||
"description": "Set up Coder on a GCP Compute Engine VM",
|
||||
|
@ -92,10 +104,9 @@
|
|||
"icon_path": "./images/google-cloud.svg"
|
||||
},
|
||||
{
|
||||
"title": "Azure",
|
||||
"description": "Set up Coder on an Azure VM",
|
||||
"path": "./platforms/azure.md",
|
||||
"icon_path": "./images/azure.svg"
|
||||
"title": "JFrog",
|
||||
"description": "Integrate Coder with JFrog",
|
||||
"path": "./platforms/jfrog.md"
|
||||
},
|
||||
{
|
||||
"title": "Kubernetes",
|
||||
|
@ -114,12 +125,6 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "Docker",
|
||||
"description": "Set up Coder with Docker",
|
||||
"path": "./platforms/docker.md",
|
||||
"icon_path": "./images/icons/docker.svg"
|
||||
},
|
||||
{
|
||||
"title": "Other platforms",
|
||||
"description": "Set up Coder on an another provider",
|
||||
|
|
|
@ -0,0 +1,152 @@
|
|||
# JFrog
|
||||
|
||||
Coder and JFrog work together to provide seamless security and compliance for
|
||||
your development environments. With Coder, you can automatically authenticate
|
||||
every workspace to use Artifactory as a package registry.
|
||||
|
||||
In this page, we'll show you how to integrate both products using Docker
|
||||
as the underlying compute. But, these concepts apply to any compute platform. The full example template can be found [here](https://github.com/coder/coder/tree/main/examples/jfrog-docker).
|
||||
|
||||
## Requirements
|
||||
|
||||
- A JFrog Artifactory instance
|
||||
- 1:1 mapping of users in Coder to users in Artifactory by email address
|
||||
|
||||
## Provisioner Authentication
|
||||
|
||||
The most straight-forward way to authenticate your template with Artifactory is
|
||||
by using
|
||||
[Terraform-managed variables](https://coder.com/docs/v2/latest/templates/parameters#terraform-template-wide-variables).
|
||||
|
||||
See the following example:
|
||||
|
||||
```hcl
|
||||
terraform {
|
||||
required_providers {
|
||||
coder = {
|
||||
source = "coder/coder"
|
||||
version = "~> 0.11.1"
|
||||
}
|
||||
docker = {
|
||||
source = "kreuzwerker/docker"
|
||||
version = "~> 3.0.1"
|
||||
}
|
||||
artifactory = {
|
||||
source = "registry.terraform.io/jfrog/artifactory"
|
||||
version = "6.22.3"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
variable "jfrog_url" {
|
||||
type = string
|
||||
description = "The URL of the JFrog instance."
|
||||
}
|
||||
|
||||
variable "artifactory_access_token" {
|
||||
type = string
|
||||
description = "The admin-level access token to use for JFrog."
|
||||
}
|
||||
|
||||
# Configure the Artifactory provider
|
||||
provider "artifactory" {
|
||||
url = "${var.jfrog_url}/artifactory"
|
||||
access_token = "${var.artifactory_access_token}"
|
||||
}
|
||||
```
|
||||
|
||||
When pushing the template, you can pass in the variables using the `--variable` flag:
|
||||
|
||||
```sh
|
||||
coder templates push --variable 'jfrog_url=https://YYY.jfrog.io' --variable 'artifactory_access_token=XXX'
|
||||
```
|
||||
|
||||
## Installing jf
|
||||
|
||||
`jf` is the JFrog CLI. It can do many things across the JFrog platform, but
|
||||
we'll focus on its ability to configure package managers, as that's the relevant
|
||||
functionality for most developers.
|
||||
|
||||
The generic method of installing the JFrog CLI is the following command:
|
||||
|
||||
```sh
|
||||
curl -fL https://install-cli.jfrog.io | sh
|
||||
```
|
||||
|
||||
Other methods are listed [here](https://jfrog.com/help/r/jfrog-cli/download-and-installation).
|
||||
|
||||
In our Docker-based example, we install `jf` by adding these lines to our `Dockerfile`:
|
||||
|
||||
```Dockerfile
|
||||
RUN curl -fL https://install-cli.jfrog.io | sh
|
||||
RUN chmod 755 $(which jf)
|
||||
```
|
||||
|
||||
and use this `coder_agent` block:
|
||||
|
||||
```hcl
|
||||
resource "coder_agent" "main" {
|
||||
arch = data.coder_provisioner.me.arch
|
||||
os = "linux"
|
||||
startup_script_timeout = 180
|
||||
startup_script = <<-EOT
|
||||
set -e
|
||||
|
||||
# install and start code-server
|
||||
curl -fsSL https://code-server.dev/install.sh | sh -s -- --method=standalone --prefix=/tmp/code-server --version 4.11.0
|
||||
/tmp/code-server/bin/code-server --auth none --port 13337 >/tmp/code-server.log 2>&1 &
|
||||
|
||||
# The jf CLI checks $CI when determining whether to use interactive
|
||||
# flows.
|
||||
export CI=true
|
||||
|
||||
jf c rm 0 || true
|
||||
echo ${artifactory_access_token.me.access_token} | \
|
||||
jf c add --access-token-stdin --url ${var.jfrog_url} 0
|
||||
EOT
|
||||
}
|
||||
```
|
||||
|
||||
You can verify that `jf` is configured correctly in your workspace by
|
||||
running `jf c show`. It should display output like:
|
||||
|
||||
```text
|
||||
coder@jf:~$ jf c show
|
||||
Server ID: 0
|
||||
JFrog Platform URL: https://cdr.jfrog.io/
|
||||
Artifactory URL: https://cdr.jfrog.io/artifactory/
|
||||
Distribution URL: https://cdr.jfrog.io/distribution/
|
||||
Xray URL: https://cdr.jfrog.io/xray/
|
||||
Mission Control URL: https://cdr.jfrog.io/mc/
|
||||
Pipelines URL: https://cdr.jfrog.io/pipelines/
|
||||
User: ammar@....com
|
||||
Access token: ...
|
||||
Default: true
|
||||
```
|
||||
|
||||
## Configuring npm
|
||||
|
||||
Add the following line to your `startup_script` to configure `npm` to use
|
||||
Artifactory:
|
||||
|
||||
```sh
|
||||
# Configure the `npm` CLI to use the Artifactory "npm" registry.
|
||||
cat << EOF > ~/.npmrc
|
||||
email = ${data.coder_workspace.me.owner_email}
|
||||
registry=${var.jfrog_url}/artifactory/api/npm/npm/
|
||||
EOF
|
||||
jf rt curl /api/npm/auth >> .npmrc
|
||||
```
|
||||
|
||||
Now, your developers can run `npm install`, `npm audit`, etc. and transparently
|
||||
use Artifactory as the package registry. You can verify that `npm` is configured
|
||||
correctly by running `npm install --loglevel=http react` and checking that
|
||||
npm is only hitting your Artifactory URL.
|
||||
|
||||
You can apply the same concepts to Docker, Go, Maven, and other package managers
|
||||
supported by Artifactory.
|
||||
|
||||
## More reading
|
||||
|
||||
- See the full example template [here](https://github.com/coder/coder/tree/main/examples/jfrog-docker).
|
||||
- To serve extensions from your own VS Code Marketplace, check out [code-marketplace](https://github.com/coder/code-marketplace#artifactory-storage).
|
|
@ -0,0 +1,26 @@
|
|||
---
|
||||
name: JFrog and Docker
|
||||
description: Develop inside Docker containers using your local daemon
|
||||
tags: [local, docker, jfrog]
|
||||
icon: /icon/docker.png
|
||||
---
|
||||
|
||||
# jfrog-docker
|
||||
|
||||
To get started, run `coder templates init`. When prompted, select this template.
|
||||
Follow the on-screen instructions to proceed.
|
||||
|
||||
## Editing the image
|
||||
|
||||
Edit the `Dockerfile` and run `coder templates push` to update workspaces.
|
||||
|
||||
## code-server
|
||||
|
||||
`code-server` is installed via the `startup_script` argument in the `coder_agent`
|
||||
resource block. The `coder_app` resource is defined to access `code-server` through
|
||||
the dashboard UI over `localhost:13337`.
|
||||
|
||||
# Next steps
|
||||
|
||||
Check out our [Docker](../docker/) template for a more fully featured Docker
|
||||
example.
|
|
@ -0,0 +1,21 @@
|
|||
FROM ubuntu
|
||||
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y \
|
||||
curl \
|
||||
git \
|
||||
golang \
|
||||
sudo \
|
||||
vim \
|
||||
wget \
|
||||
npm \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
ARG USER=coder
|
||||
RUN useradd --groups sudo --no-create-home --shell /bin/bash ${USER} \
|
||||
&& echo "${USER} ALL=(ALL) NOPASSWD:ALL" >/etc/sudoers.d/${USER} \
|
||||
&& chmod 0440 /etc/sudoers.d/${USER}
|
||||
RUN curl -fL https://install-cli.jfrog.io | sh
|
||||
RUN chmod 755 $(which jf)
|
||||
USER ${USER}
|
||||
WORKDIR /home/${USER}
|
|
@ -0,0 +1,137 @@
|
|||
terraform {
|
||||
required_providers {
|
||||
coder = {
|
||||
source = "coder/coder"
|
||||
version = "~> 0.11.1"
|
||||
}
|
||||
docker = {
|
||||
source = "kreuzwerker/docker"
|
||||
version = "~> 3.0.1"
|
||||
}
|
||||
artifactory = {
|
||||
source = "registry.terraform.io/jfrog/artifactory"
|
||||
version = "6.22.3"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
locals {
|
||||
username = data.coder_workspace.me.owner
|
||||
}
|
||||
|
||||
data "coder_provisioner" "me" {
|
||||
}
|
||||
|
||||
provider "docker" {
|
||||
}
|
||||
|
||||
data "coder_workspace" "me" {
|
||||
}
|
||||
|
||||
variable "jfrog_url" {
|
||||
type = string
|
||||
description = "The URL of the JFrog instance."
|
||||
}
|
||||
|
||||
variable "artifactory_access_token" {
|
||||
type = string
|
||||
description = "The admin-level access token to use for JFrog."
|
||||
}
|
||||
|
||||
|
||||
# Configure the Artifactory provider
|
||||
provider "artifactory" {
|
||||
url = "${var.jfrog_url}/artifactory"
|
||||
access_token = var.artifactory_access_token
|
||||
}
|
||||
|
||||
resource "artifactory_access_token" "me" {
|
||||
username = data.coder_workspace.me.owner_email
|
||||
# The token should live for the duration of the workspace.
|
||||
end_date_relative = "0s"
|
||||
}
|
||||
|
||||
resource "coder_agent" "main" {
|
||||
arch = data.coder_provisioner.me.arch
|
||||
os = "linux"
|
||||
startup_script_timeout = 180
|
||||
startup_script = <<-EOT
|
||||
set -e
|
||||
|
||||
# install and start code-server
|
||||
curl -fsSL https://code-server.dev/install.sh | sh -s -- --method=standalone --prefix=/tmp/code-server --version 4.11.0
|
||||
/tmp/code-server/bin/code-server --auth none --port 13337 >/tmp/code-server.log 2>&1 &
|
||||
|
||||
# The jf CLI checks $CI when determining whether to use interactive
|
||||
# flows.
|
||||
export CI=true
|
||||
|
||||
jf c rm 0 || true
|
||||
echo ${artifactory_access_token.me.access_token} | \
|
||||
jf c add --access-token-stdin --url ${var.jfrog_url} 0
|
||||
|
||||
# Configure the `npm` CLI to use the Artifactory "npm" registry.
|
||||
cat << EOF > ~/.npmrc
|
||||
email = ${data.coder_workspace.me.owner_email}
|
||||
registry=${var.jfrog_url}/artifactory/api/npm/npm/
|
||||
EOF
|
||||
jf rt curl /api/npm/auth >> .npmrc
|
||||
EOT
|
||||
}
|
||||
|
||||
resource "coder_app" "code-server" {
|
||||
agent_id = coder_agent.main.id
|
||||
slug = "code-server"
|
||||
display_name = "code-server"
|
||||
url = "http://localhost:13337/?folder=/home/${local.username}"
|
||||
icon = "/icon/code.svg"
|
||||
subdomain = false
|
||||
share = "owner"
|
||||
|
||||
healthcheck {
|
||||
url = "http://localhost:13337/healthz"
|
||||
interval = 5
|
||||
threshold = 6
|
||||
}
|
||||
}
|
||||
|
||||
resource "docker_volume" "home_volume" {
|
||||
name = "coder-${data.coder_workspace.me.id}-home"
|
||||
# Protect the volume from being deleted due to changes in attributes.
|
||||
lifecycle {
|
||||
ignore_changes = all
|
||||
}
|
||||
}
|
||||
|
||||
resource "docker_image" "main" {
|
||||
name = "coder-${data.coder_workspace.me.id}"
|
||||
build {
|
||||
context = "./build"
|
||||
build_args = {
|
||||
USER = local.username
|
||||
}
|
||||
}
|
||||
triggers = {
|
||||
dir_sha1 = sha1(join("", [for f in fileset(path.module, "build/*") : filesha1(f)]))
|
||||
}
|
||||
}
|
||||
|
||||
resource "docker_container" "workspace" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
image = docker_image.main.name
|
||||
# Uses lower() to avoid Docker restriction on container names.
|
||||
name = "coder-${data.coder_workspace.me.owner}-${lower(data.coder_workspace.me.name)}"
|
||||
# Hostname makes the shell more user friendly: coder@my-workspace:~$
|
||||
hostname = data.coder_workspace.me.name
|
||||
entrypoint = ["sh", "-c", coder_agent.main.init_script]
|
||||
env = ["CODER_AGENT_TOKEN=${coder_agent.main.token}"]
|
||||
host {
|
||||
host = "host.docker.internal"
|
||||
ip = "host-gateway"
|
||||
}
|
||||
volumes {
|
||||
container_path = "/home/${local.username}"
|
||||
volume_name = docker_volume.home_volume.name
|
||||
read_only = false
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="120" height="60"><path d="M57.117 37.792l-2.72.757c.237.686.426 1.917.426 3.573v8.14h3.053V41.65c.568-.686 1.183-1.018 1.846-1.018.33 0 .592.07.876.237l.828-2.816c-.473-.213-.686-.26-1.136-.26-.33 0-.734.07-.994.19-.568.284-1.278.923-1.727 1.538 0-.686-.166-1.23-.45-1.727zM46.6 33.77h-.33v16.47h3.17v-7.29h4v-2.72h-4v-3.786h4.993l.19-1.444a50.36 50.36 0 0 1-8.022-1.231zm-7.407 18.67l1.467 1.704c1.42-.568 3.195-1.846 3.668-3.88.166-.663.213-1.09.213-3.242V33.793h-3.195v13.583c0 1.775-.07 2.437-.308 3.053-.308.686-1.04 1.49-1.846 2.01zm28.8-8.353c0 2.887-.568 4.118-1.87 4.118-.592 0-1.254-.33-1.538-.994-.237-.615-.38-1.656-.38-3.076 0-1.207.118-2.06.308-2.72.237-.757.828-1.23 1.562-1.23.544 0 1.018.237 1.302.64.426.568.615 1.633.615 3.266zm1.87 4.733c.994-1.183 1.444-2.627 1.444-4.71 0-1.964-.402-3.313-1.325-4.45-.994-1.23-2.272-1.822-3.928-1.822-3.124 0-5.206 2.532-5.206 6.366s2.06 6.295 5.206 6.295c1.775.024 2.934-.64 3.8-1.68zm8.66-6.815c0 1.112-.663 1.727-1.846 1.727-1.065 0-1.775-.497-1.775-1.727 0-1.136.663-1.798 1.798-1.798s1.822.663 1.822 1.798zm5.372-2.603L82.65 37.4c-.7.663-1.562 1.04-2.4 1.04-.38 0-.592-.047-1.42-.26a7.04 7.04 0 0 0-2.082-.308c-2.958 0-4.875 1.61-4.875 4.118 0 1.798.805 2.934 2.485 3.384-.686.166-1.42.52-1.75.923-.237.284-.355.663-.355 1.112a2.2 2.2 0 0 0 .237.994c.166.26.38.473.663.592.544.213 1.42.355 2.77.38l1.278.024c.828.047 1.254.19 1.585.355.308.19.544.615.544 1.09s-.284.947-.734 1.23c-.402.284-1.065.402-1.917.402-1.396 0-2.177-.52-2.177-1.49 0-.426.047-.52.142-.78H71.86c-.118.237-.26.568-.26 1.23 0 .828.308 1.538.947 2.153 1.04 1.018 2.745 1.302 4.378 1.302 1.798 0 3.55-.426 4.567-1.562.64-.7.923-1.49.923-2.508 0-1.09-.308-1.917-.994-2.603-.805-.78-1.727-1.065-3.502-1.09l-1.633-.024c-.308 0-.497-.118-.497-.284 0-.33.426-.615 1.207-.994l.45.024c2.46 0 4.26-1.514 4.26-3.62 0-.805-.237-1.42-.686-1.988.38.047.497.07.78.07.805 0 1.444-.26 2.106-.9zm-38.1-19.95c-3.786.923-6.366 2.745-6.366 4.827 0 1.302.994 2.485 2.627 3.408-.497-.78-.757-1.633-.757-2.485.024-2.153 1.704-4.165 4.496-5.75zm39.945 8.164c0-1.373-.852-2.627-2.272-3.668.118.426.213.852.213 1.278 0 3.905-5.466 7.265-13.228 8.66a25.21 25.21 0 0 0 2.721.142c6.934-.024 12.566-2.887 12.566-6.413zm-4.472-2.13c0-1.444-1.23-2.77-3.337-3.857.497.592.757 1.23.757 1.893 0 3.48-7.383 6.295-16.517 6.295-9.11 0-16.517-2.816-16.517-6.295a2.48 2.48 0 0 1 .355-1.278c-1.467.97-2.295 2.082-2.295 3.266 0 3.763 8.4 6.815 18.766 6.815s18.79-3.1 18.79-6.84zm-8.188-.19c-3.834 2.46-15.618 3.408-20.682.237-3.976-2.485-2.603-6.437-13.985-15.098-1.49-1.136.284-2.343 1.396-1.562s.095.97 2.343 3.218c4.543 4.543 4.496.45 5.206 2.01 1.514 3.242 4.827 6.508 4.827 6.508 3.337 2.177 5.987 2.65 10.91-.686 3.124-2.106 1.846 3.36 9.49-.592 2.792-1.444 2.674-.473 5.514-4.425 1.183-1.633 3.43 1.254.876 1.656-1.018.166-2.745 1.278-3.48 3.03-1.065 2.627-.615 4.567-2.414 5.703zm-21.25-6.673c-.947-.426-1.94-2.035-2.32-2.674 1.065-1.04.64-2.77.024-3.715-.592-.947-1.325-.686-2.106-1.562-.805-.876.308-3.147 1.325-1.396 3.8 6.555 6.318 3.834 9.418 3.43 2.982-.38 5.632 1.254 6.437-3.36.142-.757.876-.923.947.308.07 1.254.544 4.283 2.177 4.662 1.633.402 2.958-.38 3.337-.805s.592-.38.757.7c.166 1.065.592 2.556 2.887.9 4.71-3.36 3.36-4.662 5.206-5.537 1.04-.497 2.698 1.112.308 2.32-3.408 1.727-3.763 3.857-5.916 5.206-3.62 2.272-2.508.095-8.33-.734-2.248-.308-2.958 2.177-4.71 1.467-4-1.656-6.815-1.325-9.442.78zm12.613-12.14c.142.994.308.97.663 1.04.355.095.805-.473.805-.994.024-.544-.237-.876-.757-.852-.544.024-.734.284-.7.805zm17.51 1.775c.426.402 1.562.142 1.822-.166.686-.757.7-1.207.355-1.727-.355-.497-1.09-.426-1.822.118s-.592 1.562-.355 1.775zm-.308 5.017c-.355.473-.38.828-.118 1.09.284.284.852.52 1.254.213.402-.33.402-.805.07-1.207-.355-.426-.828-.426-1.207-.095zM45.734 7.36c.544.166.805.686 1.254.095.237-.284.26-.686-.047-1.112-.19-.26-1.09-.45-1.467-.07s-.024.994.26 1.09zm-11.098-.33c.994.615 1.633 1.538 2.4.7.26-.284.568-.78.024-1.775-.402-.734-1.704-1.018-2.153-.734-.473.26-1.04 1.325-.26 1.798zm9.158 4.71c.308.33.852.308 1.183.118.308-.19.26-.686-.047-1.112-.19-.26-.757-.402-1.136 0s-.213.757 0 .994z" fill="#41bf47"/></svg>
|
After Width: | Height: | Size: 4.1 KiB |
Loading…
Reference in New Issue