Skip to content

Commit 2e7584b

Browse files
committed
docs: explain JFrog integration 🐸
1 parent ac973a4 commit 2e7584b

File tree

6 files changed

+353
-10
lines changed

6 files changed

+353
-10
lines changed

docs/manifest.json

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -85,17 +85,28 @@
8585
"path": "./platforms/aws.md",
8686
"icon_path": "./images/aws.svg"
8787
},
88+
{
89+
"title": "Azure",
90+
"description": "Set up Coder on an Azure VM",
91+
"path": "./platforms/azure.md",
92+
"icon_path": "./images/azure.svg"
93+
},
94+
{
95+
"title": "Docker",
96+
"description": "Set up Coder with Docker",
97+
"path": "./platforms/docker.md",
98+
"icon_path": "./images/icons/docker.svg"
99+
},
88100
{
89101
"title": "GCP",
90102
"description": "Set up Coder on a GCP Compute Engine VM",
91103
"path": "./platforms/google-cloud-platform.md",
92104
"icon_path": "./images/google-cloud.svg"
93105
},
94106
{
95-
"title": "Azure",
96-
"description": "Set up Coder on an Azure VM",
97-
"path": "./platforms/azure.md",
98-
"icon_path": "./images/azure.svg"
107+
"title": "JFrog",
108+
"description": "Integrate Coder with JFrog",
109+
"path": "./platforms/jfrog.md"
99110
},
100111
{
101112
"title": "Kubernetes",
@@ -109,12 +120,6 @@
109120
}
110121
]
111122
},
112-
{
113-
"title": "Docker",
114-
"description": "Set up Coder with Docker",
115-
"path": "./platforms/docker.md",
116-
"icon_path": "./images/icons/docker.svg"
117-
},
118123
{
119124
"title": "Other platforms",
120125
"description": "Set up Coder on an another provider",

docs/platforms/jfrog.md

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
# JFrog
2+
3+
Coder and JFrog work together to provide seamless security and compliance for
4+
your development environments. With Coder, you can automatically authenticate
5+
every workspace to use Artifactory as a package registry.
6+
7+
In this page, we'll show you how to integrate both products using Docker
8+
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).
9+
10+
## Requirements
11+
12+
- A JFrog Artifactory instance
13+
- 1:1 mapping of users in Coder to users in Artifactory by email address
14+
15+
## Provisioner Authentication
16+
17+
The most straight-forward way to authenticate your template with Artifactory is
18+
by using
19+
[Terraform-managed variables](https://coder.com/docs/v2/latest/templates/parameters#terraform-template-wide-variables).
20+
21+
See the following example:
22+
23+
```hcl
24+
terraform {
25+
required_providers {
26+
coder = {
27+
source = "coder/coder"
28+
version = "~> 0.11.1"
29+
}
30+
docker = {
31+
source = "kreuzwerker/docker"
32+
version = "~> 3.0.1"
33+
}
34+
artifactory = {
35+
source = "registry.terraform.io/jfrog/artifactory"
36+
version = "6.22.3"
37+
}
38+
}
39+
}
40+
41+
variable "jfrog_url" {
42+
type = string
43+
description = "The URL of the JFrog instance."
44+
}
45+
46+
variable "artifactory_access_token" {
47+
type = string
48+
description = "The access token to use for JFrog."
49+
}
50+
51+
52+
# Configure the Artifactory provider
53+
provider "artifactory" {
54+
url = "${var.jfrog_url}/artifactory"
55+
access_token = "${var.artifactory_access_token}"
56+
}
57+
```
58+
59+
When pushing the template, you can pass in the variables using the `--variable` flag:
60+
61+
```sh
62+
coder templates push --variable 'jfrog_url=https://YYY.jfrog.io' --variable 'artifactory_access_token=XXX'
63+
```
64+
65+
## Installing jf
66+
67+
`jf` is the JFrog CLI. It can do many things across the JFrog platform, but
68+
we'll focus on its ability to configure package managers, as that's the relevant
69+
functionality for most developers.
70+
71+
The generic method of installing the JFrog CLI is the following command:
72+
73+
```sh
74+
curl -fL https://install-cli.jfrog.io | sh
75+
```
76+
77+
Other methods are listed [here](https://jfrog.com/help/r/jfrog-cli/download-and-installation).
78+
79+
In our Docker-based example, we install `jf` by adding these lines to our `Dockerfile`:
80+
81+
```Dockerfile
82+
RUN curl -fL https://install-cli.jfrog.io | sh
83+
RUN chmod 755 $(which jf)
84+
```
85+
86+
and use this `coder_agent` block:
87+
88+
```hcl
89+
resource "coder_agent" "main" {
90+
arch = data.coder_provisioner.me.arch
91+
os = "linux"
92+
startup_script_timeout = 180
93+
startup_script = <<-EOT
94+
set -e
95+
96+
# install and start code-server
97+
curl -fsSL https://code-server.dev/install.sh | sh -s -- --method=standalone --prefix=/tmp/code-server --version 4.11.0
98+
/tmp/code-server/bin/code-server --auth none --port 13337 >/tmp/code-server.log 2>&1 &
99+
100+
# The jf CLI checks $CI when determining whether to use interactive
101+
# flows.
102+
export CI=true
103+
104+
jf c rm 0 || true
105+
echo ${artifactory_access_token.me.access_token} | \
106+
jf c add --access-token-stdin --url ${var.jfrog_url} 0
107+
EOT
108+
}
109+
```
110+
111+
You can verify that `jf` is configured correctly in your workspace by
112+
running `jf c show`. It should display output like:
113+
114+
```text
115+
coder@jf:~$ jf c show
116+
Server ID: 0
117+
JFrog Platform URL: https://cdr.jfrog.io/
118+
Artifactory URL: https://cdr.jfrog.io/artifactory/
119+
Distribution URL: https://cdr.jfrog.io/distribution/
120+
Xray URL: https://cdr.jfrog.io/xray/
121+
Mission Control URL: https://cdr.jfrog.io/mc/
122+
Pipelines URL: https://cdr.jfrog.io/pipelines/
123+
User: ammar@....com
124+
Access token: ...
125+
Default: true
126+
```
127+
128+
## Configuring npm
129+
130+
Add the following line to your `startup_script` to configure `npm` to use
131+
Artifactory:
132+
133+
```sh
134+
# Configure the `npm` CLI to use the Artifactory "npm" registry.
135+
cat << EOF > ~/.npmrc
136+
email = ${data.coder_workspace.me.owner_email}
137+
registry=${var.jfrog_url}/artifactory/api/npm/npm/
138+
EOF
139+
jf rt curl /api/npm/auth >> .npmrc
140+
```
141+
142+
Now, your developers can run `npm install`, `npm audit`, etc. and transparently
143+
use Artifactory as the package registry. You can verify that `npm` is configured
144+
correctly by running `npm install --loglevel=http react` and checking that
145+
npm is only hitting your Artifactory URL.
146+
147+
You can apply the same concepts to Docker, Go, Maven, and other package managers
148+
supported by Artifactory.
149+
150+
## More reading
151+
152+
* See the full example template [here](https://github.com/coder/coder/tree/main/examples/jfrog-docker).
153+
* To serve extensions from your own VS Code Marketplace, check out [code-marketplace](https://github.com/coder/code-marketplace#artifactory-storage).
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
---
2+
name: JFrog and Docker
3+
description: Develop inside Docker containers using your local daemon
4+
tags: [local, docker, jfrog]
5+
icon: /icon/docker.png
6+
---
7+
8+
# jfrog-docker
9+
10+
To get started, run `coder templates init`. When prompted, select this template.
11+
Follow the on-screen instructions to proceed.
12+
13+
## Editing the image
14+
15+
Edit the `Dockerfile` and run `coder templates push` to update workspaces.
16+
17+
## code-server
18+
19+
`code-server` is installed via the `startup_script` argument in the `coder_agent`
20+
resource block. The `coder_app` resource is defined to access `code-server` through
21+
the dashboard UI over `localhost:13337`.
22+
23+
# Next steps
24+
25+
Check out our [Docker](../docker/) template for a more fully featured Docker
26+
example.
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
FROM ubuntu
2+
3+
RUN apt-get update \
4+
&& apt-get install -y \
5+
curl \
6+
git \
7+
golang \
8+
sudo \
9+
vim \
10+
wget \
11+
npm \
12+
&& rm -rf /var/lib/apt/lists/*
13+
14+
ARG USER=coder
15+
RUN useradd --groups sudo --no-create-home --shell /bin/bash ${USER} \
16+
&& echo "${USER} ALL=(ALL) NOPASSWD:ALL" >/etc/sudoers.d/${USER} \
17+
&& chmod 0440 /etc/sudoers.d/${USER}
18+
RUN curl -fL https://install-cli.jfrog.io | sh
19+
RUN chmod 755 $(which jf)
20+
USER ${USER}
21+
WORKDIR /home/${USER}
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
terraform {
2+
required_providers {
3+
coder = {
4+
source = "coder/coder"
5+
version = "~> 0.11.1"
6+
}
7+
docker = {
8+
source = "kreuzwerker/docker"
9+
version = "~> 3.0.1"
10+
}
11+
artifactory = {
12+
source = "registry.terraform.io/jfrog/artifactory"
13+
version = "6.22.3"
14+
}
15+
}
16+
}
17+
18+
locals {
19+
username = data.coder_workspace.me.owner
20+
}
21+
22+
data "coder_provisioner" "me" {
23+
}
24+
25+
provider "docker" {
26+
}
27+
28+
data "coder_workspace" "me" {
29+
}
30+
31+
variable "jfrog_url" {
32+
type = string
33+
description = "The URL of the JFrog instance."
34+
}
35+
36+
variable "artifactory_access_token" {
37+
type = string
38+
description = "The access token to use for JFrog."
39+
}
40+
41+
42+
# Configure the Artifactory provider
43+
provider "artifactory" {
44+
url = "${var.jfrog_url}/artifactory"
45+
access_token = "${var.artifactory_access_token}"
46+
}
47+
48+
resource "artifactory_access_token" "me" {
49+
username = "${data.coder_workspace.me.owner_email}"
50+
# The token should live for the duration of the workspace.
51+
end_date_relative = "0s"
52+
}
53+
54+
resource "coder_agent" "main" {
55+
arch = data.coder_provisioner.me.arch
56+
os = "linux"
57+
startup_script_timeout = 180
58+
startup_script = <<-EOT
59+
set -e
60+
61+
# install and start code-server
62+
curl -fsSL https://code-server.dev/install.sh | sh -s -- --method=standalone --prefix=/tmp/code-server --version 4.11.0
63+
/tmp/code-server/bin/code-server --auth none --port 13337 >/tmp/code-server.log 2>&1 &
64+
65+
# The jf CLI checks $CI when determining whether to use interactive
66+
# flows.
67+
export CI=true
68+
69+
jf c rm 0 || true
70+
echo ${artifactory_access_token.me.access_token} | \
71+
jf c add --access-token-stdin --url ${var.jfrog_url} 0
72+
73+
# Configure the `npm` CLI to use the Artifactory "npm" registry.
74+
cat << EOF > ~/.npmrc
75+
email = ${data.coder_workspace.me.owner_email}
76+
registry=${var.jfrog_url}/artifactory/api/npm/npm/
77+
EOF
78+
jf rt curl /api/npm/auth >> .npmrc
79+
EOT
80+
}
81+
82+
resource "coder_app" "code-server" {
83+
agent_id = coder_agent.main.id
84+
slug = "code-server"
85+
display_name = "code-server"
86+
url = "http://localhost:13337/?folder=/home/${local.username}"
87+
icon = "/icon/code.svg"
88+
subdomain = false
89+
share = "owner"
90+
91+
healthcheck {
92+
url = "http://localhost:13337/healthz"
93+
interval = 5
94+
threshold = 6
95+
}
96+
}
97+
98+
resource "docker_volume" "home_volume" {
99+
name = "coder-${data.coder_workspace.me.id}-home"
100+
# Protect the volume from being deleted due to changes in attributes.
101+
lifecycle {
102+
ignore_changes = all
103+
}
104+
}
105+
106+
resource "docker_image" "main" {
107+
name = "coder-${data.coder_workspace.me.id}"
108+
build {
109+
context = "./build"
110+
build_args = {
111+
USER = local.username
112+
}
113+
}
114+
triggers = {
115+
dir_sha1 = sha1(join("", [for f in fileset(path.module, "build/*") : filesha1(f)]))
116+
}
117+
}
118+
119+
resource "docker_container" "workspace" {
120+
count = data.coder_workspace.me.start_count
121+
image = docker_image.main.name
122+
# Uses lower() to avoid Docker restriction on container names.
123+
name = "coder-${data.coder_workspace.me.owner}-${lower(data.coder_workspace.me.name)}"
124+
# Hostname makes the shell more user friendly: coder@my-workspace:~$
125+
hostname = data.coder_workspace.me.name
126+
entrypoint = ["sh", "-c", coder_agent.main.init_script]
127+
env = ["CODER_AGENT_TOKEN=${coder_agent.main.token}"]
128+
host {
129+
host = "host.docker.internal"
130+
ip = "host-gateway"
131+
}
132+
volumes {
133+
container_path = "/home/${local.username}"
134+
volume_name = docker_volume.home_volume.name
135+
read_only = false
136+
}
137+
}

site/static/icon/jfrog.svg

Lines changed: 1 addition & 0 deletions
Loading

0 commit comments

Comments
 (0)