initial git

This commit is contained in:
2025-08-24 20:02:32 -04:00
parent 77f8dafedb
commit 758dfe062a
36 changed files with 9704 additions and 0 deletions

1
.python-version Normal file
View File

@@ -0,0 +1 @@
3.12

106
coder-compose.yaml Normal file
View File

@@ -0,0 +1,106 @@
services:
coder:
user: root
group_add:
- 988
image: 'ghcr.io/coder/coder:${CODER_VERSION:-latest}'
expose:
- '7080'
environment:
CODER_PG_CONNECTION_URL: 'postgresql://${POSTGRES_USER:-username}:${POSTGRES_PASSWORD:-password}@database/${POSTGRES_DB:-coder}?sslmode=disable'
CODER_HTTP_ADDRESS: '0.0.0.0:7080'
CODER_ACCESS_URL: '${CODER_ACCESS_URL}'
CODER_WILDCARD_ACCESS_URL: '${CODER_WILDCARD_ACCESS_URL}'
CODER_ADDRESS: '${CODER_ADDRESS}'
COOLIFY_RESOURCE_UUID: bwk8ckcok8o84cc0o4os4sso
COOLIFY_CONTAINER_NAME: coder-bwk8ckcok8o84cc0o4os4sso
COOLIFY_URL: 'http://dev.lab'
COOLIFY_FQDN: dev.lab
volumes:
- '/var/run/docker.sock:/var/run/docker.sock'
- 'bwk8ckcok8o84cc0o4os4sso_coder-home:/home/coder'
depends_on:
database:
condition: service_healthy
labels:
- glance.name=Coder
- 'glance.icon=https://cdn.jsdelivr.net/gh/selfhst/icons/webp/coder.webp'
- 'glance.url=http://dev.lab'
- 'glance.description=Mad Science Lab'
- glance.id=coder
- glance.category=dev
- glance.hide=false
- coolify.managed=true
- coolify.version=4.0.0-beta.420.6
- coolify.serviceId=41
- coolify.type=service
- coolify.name=coder-bwk8ckcok8o84cc0o4os4sso
- coolify.resourceName=coder
- coolify.projectName=development
- coolify.serviceName=coder
- coolify.environmentName=production
- coolify.pullRequestId=0
- coolify.service.subId=308
- coolify.service.subType=application
- coolify.service.subName=coder
- traefik.enable=true
- traefik.http.middlewares.gzip.compress=true
- traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https
- traefik.http.routers.http-0-bwk8ckcok8o84cc0o4os4sso-coder.entryPoints=http
- traefik.http.routers.http-0-bwk8ckcok8o84cc0o4os4sso-coder.middlewares=gzip
- 'traefik.http.routers.http-0-bwk8ckcok8o84cc0o4os4sso-coder.rule=Host(`dev.lab`) && PathPrefix(`/`)'
- traefik.http.routers.http-0-bwk8ckcok8o84cc0o4os4sso-coder.service=http-0-bwk8ckcok8o84cc0o4os4sso-coder
- traefik.http.services.http-0-bwk8ckcok8o84cc0o4os4sso-coder.loadbalancer.server.port=7080
container_name: coder-bwk8ckcok8o84cc0o4os4sso
restart: unless-stopped
networks:
bwk8ckcok8o84cc0o4os4sso: null
database:
image: 'postgres:17'
environment:
POSTGRES_USER: '${POSTGRES_USER:-username}'
POSTGRES_PASSWORD: '${POSTGRES_PASSWORD:-password}'
POSTGRES_DB: '${POSTGRES_DB:-coder}'
COOLIFY_RESOURCE_UUID: bwk8ckcok8o84cc0o4os4sso
COOLIFY_CONTAINER_NAME: database-bwk8ckcok8o84cc0o4os4sso
volumes:
- 'bwk8ckcok8o84cc0o4os4sso_coder-data:/var/lib/postgresql/data'
healthcheck:
test:
- CMD-SHELL
- 'pg_isready -U ${POSTGRES_USER:-username} -d ${POSTGRES_DB:-coder}'
interval: 5s
timeout: 5s
retries: 5
labels:
- glance.name=Postgres-Coder
- glance.parent=coder
- glance.hide=false
- coolify.managed=true
- coolify.version=4.0.0-beta.420.6
- coolify.serviceId=41
- coolify.type=service
- coolify.name=database-bwk8ckcok8o84cc0o4os4sso
- coolify.resourceName=coder
- coolify.projectName=development
- coolify.serviceName=database
- coolify.environmentName=production
- coolify.pullRequestId=0
- coolify.service.subId=38
- coolify.service.subType=database
- coolify.service.subName=database
container_name: database-bwk8ckcok8o84cc0o4os4sso
restart: unless-stopped
networks:
bwk8ckcok8o84cc0o4os4sso: null
volumes:
bwk8ckcok8o84cc0o4os4sso_coder-home:
name: bwk8ckcok8o84cc0o4os4sso_coder-home
bwk8ckcok8o84cc0o4os4sso_coder-data:
name: bwk8ckcok8o84cc0o4os4sso_coder-data
networks:
bwk8ckcok8o84cc0o4os4sso:
name: bwk8ckcok8o84cc0o4os4sso
external: true
configs: { }
secrets: { }

6
main.py Normal file
View File

@@ -0,0 +1,6 @@
def main():
print("Hello from code-tools!")
if __name__ == "__main__":
main()

7
pyproject.toml Normal file
View File

@@ -0,0 +1,7 @@
[project]
name = "code-tools"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.12"
dependencies = []

59
tf/.terraform.lock.hcl generated Normal file
View File

@@ -0,0 +1,59 @@
# This file is maintained automatically by "terraform init".
# Manual edits may be lost in future updates.
provider "registry.terraform.io/coder/coder" {
version = "2.10.0"
constraints = "~> 2.0"
hashes = [
"h1:hOsj4BaX4JNy2wQbJB2ROqI/1uf8ObtweRTDZI8Sj7U=",
"zh:040183aa59daec3d3d8321982a7641fe191a81bc614302a92bfd82cc93a3dde9",
"zh:11e9f51483ad3a6461325d352c264f5619cdb9590e311774eb1a2bf48aa55f82",
"zh:362ade1c76fabb51e8e0fffb494a032601cf1867f74813d47478629ca9aa9f40",
"zh:3812ef65fa5d97e26e0609d854d2b1909c0f1c9d99506c3b68cdb6e30005c5b1",
"zh:3ec6e25bc6dca613772a9612aee00ca6a0aec76c67c000150fd04c36c62678d7",
"zh:411322b5abc25815a516af4ff63614137b3ba3d1104f65a3e8e66b848dbe0f88",
"zh:4a19f3ed8240767ce49e40c122b13767eb67581fdbbad99ba1904448098128f2",
"zh:4e0a8f41cc4497a5fbc814cb538a536b304141583c734c74e8f8448e20f9614b",
"zh:64b6eba9d8af58f7976ec8c909d5642d636cd81c9ef09b7b60b00f905386c4fc",
"zh:6f841289beda7e1300e495f2bc779a0a608e3191cf1fe6a90599291c54ef7a58",
"zh:a4e6d3fce198f4c03bd956f76460d77ee31e7c08feaa2c35db18c91752be7403",
"zh:b12be11f74daea4acb88f3f4cb0b60044d181084bfd5d0eb0535e314272913b4",
"zh:c795ab3eca672796b0bd76d426f397703e48648aea110acbd2ae09f012a31893",
"zh:e6eb0380c8622106d9f443ffc4b4318451055539a046350e9f9e958ad078bf93",
"zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c",
]
}
provider "registry.terraform.io/coder/envbuilder" {
version = "1.0.0"
constraints = "~> 1.0"
hashes = [
"h1:EijMsTkZ+GM+0gSaTR2Rw9FO9vJE7i6w3U5/Z76zBsQ=",
"zh:638f85855a86dd9f783ac667d302a2fe072ff6570e866dabed8082d74a246c09",
"zh:8316dd29b5015d178cb6f8ecd4b10e4df766a82496d06883ba4c91ef410ce719",
"zh:890df766e9b839623b1f0437355032a3c006226a6c200cd911e15ee1a9014e9f",
"zh:d91bc816e66c01ef552b04413bd0d83f35a217eb578148da31ba54c0fe0aca31",
]
}
provider "registry.terraform.io/kreuzwerker/docker" {
version = "2.25.0"
constraints = "~> 2.25"
hashes = [
"h1:nB2atWOMNrq3tfVH216oFFCQ/TNjAXXno6ZyZhlGdQs=",
"zh:02ca00d987b2e56195d2e97d82349f680d4b94a6a0d514dc6c0031317aec4f11",
"zh:432d333412f01b7547b3b264ec85a2627869fdf5f75df9d237b0dc6a6848b292",
"zh:4709e81fea2b9132020d6c786a1d1d02c77254fc0e299ea1bb636892b6cadac6",
"zh:53c4a4ab59a1e0671d2292d74f14e060489482d430ad811016bf7cb95503c5de",
"zh:6c0865e514ceffbf19ace806fb4595bf05d0a165dd9c8664f8768da385ccc091",
"zh:6d72716d58b8c18cd0b223265b2a190648a14973223cc198a019b300ede07570",
"zh:a710ce90557c54396dfc27b282452a8f5373eb112a10e9fd77043ca05d30e72f",
"zh:e0868c7ac58af596edfa578473013bd550e40c0a1f6adc2c717445ebf9fd694e",
"zh:e2ab2c40631f100130e7b525e07be7a9b8d8fcb8f57f21dca235a3e15818636b",
"zh:e40c93b1d99660f92dd0c75611bcb9e68ae706d4c0bc6fac32f672e19e6f05bf",
"zh:e480501b2dd1399135ec7eb820e1be88f9381d32c4df093f2f4645863f8c48f4",
"zh:f1a71e90aa388d34691595883f6526543063f8e338792b7c2c003b2c8c63d108",
"zh:f346cd5d25a31991487ca5dc7a05e104776c3917482bc2a24ec6a90bb697b22e",
"zh:fa822a4eb4e6385e88fbb133fd63d3a953693712a7adeb371913a2d477c0148c",
]
}

View File

@@ -0,0 +1,373 @@
Mozilla Public License Version 2.0
==================================
1. Definitions
--------------
1.1. "Contributor"
means each individual or legal entity that creates, contributes to
the creation of, or owns Covered Software.
1.2. "Contributor Version"
means the combination of the Contributions of others (if any) used
by a Contributor and that particular Contributor's Contribution.
1.3. "Contribution"
means Covered Software of a particular Contributor.
1.4. "Covered Software"
means Source Code Form to which the initial Contributor has attached
the notice in Exhibit A, the Executable Form of such Source Code
Form, and Modifications of such Source Code Form, in each case
including portions thereof.
1.5. "Incompatible With Secondary Licenses"
means
(a) that the initial Contributor has attached the notice described
in Exhibit B to the Covered Software; or
(b) that the Covered Software was made available under the terms of
version 1.1 or earlier of the License, but not also under the
terms of a Secondary License.
1.6. "Executable Form"
means any form of the work other than Source Code Form.
1.7. "Larger Work"
means a work that combines Covered Software with other material, in
a separate file or files, that is not Covered Software.
1.8. "License"
means this document.
1.9. "Licensable"
means having the right to grant, to the maximum extent possible,
whether at the time of the initial grant or subsequently, any and
all of the rights conveyed by this License.
1.10. "Modifications"
means any of the following:
(a) any file in Source Code Form that results from an addition to,
deletion from, or modification of the contents of Covered
Software; or
(b) any new file in Source Code Form that contains any Covered
Software.
1.11. "Patent Claims" of a Contributor
means any patent claim(s), including without limitation, method,
process, and apparatus claims, in any patent Licensable by such
Contributor that would be infringed, but for the grant of the
License, by the making, using, selling, offering for sale, having
made, import, or transfer of either its Contributions or its
Contributor Version.
1.12. "Secondary License"
means either the GNU General Public License, Version 2.0, the GNU
Lesser General Public License, Version 2.1, the GNU Affero General
Public License, Version 3.0, or any later versions of those
licenses.
1.13. "Source Code Form"
means the form of the work preferred for making modifications.
1.14. "You" (or "Your")
means an individual or a legal entity exercising rights under this
License. For legal entities, "You" includes any entity that
controls, is controlled by, or is under common control with You. For
purposes of this definition, "control" means (a) the power, direct
or indirect, to cause the direction or management of such entity,
whether by contract or otherwise, or (b) ownership of more than
fifty percent (50%) of the outstanding shares or beneficial
ownership of such entity.
2. License Grants and Conditions
--------------------------------
2.1. Grants
Each Contributor hereby grants You a world-wide, royalty-free,
non-exclusive license:
(a) under intellectual property rights (other than patent or trademark)
Licensable by such Contributor to use, reproduce, make available,
modify, display, perform, distribute, and otherwise exploit its
Contributions, either on an unmodified basis, with Modifications, or
as part of a Larger Work; and
(b) under Patent Claims of such Contributor to make, use, sell, offer
for sale, have made, import, and otherwise transfer either its
Contributions or its Contributor Version.
2.2. Effective Date
The licenses granted in Section 2.1 with respect to any Contribution
become effective for each Contribution on the date the Contributor first
distributes such Contribution.
2.3. Limitations on Grant Scope
The licenses granted in this Section 2 are the only rights granted under
this License. No additional rights or licenses will be implied from the
distribution or licensing of Covered Software under this License.
Notwithstanding Section 2.1(b) above, no patent license is granted by a
Contributor:
(a) for any code that a Contributor has removed from Covered Software;
or
(b) for infringements caused by: (i) Your and any other third party's
modifications of Covered Software, or (ii) the combination of its
Contributions with other software (except as part of its Contributor
Version); or
(c) under Patent Claims infringed by Covered Software in the absence of
its Contributions.
This License does not grant any rights in the trademarks, service marks,
or logos of any Contributor (except as may be necessary to comply with
the notice requirements in Section 3.4).
2.4. Subsequent Licenses
No Contributor makes additional grants as a result of Your choice to
distribute the Covered Software under a subsequent version of this
License (see Section 10.2) or under the terms of a Secondary License (if
permitted under the terms of Section 3.3).
2.5. Representation
Each Contributor represents that the Contributor believes its
Contributions are its original creation(s) or it has sufficient rights
to grant the rights to its Contributions conveyed by this License.
2.6. Fair Use
This License is not intended to limit any rights You have under
applicable copyright doctrines of fair use, fair dealing, or other
equivalents.
2.7. Conditions
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
in Section 2.1.
3. Responsibilities
-------------------
3.1. Distribution of Source Form
All distribution of Covered Software in Source Code Form, including any
Modifications that You create or to which You contribute, must be under
the terms of this License. You must inform recipients that the Source
Code Form of the Covered Software is governed by the terms of this
License, and how they can obtain a copy of this License. You may not
attempt to alter or restrict the recipients' rights in the Source Code
Form.
3.2. Distribution of Executable Form
If You distribute Covered Software in Executable Form then:
(a) such Covered Software must also be made available in Source Code
Form, as described in Section 3.1, and You must inform recipients of
the Executable Form how they can obtain a copy of such Source Code
Form by reasonable means in a timely manner, at a charge no more
than the cost of distribution to the recipient; and
(b) You may distribute such Executable Form under the terms of this
License, or sublicense it under different terms, provided that the
license for the Executable Form does not attempt to limit or alter
the recipients' rights in the Source Code Form under this License.
3.3. Distribution of a Larger Work
You may create and distribute a Larger Work under terms of Your choice,
provided that You also comply with the requirements of this License for
the Covered Software. If the Larger Work is a combination of Covered
Software with a work governed by one or more Secondary Licenses, and the
Covered Software is not Incompatible With Secondary Licenses, this
License permits You to additionally distribute such Covered Software
under the terms of such Secondary License(s), so that the recipient of
the Larger Work may, at their option, further distribute the Covered
Software under the terms of either this License or such Secondary
License(s).
3.4. Notices
You may not remove or alter the substance of any license notices
(including copyright notices, patent notices, disclaimers of warranty,
or limitations of liability) contained within the Source Code Form of
the Covered Software, except that You may alter any license notices to
the extent required to remedy known factual inaccuracies.
3.5. Application of Additional Terms
You may choose to offer, and to charge a fee for, warranty, support,
indemnity or liability obligations to one or more recipients of Covered
Software. However, You may do so only on Your own behalf, and not on
behalf of any Contributor. You must make it absolutely clear that any
such warranty, support, indemnity, or liability obligation is offered by
You alone, and You hereby agree to indemnify every Contributor for any
liability incurred by such Contributor as a result of warranty, support,
indemnity or liability terms You offer. You may include additional
disclaimers of warranty and limitations of liability specific to any
jurisdiction.
4. Inability to Comply Due to Statute or Regulation
---------------------------------------------------
If it is impossible for You to comply with any of the terms of this
License with respect to some or all of the Covered Software due to
statute, judicial order, or regulation then You must: (a) comply with
the terms of this License to the maximum extent possible; and (b)
describe the limitations and the code they affect. Such description must
be placed in a text file included with all distributions of the Covered
Software under this License. Except to the extent prohibited by statute
or regulation, such description must be sufficiently detailed for a
recipient of ordinary skill to be able to understand it.
5. Termination
--------------
5.1. The rights granted under this License will terminate automatically
if You fail to comply with any of its terms. However, if You become
compliant, then the rights granted under this License from a particular
Contributor are reinstated (a) provisionally, unless and until such
Contributor explicitly and finally terminates Your grants, and (b) on an
ongoing basis, if such Contributor fails to notify You of the
non-compliance by some reasonable means prior to 60 days after You have
come back into compliance. Moreover, Your grants from a particular
Contributor are reinstated on an ongoing basis if such Contributor
notifies You of the non-compliance by some reasonable means, this is the
first time You have received notice of non-compliance with this License
from such Contributor, and You become compliant prior to 30 days after
Your receipt of the notice.
5.2. If You initiate litigation against any entity by asserting a patent
infringement claim (excluding declaratory judgment actions,
counter-claims, and cross-claims) alleging that a Contributor Version
directly or indirectly infringes any patent, then the rights granted to
You by any and all Contributors for the Covered Software under Section
2.1 of this License shall terminate.
5.3. In the event of termination under Sections 5.1 or 5.2 above, all
end user license agreements (excluding distributors and resellers) which
have been validly granted by You or Your distributors under this License
prior to termination shall survive termination.
************************************************************************
* *
* 6. Disclaimer of Warranty *
* ------------------------- *
* *
* Covered Software is provided under this License on an "as is" *
* basis, without warranty of any kind, either expressed, implied, or *
* statutory, including, without limitation, warranties that the *
* Covered Software is free of defects, merchantable, fit for a *
* particular purpose or non-infringing. The entire risk as to the *
* quality and performance of the Covered Software is with You. *
* Should any Covered Software prove defective in any respect, You *
* (not any Contributor) assume the cost of any necessary servicing, *
* repair, or correction. This disclaimer of warranty constitutes an *
* essential part of this License. No use of any Covered Software is *
* authorized under this License except under this disclaimer. *
* *
************************************************************************
************************************************************************
* *
* 7. Limitation of Liability *
* -------------------------- *
* *
* Under no circumstances and under no legal theory, whether tort *
* (including negligence), contract, or otherwise, shall any *
* Contributor, or anyone who distributes Covered Software as *
* permitted above, be liable to You for any direct, indirect, *
* special, incidental, or consequential damages of any character *
* including, without limitation, damages for lost profits, loss of *
* goodwill, work stoppage, computer failure or malfunction, or any *
* and all other commercial damages or losses, even if such party *
* shall have been informed of the possibility of such damages. This *
* limitation of liability shall not apply to liability for death or *
* personal injury resulting from such party's negligence to the *
* extent applicable law prohibits such limitation. Some *
* jurisdictions do not allow the exclusion or limitation of *
* incidental or consequential damages, so this exclusion and *
* limitation may not apply to You. *
* *
************************************************************************
8. Litigation
-------------
Any litigation relating to this License may be brought only in the
courts of a jurisdiction where the defendant maintains its principal
place of business and such litigation shall be governed by laws of that
jurisdiction, without reference to its conflict-of-law provisions.
Nothing in this Section shall prevent a party's ability to bring
cross-claims or counter-claims.
9. Miscellaneous
----------------
This License represents the complete agreement concerning the subject
matter hereof. If any provision of this License is held to be
unenforceable, such provision shall be reformed only to the extent
necessary to make it enforceable. Any law or regulation which provides
that the language of a contract shall be construed against the drafter
shall not be used to construe this License against a Contributor.
10. Versions of the License
---------------------------
10.1. New Versions
Mozilla Foundation is the license steward. Except as provided in Section
10.3, no one other than the license steward has the right to modify or
publish new versions of this License. Each version will be given a
distinguishing version number.
10.2. Effect of New Versions
You may distribute the Covered Software under the terms of the version
of the License under which You originally received the Covered Software,
or under the terms of any subsequent version published by the license
steward.
10.3. Modified Versions
If you create software not governed by this License, and you want to
create a new license for such software, you may create and use a
modified version of this License if you rename the license and remove
any references to the name of the license steward (except to note that
such modified license differs from this License).
10.4. Distributing Source Code Form that is Incompatible With Secondary
Licenses
If You choose to distribute Source Code Form that is Incompatible With
Secondary Licenses under the terms of this version of the License, the
notice described in Exhibit B of this License must be attached.
Exhibit A - Source Code Form License Notice
-------------------------------------------
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
If it is not possible or desirable to put the notice in a particular
file, then You may include the notice in a location (such as a LICENSE
file in a relevant directory) where a recipient would be likely to look
for such a notice.
You may add additional accurate notices of copyright ownership.
Exhibit B - "Incompatible With Secondary Licenses" Notice
---------------------------------------------------------
This Source Code Form is "Incompatible With Secondary Licenses", as
defined by the Mozilla Public License, v. 2.0.

View File

@@ -0,0 +1,103 @@
# terraform-provider-coder
Terraform provider for [Coder](https://github.com/coder/coder).
### Developing
#### Prerequisites
- [Go](https://golang.org/doc/install)
- [Terraform](https://learn.hashicorp.com/tutorials/terraform/install-cli)
We recommend using [`nix`](https://nixos.org/download.html) to manage your development environment. If you have `nix` installed, you can run `nix develop` to enter a shell with all the necessary dependencies.
Alternatively, you can install the dependencies manually.
#### Building
Follow the instructions outlined in the [Terraform documentation](https://developer.hashicorp.com/terraform/cli/config/config-file#development-overrides-for-provider-developers)
to setup your local Terraform to use your local version rather than the registry version.
1. Create a file named `.terraformrc` in your `$HOME` directory
2. Add the following content:
```hcl
provider_installation {
# Override the coder/coder provider to use your local version
dev_overrides {
"coder/coder" = "/path/to/terraform-provider-coder"
}
# For all other providers, install them directly from their origin provider
# registries as normal. If you omit this, Terraform will _only_ use
# the dev_overrides block, and so no other providers will be available.
direct {}
}
```
3. (optional, but recommended) Validate your configuration:
1. Create a new `main.tf` file and include:
```hcl
terraform {
required_providers {
coder = {
source = "coder/coder"
}
}
}
```
2. Run `terraform init` and observe a warning like `Warning: Provider development overrides are in effect`
4. Run `make build` to build the provider binary, which Terraform will try locate and execute
5. All local Terraform runs will now use your local provider!
6. **NOTE**: We vendor this provider into `github.com/coder/coder`, so if you're testing with a local clone, make sure to run the following in your local clone of `coder`:
```console
go mod edit -replace github.com/coder/terraform-provider-coder/v2=/path/to/terraform-provider-coder
go mod tidy
```
⚠️ Be sure to include `/v2` in the module path as it needs to match the version declared in the providers `go.mod`.
#### Terraform Acceptance Tests
To run Terraform acceptance tests, run `make testacc`. This will test the provider against the locally installed version of Terraform.
> [!Note]
> Our [CI workflow](./github/workflows/test.yml) runs a test matrix against multiple Terraform versions.
#### Integration Tests
The tests under the `./integration` directory perform the following steps:
- Build the local version of the provider,
- Run an in-memory Coder instance with a specified version,
- Validate the behaviour of the local provider against that specific version of Coder.
To run these integration tests locally:
1. Pull the version of the Coder image you wish to test:
```console
docker pull ghcr.io/coder/coder-preview:main-x.y.z-devel-abcd1234
```
1. Run `CODER_IMAGE=ghcr.io/coder/coder-preview CODER_VERSION=main-x.y.z-devel-abcd1234 make test-integration`.
> [!Note]
> You can specify `CODER_IMAGE` if the Coder image you wish to test is hosted somewhere other than `ghcr.io/coder/coder`.
> For example, `CODER_IMAGE=example.com/repo/coder CODER_VERSION=foobar make test-integration`.
### How to create a new release
> [!Warning]
> Before creating a new release, make sure you have pulled the latest commit from the main branch i.e. `git pull origin main`
1. Create a new tag with a version number (following semantic versioning):
```console
git tag -a v2.1.2 -m "v2.1.2"
```
2. Push the tag to the remote repository:
```console
git push origin tag v2.1.2
```
A GitHub Actions workflow named "Release" will automatically trigger, run integration tests, and publish the new release.

View File

@@ -0,0 +1,382 @@
# Mozilla Public License Version 2.0
1. Definitions
---
1.1. "Contributor"
means each individual or legal entity that creates, contributes to
the creation of, or owns Covered Software.
1.2. "Contributor Version"
means the combination of the Contributions of others (if any) used
by a Contributor and that particular Contributor's Contribution.
1.3. "Contribution"
means Covered Software of a particular Contributor.
1.4. "Covered Software"
means Source Code Form to which the initial Contributor has attached
the notice in Exhibit A, the Executable Form of such Source Code
Form, and Modifications of such Source Code Form, in each case
including portions thereof.
1.5. "Incompatible With Secondary Licenses"
means
(a) that the initial Contributor has attached the notice described
in Exhibit B to the Covered Software; or
(b) that the Covered Software was made available under the terms of
version 1.1 or earlier of the License, but not also under the
terms of a Secondary License.
1.6. "Executable Form"
means any form of the work other than Source Code Form.
1.7. "Larger Work"
means a work that combines Covered Software with other material, in
a separate file or files, that is not Covered Software.
1.8. "License"
means this document.
1.9. "Licensable"
means having the right to grant, to the maximum extent possible,
whether at the time of the initial grant or subsequently, any and
all of the rights conveyed by this License.
1.10. "Modifications"
means any of the following:
(a) any file in Source Code Form that results from an addition to,
deletion from, or modification of the contents of Covered
Software; or
(b) any new file in Source Code Form that contains any Covered
Software.
1.11. "Patent Claims" of a Contributor
means any patent claim(s), including without limitation, method,
process, and apparatus claims, in any patent Licensable by such
Contributor that would be infringed, but for the grant of the
License, by the making, using, selling, offering for sale, having
made, import, or transfer of either its Contributions or its
Contributor Version.
1.12. "Secondary License"
means either the GNU General Public License, Version 2.0, the GNU
Lesser General Public License, Version 2.1, the GNU Affero General
Public License, Version 3.0, or any later versions of those
licenses.
1.13. "Source Code Form"
means the form of the work preferred for making modifications.
1.14. "You" (or "Your")
means an individual or a legal entity exercising rights under this
License. For legal entities, "You" includes any entity that
controls, is controlled by, or is under common control with You. For
purposes of this definition, "control" means (a) the power, direct
or indirect, to cause the direction or management of such entity,
whether by contract or otherwise, or (b) ownership of more than
fifty percent (50%) of the outstanding shares or beneficial
ownership of such entity.
2. License Grants and Conditions
---
2.1. Grants
Each Contributor hereby grants You a world-wide, royalty-free,
non-exclusive license:
(a) under intellectual property rights (other than patent or trademark)
Licensable by such Contributor to use, reproduce, make available,
modify, display, perform, distribute, and otherwise exploit its
Contributions, either on an unmodified basis, with Modifications, or
as part of a Larger Work; and
(b) under Patent Claims of such Contributor to make, use, sell, offer
for sale, have made, import, and otherwise transfer either its
Contributions or its Contributor Version.
2.2. Effective Date
The licenses granted in Section 2.1 with respect to any Contribution
become effective for each Contribution on the date the Contributor first
distributes such Contribution.
2.3. Limitations on Grant Scope
The licenses granted in this Section 2 are the only rights granted under
this License. No additional rights or licenses will be implied from the
distribution or licensing of Covered Software under this License.
Notwithstanding Section 2.1(b) above, no patent license is granted by a
Contributor:
(a) for any code that a Contributor has removed from Covered Software;
or
(b) for infringements caused by: (i) Your and any other third party's
modifications of Covered Software, or (ii) the combination of its
Contributions with other software (except as part of its Contributor
Version); or
(c) under Patent Claims infringed by Covered Software in the absence of
its Contributions.
This License does not grant any rights in the trademarks, service marks,
or logos of any Contributor (except as may be necessary to comply with
the notice requirements in Section 3.4).
2.4. Subsequent Licenses
No Contributor makes additional grants as a result of Your choice to
distribute the Covered Software under a subsequent version of this
License (see Section 10.2) or under the terms of a Secondary License (if
permitted under the terms of Section 3.3).
2.5. Representation
Each Contributor represents that the Contributor believes its
Contributions are its original creation(s) or it has sufficient rights
to grant the rights to its Contributions conveyed by this License.
2.6. Fair Use
This License is not intended to limit any rights You have under
applicable copyright doctrines of fair use, fair dealing, or other
equivalents.
2.7. Conditions
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
in Section 2.1.
3. Responsibilities
---
3.1. Distribution of Source Form
All distribution of Covered Software in Source Code Form, including any
Modifications that You create or to which You contribute, must be under
the terms of this License. You must inform recipients that the Source
Code Form of the Covered Software is governed by the terms of this
License, and how they can obtain a copy of this License. You may not
attempt to alter or restrict the recipients' rights in the Source Code
Form.
3.2. Distribution of Executable Form
If You distribute Covered Software in Executable Form then:
(a) such Covered Software must also be made available in Source Code
Form, as described in Section 3.1, and You must inform recipients of
the Executable Form how they can obtain a copy of such Source Code
Form by reasonable means in a timely manner, at a charge no more
than the cost of distribution to the recipient; and
(b) You may distribute such Executable Form under the terms of this
License, or sublicense it under different terms, provided that the
license for the Executable Form does not attempt to limit or alter
the recipients' rights in the Source Code Form under this License.
3.3. Distribution of a Larger Work
You may create and distribute a Larger Work under terms of Your choice,
provided that You also comply with the requirements of this License for
the Covered Software. If the Larger Work is a combination of Covered
Software with a work governed by one or more Secondary Licenses, and the
Covered Software is not Incompatible With Secondary Licenses, this
License permits You to additionally distribute such Covered Software
under the terms of such Secondary License(s), so that the recipient of
the Larger Work may, at their option, further distribute the Covered
Software under the terms of either this License or such Secondary
License(s).
3.4. Notices
You may not remove or alter the substance of any license notices
(including copyright notices, patent notices, disclaimers of warranty,
or limitations of liability) contained within the Source Code Form of
the Covered Software, except that You may alter any license notices to
the extent required to remedy known factual inaccuracies.
3.5. Application of Additional Terms
You may choose to offer, and to charge a fee for, warranty, support,
indemnity or liability obligations to one or more recipients of Covered
Software. However, You may do so only on Your own behalf, and not on
behalf of any Contributor. You must make it absolutely clear that any
such warranty, support, indemnity, or liability obligation is offered by
You alone, and You hereby agree to indemnify every Contributor for any
liability incurred by such Contributor as a result of warranty, support,
indemnity or liability terms You offer. You may include additional
disclaimers of warranty and limitations of liability specific to any
jurisdiction.
4. Inability to Comply Due to Statute or Regulation
---
If it is impossible for You to comply with any of the terms of this
License with respect to some or all of the Covered Software due to
statute, judicial order, or regulation then You must: (a) comply with
the terms of this License to the maximum extent possible; and (b)
describe the limitations and the code they affect. Such description must
be placed in a text file included with all distributions of the Covered
Software under this License. Except to the extent prohibited by statute
or regulation, such description must be sufficiently detailed for a
recipient of ordinary skill to be able to understand it.
5. Termination
---
5.1. The rights granted under this License will terminate automatically
if You fail to comply with any of its terms. However, if You become
compliant, then the rights granted under this License from a particular
Contributor are reinstated (a) provisionally, unless and until such
Contributor explicitly and finally terminates Your grants, and (b) on an
ongoing basis, if such Contributor fails to notify You of the
non-compliance by some reasonable means prior to 60 days after You have
come back into compliance. Moreover, Your grants from a particular
Contributor are reinstated on an ongoing basis if such Contributor
notifies You of the non-compliance by some reasonable means, this is the
first time You have received notice of non-compliance with this License
from such Contributor, and You become compliant prior to 30 days after
Your receipt of the notice.
5.2. If You initiate litigation against any entity by asserting a patent
infringement claim (excluding declaratory judgment actions,
counter-claims, and cross-claims) alleging that a Contributor Version
directly or indirectly infringes any patent, then the rights granted to
You by any and all Contributors for the Covered Software under Section
2.1 of this License shall terminate.
5.3. In the event of termination under Sections 5.1 or 5.2 above, all
end user license agreements (excluding distributors and resellers) which
have been validly granted by You or Your distributors under this License
prior to termination shall survive termination.
---
- *
- 6. Disclaimer of Warranty \*
- ------------------------- \*
- *
- Covered Software is provided under this License on an "as is" \*
- basis, without warranty of any kind, either expressed, implied, or \*
- statutory, including, without limitation, warranties that the \*
- Covered Software is free of defects, merchantable, fit for a \*
- particular purpose or non-infringing. The entire risk as to the \*
- quality and performance of the Covered Software is with You. \*
- Should any Covered Software prove defective in any respect, You \*
- (not any Contributor) assume the cost of any necessary servicing, \*
- repair, or correction. This disclaimer of warranty constitutes an \*
- essential part of this License. No use of any Covered Software is \*
- authorized under this License except under this disclaimer. \*
- *
---
---
- *
- 7. Limitation of Liability \*
- -------------------------- \*
- *
- Under no circumstances and under no legal theory, whether tort \*
- (including negligence), contract, or otherwise, shall any \*
- Contributor, or anyone who distributes Covered Software as \*
- permitted above, be liable to You for any direct, indirect, \*
- special, incidental, or consequential damages of any character \*
- including, without limitation, damages for lost profits, loss of \*
- goodwill, work stoppage, computer failure or malfunction, or any \*
- and all other commercial damages or losses, even if such party \*
- shall have been informed of the possibility of such damages. This \*
- limitation of liability shall not apply to liability for death or \*
- personal injury resulting from such party's negligence to the \*
- extent applicable law prohibits such limitation. Some \*
- jurisdictions do not allow the exclusion or limitation of \*
- incidental or consequential damages, so this exclusion and \*
- limitation may not apply to You. \*
- *
---
8. Litigation
---
Any litigation relating to this License may be brought only in the
courts of a jurisdiction where the defendant maintains its principal
place of business and such litigation shall be governed by laws of that
jurisdiction, without reference to its conflict-of-law provisions.
Nothing in this Section shall prevent a party's ability to bring
cross-claims or counter-claims.
9. Miscellaneous
---
This License represents the complete agreement concerning the subject
matter hereof. If any provision of this License is held to be
unenforceable, such provision shall be reformed only to the extent
necessary to make it enforceable. Any law or regulation which provides
that the language of a contract shall be construed against the drafter
shall not be used to construe this License against a Contributor.
10. Versions of the License
---
10.1. New Versions
Mozilla Foundation is the license steward. Except as provided in Section
10.3, no one other than the license steward has the right to modify or
publish new versions of this License. Each version will be given a
distinguishing version number.
10.2. Effect of New Versions
You may distribute the Covered Software under the terms of the version
of the License under which You originally received the Covered Software,
or under the terms of any subsequent version published by the license
steward.
10.3. Modified Versions
If you create software not governed by this License, and you want to
create a new license for such software, you may create and use a
modified version of this License if you rename the license and remove
any references to the name of the license steward (except to note that
such modified license differs from this License).
10.4. Distributing Source Code Form that is Incompatible With Secondary
Licenses
If You choose to distribute Source Code Form that is Incompatible With
Secondary Licenses under the terms of this version of the License, the
notice described in Exhibit B of this License must be attached.
## Exhibit A - Source Code Form License Notice
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
If it is not possible or desirable to put the notice in a particular
file, then You may include the notice in a location (such as a LICENSE
file in a relevant directory) where a recipient would be likely to look
for such a notice.
You may add additional accurate notices of copyright ownership.
## Exhibit B - "Incompatible With Secondary Licenses" Notice
This Source Code Form is "Incompatible With Secondary Licenses", as
defined by the Mozilla Public License, v. 2.0.

View File

@@ -0,0 +1,49 @@
# terraform-provider-envbuilder
The `terraform-provider-envbuilder` is a Terraform provider that acts as a helper for setting up [`envbuilder`](https://envbuilder.sh) environments.
It is used to determine if a pre-built image of a dev container built from a given Git repository is present in a given Docker registry.
If it is found that building a particular dev container would produce the same image that is already present in the remote registry, then that image can be used to start the container instead, skipping over the build phase.
> **Note:** currently, this provider can only be run on Linux platforms. We are [investigating support](https://github.com/coder/terraform-provider-envbuilder/issues/26) for other platforms.
## Usage
Take a look at the [`envbuilder_cached_image_resource.tf`](./examples/resources/envbuilder_cached_image/envbuilder_cached_image_resource.tf) example for a detailed usage example.
For use with [Coder](https://github.com/coder/coder), see the [Dev Containers documentation](https://coder.com/docs/templates/dev-containers) and check out the example templates:
- [Docker](https://github.com/coder/coder/tree/main/examples/templates/devcontainer-docker)
- [Kubernetes](https://github.com/coder/coder/tree/main/examples/templates/devcontainer-kuberntes)
- [AWS VM](https://github.com/coder/coder/tree/main/examples/templates/devcontainer-aws-vm)
- [GCP VM](https://github.com/coder/coder/tree/main/examples/templates/devcontainer-gcp-vm)
## Requirements
- [Terraform](https://developer.hashicorp.com/terraform/downloads) >= 1.0
- [Go](https://golang.org/doc/install) >= 1.22
## Building The Provider
1. Clone the repository
1. Enter the repository directory
1. Build the provider using the Go `install` command:
```shell
go install
```
## Developing the Provider
If you wish to work on the provider, you'll first need [Go](http://www.golang.org) installed on your machine (see [Requirements](#requirements) above).
To compile the provider, run `go install`. This will build the provider and put the provider binary in the `$GOPATH/bin` directory.
To generate or update documentation, run `go generate`.
In order to run the full suite of Acceptance tests, run `make testacc`.
*Note:* Acceptance tests create real resources, and often cost money to run.
```shell
make testacc
```

View File

@@ -0,0 +1,610 @@
<a name="v2.25.0"></a>
## [v2.25.0](https://github.com/kreuzwerker/terraform-provider-docker/compare/v2.24.0...v2.25.0) (2023-01-05)
### Docs
* Add documentation of remote hosts. ([#498](https://github.com/kreuzwerker/terraform-provider-docker/issues/498))
### Feat
* Migrate build block to `docker_image` ([#501](https://github.com/kreuzwerker/terraform-provider-docker/issues/501))
* Add platform attribute to docker_image resource ([#500](https://github.com/kreuzwerker/terraform-provider-docker/issues/500))
* Add sysctl implementation to container of docker_service. ([#499](https://github.com/kreuzwerker/terraform-provider-docker/issues/499))
<a name="v2.24.0"></a>
## [v2.24.0](https://github.com/kreuzwerker/terraform-provider-docker/compare/v2.23.1...v2.24.0) (2022-12-23)
### Chore
* Prepare release v2.24.0
### Docs
* Fix generated website.
* Update command typo ([#487](https://github.com/kreuzwerker/terraform-provider-docker/issues/487))
### Feat
* cgroupns support ([#497](https://github.com/kreuzwerker/terraform-provider-docker/issues/497))
* Add triggers attribute to docker_registry_image ([#496](https://github.com/kreuzwerker/terraform-provider-docker/issues/496))
* Support registries with disabled auth ([#494](https://github.com/kreuzwerker/terraform-provider-docker/issues/494))
* add IPAM options block for docker networks ([#491](https://github.com/kreuzwerker/terraform-provider-docker/issues/491))
### Fix
* Pin data source specific tag test to older tag.
### Tests
* Add test for parsing auth headers.
<a name="v2.23.1"></a>
## [v2.23.1](https://github.com/kreuzwerker/terraform-provider-docker/compare/v2.23.0...v2.23.1) (2022-11-23)
### Chore
* Prepare release v2.23.1
### Fix
* Update shasum of busybox:1.35.0 tag in test.
* Handle Auth Header Scopes ([#482](https://github.com/kreuzwerker/terraform-provider-docker/issues/482))
* Set OS_ARCH from GOHOSTOS and GOHOSTARCH ([#477](https://github.com/kreuzwerker/terraform-provider-docker/issues/477))
<a name="v2.23.0"></a>
## [v2.23.0](https://github.com/kreuzwerker/terraform-provider-docker/compare/v2.22.0...v2.23.0) (2022-11-02)
### Chore
* Prepare release v2.23.0
### Feat
* wait container healthy state ([#467](https://github.com/kreuzwerker/terraform-provider-docker/issues/467))
* add docker logs data source ([#471](https://github.com/kreuzwerker/terraform-provider-docker/issues/471))
### Fix
* Update shasum of busybox:1.35.0 tag in test.
* Update shasum of busybox:1.35.0 tag
* Correct provider name to match the public registry ([#462](https://github.com/kreuzwerker/terraform-provider-docker/issues/462))
<a name="v2.22.0"></a>
## [v2.22.0](https://github.com/kreuzwerker/terraform-provider-docker/compare/v2.21.0...v2.22.0) (2022-09-20)
### Chore
* Prepare release v2.22.0
### Feat
* Configurable timeout for docker_container resource stateChangeConf ([#454](https://github.com/kreuzwerker/terraform-provider-docker/issues/454))
### Fix
* oauth authorization support for azurecr ([#451](https://github.com/kreuzwerker/terraform-provider-docker/issues/451))
<a name="v2.21.0"></a>
## [v2.21.0](https://github.com/kreuzwerker/terraform-provider-docker/compare/v2.20.3...v2.21.0) (2022-09-05)
### Chore
* Prepare release v2.21.0
### Docs
* Fix docker config example.
### Feat
* Add image_id attribute to docker_image resource. ([#450](https://github.com/kreuzwerker/terraform-provider-docker/issues/450))
* Update used goversion to 1.18. ([#449](https://github.com/kreuzwerker/terraform-provider-docker/issues/449))
### Fix
* Replace deprecated .latest attribute with new image_id. ([#453](https://github.com/kreuzwerker/terraform-provider-docker/issues/453))
* Remove reading part of docker_tag resource. ([#448](https://github.com/kreuzwerker/terraform-provider-docker/issues/448))
* Fix repo_digest value for DockerImageDatasource test.
<a name="v2.20.3"></a>
## [v2.20.3](https://github.com/kreuzwerker/terraform-provider-docker/compare/v2.20.2...v2.20.3) (2022-08-31)
### Chore
* Prepare release v2.20.3
### Fix
* Docker Registry Image data source use HEAD request to query image digest ([#433](https://github.com/kreuzwerker/terraform-provider-docker/issues/433))
* Adding Support for Windows Paths in Bash ([#438](https://github.com/kreuzwerker/terraform-provider-docker/issues/438))
<a name="v2.20.2"></a>
## [v2.20.2](https://github.com/kreuzwerker/terraform-provider-docker/compare/v2.20.1...v2.20.2) (2022-08-10)
### Chore
* Prepare release v2.20.2
### Fix
* Check the operating system for determining the default Docker socket ([#427](https://github.com/kreuzwerker/terraform-provider-docker/issues/427))
### Reverts
* fix(deps): update module github.com/golangci/golangci-lint to v1.48.0 ([#423](https://github.com/kreuzwerker/terraform-provider-docker/issues/423))
<a name="v2.20.1"></a>
## [v2.20.1](https://github.com/kreuzwerker/terraform-provider-docker/compare/v2.20.0...v2.20.1) (2022-08-10)
### Chore
* Prepare release v2.20.1
* Reduce time to setup AccTests ([#430](https://github.com/kreuzwerker/terraform-provider-docker/issues/430))
### Docs
* Improve docker network usage documentation [skip-ci]
### Feat
* Implement triggers attribute for docker_image. ([#425](https://github.com/kreuzwerker/terraform-provider-docker/issues/425))
### Fix
* Add ForceTrue to docker_image name attribute. ([#421](https://github.com/kreuzwerker/terraform-provider-docker/issues/421))
<a name="v2.20.0"></a>
## [v2.20.0](https://github.com/kreuzwerker/terraform-provider-docker/compare/v2.19.0...v2.20.0) (2022-07-28)
### Chore
* Prepare release v2.20.0
* Fix release targets in Makefile.
### Feat
* Implementation of `docker_tag` resource. ([#418](https://github.com/kreuzwerker/terraform-provider-docker/issues/418))
* Implement support for insecure registries ([#414](https://github.com/kreuzwerker/terraform-provider-docker/issues/414))
<a name="v2.19.0"></a>
## [v2.19.0](https://github.com/kreuzwerker/terraform-provider-docker/compare/v2.18.1...v2.19.0) (2022-07-15)
### Chore
* Prepare release v2.19.0
### Feat
* Add gpu flag to docker_container resource ([#405](https://github.com/kreuzwerker/terraform-provider-docker/issues/405))
### Fix
* Enable authentication to multiple registries again. ([#400](https://github.com/kreuzwerker/terraform-provider-docker/issues/400))
* ECR authentication ([#409](https://github.com/kreuzwerker/terraform-provider-docker/issues/409))
<a name="v2.18.1"></a>
## [v2.18.1](https://github.com/kreuzwerker/terraform-provider-docker/compare/v2.18.0...v2.18.1) (2022-07-14)
### Chore
* Prepare release v2.18.1
* Automate changelog generation [skip ci]
### Fix
* Improve searchLocalImages error handling. ([#407](https://github.com/kreuzwerker/terraform-provider-docker/issues/407))
* Throw errors when any part of docker config file handling goes wrong. ([#406](https://github.com/kreuzwerker/terraform-provider-docker/issues/406))
* Enables having a Dockerfile outside the context ([#402](https://github.com/kreuzwerker/terraform-provider-docker/issues/402))
<a name="v2.18.0"></a>
## [v2.18.0](https://github.com/kreuzwerker/terraform-provider-docker/compare/v2.17.0...v2.18.0) (2022-07-11)
### Chore
* prepare release v2.18.0
### Feat
* add runtime, stop_signal and stop_timeout properties to the docker_container resource ([#364](https://github.com/kreuzwerker/terraform-provider-docker/issues/364))
### Fix
* Correctly handle build files and context for docker_registry_image ([#398](https://github.com/kreuzwerker/terraform-provider-docker/issues/398))
* Switch to proper go tools mechanism to fix website-* workflows. ([#399](https://github.com/kreuzwerker/terraform-provider-docker/issues/399))
* compare relative paths when excluding, fixes kreuzwerker[#280](https://github.com/kreuzwerker/terraform-provider-docker/issues/280) ([#397](https://github.com/kreuzwerker/terraform-provider-docker/issues/397))
<a name="v2.17.0"></a>
## [v2.17.0](https://github.com/kreuzwerker/terraform-provider-docker/compare/v2.16.0...v2.17.0) (2022-06-23)
### Chore
* prepare release v2.17.0
* Exclude examples directory from renovate.
* remove the workflow to close stale issues and pull requests ([#371](https://github.com/kreuzwerker/terraform-provider-docker/issues/371))
### Fix
* update go package files directly on master to fix build.
* correct authentication for ghcr.io registry([#349](https://github.com/kreuzwerker/terraform-provider-docker/issues/349))
<a name="v2.16.0"></a>
## [v2.16.0](https://github.com/kreuzwerker/terraform-provider-docker/compare/v2.15.0...v2.16.0) (2022-01-24)
### Chore
* prepare release v2.16.0
### Docs
* fix service options ([#337](https://github.com/kreuzwerker/terraform-provider-docker/issues/337))
* update registry_image.md ([#321](https://github.com/kreuzwerker/terraform-provider-docker/issues/321))
* fix r/registry_image truncated docs ([#304](https://github.com/kreuzwerker/terraform-provider-docker/issues/304))
### Feat
* add parameter for SSH options ([#335](https://github.com/kreuzwerker/terraform-provider-docker/issues/335))
### Fix
* pass container rm flag ([#322](https://github.com/kreuzwerker/terraform-provider-docker/issues/322))
* add nil check of DriverConfig ([#315](https://github.com/kreuzwerker/terraform-provider-docker/issues/315))
* fmt of go files for go 1.17
<a name="v2.15.0"></a>
## [v2.15.0](https://github.com/kreuzwerker/terraform-provider-docker/compare/v2.14.0...v2.15.0) (2021-08-11)
### Chore
* prepare release v2.15.0
* re go gets terraform-plugin-docs
### Docs
* corrects authentication misspell. Closes [#264](https://github.com/kreuzwerker/terraform-provider-docker/issues/264)
### Feat
* add container storage opts ([#258](https://github.com/kreuzwerker/terraform-provider-docker/issues/258))
### Fix
* add current timestamp for file upload to container ([#259](https://github.com/kreuzwerker/terraform-provider-docker/issues/259))
<a name="v2.14.0"></a>
## [v2.14.0](https://github.com/kreuzwerker/terraform-provider-docker/compare/v2.13.0...v2.14.0) (2021-07-09)
### Chore
* prepare release v2.14.0
### Docs
* update to absolute path for registry image context ([#246](https://github.com/kreuzwerker/terraform-provider-docker/issues/246))
* update readme with logos and subsections ([#235](https://github.com/kreuzwerker/terraform-provider-docker/issues/235))
### Feat
* support terraform v1 ([#242](https://github.com/kreuzwerker/terraform-provider-docker/issues/242))
### Fix
* Update the URL of the docker hub registry ([#230](https://github.com/kreuzwerker/terraform-provider-docker/issues/230))
<a name="v2.13.0"></a>
## [v2.13.0](https://github.com/kreuzwerker/terraform-provider-docker/compare/v2.12.2...v2.13.0) (2021-06-22)
### Chore
* prepare release v2.13.0
### Docs
* fix a few typos ([#216](https://github.com/kreuzwerker/terraform-provider-docker/issues/216))
* fix typos in docker_image example usage ([#213](https://github.com/kreuzwerker/terraform-provider-docker/issues/213))
<a name="v2.12.2"></a>
## [v2.12.2](https://github.com/kreuzwerker/terraform-provider-docker/compare/v2.12.1...v2.12.2) (2021-05-26)
### Chore
* prepare release v2.12.2
<a name="v2.12.1"></a>
## [v2.12.1](https://github.com/kreuzwerker/terraform-provider-docker/compare/v2.12.0...v2.12.1) (2021-05-26)
### Chore
* update changelog for v2.12.1
### Fix
* add service host flattener with space split ([#205](https://github.com/kreuzwerker/terraform-provider-docker/issues/205))
* service state upgradeV2 for empty auth
<a name="v2.12.0"></a>
## [v2.12.0](https://github.com/kreuzwerker/terraform-provider-docker/compare/v2.11.0...v2.12.0) (2021-05-23)
### Chore
* update changelog for v2.12.0
* ignore dist folder
* configure actions/stale ([#157](https://github.com/kreuzwerker/terraform-provider-docker/issues/157))
* add the guide about Terraform Configuration in Bug Report ([#139](https://github.com/kreuzwerker/terraform-provider-docker/issues/139))
* bump docker dependency to v20.10.5 ([#119](https://github.com/kreuzwerker/terraform-provider-docker/issues/119))
### Ci
* run acceptance tests with multiple Terraform versions ([#129](https://github.com/kreuzwerker/terraform-provider-docker/issues/129))
### Docs
* update for v2.12.0
* add releasing steps
* format `Guide of Bug report` ([#159](https://github.com/kreuzwerker/terraform-provider-docker/issues/159))
* add an example to build an image with docker_image ([#158](https://github.com/kreuzwerker/terraform-provider-docker/issues/158))
* add a guide about writing issues to CONTRIBUTING.md ([#149](https://github.com/kreuzwerker/terraform-provider-docker/issues/149))
* fix Github repository URL in README ([#136](https://github.com/kreuzwerker/terraform-provider-docker/issues/136))
### Feat
* support darwin arm builds and golang 1.16 ([#140](https://github.com/kreuzwerker/terraform-provider-docker/issues/140))
* migrate to terraform-sdk v2 ([#102](https://github.com/kreuzwerker/terraform-provider-docker/issues/102))
### Fix
* rewriting tar header fields ([#198](https://github.com/kreuzwerker/terraform-provider-docker/issues/198))
* test spaces for windows ([#190](https://github.com/kreuzwerker/terraform-provider-docker/issues/190))
* replace for loops with StateChangeConf ([#182](https://github.com/kreuzwerker/terraform-provider-docker/issues/182))
* skip sign on compile action
* assign map to rawState when it is nil to prevent panic ([#180](https://github.com/kreuzwerker/terraform-provider-docker/issues/180))
* search local images with Docker image ID ([#151](https://github.com/kreuzwerker/terraform-provider-docker/issues/151))
* set "ForceNew: true" to labelSchema ([#152](https://github.com/kreuzwerker/terraform-provider-docker/issues/152))
<a name="v2.11.0"></a>
## [v2.11.0](https://github.com/kreuzwerker/terraform-provider-docker/compare/v2.10.0...v2.11.0) (2021-01-22)
### Chore
* update changelog for v2.11.0
* updates changelog for v2.10.0
### Docs
* fix legacy configuration style ([#126](https://github.com/kreuzwerker/terraform-provider-docker/issues/126))
### Feat
* add properties -it (tty and stdin_opn) to docker container
<a name="v2.10.0"></a>
## [v2.10.0](https://github.com/kreuzwerker/terraform-provider-docker/compare/v2.9.0...v2.10.0) (2021-01-08)
### Chore
* updates changelog for 2.10.0
* ignores testing folders
* adds separate bug and ft req templates
### Ci
* bumps to docker version 20.10.1
* pins workflows to ubuntu:20.04 image
### Docs
* add labels to arguments of docker_service ([#105](https://github.com/kreuzwerker/terraform-provider-docker/issues/105))
* cleans readme
* adds coc and contributing
### Feat
* supports Docker plugin ([#35](https://github.com/kreuzwerker/terraform-provider-docker/issues/35))
* support max replicas of Docker Service Task Spec ([#112](https://github.com/kreuzwerker/terraform-provider-docker/issues/112))
* add force_remove option to r/image ([#104](https://github.com/kreuzwerker/terraform-provider-docker/issues/104))
* add local semantic commit validation ([#99](https://github.com/kreuzwerker/terraform-provider-docker/issues/99))
* add ability to lint/check of links in documentation locally ([#98](https://github.com/kreuzwerker/terraform-provider-docker/issues/98))
### Fix
* set "latest" to tag when tag isn't specified ([#117](https://github.com/kreuzwerker/terraform-provider-docker/issues/117))
* image label for workflows
* remove all azure cps
### Pull Requests
* Merge pull request [#38](https://github.com/kreuzwerker/terraform-provider-docker/issues/38) from kreuzwerker/ci-ubuntu2004-workflow
* Merge pull request [#36](https://github.com/kreuzwerker/terraform-provider-docker/issues/36) from kreuzwerker/chore-gh-issue-tpl
<a name="v2.9.0"></a>
## [v2.9.0](https://github.com/kreuzwerker/terraform-provider-docker/compare/v2.8.0...v2.9.0) (2020-12-25)
### Chore
* updates changelog for 2.9.0
* update changelog 2.8.0 release date
* introduces golangci-lint ([#32](https://github.com/kreuzwerker/terraform-provider-docker/issues/32))
* fix changelog links
### Ci
* add gofmt's '-s' option
* remove unneeded make tasks
* fix test of website
### Doc
* devices is a block, not a boolean
### Feat
* adds support for OCI manifests ([#316](https://github.com/kreuzwerker/terraform-provider-docker/issues/316))
* adds security_opts to container config. ([#308](https://github.com/kreuzwerker/terraform-provider-docker/issues/308))
* adds support for init process injection for containers. ([#300](https://github.com/kreuzwerker/terraform-provider-docker/issues/300))
### Fix
* changing mounts requires ForceNew ([#314](https://github.com/kreuzwerker/terraform-provider-docker/issues/314))
* allow healthcheck to be computed as container can specify ([#312](https://github.com/kreuzwerker/terraform-provider-docker/issues/312))
* treat null user as a no-op ([#318](https://github.com/kreuzwerker/terraform-provider-docker/issues/318))
* workdir null behavior ([#320](https://github.com/kreuzwerker/terraform-provider-docker/issues/320))
### Style
* format with gofumpt
### Pull Requests
* Merge pull request [#33](https://github.com/kreuzwerker/terraform-provider-docker/issues/33) from brandonros/patch-1
* Merge pull request [#11](https://github.com/kreuzwerker/terraform-provider-docker/issues/11) from suzuki-shunsuke/format-with-gofumpt
* Merge pull request [#26](https://github.com/kreuzwerker/terraform-provider-docker/issues/26) from kreuzwerker/ci/fix-website-ci
* Merge pull request [#8](https://github.com/kreuzwerker/terraform-provider-docker/issues/8) from dubo-dubon-duponey/patch1
<a name="v2.8.0"></a>
## v2.8.0 (2020-11-11)
### Chore
* updates changelog for 2.8.0
* removes travis.yml
* deactivates travis
* removes vendor dir ([#298](https://github.com/kreuzwerker/terraform-provider-docker/issues/298))
* bump go 115 ([#297](https://github.com/kreuzwerker/terraform-provider-docker/issues/297))
* documentation updates ([#286](https://github.com/kreuzwerker/terraform-provider-docker/issues/286))
* updates link syntax ([#287](https://github.com/kreuzwerker/terraform-provider-docker/issues/287))
* fix typo ([#292](https://github.com/kreuzwerker/terraform-provider-docker/issues/292))
### Ci
* reactivats all workflows
* fix website
* only run website workflow
* exports gopath manually
* fix absolute gopath for website
* make website check separate workflow
* fix workflow names
* adds website test to unit test
* adds acc test
* adds compile
* adds go version and goproxy env
* enables unit tests for master branch
* adds unit test workflow
* adds goreleaser and gh action
* bumps docker and ubuntu versions ([#241](https://github.com/kreuzwerker/terraform-provider-docker/issues/241))
* removes debug option from acc tests
* skips test which is flaky only on travis
### Deps
* github.com/hashicorp/terraform[@sdk](https://github.com/sdk)-v0.11-with-go-modules Updated via: go get github.com/hashicorp/terraform[@sdk](https://github.com/sdk)-v0.11-with-go-modules and go mod tidy
* use go modules for dep mgmt run go mod tidy remove govendor from makefile and travis config set appropriate env vars for go modules
### Docker
* improve validation of runtime constraints
### Docs
* update container.html.markdown ([#278](https://github.com/kreuzwerker/terraform-provider-docker/issues/278))
* update service.html.markdown ([#281](https://github.com/kreuzwerker/terraform-provider-docker/issues/281))
* update restart_policy for service. Closes [#228](https://github.com/kreuzwerker/terraform-provider-docker/issues/228)
* adds new label structure. Closes [#214](https://github.com/kreuzwerker/terraform-provider-docker/issues/214)
* update anchors with -1 suffix ([#178](https://github.com/kreuzwerker/terraform-provider-docker/issues/178))
* Fix misspelled words
* Fix exported attribute name in docker_registry_image
* Fix example for docker_registry_image ([#8308](https://github.com/kreuzwerker/terraform-provider-docker/issues/8308))
* provider/docker - network settings attrs
### Feat
* conditionally adding port binding ([#293](https://github.com/kreuzwerker/terraform-provider-docker/issues/293)).
* adds docker Image build feature ([#283](https://github.com/kreuzwerker/terraform-provider-docker/issues/283))
* adds complete support for Docker credential helpers ([#253](https://github.com/kreuzwerker/terraform-provider-docker/issues/253))
* Expose IPv6 properties as attributes
* allow use of source file instead of content / content_base64 ([#240](https://github.com/kreuzwerker/terraform-provider-docker/issues/240))
* supports to update docker_container ([#236](https://github.com/kreuzwerker/terraform-provider-docker/issues/236))
* support to import some docker_container's attributes ([#234](https://github.com/kreuzwerker/terraform-provider-docker/issues/234))
* adds config file content as plain string ([#232](https://github.com/kreuzwerker/terraform-provider-docker/issues/232))
* make UID, GID, & mode for secrets and configs configurable ([#231](https://github.com/kreuzwerker/terraform-provider-docker/issues/231))
* adds import for resources ([#196](https://github.com/kreuzwerker/terraform-provider-docker/issues/196))
* add container ipc mode. ([#182](https://github.com/kreuzwerker/terraform-provider-docker/issues/182))
* adds container working dir ([#181](https://github.com/kreuzwerker/terraform-provider-docker/issues/181))
### Fix
* ignores 'remove_volumes' on container import
* duplicated buildImage function
* port objects with the same internal port but different protocol trigger recreation of container ([#274](https://github.com/kreuzwerker/terraform-provider-docker/issues/274))
* panic to migrate schema of docker_container from v1 to v2 ([#271](https://github.com/kreuzwerker/terraform-provider-docker/issues/271)). Closes [#264](https://github.com/kreuzwerker/terraform-provider-docker/issues/264)
* pins docker registry for tests to v2.7.0
* prevent force recreate of container about some attributes ([#269](https://github.com/kreuzwerker/terraform-provider-docker/issues/269))
* service endpoint spec flattening
* corrects IPAM config read on the data provider ([#229](https://github.com/kreuzwerker/terraform-provider-docker/issues/229))
* replica to 0 in current schema. Closes [#221](https://github.com/kreuzwerker/terraform-provider-docker/issues/221)
* label for network and volume after improt
* binary upload as base 64 content ([#194](https://github.com/kreuzwerker/terraform-provider-docker/issues/194))
* service env truncation for multiple delimiters ([#193](https://github.com/kreuzwerker/terraform-provider-docker/issues/193))
* destroy_grace_seconds are considered ([#179](https://github.com/kreuzwerker/terraform-provider-docker/issues/179))
### Make
* Add website + website-test targets
### Provider
* Ensured Go 1.11 in TravisCI and README provider: Run go fix provider: Run go fmt provider: Encode go version 1.11.5 to .go-version file
* Require Go 1.11 in TravisCI and README provider: Run go fix provider: Run go fmt
### Tests
* Skip test if swap limit isn't available ([#136](https://github.com/kreuzwerker/terraform-provider-docker/issues/136))
* Simplify Dockerfile(s)
### Vendor
* github.com/hashicorp/terraform/...[@v0](https://github.com/v0).10.0
* Ignore github.com/hashicorp/terraform/backend
### Website
* Docs sweep for lists & maps
* note on docker
* docker docs
### Pull Requests
* Merge pull request [#134](https://github.com/kreuzwerker/terraform-provider-docker/issues/134) from terraform-providers/go-modules-2019-03-01
* Merge pull request [#135](https://github.com/kreuzwerker/terraform-provider-docker/issues/135) from terraform-providers/t-simplify-dockerfile
* Merge pull request [#47](https://github.com/kreuzwerker/terraform-provider-docker/issues/47) from captn3m0/docker-link-warning
* Merge pull request [#60](https://github.com/kreuzwerker/terraform-provider-docker/issues/60) from terraform-providers/f-make-website
* Merge pull request [#23](https://github.com/kreuzwerker/terraform-provider-docker/issues/23) from JamesLaverack/patch-1
* Merge pull request [#18](https://github.com/kreuzwerker/terraform-provider-docker/issues/18) from terraform-providers/vendor-tf-0.10
* Merge pull request [#5046](https://github.com/kreuzwerker/terraform-provider-docker/issues/5046) from tpounds/use-built-in-schema-string-hash
* Merge pull request [#3761](https://github.com/kreuzwerker/terraform-provider-docker/issues/3761) from ryane/f-provider-docker-improvements
* Merge pull request [#3383](https://github.com/kreuzwerker/terraform-provider-docker/issues/3383) from apparentlymart/docker-container-command-docs
* Merge pull request [#1564](https://github.com/kreuzwerker/terraform-provider-docker/issues/1564) from nickryand/docker_links

View File

@@ -0,0 +1,373 @@
Mozilla Public License Version 2.0
==================================
1. Definitions
--------------
1.1. "Contributor"
means each individual or legal entity that creates, contributes to
the creation of, or owns Covered Software.
1.2. "Contributor Version"
means the combination of the Contributions of others (if any) used
by a Contributor and that particular Contributor's Contribution.
1.3. "Contribution"
means Covered Software of a particular Contributor.
1.4. "Covered Software"
means Source Code Form to which the initial Contributor has attached
the notice in Exhibit A, the Executable Form of such Source Code
Form, and Modifications of such Source Code Form, in each case
including portions thereof.
1.5. "Incompatible With Secondary Licenses"
means
(a) that the initial Contributor has attached the notice described
in Exhibit B to the Covered Software; or
(b) that the Covered Software was made available under the terms of
version 1.1 or earlier of the License, but not also under the
terms of a Secondary License.
1.6. "Executable Form"
means any form of the work other than Source Code Form.
1.7. "Larger Work"
means a work that combines Covered Software with other material, in
a separate file or files, that is not Covered Software.
1.8. "License"
means this document.
1.9. "Licensable"
means having the right to grant, to the maximum extent possible,
whether at the time of the initial grant or subsequently, any and
all of the rights conveyed by this License.
1.10. "Modifications"
means any of the following:
(a) any file in Source Code Form that results from an addition to,
deletion from, or modification of the contents of Covered
Software; or
(b) any new file in Source Code Form that contains any Covered
Software.
1.11. "Patent Claims" of a Contributor
means any patent claim(s), including without limitation, method,
process, and apparatus claims, in any patent Licensable by such
Contributor that would be infringed, but for the grant of the
License, by the making, using, selling, offering for sale, having
made, import, or transfer of either its Contributions or its
Contributor Version.
1.12. "Secondary License"
means either the GNU General Public License, Version 2.0, the GNU
Lesser General Public License, Version 2.1, the GNU Affero General
Public License, Version 3.0, or any later versions of those
licenses.
1.13. "Source Code Form"
means the form of the work preferred for making modifications.
1.14. "You" (or "Your")
means an individual or a legal entity exercising rights under this
License. For legal entities, "You" includes any entity that
controls, is controlled by, or is under common control with You. For
purposes of this definition, "control" means (a) the power, direct
or indirect, to cause the direction or management of such entity,
whether by contract or otherwise, or (b) ownership of more than
fifty percent (50%) of the outstanding shares or beneficial
ownership of such entity.
2. License Grants and Conditions
--------------------------------
2.1. Grants
Each Contributor hereby grants You a world-wide, royalty-free,
non-exclusive license:
(a) under intellectual property rights (other than patent or trademark)
Licensable by such Contributor to use, reproduce, make available,
modify, display, perform, distribute, and otherwise exploit its
Contributions, either on an unmodified basis, with Modifications, or
as part of a Larger Work; and
(b) under Patent Claims of such Contributor to make, use, sell, offer
for sale, have made, import, and otherwise transfer either its
Contributions or its Contributor Version.
2.2. Effective Date
The licenses granted in Section 2.1 with respect to any Contribution
become effective for each Contribution on the date the Contributor first
distributes such Contribution.
2.3. Limitations on Grant Scope
The licenses granted in this Section 2 are the only rights granted under
this License. No additional rights or licenses will be implied from the
distribution or licensing of Covered Software under this License.
Notwithstanding Section 2.1(b) above, no patent license is granted by a
Contributor:
(a) for any code that a Contributor has removed from Covered Software;
or
(b) for infringements caused by: (i) Your and any other third party's
modifications of Covered Software, or (ii) the combination of its
Contributions with other software (except as part of its Contributor
Version); or
(c) under Patent Claims infringed by Covered Software in the absence of
its Contributions.
This License does not grant any rights in the trademarks, service marks,
or logos of any Contributor (except as may be necessary to comply with
the notice requirements in Section 3.4).
2.4. Subsequent Licenses
No Contributor makes additional grants as a result of Your choice to
distribute the Covered Software under a subsequent version of this
License (see Section 10.2) or under the terms of a Secondary License (if
permitted under the terms of Section 3.3).
2.5. Representation
Each Contributor represents that the Contributor believes its
Contributions are its original creation(s) or it has sufficient rights
to grant the rights to its Contributions conveyed by this License.
2.6. Fair Use
This License is not intended to limit any rights You have under
applicable copyright doctrines of fair use, fair dealing, or other
equivalents.
2.7. Conditions
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
in Section 2.1.
3. Responsibilities
-------------------
3.1. Distribution of Source Form
All distribution of Covered Software in Source Code Form, including any
Modifications that You create or to which You contribute, must be under
the terms of this License. You must inform recipients that the Source
Code Form of the Covered Software is governed by the terms of this
License, and how they can obtain a copy of this License. You may not
attempt to alter or restrict the recipients' rights in the Source Code
Form.
3.2. Distribution of Executable Form
If You distribute Covered Software in Executable Form then:
(a) such Covered Software must also be made available in Source Code
Form, as described in Section 3.1, and You must inform recipients of
the Executable Form how they can obtain a copy of such Source Code
Form by reasonable means in a timely manner, at a charge no more
than the cost of distribution to the recipient; and
(b) You may distribute such Executable Form under the terms of this
License, or sublicense it under different terms, provided that the
license for the Executable Form does not attempt to limit or alter
the recipients' rights in the Source Code Form under this License.
3.3. Distribution of a Larger Work
You may create and distribute a Larger Work under terms of Your choice,
provided that You also comply with the requirements of this License for
the Covered Software. If the Larger Work is a combination of Covered
Software with a work governed by one or more Secondary Licenses, and the
Covered Software is not Incompatible With Secondary Licenses, this
License permits You to additionally distribute such Covered Software
under the terms of such Secondary License(s), so that the recipient of
the Larger Work may, at their option, further distribute the Covered
Software under the terms of either this License or such Secondary
License(s).
3.4. Notices
You may not remove or alter the substance of any license notices
(including copyright notices, patent notices, disclaimers of warranty,
or limitations of liability) contained within the Source Code Form of
the Covered Software, except that You may alter any license notices to
the extent required to remedy known factual inaccuracies.
3.5. Application of Additional Terms
You may choose to offer, and to charge a fee for, warranty, support,
indemnity or liability obligations to one or more recipients of Covered
Software. However, You may do so only on Your own behalf, and not on
behalf of any Contributor. You must make it absolutely clear that any
such warranty, support, indemnity, or liability obligation is offered by
You alone, and You hereby agree to indemnify every Contributor for any
liability incurred by such Contributor as a result of warranty, support,
indemnity or liability terms You offer. You may include additional
disclaimers of warranty and limitations of liability specific to any
jurisdiction.
4. Inability to Comply Due to Statute or Regulation
---------------------------------------------------
If it is impossible for You to comply with any of the terms of this
License with respect to some or all of the Covered Software due to
statute, judicial order, or regulation then You must: (a) comply with
the terms of this License to the maximum extent possible; and (b)
describe the limitations and the code they affect. Such description must
be placed in a text file included with all distributions of the Covered
Software under this License. Except to the extent prohibited by statute
or regulation, such description must be sufficiently detailed for a
recipient of ordinary skill to be able to understand it.
5. Termination
--------------
5.1. The rights granted under this License will terminate automatically
if You fail to comply with any of its terms. However, if You become
compliant, then the rights granted under this License from a particular
Contributor are reinstated (a) provisionally, unless and until such
Contributor explicitly and finally terminates Your grants, and (b) on an
ongoing basis, if such Contributor fails to notify You of the
non-compliance by some reasonable means prior to 60 days after You have
come back into compliance. Moreover, Your grants from a particular
Contributor are reinstated on an ongoing basis if such Contributor
notifies You of the non-compliance by some reasonable means, this is the
first time You have received notice of non-compliance with this License
from such Contributor, and You become compliant prior to 30 days after
Your receipt of the notice.
5.2. If You initiate litigation against any entity by asserting a patent
infringement claim (excluding declaratory judgment actions,
counter-claims, and cross-claims) alleging that a Contributor Version
directly or indirectly infringes any patent, then the rights granted to
You by any and all Contributors for the Covered Software under Section
2.1 of this License shall terminate.
5.3. In the event of termination under Sections 5.1 or 5.2 above, all
end user license agreements (excluding distributors and resellers) which
have been validly granted by You or Your distributors under this License
prior to termination shall survive termination.
************************************************************************
* *
* 6. Disclaimer of Warranty *
* ------------------------- *
* *
* Covered Software is provided under this License on an "as is" *
* basis, without warranty of any kind, either expressed, implied, or *
* statutory, including, without limitation, warranties that the *
* Covered Software is free of defects, merchantable, fit for a *
* particular purpose or non-infringing. The entire risk as to the *
* quality and performance of the Covered Software is with You. *
* Should any Covered Software prove defective in any respect, You *
* (not any Contributor) assume the cost of any necessary servicing, *
* repair, or correction. This disclaimer of warranty constitutes an *
* essential part of this License. No use of any Covered Software is *
* authorized under this License except under this disclaimer. *
* *
************************************************************************
************************************************************************
* *
* 7. Limitation of Liability *
* -------------------------- *
* *
* Under no circumstances and under no legal theory, whether tort *
* (including negligence), contract, or otherwise, shall any *
* Contributor, or anyone who distributes Covered Software as *
* permitted above, be liable to You for any direct, indirect, *
* special, incidental, or consequential damages of any character *
* including, without limitation, damages for lost profits, loss of *
* goodwill, work stoppage, computer failure or malfunction, or any *
* and all other commercial damages or losses, even if such party *
* shall have been informed of the possibility of such damages. This *
* limitation of liability shall not apply to liability for death or *
* personal injury resulting from such party's negligence to the *
* extent applicable law prohibits such limitation. Some *
* jurisdictions do not allow the exclusion or limitation of *
* incidental or consequential damages, so this exclusion and *
* limitation may not apply to You. *
* *
************************************************************************
8. Litigation
-------------
Any litigation relating to this License may be brought only in the
courts of a jurisdiction where the defendant maintains its principal
place of business and such litigation shall be governed by laws of that
jurisdiction, without reference to its conflict-of-law provisions.
Nothing in this Section shall prevent a party's ability to bring
cross-claims or counter-claims.
9. Miscellaneous
----------------
This License represents the complete agreement concerning the subject
matter hereof. If any provision of this License is held to be
unenforceable, such provision shall be reformed only to the extent
necessary to make it enforceable. Any law or regulation which provides
that the language of a contract shall be construed against the drafter
shall not be used to construe this License against a Contributor.
10. Versions of the License
---------------------------
10.1. New Versions
Mozilla Foundation is the license steward. Except as provided in Section
10.3, no one other than the license steward has the right to modify or
publish new versions of this License. Each version will be given a
distinguishing version number.
10.2. Effect of New Versions
You may distribute the Covered Software under the terms of the version
of the License under which You originally received the Covered Software,
or under the terms of any subsequent version published by the license
steward.
10.3. Modified Versions
If you create software not governed by this License, and you want to
create a new license for such software, you may create and use a
modified version of this License if you rename the license and remove
any references to the name of the license steward (except to note that
such modified license differs from this License).
10.4. Distributing Source Code Form that is Incompatible With Secondary
Licenses
If You choose to distribute Source Code Form that is Incompatible With
Secondary Licenses under the terms of this version of the License, the
notice described in Exhibit B of this License must be attached.
Exhibit A - Source Code Form License Notice
-------------------------------------------
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
If it is not possible or desirable to put the notice in a particular
file, then You may include the notice in a location (such as a LICENSE
file in a relevant directory) where a recipient would be likely to look
for such a notice.
You may add additional accurate notices of copyright ownership.
Exhibit B - "Incompatible With Secondary Licenses" Notice
---------------------------------------------------------
This Source Code Form is "Incompatible With Secondary Licenses", as
defined by the Mozilla Public License, v. 2.0.

View File

@@ -0,0 +1,116 @@
<a href="https://docker.com">
<img src="https://raw.githubusercontent.com/kreuzwerker/terraform-provider-docker/master/assets/docker-logo.png" alt="Docker logo" title="Docker" align="right" height="100" />
</a>
<a href="https://terraform.io">
<img src="https://raw.githubusercontent.com/kreuzwerker/terraform-provider-docker/master/assets/terraform-logo.png" alt="Terraform logo" title="Terraform" align="right" height="100" />
</a>
<a href="https://kreuzwerker.de">
<img src="https://raw.githubusercontent.com/kreuzwerker/terraform-provider-docker/master/assets/xw-logo.png" alt="Kreuzwerker logo" title="Kreuzwerker" align="right" height="100" />
</a>
# Terraform Provider for Docker
[![Release](https://img.shields.io/github/v/release/kreuzwerker/terraform-provider-docker)](https://github.com/kreuzwerker/terraform-provider-docker/releases)
[![Installs](https://img.shields.io/badge/dynamic/json?logo=terraform&label=installs&query=$.data.attributes.downloads&url=https%3A%2F%2Fregistry.terraform.io%2Fv2%2Fproviders%2F713)](https://registry.terraform.io/providers/kreuzwerker/docker)
[![Registry](https://img.shields.io/badge/registry-doc%40latest-lightgrey?logo=terraform)](https://registry.terraform.io/providers/kreuzwerker/docker/latest/docs)
[![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/kreuzwerker/terraform-provider-docker/blob/main/LICENSE)
[![Go Status](https://github.com/kreuzwerker/terraform-provider-docker/workflows/Acc%20Tests/badge.svg)](https://github.com/kreuzwerker/terraform-provider-docker/actions)
[![Lint Status](https://github.com/kreuzwerker/terraform-provider-docker/workflows/golangci-lint/badge.svg)](https://github.com/kreuzwerker/terraform-provider-docker/actions)
[![Go Report Card](https://goreportcard.com/badge/github.com/kreuzwerker/terraform-provider-docker)](https://goreportcard.com/report/github.com/kreuzwerker/terraform-provider-docker)
- Website: https://www.terraform.io
- Provider: [kreuzwerker/docker](https://registry.terraform.io/providers/kreuzwerker/docker/latest)
- Slack: [@gophers/terraform-provider-docker](https://gophers.slack.com/archives/C01G9TN5V36)
## Requirements
- [Terraform](https://www.terraform.io/downloads.html) >=0.12.x
- [Go](https://golang.org/doc/install) 1.18.x (to build the provider plugin)
## Building The Provider
```sh
$ git clone git@github.com:kreuzwerker/terraform-provider-docker
$ make build
```
## Example usage
Take a look at the examples in the [documentation](https://registry.terraform.io/providers/kreuzwerker/docker/2.25.0/docs) of the registry
or use the following example:
```hcl
# Set the required provider and versions
terraform {
required_providers {
# We recommend pinning to the specific version of the Docker Provider you're using
# since new versions are released frequently
docker = {
source = "kreuzwerker/docker"
version = "2.25.0"
}
}
}
# Configure the docker provider
provider "docker" {
}
# Create a docker image resource
# -> docker pull nginx:latest
resource "docker_image" "nginx" {
name = "nginx:latest"
keep_locally = true
}
# Create a docker container resource
# -> same as 'docker run --name nginx -p8080:80 -d nginx:latest'
resource "docker_container" "nginx" {
name = "nginx"
image = docker_image.nginx.image_id
ports {
external = 8080
internal = 80
}
}
# Or create a service resource
# -> same as 'docker service create -d -p 8081:80 --name nginx-service --replicas 2 nginx:latest'
resource "docker_service" "nginx_service" {
name = "nginx-service"
task_spec {
container_spec {
image = docker_image.nginx.repo_digest
}
}
mode {
replicated {
replicas = 2
}
}
endpoint_spec {
ports {
published_port = 8081
target_port = 80
}
}
}
```
## Contributing
The Terraform Docker Provider is the work of many of contributors. We appreciate your help!
To contribute, please read the contribution guidelines: [Contributing to Terraform - Docker Provider](CONTRIBUTING.md)
## License
The Terraform Provider Docker is available to everyone under the terms of the Mozilla Public License Version 2.0. [Take a look the LICENSE file](LICENSE).
## Stargazers over time
[![Stargazers over time](https://starchart.cc/kreuzwerker/terraform-provider-docker.svg)](https://starchart.cc/kreuzwerker/terraform-provider-docker)

92
tf/LICENSE.txt Normal file
View File

@@ -0,0 +1,92 @@
License text copyright (c) 2020 MariaDB Corporation Ab, All Rights Reserved.
"Business Source License" is a trademark of MariaDB Corporation Ab.
Parameters
Licensor: HashiCorp, Inc.
Licensed Work: Terraform Version 1.6.0 or later. The Licensed Work is (c) 2024
HashiCorp, Inc.
Additional Use Grant: You may make production use of the Licensed Work, provided
Your use does not include offering the Licensed Work to third
parties on a hosted or embedded basis in order to compete with
HashiCorp's paid version(s) of the Licensed Work. For purposes
of this license:
A "competitive offering" is a Product that is offered to third
parties on a paid basis, including through paid support
arrangements, that significantly overlaps with the capabilities
of HashiCorp's paid version(s) of the Licensed Work. If Your
Product is not a competitive offering when You first make it
generally available, it will not become a competitive offering
later due to HashiCorp releasing a new version of the Licensed
Work with additional capabilities. In addition, Products that
are not provided on a paid basis are not competitive.
"Product" means software that is offered to end users to manage
in their own environments or offered as a service on a hosted
basis.
"Embedded" means including the source code or executable code
from the Licensed Work in a competitive offering. "Embedded"
also means packaging the competitive offering in such a way
that the Licensed Work must be accessed or downloaded for the
competitive offering to operate.
Hosting or using the Licensed Work(s) for internal purposes
within an organization is not considered a competitive
offering. HashiCorp considers your organization to include all
of your affiliates under common control.
For binding interpretive guidance on using HashiCorp products
under the Business Source License, please visit our FAQ.
(https://www.hashicorp.com/license-faq)
Change Date: Four years from the date the Licensed Work is published.
Change License: MPL 2.0
For information about alternative licensing arrangements for the Licensed Work,
please contact licensing@hashicorp.com.
Notice
Business Source License 1.1
Terms
The Licensor hereby grants you the right to copy, modify, create derivative
works, redistribute, and make non-production use of the Licensed Work. The
Licensor may make an Additional Use Grant, above, permitting limited production use.
Effective on the Change Date, or the fourth anniversary of the first publicly
available distribution of a specific version of the Licensed Work under this
License, whichever comes first, the Licensor hereby grants you rights under
the terms of the Change License, and the rights granted in the paragraph
above terminate.
If your use of the Licensed Work does not comply with the requirements
currently in effect as described in this License, you must purchase a
commercial license from the Licensor, its affiliated entities, or authorized
resellers, or you must refrain from using the Licensed Work.
All copies of the original and modified Licensed Work, and derivative works
of the Licensed Work, are subject to this License. This License applies
separately for each version of the Licensed Work and the Change Date may vary
for each version of the Licensed Work released by Licensor.
You must conspicuously display this License on each original or modified copy
of the Licensed Work. If you receive the Licensed Work in original or
modified form from a third party, the terms and conditions set forth in this
License apply to your use of that work.
Any use of the Licensed Work in violation of this License will automatically
terminate your rights under this License for the current and all other
versions of the Licensed Work.
This License does not grant you any right in any trademark or logo of
Licensor or its affiliates (provided that you may use a trademark or logo of
Licensor as expressly required by this License).
TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON
AN "AS IS" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,
EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND
TITLE.

502
tf/README.md Normal file
View File

@@ -0,0 +1,502 @@
# Terraform Coder Development Environment
A comprehensive development environment deployment using Terraform and Coder, providing isolated workspaces with integrated development tools, databases, and AI-powered coding assistants.
## 🏗️ Architecture Overview
This configuration deploys self-contained development workspaces using Docker containers orchestrated by Coder. Each workspace includes:
- **Isolated Development Container** with VS Code, terminal access, and full development toolchain
- **Database Services** (PostgreSQL, Redis, Qdrant) with persistent storage
- **Management Interfaces** (pgAdmin, Qdrant Dashboard)
- **AI Development Tools** (Claude Code, Cursor, Windsurf support)
- **Reverse Proxy Integration** for seamless web access
### Network Architecture
```
┌─────────────────────────────────────────────────────────────┐
│ Reverse Proxy │
│ http://dev.lab │
│ *.dev.lab wildcard │
└─────────────────────────┬───────────────────────────────────┘
┌─────────────────────┼─────────────────────┐
│ Workspace A │ Workspace B │
│ network-{id-a} │ network-{id-b} │
│ │ │
│ ┌─────────────────┐ │ ┌─────────────────┐ │
│ │ Dev Container │ │ │ Dev Container │ │
│ │ VS Code:8080 │ │ │ VS Code:8080 │ │
│ └─────────────────┘ │ └─────────────────┘ │
│ │ │
│ ┌─────────────────┐ │ ┌─────────────────┐ │
│ │ PostgreSQL:5432 │ │ │ PostgreSQL:5432 │ │
│ │ Redis:6379 │ │ │ Redis:6379 │ │
│ │ Qdrant:6333 │ │ │ Qdrant:6333 │ │
│ │ pgAdmin:5050 │ │ │ pgAdmin:5050 │ │
│ └─────────────────┘ │ └─────────────────┘ │
└─────────────────────┼─────────────────────┘
```
**Key Benefits:**
-**Complete Network Isolation** between workspaces
-**No Port Conflicts** - same ports used in different networks
-**Scalable** - unlimited concurrent workspaces
-**Secure** - services only accessible through authenticated Coder session
## 📁 File Structure
```
tf/
├── README.md # This file
├── main.tf # Provider config, parameters, networks, volumes
├── variables.tf # All configurable parameters
├── terraform.tfvars # Variable assignments
├── workspace.tf # Main development container and Coder agent
├── services.tf # Database containers (PostgreSQL, Redis, Qdrant)
├── apps.tf # Coder applications for service access
├── scripts.tf # AI tools installation and configuration
├── outputs.tf # Workspace information exports
└── scripts/ # External shell scripts (prevents CRLF issues)
├── workspace-setup.sh # Main workspace initialization
├── claude-install.sh # Claude Code CLI installation
├── cursor-setup.sh # Cursor IDE configuration
├── windsurf-setup.sh # Windsurf IDE configuration
├── dev-tools.sh # Development tools installation
└── git-hooks.sh # Git hooks and metadata setup
```
## 🛠️ Included Services & Tools
### Development Environment
- **Container Base**: Microsoft DevContainers Universal image
- **Languages**: Node.js 20, Python 3.12, Rust (latest stable)
- **Package Managers**: npm, uv (Python), Cargo (Rust)
- **System Tools**: make, tree, jq, curl, wget, build-essential
### Database Services
- **PostgreSQL 17** with Alpine Linux base
- Connection pooling and performance optimization
- pg_stat_statements enabled for query analysis
- PostgreSQL client tools included in workspace
- **Redis 7** with Alpine Linux base
- Authentication enabled with configurable password
- AOF persistence with everysec fsync
- LRU eviction policy with configurable memory limits
- **Qdrant Vector Database** (latest)
- HTTP API on port 6333, gRPC on port 6334
- Persistent storage for vector collections
- Web dashboard for collection management
### Management Interfaces
- **pgAdmin 4** - PostgreSQL administration interface
- **Qdrant Dashboard** - Vector database management
- **VS Code Server** - Browser-based IDE
- **Terminal Access** - Full bash shell access
### AI Development Tools
- **Claude Code CLI** - Anthropic's official CLI
- **Cursor Support** - AI-powered code editor integration
- **Windsurf Support** - Codeium's development environment
### Development Packages
#### Node.js (Global)
```javascript
repomix, create-next-app, nodemon, concurrently
@types/node, typescript, eslint, prettier
```
#### Python (via uv)
```python
fastapi, uvicorn, requests, pandas, numpy
psycopg2-binary, redis, qdrant-client, python-dotenv
```
## 🗂️ Script Architecture
### External Shell Scripts Approach
This configuration uses **external shell scripts** instead of Terraform heredocs for better maintainability and cross-platform compatibility:
**Benefits:**
-**No CRLF Issues** - Shell scripts handle line endings correctly
-**Version Control Friendly** - Better diffs and change tracking
-**IDE Support** - Syntax highlighting and linting for shell scripts
-**Testable** - Scripts can be tested independently of Terraform
-**Maintainable** - Easier to read and modify than embedded heredocs
### Script Files
| Script | Purpose | When It Runs |
|--------|---------|--------------|
| `workspace-setup.sh` | Main environment initialization | Workspace startup |
| `claude-install.sh` | Claude Code CLI installation | If AI tools enabled |
| `cursor-setup.sh` | Cursor IDE configuration | If AI tools enabled |
| `windsurf-setup.sh` | Windsurf IDE configuration | If AI tools enabled |
| `dev-tools.sh` | Additional development tools | Always |
| `git-hooks.sh` | Git hooks and metadata capture | Always |
### Testing Scripts Independently
You can test individual scripts before deployment:
```bash
# Test workspace setup (as root in container)
sudo bash scripts/workspace-setup.sh
# Test Claude Code installation (as coder user)
sudo -u coder bash scripts/claude-install.sh
# Test development tools installation
sudo bash scripts/dev-tools.sh
```
## 🚀 Quick Start
### Prerequisites
1. **Coder Instance** running and accessible
2. **Reverse Proxy** configured with wildcard subdomain support
3. **Docker** daemon accessible to Coder
4. **Terraform** >= 1.0 installed
### Environment Setup
Set these environment variables in your Coder deployment:
```bash
CODER_ACCESS_URL=http://dev.lab
CODER_WILDCARD_ACCESS_URL=*.dev.lab
```
### Deployment Steps
1. **Clone and Navigate**
```bash
git clone <your-repo>
cd tf/
```
2. **Fix Line Endings (Important for Windows/WSL users)**
```bash
# Convert all files to Unix line endings
# This prevents bash execution errors in containers
find . -name "*.tf" -exec dos2unix {} \;
find . -name "*.sh" -exec dos2unix {} \;
```
**Note**: This configuration uses external shell scripts (in `scripts/` directory) instead of Terraform heredocs to prevent CRLF line ending issues when copying from Windows environments. The shell scripts are more maintainable and testable than embedded heredocs.
3. **Review Configuration**
```bash
# Edit terraform.tfvars to match your needs
vim terraform.tfvars
```
4. **Deploy Infrastructure**
```bash
terraform init
terraform plan
terraform apply
```
4. **Access Workspace**
- Navigate to your Coder instance
- Create new workspace using this template
- Select your preferred Git repository
- Choose whether to enable database services
## ⚙️ Configuration
### Key Variables (terraform.tfvars)
#### Resource Limits
```hcl
workspace_memory_limit = 16384 # 16GB RAM
workspace_cpu_limit = 4 # 4 CPU cores
```
#### Service Configuration
```hcl
# Database passwords (change in production!)
postgres_password = "devpassword"
redis_password = "devpassword"
# Database tuning
postgres_max_connections = 100
redis_max_memory = "512mb"
```
#### Feature Toggles
```hcl
enable_pgadmin = true # PostgreSQL admin interface
enable_monitoring = true # Resource monitoring
enable_jupyter = false # Jupyter Lab for data science
```
#### Tool Versions
```hcl
node_version = "20" # Node.js LTS
python_version = "3.12" # Python latest stable
postgres_version = "17" # PostgreSQL latest
redis_version = "7" # Redis latest stable
```
### Coder Parameters
When creating a workspace, you'll be prompted for:
1. **Git Repository** - Select from your available repositories
2. **Enable Services** - Toggle database services on/off
3. **Enable AI Tools** - Toggle AI development tool installation
## 🌐 Service Access
### Web Applications
All services are accessible through Coder's reverse proxy with subdomain routing:
| Service | URL Pattern | Description |
|---------|-------------|-------------|
| VS Code | `code-server-{workspace}.dev.lab` | Browser-based IDE |
| Terminal | Available in Coder dashboard | Full bash shell |
| pgAdmin | `pgadmin-{workspace}.dev.lab` | PostgreSQL management |
| Qdrant | `qdrant-dashboard-{workspace}.dev.lab` | Vector DB dashboard |
| Dev Server | `nextjs-3000-{workspace}.dev.lab` | Next.js dev server |
| API Server | `api-8000-{workspace}.dev.lab` | FastAPI/Flask server |
| Vite Dev | `vite-5173-{workspace}.dev.lab` | Vite development |
### Database Connections
From within your workspace container:
```bash
# PostgreSQL
export POSTGRES_URL="postgresql://postgres:devpassword@postgres-{workspace-id}:5432/postgres"
psql $POSTGRES_URL
# Redis
export REDIS_URL="redis://:devpassword@redis-{workspace-id}:6379"
redis-cli -u $REDIS_URL
# Qdrant
export QDRANT_URL="http://qdrant-{workspace-id}:6333"
curl $QDRANT_URL/health
```
### Environment Variables
These are automatically set in your workspace:
```bash
NODE_VERSION=20
PYTHON_VERSION=3.12
POSTGRES_URL=postgresql://postgres:***@postgres-{id}:5432/postgres
REDIS_URL=redis://:***@redis-{id}:6379
QDRANT_URL=http://qdrant-{id}:6333
```
## 🔧 Development Workflow
### Initial Setup
1. **Access Workspace**
```bash
# Run environment info script
devinfo
```
2. **Verify Services**
```bash
# Check PostgreSQL
pg_isready -h postgres-{workspace-id} -U postgres
# Check Redis
redis-cli -h redis-{workspace-id} ping
# Check Qdrant
curl http://qdrant-{workspace-id}:6333/health
```
### Common Tasks
#### Next.js Project
```bash
# Create new Next.js app
npx create-next-app@latest my-app
cd my-app
npm run dev # Accessible at nextjs-3000-{workspace}.dev.lab
```
#### Python FastAPI Project
```bash
# Activate Python environment
source /home/coder/.venv/bin/activate
# Create FastAPI app
uv add fastapi uvicorn
# Your app runs on port 8000, accessible via reverse proxy
```
#### Database Development
```bash
# Connect to PostgreSQL
psql $POSTGRES_URL
# Create tables, run migrations, etc.
# Access pgAdmin for GUI management
```
## 🔍 Monitoring & Debugging
### Built-in Monitoring
Coder automatically tracks:
- **CPU Usage** - Updated every 60 seconds
- **RAM Usage** - Updated every 60 seconds
- **Disk Usage** - Updated every 5 minutes
- **Git Branch** - Updated every 5 minutes
### Health Checks
All services include comprehensive health checks:
- **PostgreSQL**: `pg_isready` command
- **Redis**: Connection test with `redis-cli`
- **Qdrant**: HTTP health endpoint
- **Web Services**: HTTP response verification
### Logs and Debugging
```bash
# Container logs
docker logs postgres-{workspace-id}
docker logs redis-{workspace-id}
docker logs qdrant-{workspace-id}
# Service status
docker ps --filter label=coder.workspace_id={workspace-id}
# Network inspection
docker network inspect coder-{workspace-id}
```
## 🔐 Security Considerations
### Network Security
- **Isolated Networks** - Each workspace has its own Docker network
- **No Host Exposure** - Services only accessible through authenticated Coder session
- **Internal Communication** - Services communicate using internal DNS names
### Authentication
- **Database Passwords** - Configurable via terraform.tfvars
- **Coder Authentication** - All access requires Coder login
- **sudo Access** - Granted to `coder` user for development flexibility
### Data Persistence
- **Database Data** - Persistent Docker volumes per workspace
- **Workspace Files** - Persistent across container restarts
- **User Configuration** - Home directory persistence
## 🚨 Troubleshooting
### Common Issues
#### "Unable to find user coder"
**Solution**: Container automatically creates `coder` user during startup. If issues persist, check container logs.
#### Port Already in Use
**Solution**: This configuration uses no host port mappings. All routing is handled internally.
#### Services Not Accessible
**Solutions**:
1. Verify reverse proxy wildcard configuration
2. Check Coder environment variables:
```bash
echo $CODER_ACCESS_URL
echo $CODER_WILDCARD_ACCESS_URL
```
3. Confirm service health via Coder dashboard
#### Database Connection Issues
**Solutions**:
1. Verify service is enabled in workspace parameters
2. Check container status: `docker ps`
3. Test internal connectivity: `curl http://postgres-{id}:5432`
### Debug Commands
```bash
# Environment information
devinfo
# Network connectivity
docker network ls | grep coder
docker network inspect coder-{workspace-id}
# Service health
curl http://qdrant-{workspace-id}:6333/health
pg_isready -h postgres-{workspace-id} -U postgres
redis-cli -h redis-{workspace-id} ping
# Container status
docker ps --filter label=coder.workspace_id={workspace-id}
```
## 🔄 Updates & Maintenance
### Updating Tool Versions
1. **Modify terraform.tfvars**
```hcl
node_version = "22" # Update Node.js version
python_version = "3.13" # Update Python version
```
2. **Apply Changes**
```bash
terraform plan
terraform apply
```
3. **Restart Workspaces** - Changes apply to new workspace instances
### Adding New Services
1. **Add to services.tf** - Define new container resource
2. **Add to apps.tf** - Create Coder app for access
3. **Update variables.tf** - Add configuration options
4. **Update startup script** in workspace.tf if needed
## 🤝 Contributing
### Adding New Features
1. Follow the existing file structure and naming conventions
2. Add proper health checks for new services
3. Update this README with new service documentation
4. Test with multiple concurrent workspaces
### Best Practices
- **Resource Labels** - All resources should include `coder.workspace_id` label
- **Network Isolation** - New services should join workspace network
- **No Host Ports** - Use internal networking only
- **Health Checks** - All web services need health check endpoints
- **Persistent Data** - Use Docker volumes for data that should survive restarts
## 📚 References
- [Coder Documentation](https://coder.com/docs)
- [Terraform Docker Provider](https://registry.terraform.io/providers/kreuzwerker/docker/latest/docs)
- [PostgreSQL Docker Hub](https://hub.docker.com/_/postgres)
- [Redis Docker Hub](https://hub.docker.com/_/redis)
- [Qdrant Documentation](https://qdrant.tech/documentation/)
## 📝 License
This configuration is provided as-is for development purposes. Modify passwords and security settings for production use.
---
**🚀 Happy Coding!** Your isolated development environment is ready for productive development with full database support and AI-powered tools.

250
tf/apps.tf Normal file
View File

@@ -0,0 +1,250 @@
# =============================================================================
# Coder Applications - Service Access Points
# Web interfaces and tools for development services
# =============================================================================
# =============================================================================
# IDE and Code Editor Access
# =============================================================================
# VS Code Server
resource "coder_app" "code_server" {
agent_id = coder_agent.main.id
slug = "code-server"
display_name = "VS Code"
url = "http://localhost:8080"
icon = "/icon/code.svg"
subdomain = true
share = "owner"
healthcheck {
url = "http://localhost:8080/healthz"
interval = 10
threshold = 5
}
}
# Terminal Access
resource "coder_app" "terminal" {
agent_id = coder_agent.main.id
slug = "terminal"
display_name = "Terminal"
icon = "/icon/terminal.svg"
command = "bash"
}
# =============================================================================
# Database Management Interfaces
# =============================================================================
# pgAdmin - PostgreSQL Administration
resource "coder_app" "pgadmin" {
count = data.coder_parameter.enable_services.value && var.enable_pgadmin ? 1 : 0
agent_id = coder_agent.main.id
slug = "pgadmin"
display_name = "pgAdmin"
url = "http://localhost:${var.pgadmin_port}"
icon = "/icon/postgresql.svg"
subdomain = true
share = "owner"
healthcheck {
url = "http://localhost:${var.pgadmin_port}/misc/ping"
interval = 15
threshold = 5
}
}
# Qdrant Dashboard - Vector Database Management
resource "coder_app" "qdrant" {
count = data.coder_parameter.enable_services.value ? 1 : 0
agent_id = coder_agent.main.id
slug = "qdrant-dashboard"
display_name = "Qdrant Dashboard"
url = "http://localhost:6333/dashboard"
icon = "/icon/database.svg"
subdomain = true
share = "owner"
healthcheck {
url = "http://localhost:6333/health"
interval = 20
threshold = 5
}
}
# =============================================================================
# Development Server Ports
# =============================================================================
# Next.js Development Server (default port 3000)
resource "coder_app" "nextjs_dev" {
agent_id = coder_agent.main.id
slug = "nextjs-3000"
display_name = "Next.js Dev Server"
url = "http://localhost:3000"
icon = "/icon/nextjs.svg"
subdomain = true
share = "owner"
healthcheck {
url = "http://localhost:3000"
interval = 10
threshold = 10
}
}
# Generic Development Server (port 3000)
resource "coder_app" "dev_server_3000" {
agent_id = coder_agent.main.id
slug = "dev-3000"
display_name = "Dev Server (3000)"
url = "http://localhost:3000"
icon = "/icon/web.svg"
subdomain = true
share = "owner"
healthcheck {
url = "http://localhost:3000"
interval = 10
threshold = 10
}
}
# API Server - FastAPI/Flask (port 8000)
resource "coder_app" "api_server_8000" {
agent_id = coder_agent.main.id
slug = "api-8000"
display_name = "API Server (8000)"
url = "http://localhost:8000"
icon = "/icon/api.svg"
subdomain = true
share = "owner"
healthcheck {
url = "http://localhost:8000/health"
interval = 10
threshold = 10
}
}
# Vite Development Server (port 5173)
resource "coder_app" "vite_dev" {
agent_id = coder_agent.main.id
slug = "vite-5173"
display_name = "Vite Dev Server"
url = "http://localhost:5173"
icon = "/icon/web.svg"
subdomain = true
share = "owner"
healthcheck {
url = "http://localhost:5173"
interval = 10
threshold = 10
}
}
# Rust Development Server (port 8080)
resource "coder_app" "rust_server" {
agent_id = coder_agent.main.id
slug = "rust-8080"
display_name = "Rust Server (8080)"
url = "http://localhost:8080"
icon = "/icon/rust.svg"
subdomain = true
share = "owner"
healthcheck {
url = "http://localhost:8080/health"
interval = 10
threshold = 10
}
}
# =============================================================================
# Data Science and Analytics Tools
# =============================================================================
# Jupyter Lab (if enabled)
resource "coder_app" "jupyter" {
count = var.enable_jupyter ? 1 : 0
agent_id = coder_agent.main.id
slug = "jupyter"
display_name = "Jupyter Lab"
url = "http://localhost:8888"
icon = "/icon/jupyter.svg"
subdomain = true
share = "owner"
healthcheck {
url = "http://localhost:8888"
interval = 15
threshold = 10
}
}
# =============================================================================
# Utility and Management Applications
# =============================================================================
# Environment Information
resource "coder_app" "env_info" {
agent_id = coder_agent.main.id
slug = "env-info"
display_name = "Environment Info"
icon = "/icon/info.svg"
command = "devinfo"
}
# Database Connection Tester
resource "coder_app" "db_tester" {
count = data.coder_parameter.enable_services.value ? 1 : 0
agent_id = coder_agent.main.id
slug = "db-tester"
display_name = "Database Tester"
icon = "/icon/terminal.svg"
command = "bash"
}
# Development Logs Viewer
resource "coder_app" "dev_logs" {
agent_id = coder_agent.main.id
slug = "dev-logs"
display_name = "Development Logs"
icon = "/icon/terminal.svg"
command = "bash"
}
# Git Repository Manager
resource "coder_app" "git_manager" {
agent_id = coder_agent.main.id
slug = "git"
display_name = "Git Repository"
icon = "/icon/git.svg"
command = "bash"
}
# =============================================================================
# AI Development Tools Access
# =============================================================================
# Claude Code CLI Access
resource "coder_app" "claude_code" {
count = data.coder_parameter.enable_ai_tools.value && var.install_claude_code ? 1 : 0
agent_id = coder_agent.main.id
slug = "claude-code"
display_name = "Claude Code"
icon = "/icon/claude.svg"
command = "claude"
}
# File Manager
resource "coder_app" "file_manager" {
agent_id = coder_agent.main.id
slug = "files"
display_name = "File Manager"
icon = "/icon/folder.svg"
command = "bash"
}

176
tf/main.tf Normal file
View File

@@ -0,0 +1,176 @@
terraform {
required_version = ">= 1.0"
required_providers {
coder = {
source = "coder/coder"
version = "~> 2.0"
}
docker = {
source = "kreuzwerker/docker"
version = "~> 2.25"
}
envbuilder = {
source = "coder/envbuilder"
version = "~> 1.0"
}
}
}
provider "coder" {}
provider "docker" {
host = var.docker_socket != "" ? var.docker_socket : null
}
provider "envbuilder" {}
# Data Sources
data "coder_provisioner" "me" {}
data "coder_workspace" "me" {}
data "coder_workspace_owner" "me" {}
# Parameters
data "coder_parameter" "repo" {
name = "repo"
display_name = "Repository"
description = "Select a repository to clone"
mutable = true
order = 1
option {
name = "Custom Development Environment"
description = "Full-stack development with all services"
value = "custom"
}
option {
name = "vercel/next.js"
description = "The React Framework"
value = "https://github.com/vercel/next.js"
}
option {
name = "Custom URL"
description = "Specify a custom repo URL below"
value = "custom-url"
}
}
data "coder_parameter" "custom_repo_url" {
name = "custom_repo_url"
display_name = "Custom Repository URL"
description = "Enter a custom repository URL"
default = ""
mutable = true
order = 2
}
data "coder_parameter" "enable_services" {
name = "enable_services"
display_name = "Enable Database Services"
description = "Enable PostgreSQL, Redis, Qdrant, and Docker Registry"
type = "bool"
default = "true"
mutable = true
order = 3
}
data "coder_parameter" "enable_ai_tools" {
name = "enable_ai_tools"
display_name = "Enable AI Assistant Tools"
description = "Install Claude Code and AI development tools"
type = "bool"
default = "true"
mutable = true
order = 4
}
# Local Variables
locals {
# Container and workspace naming
container_name = "coder-${data.coder_workspace_owner.me.name}-${lower(data.coder_workspace.me.name)}"
workspace_id = data.coder_workspace.me.id
# Git configuration
git_author_name = coalesce(data.coder_workspace_owner.me.full_name, data.coder_workspace_owner.me.name)
git_author_email = data.coder_workspace_owner.me.email
# Repository URL logic
repo_url = (
data.coder_parameter.repo.value == "custom" ? "https://github.com/coder/envbuilder" :
data.coder_parameter.repo.value == "custom-url" ? data.coder_parameter.custom_repo_url.value :
data.coder_parameter.repo.value
)
# Development container image with all required tools
devcontainer_image = var.devcontainer_image
# Environment variables for the development container
dev_environment = {
# Git configuration
"GIT_AUTHOR_NAME" = local.git_author_name
"GIT_AUTHOR_EMAIL" = local.git_author_email
"GIT_COMMITTER_NAME" = local.git_author_name
"GIT_COMMITTER_EMAIL" = local.git_author_email
# Development tools
"NODE_VERSION" = var.node_version
"PYTHON_VERSION" = var.python_version
"RUST_VERSION" = "stable"
# Service URLs (when services are enabled)
"POSTGRES_URL" = data.coder_parameter.enable_services.value ? "postgresql://postgres:${var.postgres_password}@postgres-${local.workspace_id}:5432/postgres" : ""
"REDIS_URL" = data.coder_parameter.enable_services.value ? "redis://:${var.redis_password}@redis-${local.workspace_id}:6379" : ""
"QDRANT_URL" = data.coder_parameter.enable_services.value ? "http://qdrant-${local.workspace_id}:6333" : ""
# Development configuration
"EDITOR" = "code"
"PYTHONPATH" = "/workspaces"
"CARGO_HOME" = "/home/coder/.cargo"
"RUSTUP_HOME" = "/home/coder/.rustup"
}
# Legacy service URLs for backward compatibility
postgres_url = "postgresql://postgres:${var.postgres_password}@postgres-${local.workspace_id}:5432/postgres"
redis_url = "redis://:${var.redis_password}@redis-${local.workspace_id}:6379"
qdrant_url = "http://qdrant-${local.workspace_id}:6333"
}
# Docker Network
resource "docker_network" "workspace" {
name = "coder-${local.workspace_id}"
driver = "bridge"
labels {
label = "coder.workspace_id"
value = local.workspace_id
}
labels {
label = "coder.owner"
value = data.coder_workspace_owner.me.name
}
labels {
label = "coder.project"
value = var.project_name
}
}
# Workspace Volume
resource "docker_volume" "workspaces" {
name = "workspaces-${local.workspace_id}"
labels {
label = "coder.workspace_id"
value = local.workspace_id
}
labels {
label = "coder.owner"
value = data.coder_workspace_owner.me.name
}
labels {
label = "coder.type"
value = "workspace-data"
}
}
# Development Container Image
resource "docker_image" "devcontainer" {
name = local.devcontainer_image
keep_locally = true
}

118
tf/outputs.tf Normal file
View File

@@ -0,0 +1,118 @@
# =============================================================================
# Terraform Outputs
# Expose important values for reference and external use
# =============================================================================
# =============================================================================
# Workspace Information
# =============================================================================
output "workspace_id" {
description = "Unique identifier for the Coder workspace"
value = local.workspace_id
}
output "workspace_name" {
description = "Name of the Coder workspace"
value = data.coder_workspace.me.name
}
output "workspace_owner" {
description = "Owner of the Coder workspace"
value = data.coder_workspace_owner.me.name
}
output "container_name" {
description = "Name of the main development container"
value = local.container_name
}
# =============================================================================
# Git Configuration
# =============================================================================
output "git_author_name" {
description = "Git author name configured for the workspace"
value = local.git_author_name
}
output "git_author_email" {
description = "Git author email configured for the workspace"
value = local.git_author_email
sensitive = true
}
output "repository_url" {
description = "Repository URL that will be cloned"
value = local.repo_url
}
# =============================================================================
# Service Connection Information
# =============================================================================
output "postgres_connection_url" {
description = "PostgreSQL connection URL for applications"
value = data.coder_parameter.enable_services.value ? local.postgres_url : null
sensitive = true
}
output "redis_connection_url" {
description = "Redis connection URL for applications"
value = data.coder_parameter.enable_services.value ? local.redis_url : null
sensitive = true
}
output "qdrant_api_url" {
description = "Qdrant vector database API URL"
value = data.coder_parameter.enable_services.value ? local.qdrant_url : null
}
# =============================================================================
# Network Information
# =============================================================================
output "docker_network_name" {
description = "Name of the Docker network for service communication"
value = docker_network.workspace.name
}
output "workspace_volume_name" {
description = "Name of the persistent workspace volume"
value = docker_volume.workspaces.name
}
# =============================================================================
# Development Environment Information
# =============================================================================
output "development_tools" {
description = "Information about installed development tools"
value = {
node_version = var.node_version
python_version = var.python_version
container_image = local.devcontainer_image
}
}
output "service_status" {
description = "Status of optional development services"
value = {
services_enabled = data.coder_parameter.enable_services.value
ai_tools_enabled = data.coder_parameter.enable_ai_tools.value
pgadmin_enabled = var.enable_pgadmin
jupyter_enabled = var.enable_jupyter
}
}
# =============================================================================
# Access Information
# =============================================================================
output "external_ports" {
description = "External ports exposed for services"
value = data.coder_parameter.enable_services.value ? {
pgadmin = var.enable_pgadmin ? var.pgadmin_port : null
} : {}
}

72
tf/scripts.tf Normal file
View File

@@ -0,0 +1,72 @@
# =============================================================================
# Provisioning Scripts - AI Development Tools and Extensions
# Installation scripts for Cursor, Claude Code, Windsurf support
# =============================================================================
# =============================================================================
# Claude Code CLI Installation
# =============================================================================
resource "coder_script" "claude_code_setup" {
count = data.coder_parameter.enable_ai_tools.value && var.install_claude_code ? 1 : 0
agent_id = coder_agent.main.id
display_name = "Install Claude Code CLI"
icon = "/icon/claude.svg"
run_on_start = true
script = file("${path.module}/scripts/claude-install.sh")
}
# =============================================================================
# Cursor IDE Support Setup
# =============================================================================
resource "coder_script" "cursor_setup" {
count = data.coder_parameter.enable_ai_tools.value && var.install_cursor_support ? 1 : 0
agent_id = coder_agent.main.id
display_name = "Configure Cursor IDE Support"
icon = "/icon/cursor.svg"
run_on_start = true
script = file("${path.module}/scripts/cursor-setup.sh")
}
# =============================================================================
# Windsurf IDE Support Setup
# =============================================================================
resource "coder_script" "windsurf_setup" {
count = data.coder_parameter.enable_ai_tools.value && var.install_windsurf_support ? 1 : 0
agent_id = coder_agent.main.id
display_name = "Configure Windsurf IDE Support"
icon = "/icon/windsurf.svg"
run_on_start = true
script = file("${path.module}/scripts/windsurf-setup.sh")
}
# =============================================================================
# Development Tools and Extensions
# =============================================================================
resource "coder_script" "dev_extensions" {
agent_id = coder_agent.main.id
display_name = "Install Development Tools"
icon = "/icon/tools.svg"
run_on_start = true
script = file("${path.module}/scripts/dev-tools.sh")
}
# =============================================================================
# Git Hooks and Metadata Capture Setup
# =============================================================================
resource "coder_script" "git_hooks_setup" {
agent_id = coder_agent.main.id
display_name = "Setup Git Hooks"
icon = "/icon/git.svg"
run_on_start = true
script = file("${path.module}/scripts/git-hooks.sh")
}

67
tf/scripts/claude-install.sh Executable file
View File

@@ -0,0 +1,67 @@
#!/bin/bash
set -e
echo "🤖 Installing Claude Code CLI..."
# Check if already installed
if command -v claude >/dev/null 2>&1; then
echo "✅ Claude Code already installed"
claude --version || echo "Claude Code version check failed"
exit 0
fi
# Ensure npm is available
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"
if ! command -v npm >/dev/null 2>&1; then
echo "❌ npm not found - Node.js installation required"
exit 1
fi
echo "📥 Installing Claude Code globally via npm..."
npm install -g @anthropic-ai/claude
# Verify installation
if command -v claude >/dev/null 2>&1; then
echo "✅ Claude Code installed successfully!"
echo "🔧 Run 'claude auth login' to authenticate"
echo "💡 Use 'claude chat' for interactive assistance"
echo "💡 Use 'claude edit <file>' to edit files with AI"
# Create helper script
mkdir -p /home/coder/bin
cat > /home/coder/bin/claude-help << 'CLAUDE_HELP_END'
#!/bin/bash
echo "🤖 Claude Code AI Assistant"
echo "=========================="
echo ""
echo "Authentication:"
echo " claude auth login # Authenticate with Anthropic"
echo " claude auth logout # Sign out"
echo " claude auth whoami # Check current user"
echo ""
echo "Interactive Chat:"
echo " claude chat # Start interactive session"
echo " claude chat 'question' # Single question"
echo ""
echo "File Editing:"
echo " claude edit file.py # AI-powered file editing"
echo " claude edit --help # Edit command options"
echo ""
echo "Code Analysis:"
echo " claude analyze . # Analyze current directory"
echo " claude review file.py # Code review"
echo ""
echo "Project Operations:"
echo " claude init # Initialize Claude in project"
echo " claude status # Show project status"
echo ""
echo "💡 For full documentation: https://docs.anthropic.com/claude/docs"
CLAUDE_HELP_END
chmod +x /home/coder/bin/claude-help
echo "💡 Run 'claude-help' for quick reference"
else
echo "❌ Claude Code installation failed"
exit 1
fi

182
tf/scripts/cursor-setup.sh Executable file
View File

@@ -0,0 +1,182 @@
#!/bin/bash
set -e
echo "🎯 Setting up Cursor IDE support..."
# Create Cursor configuration directories
mkdir -p /home/coder/.cursor-server/data/User
mkdir -p /home/coder/.cursor-server/extensions
# Create optimized Cursor settings
cat > /home/coder/.cursor-server/data/User/settings.json << 'CURSOR_SETTINGS_END'
{
"workbench.colorTheme": "Dark+ (default dark)",
"editor.fontSize": 14,
"editor.tabSize": 2,
"editor.insertSpaces": true,
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll": true,
"source.organizeImports": true
},
"files.autoSave": "afterDelay",
"files.autoSaveDelay": 1000,
"terminal.integrated.fontSize": 13,
"git.enableSmartCommit": true,
"git.confirmSync": false,
"python.defaultInterpreterPath": "/home/coder/.venv/bin/python",
"python.linting.enabled": true,
"python.linting.pylintEnabled": false,
"python.linting.flake8Enabled": true,
"typescript.preferences.includePackageJsonAutoImports": "auto",
"javascript.preferences.includePackageJsonAutoImports": "auto",
"cursor.chat.showInEditorContextMenu": true,
"cursor.chat.alwaysShowInEditorContextMenu": true,
"cursor.general.enableWindowAIFeatures": true
}
CURSOR_SETTINGS_END
# Create development tasks configuration
mkdir -p /home/coder/.cursor-server/data/User
cat > /home/coder/.cursor-server/data/User/tasks.json << 'CURSOR_TASKS_END'
{
"version": "2.0.0",
"tasks": [
{
"label": "Dev Server",
"type": "shell",
"command": "npm run dev",
"group": "build",
"presentation": {
"echo": true,
"reveal": "always",
"focus": false,
"panel": "new"
},
"problemMatcher": []
},
{
"label": "Python Dev Server",
"type": "shell",
"command": "uvicorn main:app --reload --host 0.0.0.0 --port 8000",
"group": "build",
"presentation": {
"echo": true,
"reveal": "always",
"focus": false,
"panel": "new"
},
"problemMatcher": []
},
{
"label": "Install Dependencies",
"type": "shell",
"command": "npm install",
"group": "build",
"presentation": {
"echo": true,
"reveal": "always",
"focus": false,
"panel": "new"
}
},
{
"label": "Python Install",
"type": "shell",
"command": "uv pip install -r requirements.txt",
"group": "build",
"presentation": {
"echo": true,
"reveal": "always",
"focus": false,
"panel": "new"
}
}
]
}
CURSOR_TASKS_END
# Create useful code snippets
mkdir -p /home/coder/.cursor-server/data/User/snippets
cat > /home/coder/.cursor-server/data/User/snippets/global.code-snippets << 'CURSOR_SNIPPETS_END'
{
"FastAPI Basic App": {
"prefix": "fastapi-app",
"body": [
"from fastapi import FastAPI",
"from fastapi.middleware.cors import CORSMiddleware",
"",
"app = FastAPI(title=\"${1:My API}\", version=\"0.1.0\")",
"",
"app.add_middleware(",
" CORSMiddleware,",
" allow_origins=[\"*\"],",
" allow_credentials=True,",
" allow_methods=[\"*\"],",
" allow_headers=[\"*\"],",
")",
"",
"@app.get(\"/\")",
"async def root():",
" return {\"message\": \"${2:Hello World}\"}",
"",
"@app.get(\"/health\")",
"async def health():",
" return {\"status\": \"healthy\"}",
"",
"if __name__ == \"__main__\":",
" import uvicorn",
" uvicorn.run(app, host=\"0.0.0.0\", port=8000)"
],
"description": "FastAPI basic application template"
},
"Next.js API Route": {
"prefix": "nextapi",
"body": [
"import { NextRequest, NextResponse } from 'next/server';",
"",
"export async function ${1:GET}(request: NextRequest) {",
" try {",
" // Your API logic here",
" return NextResponse.json({ message: '${2:Success}' });",
" } catch (error) {",
" return NextResponse.json(",
" { error: 'Internal Server Error' },",
" { status: 500 }",
" );",
" }",
"}"
],
"description": "Next.js API route template"
},
"Database Connection": {
"prefix": "db-connect",
"body": [
"import os",
"from sqlalchemy import create_engine",
"from sqlalchemy.orm import sessionmaker",
"",
"DATABASE_URL = os.getenv(",
" \"POSTGRES_URL\",",
" \"postgresql://postgres:password@localhost:5432/postgres\"",
")",
"",
"engine = create_engine(DATABASE_URL)",
"SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)",
"",
"def get_db():",
" db = SessionLocal()",
" try:",
" yield db",
" finally:",
" db.close()"
],
"description": "Database connection setup"
}
}
CURSOR_SNIPPETS_END
# Set proper ownership
chown -R coder:coder /home/coder/.cursor-server
echo "✅ Cursor IDE support configured"
echo "🎯 Cursor will use optimized settings for this development environment"

120
tf/scripts/dev-tools.sh Executable file
View File

@@ -0,0 +1,120 @@
#!/bin/bash
set -e
echo "🔧 Installing development extensions and tools..."
# Ensure we're running as root for system packages
if [ "$EUID" -ne 0 ]; then
echo "This script needs to run as root for system package installation"
exit 1
fi
echo "📦 Installing additional CLI tools..."
# Ensure curl is available first
type -p curl >/dev/null || (apt-get update && apt-get install curl -y)
# Function to install various development tools
install_development_tools() {
echo "🛠️ Installing development utilities..."
# GitHub CLI
if ! command -v gh &> /dev/null; then
echo "📥 Installing GitHub CLI..."
curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg
chmod go+r /usr/share/keyrings/githubcli-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | tee /etc/apt/sources.list.d/github-cli.list > /dev/null
apt-get update
apt-get install gh -y
fi
# Docker Compose (if not already installed)
if ! command -v docker-compose &> /dev/null; then
echo "🐳 Installing Docker Compose..."
curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
fi
# Lazygit for better git UI
if ! command -v lazygit &> /dev/null; then
echo "🌿 Installing lazygit..."
LAZYGIT_VERSION=$(curl -s "https://api.github.com/repos/jesseduffield/lazygit/releases/latest" | grep '"tag_name":' | sed -E 's/.*"v*([^"]+)".*/\1/')
curl -Lo lazygit.tar.gz "https://github.com/jesseduffield/lazygit/releases/latest/download/lazygit_${LAZYGIT_VERSION}_Linux_x86_64.tar.gz"
tar xf lazygit.tar.gz lazygit
install lazygit /usr/local/bin
rm lazygit.tar.gz lazygit
fi
# btop for system monitoring
if ! command -v btop &> /dev/null; then
echo "📊 Installing btop..."
apt-get install btop -y
fi
# fd-find for better file searching
if ! command -v fd &> /dev/null; then
echo "🔍 Installing fd-find..."
apt-get install fd-find -y
# Create symlink for easier usage
ln -sf /usr/bin/fdfind /usr/local/bin/fd
fi
# ripgrep for better text searching
if ! command -v rg &> /dev/null; then
echo "🔎 Installing ripgrep..."
apt-get install ripgrep -y
fi
# bat for better cat with syntax highlighting
if ! command -v bat &> /dev/null; then
echo "🦇 Installing bat..."
apt-get install bat -y
# Create symlink for easier usage
ln -sf /usr/bin/batcat /usr/local/bin/bat
fi
# eza for better ls (modern replacement for exa)
if ! command -v eza &> /dev/null; then
echo "📁 Installing eza..."
curl -L "https://github.com/eza-community/eza/releases/latest/download/eza_x86_64-unknown-linux-gnu.tar.gz" | tar xz -C /usr/local/bin
fi
}
# Install all development tools
install_development_tools
# Switch to coder user for user-specific installations
echo "👤 Setting up user-specific tools..."
su - coder << 'USER_SETUP_END'
# Add useful aliases to .bashrc if not already present
if ! grep -q "# Development tools aliases" ~/.bashrc; then
cat >> ~/.bashrc << 'ALIASES_END'
# Development tools aliases
alias cat='bat'
alias ls='eza'
alias ll='eza -la'
alias la='eza -la'
alias find='fd'
alias grep='rg'
alias git-ui='lazygit'
alias top='btop'
ALIASES_END
fi
# Install tldr for better man pages
if ! command -v tldr &> /dev/null; then
npm install -g tldr
fi
# Install fkill for better process management
if ! command -v fkill &> /dev/null; then
npm install -g fkill-cli
fi
echo "✅ Development tools installed and configured!"
USER_SETUP_END
echo "🎉 All development tools installed successfully!"
echo "💡 Available tools: gh, docker-compose, lazygit, btop, fd, rg, bat, eza, tldr, fkill"
echo "💡 Aliases configured: cat→bat, ls→eza, find→fd, grep→rg, git-ui→lazygit, top→btop"

83
tf/scripts/git-hooks.sh Executable file
View File

@@ -0,0 +1,83 @@
#!/bin/bash
set -e
echo "📝 Setting up Git hooks and metadata capture..."
# Ensure we're in the workspaces directory
cd /workspaces
# Initialize git repository if it doesn't exist
if [ ! -d ".git" ]; then
echo "🔧 Initializing git repository..."
git init
fi
# Create .git/hooks directory if it doesn't exist
mkdir -p .git/hooks
# Create post-commit hook for metadata capture
cat > .git/hooks/post-commit << 'POST_COMMIT_END'
#!/bin/bash
# Post-commit hook to capture git metadata
echo "📝 Capturing git metadata after commit..."
# Ensure metadata directory exists
mkdir -p /tmp/git-metadata
# Capture current git state
git branch --show-current > /tmp/git-metadata/current-branch 2>/dev/null || echo "main" > /tmp/git-metadata/current-branch
git rev-parse HEAD > /tmp/git-metadata/commit-hash 2>/dev/null || echo "no-commits" > /tmp/git-metadata/commit-hash
git remote get-url origin > /tmp/git-metadata/remote-url 2>/dev/null || echo "no-remote" > /tmp/git-metadata/remote-url
# Log the commit for development tracking
echo "$(date): Commit $(git rev-parse --short HEAD) on branch $(git branch --show-current)" >> /tmp/git-metadata/commit-log
echo "✅ Git metadata updated"
POST_COMMIT_END
# Make post-commit hook executable
chmod +x .git/hooks/post-commit
# Create pre-push hook for quality checks
cat > .git/hooks/pre-push << 'PRE_PUSH_END'
#!/bin/bash
# Pre-push hook for basic quality checks
echo "🔍 Running pre-push quality checks..."
# Check if package.json exists and run tests
if [ -f "package.json" ]; then
echo "📦 Found Node.js project, checking scripts..."
if npm run --silent test --if-present; then
echo "✅ Tests passed"
else
echo "⚠️ Tests not found or failed - pushing anyway"
fi
fi
# Check if requirements.txt or pyproject.toml exists
if [ -f "requirements.txt" ] || [ -f "pyproject.toml" ]; then
echo "🐍 Found Python project..."
# Could add Python linting here
echo "✅ Python project checks passed"
fi
# Check for large files
echo "📁 Checking for large files..."
large_files=$(find . -type f -size +100M 2>/dev/null | head -5)
if [ ! -z "$large_files" ]; then
echo "⚠️ Large files detected:"
echo "$large_files"
echo "Consider using Git LFS for large files"
fi
echo "✅ Pre-push checks completed"
PRE_PUSH_END
# Make pre-push hook executable
chmod +x .git/hooks/pre-push
# Set proper ownership for the coder user
chown -R coder:coder .git/hooks
echo "✅ Git hooks and metadata capture configured"
echo "📝 Git metadata will be automatically captured on commits"
echo "🔍 Pre-push quality checks will run before each push"

66
tf/scripts/windsurf-setup.sh Executable file
View File

@@ -0,0 +1,66 @@
#!/bin/bash
set -e
echo "🌊 Setting up Windsurf IDE support..."
# Create Windsurf configuration directories
mkdir -p /home/coder/.windsurf/data/User
mkdir -p /home/coder/.windsurf/extensions
# Create optimized Windsurf settings
cat > /home/coder/.windsurf/data/User/settings.json << 'WINDSURF_SETTINGS_END'
{
"workbench.colorTheme": "Windsurf Dark",
"editor.fontSize": 14,
"editor.tabSize": 2,
"editor.insertSpaces": true,
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll": true,
"source.organizeImports": true
},
"files.autoSave": "afterDelay",
"files.autoSaveDelay": 1000,
"terminal.integrated.fontSize": 13,
"git.enableSmartCommit": true,
"git.confirmSync": false,
"python.defaultInterpreterPath": "/home/coder/.venv/bin/python",
"python.linting.enabled": true,
"python.linting.pylintEnabled": false,
"python.linting.flake8Enabled": true,
"typescript.preferences.includePackageJsonAutoImports": "auto",
"javascript.preferences.includePackageJsonAutoImports": "auto",
"windsurf.ai.enabled": true,
"windsurf.ai.showInEditorContextMenu": true,
"windsurf.chat.enabled": true,
"windsurf.codeCompletion.enabled": true
}
WINDSURF_SETTINGS_END
# Create development keybindings
cat > /home/coder/.windsurf/data/User/keybindings.json << 'WINDSURF_KEYS_END'
[
{
"key": "ctrl+shift+a",
"command": "windsurf.chat.open"
},
{
"key": "ctrl+shift+c",
"command": "windsurf.ai.generateCode"
},
{
"key": "ctrl+shift+r",
"command": "windsurf.ai.refactorSelection"
},
{
"key": "ctrl+shift+e",
"command": "windsurf.ai.explainCode"
}
]
WINDSURF_KEYS_END
# Set proper ownership
chown -R coder:coder /home/coder/.windsurf
echo "✅ Windsurf IDE support configured"
echo "🌊 Windsurf AI features enabled with optimized settings"
echo "⌨️ Keyboard shortcuts: Ctrl+Shift+A (chat), Ctrl+Shift+C (generate), Ctrl+Shift+R (refactor)"

243
tf/scripts/workspace-setup.sh Executable file
View File

@@ -0,0 +1,243 @@
#!/bin/bash
set -e
echo "🚀 Initializing development environment as user: $(whoami)"
# =============================================================================
# Create coder user if it doesn't exist
# =============================================================================
if ! id -u coder >/dev/null 2>&1; then
echo "👤 Creating coder user..."
useradd -m -s /bin/bash -u 1000 coder
usermod -aG sudo coder
echo "coder ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
fi
# =============================================================================
# Create necessary directories
# =============================================================================
echo "📁 Creating user directories..."
mkdir -p /home/coder/bin
mkdir -p /home/coder/.local/bin
mkdir -p /home/coder/.config
mkdir -p /tmp/git-metadata
mkdir -p /workspaces
# Ensure proper ownership
chown -R coder:coder /home/coder /workspaces
# =============================================================================
# Switch to coder user for remaining operations
# =============================================================================
echo "🔄 Switching to coder user context..."
export HOME=/home/coder
export USER=coder
# =============================================================================
# Git Configuration
# =============================================================================
echo "⚙️ Configuring Git..."
git config --global user.name "${GIT_AUTHOR_NAME}"
git config --global user.email "${GIT_AUTHOR_EMAIL}"
git config --global commit.gpgsign false
git config --global tag.gpgsign false
git config --global init.defaultBranch main
git config --global pull.rebase false
# Capture and log git information
echo "📝 Capturing Git metadata..."
cd /workspaces
if [ -d ".git" ]; then
git branch --show-current > /tmp/git-metadata/current-branch 2>/dev/null || echo "main" > /tmp/git-metadata/current-branch
git rev-parse HEAD > /tmp/git-metadata/commit-hash 2>/dev/null || echo "no-commits" > /tmp/git-metadata/commit-hash
git remote get-url origin > /tmp/git-metadata/remote-url 2>/dev/null || echo "no-remote" > /tmp/git-metadata/remote-url
else
echo "no-repo" > /tmp/git-metadata/current-branch
echo "no-repo" > /tmp/git-metadata/commit-hash
echo "no-repo" > /tmp/git-metadata/remote-url
fi
# =============================================================================
# System Package Updates and Installation
# =============================================================================
echo "📦 Installing system packages..."
export DEBIAN_FRONTEND=noninteractive
apt-get update -qq
apt-get install -y make tree jq curl wget unzip build-essential postgresql-client redis-tools
# =============================================================================
# Node.js and npm Setup (as coder user)
# =============================================================================
echo "🟢 Setting up Node.js and npm..."
# Create Node.js setup script
cat > /tmp/node_setup.sh << 'NODE_SCRIPT_END'
#!/bin/bash
if ! command -v nvm &> /dev/null; then
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash
export NVM_DIR="/home/coder/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"
fi
export NVM_DIR="/home/coder/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"
nvm install ${NODE_VERSION}
nvm use ${NODE_VERSION}
nvm alias default ${NODE_VERSION}
echo "📦 Installing npm packages..."
npm install -g repomix create-next-app nodemon concurrently @types/node typescript eslint prettier
npm install -g create-next-app@latest
NODE_SCRIPT_END
chmod +x /tmp/node_setup.sh
su - coder -c "/tmp/node_setup.sh"
rm /tmp/node_setup.sh
# =============================================================================
# Python Setup with uv (as coder user)
# =============================================================================
echo "🐍 Setting up Python and uv..."
# Install Python version
apt-get install -y python${PYTHON_VERSION} python${PYTHON_VERSION}-dev python${PYTHON_VERSION}-venv
# Create Python setup script
cat > /tmp/python_setup.sh << 'PYTHON_SCRIPT_END'
#!/bin/bash
curl -LsSf https://astral.sh/uv/install.sh | sh
export PATH="/home/coder/.cargo/bin:$PATH"
echo "📦 Installing Python packages with uv..."
for package in fastapi uvicorn requests pandas numpy psycopg2-binary redis qdrant-client python-dotenv; do
uv tool install $package || echo "Failed to install $package"
done
uv venv /home/coder/.venv --python=${PYTHON_VERSION}
echo 'source /home/coder/.venv/bin/activate' >> /home/coder/.bashrc
PYTHON_SCRIPT_END
chmod +x /tmp/python_setup.sh
su - coder -c "/tmp/python_setup.sh"
rm /tmp/python_setup.sh
# =============================================================================
# Rust and Cargo Setup (as coder user)
# =============================================================================
echo "🦀 Installing Rust and Cargo..."
# Create Rust setup script
cat > /tmp/rust_setup.sh << 'RUST_SCRIPT_END'
#!/bin/bash
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable
source "/home/coder/.cargo/env"
echo 'export PATH="/home/coder/.cargo/bin:$PATH"' >> /home/coder/.bashrc
cargo install cargo-watch cargo-edit cargo-audit
RUST_SCRIPT_END
chmod +x /tmp/rust_setup.sh
su - coder -c "/tmp/rust_setup.sh"
rm /tmp/rust_setup.sh
# =============================================================================
# repomix Installation (as coder user)
# =============================================================================
echo "📁 Installing repomix..."
su - coder -c "npm install -g repomix"
# =============================================================================
# Shell Configuration (as coder user)
# =============================================================================
echo "🐚 Setting up shell environment..."
# Create devinfo script
cat > /tmp/devinfo_script.sh << 'DEVINFO_SCRIPT_END'
#!/bin/bash
mkdir -p /home/coder/bin
cat > /home/coder/bin/devinfo << 'DEVINFO_END'
#!/bin/bash
echo '🚀 Development Environment Info'
echo '==============================='
echo ''
echo '🔧 Installed Tools:'
echo ' Node.js: '$(node --version 2>/dev/null || echo 'Not found')
echo ' npm: '$(npm --version 2>/dev/null || echo 'Not found')
echo ' Python: '$(python${PYTHON_VERSION} --version 2>/dev/null || echo 'Not found')
echo ' uv: '$(uv --version 2>/dev/null || echo 'Not found')
echo ' Rust: '$(rustc --version 2>/dev/null || echo 'Not found')
echo ' Cargo: '$(cargo --version 2>/dev/null || echo 'Not found')
echo ' repomix: '$(repomix --version 2>/dev/null || echo 'Not found')
echo ''
echo '🗄️ Database Services:'
if [ "${ENABLE_SERVICES}" = "true" ]; then
echo ' PostgreSQL: '${POSTGRES_URL}
echo ' Redis: '${REDIS_URL}
echo ' Qdrant: '${QDRANT_URL}
else
echo ' Services disabled'
fi
echo ''
echo '📝 Git Metadata:'
if [ -f /tmp/git-metadata/current-branch ]; then
echo ' Branch: '$(cat /tmp/git-metadata/current-branch)
echo ' Commit: '$(cat /tmp/git-metadata/commit-hash)
echo ' Remote: '$(cat /tmp/git-metadata/remote-url)
fi
DEVINFO_END
chmod +x /home/coder/bin/devinfo
DEVINFO_SCRIPT_END
chmod +x /tmp/devinfo_script.sh
su - coder -c "/tmp/devinfo_script.sh"
rm /tmp/devinfo_script.sh
# Create bashrc aliases script
cat > /tmp/bashrc_setup.sh << 'BASHRC_SCRIPT_END'
#!/bin/bash
cat >> /home/coder/.bashrc << 'BASHRC_END'
# Development Environment Aliases
alias ll='ls -alF'
alias la='ls -A'
alias l='ls -CF'
alias gs='git status'
alias gp='git push'
alias gc='git commit'
alias gco='git checkout'
alias gb='git branch'
# Development workflow shortcuts
alias devinfo='/home/coder/bin/devinfo'
# Package managers
alias pip='uv pip'
alias python='python${PYTHON_VERSION}'
# Docker shortcuts
alias dps='docker ps'
alias dimg='docker images'
alias dlog='docker logs'
BASHRC_END
BASHRC_SCRIPT_END
chmod +x /tmp/bashrc_setup.sh
su - coder -c "/tmp/bashrc_setup.sh"
rm /tmp/bashrc_setup.sh
# =============================================================================
# Final Environment Setup
# =============================================================================
echo "✅ Development environment initialization complete!"
echo ""
echo "🎉 Available tools:"
echo " - Node.js ${NODE_VERSION} with npm packages"
echo " - Python ${PYTHON_VERSION} with uv package manager"
echo " - Rust with Cargo"
echo " - repomix for repository packaging"
echo " - make, tree, and other build tools"
if [ "${ENABLE_SERVICES}" = "true" ]; then
echo " - PostgreSQL, Redis, Qdrant databases"
fi
echo ""
echo "🔧 Run 'devinfo' for detailed environment information"
echo "🚀 Ready for development!"

322
tf/services.tf Normal file
View File

@@ -0,0 +1,322 @@
# =============================================================================
# Service Containers - Database and Development Services
# PostgreSQL, Redis, Qdrant, Docker Registry
# =============================================================================
# =============================================================================
# PostgreSQL Database Service
# =============================================================================
# PostgreSQL data volume for persistence
resource "docker_volume" "postgres_data" {
count = data.coder_parameter.enable_services.value ? 1 : 0
name = "postgres-data-${local.workspace_id}"
labels {
label = "coder.service"
value = "postgres"
}
labels {
label = "coder.workspace_id"
value = local.workspace_id
}
}
# PostgreSQL container
resource "docker_container" "postgres" {
count = data.coder_parameter.enable_services.value ? 1 : 0
image = "postgres:${var.postgres_version}-alpine"
name = "postgres-${local.workspace_id}"
# PostgreSQL configuration
env = [
"POSTGRES_DB=postgres",
"POSTGRES_USER=postgres",
"POSTGRES_PASSWORD=${var.postgres_password}",
"POSTGRES_INITDB_ARGS=--auth-local=trust --auth-host=md5",
"POSTGRES_SHARED_PRELOAD_LIBRARIES=pg_stat_statements",
"POSTGRES_MAX_CONNECTIONS=${var.postgres_max_connections}"
]
# Network configuration
networks_advanced {
name = docker_network.workspace.name
}
# Data persistence
volumes {
volume_name = docker_volume.postgres_data[0].name
container_path = "/var/lib/postgresql/data"
}
# Health check
healthcheck {
test = ["CMD-SHELL", "pg_isready -U postgres"]
interval = "15s"
timeout = "5s"
retries = 5
}
restart = "unless-stopped"
labels {
label = "coder.service"
value = "postgres"
}
labels {
label = "coder.workspace_id"
value = local.workspace_id
}
}
# =============================================================================
# Redis Cache Service
# =============================================================================
# Redis data volume for persistence
resource "docker_volume" "redis_data" {
count = data.coder_parameter.enable_services.value ? 1 : 0
name = "redis-data-${local.workspace_id}"
labels {
label = "coder.service"
value = "redis"
}
labels {
label = "coder.workspace_id"
value = local.workspace_id
}
}
# Redis container
resource "docker_container" "redis" {
count = data.coder_parameter.enable_services.value ? 1 : 0
image = "redis:${var.redis_version}-alpine"
name = "redis-${local.workspace_id}"
# Redis configuration with authentication
command = [
"redis-server",
"--requirepass", var.redis_password,
"--appendonly", "yes",
"--appendfsync", "everysec",
"--maxmemory", var.redis_max_memory,
"--maxmemory-policy", "allkeys-lru"
]
networks_advanced {
name = docker_network.workspace.name
}
# Data persistence
volumes {
volume_name = docker_volume.redis_data[0].name
container_path = "/data"
}
# Health check
healthcheck {
test = ["CMD", "redis-cli", "--raw", "incr", "ping"]
interval = "15s"
timeout = "3s"
retries = 5
}
restart = "unless-stopped"
labels {
label = "coder.service"
value = "redis"
}
labels {
label = "coder.workspace_id"
value = local.workspace_id
}
}
# =============================================================================
# Qdrant Vector Database Service
# =============================================================================
# Qdrant data volume for persistence
resource "docker_volume" "qdrant_data" {
count = data.coder_parameter.enable_services.value ? 1 : 0
name = "qdrant-data-${local.workspace_id}"
labels {
label = "coder.service"
value = "qdrant"
}
labels {
label = "coder.workspace_id"
value = local.workspace_id
}
}
# Qdrant container
resource "docker_container" "qdrant" {
count = data.coder_parameter.enable_services.value ? 1 : 0
image = "qdrant/qdrant:${var.qdrant_version}"
name = "qdrant-${local.workspace_id}"
# Qdrant configuration
env = [
"QDRANT__SERVICE__HTTP_PORT=6333",
"QDRANT__SERVICE__GRPC_PORT=6334",
"QDRANT__LOG_LEVEL=INFO"
]
networks_advanced {
name = docker_network.workspace.name
}
# Ports accessible within workspace network - no host exposure needed
# Data persistence
volumes {
volume_name = docker_volume.qdrant_data[0].name
container_path = "/qdrant/storage"
}
# Health check
healthcheck {
test = ["CMD", "curl", "-f", "http://localhost:6333/health"]
interval = "20s"
timeout = "5s"
retries = 5
}
restart = "unless-stopped"
labels {
label = "coder.service"
value = "qdrant"
}
labels {
label = "coder.workspace_id"
value = local.workspace_id
}
}
# =============================================================================
# pgAdmin for PostgreSQL Management (Optional)
# =============================================================================
# pgAdmin data volume
resource "docker_volume" "pgadmin_data" {
count = data.coder_parameter.enable_services.value && var.enable_pgadmin ? 1 : 0
name = "pgadmin-data-${local.workspace_id}"
labels {
label = "coder.service"
value = "pgadmin"
}
labels {
label = "coder.workspace_id"
value = local.workspace_id
}
}
# pgAdmin container
resource "docker_container" "pgadmin" {
count = data.coder_parameter.enable_services.value && var.enable_pgadmin ? 1 : 0
image = "dpage/pgadmin4:latest"
name = "pgadmin-${local.workspace_id}"
# pgAdmin configuration
env = [
"PGADMIN_DEFAULT_EMAIL=${var.pgadmin_email}",
"PGADMIN_DEFAULT_PASSWORD=${var.pgadmin_password}",
"PGADMIN_CONFIG_SERVER_MODE=False",
"PGADMIN_CONFIG_MASTER_PASSWORD_REQUIRED=False",
"PGADMIN_LISTEN_PORT=80"
]
networks_advanced {
name = docker_network.workspace.name
}
# Port accessible within workspace network - no host exposure needed
# Data persistence
volumes {
volume_name = docker_volume.pgadmin_data[0].name
container_path = "/var/lib/pgadmin"
}
restart = "unless-stopped"
labels {
label = "coder.service"
value = "pgadmin"
}
labels {
label = "coder.workspace_id"
value = local.workspace_id
}
}
# =============================================================================
# Jupyter Lab Service (Optional for Data Science)
# =============================================================================
# Jupyter data volume
resource "docker_volume" "jupyter_data" {
count = var.enable_jupyter ? 1 : 0
name = "jupyter-data-${local.workspace_id}"
labels {
label = "coder.service"
value = "jupyter"
}
labels {
label = "coder.workspace_id"
value = local.workspace_id
}
}
# Jupyter Lab container
resource "docker_container" "jupyter" {
count = var.enable_jupyter ? 1 : 0
image = "jupyter/scipy-notebook:latest"
name = "jupyter-${local.workspace_id}"
# Jupyter configuration
env = [
"JUPYTER_ENABLE_LAB=yes",
"JUPYTER_TOKEN=",
"RESTARTABLE=yes",
"JUPYTER_PORT=8888"
]
networks_advanced {
name = docker_network.workspace.name
}
# Port accessible within workspace network - no host exposure needed
# Data persistence
volumes {
volume_name = docker_volume.jupyter_data[0].name
container_path = "/home/jovyan/work"
}
# Share workspace volume
volumes {
volume_name = docker_volume.workspaces.name
container_path = "/home/jovyan/workspaces"
read_only = false
}
restart = "unless-stopped"
labels {
label = "coder.service"
value = "jupyter"
}
labels {
label = "coder.workspace_id"
value = local.workspace_id
}
}

BIN
tf/terraform Executable file

Binary file not shown.

2321
tf/terraform.tfstate Normal file

File diff suppressed because one or more lines are too long

2321
tf/terraform.tfstate.backup Normal file

File diff suppressed because one or more lines are too long

105
tf/terraform.tfvars Normal file
View File

@@ -0,0 +1,105 @@
# =============================================================================
# Terraform Variables Configuration
# Variable assignments for the development environment
# =============================================================================
# =============================================================================
# Project Configuration
# =============================================================================
project_name = "dev-environment"
environment = "dev"
# =============================================================================
# Docker Configuration
# =============================================================================
docker_socket = ""
devcontainer_image = "mcr.microsoft.com/devcontainers/universal:2-linux"
# =============================================================================
# Development Tool Versions
# =============================================================================
node_version = "20"
python_version = "3.12"
postgres_version = "17"
redis_version = "7"
qdrant_version = "latest"
# =============================================================================
# Service Configuration
# =============================================================================
postgres_password = "devpassword"
redis_password = "devpassword"
postgres_max_connections = 100
redis_max_memory = "512mb"
# =============================================================================
# Network Configuration
# =============================================================================
pgadmin_port = 5050
pgadmin_email = "admin@dev.local"
pgadmin_password = "adminpassword"
# =============================================================================
# Development Packages
# =============================================================================
npm_packages = [
"repomix",
"create-next-app",
"nodemon",
"concurrently",
"@types/node",
"typescript",
"eslint",
"prettier"
]
python_packages = [
"fastapi",
"uvicorn",
"requests",
"pandas",
"numpy",
"psycopg2-binary",
"redis",
"qdrant-client",
"python-dotenv"
]
system_packages = [
"make",
"tree",
"jq",
"curl",
"wget",
"unzip",
"build-essential"
]
# =============================================================================
# AI Development Tools
# =============================================================================
install_claude_code = true
install_cursor_support = true
install_windsurf_support = true
# =============================================================================
# Performance Configuration
# =============================================================================
workspace_memory_limit = 16384
workspace_cpu_limit = 4
# =============================================================================
# Feature Toggles
# =============================================================================
enable_pgadmin = true
enable_monitoring = true
enable_jupyter = false
# =============================================================================
# Common Tags
# =============================================================================
common_tags = {
Environment = "development"
ManagedBy = "terraform"
Purpose = "remote-development"
}

BIN
tf/terraform.zip Normal file

Binary file not shown.

322
tf/variables.tf Normal file
View File

@@ -0,0 +1,322 @@
# =============================================================================
# Variable Definitions
# Modular Development Environment Configuration
# =============================================================================
# =============================================================================
# Project Configuration
# =============================================================================
variable "project_name" {
description = "Name of the project for resource tagging and identification"
type = string
default = "dev-environment"
validation {
condition = can(regex("^[a-z0-9-]+$", var.project_name))
error_message = "Project name must contain only lowercase letters, numbers, and hyphens."
}
}
variable "environment" {
description = "Environment designation (dev, staging, prod)"
type = string
default = "dev"
validation {
condition = contains(["dev", "staging", "prod"], var.environment)
error_message = "Environment must be one of: dev, staging, prod."
}
}
# =============================================================================
# Docker Configuration
# =============================================================================
variable "docker_socket" {
description = "Docker daemon socket URI (empty for default)"
type = string
default = ""
}
variable "devcontainer_image" {
description = "Development container image with all required tools pre-installed"
type = string
default = "mcr.microsoft.com/devcontainers/universal:2-linux"
}
# =============================================================================
# Development Tool Versions
# =============================================================================
variable "node_version" {
description = "Node.js version to install"
type = string
default = "20"
validation {
condition = contains(["18", "20", "21"], var.node_version)
error_message = "Node.js version must be one of: 18, 20, 21."
}
}
variable "python_version" {
description = "Python version to install"
type = string
default = "3.12"
validation {
condition = contains(["3.10", "3.11", "3.12"], var.python_version)
error_message = "Python version must be 3.10, 3.11, or 3.12."
}
}
variable "postgres_version" {
description = "PostgreSQL version"
type = string
default = "17"
validation {
condition = contains(["13", "14", "15", "16", "17"], var.postgres_version)
error_message = "PostgreSQL version must be one of: 13, 14, 15, 16, 17."
}
}
variable "redis_version" {
description = "Redis version"
type = string
default = "7"
validation {
condition = contains(["6", "7"], var.redis_version)
error_message = "Redis version must be 6 or 7."
}
}
variable "qdrant_version" {
description = "Qdrant vector database version"
type = string
default = "latest"
}
# =============================================================================
# Service Configuration
# =============================================================================
variable "postgres_password" {
description = "PostgreSQL postgres user password"
type = string
default = "devpassword"
sensitive = true
validation {
condition = length(var.postgres_password) >= 8
error_message = "PostgreSQL password must be at least 8 characters long."
}
}
variable "redis_password" {
description = "Redis authentication password"
type = string
default = "devpassword"
sensitive = true
validation {
condition = length(var.redis_password) >= 8
error_message = "Redis password must be at least 8 characters long."
}
}
variable "postgres_max_connections" {
description = "Maximum PostgreSQL connections"
type = number
default = 100
validation {
condition = var.postgres_max_connections >= 20 && var.postgres_max_connections <= 1000
error_message = "PostgreSQL max connections must be between 20 and 1000."
}
}
variable "redis_max_memory" {
description = "Redis maximum memory (e.g., '256mb', '1gb')"
type = string
default = "512mb"
validation {
condition = can(regex("^[0-9]+[kmg]b$", var.redis_max_memory))
error_message = "Redis max memory must be in format like '256mb' or '1gb'."
}
}
# =============================================================================
# Network Configuration
# =============================================================================
variable "pgadmin_port" {
description = "pgAdmin web interface port"
type = number
default = 5050
validation {
condition = var.pgadmin_port >= 1024 && var.pgadmin_port <= 65535
error_message = "pgAdmin port must be between 1024 and 65535."
}
}
variable "pgadmin_email" {
description = "pgAdmin login email"
type = string
default = "admin@dev.local"
validation {
condition = can(regex("^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$", var.pgadmin_email))
error_message = "pgAdmin email must be a valid email address."
}
}
variable "pgadmin_password" {
description = "pgAdmin login password"
type = string
default = "adminpassword"
sensitive = true
validation {
condition = length(var.pgadmin_password) >= 8
error_message = "pgAdmin password must be at least 8 characters long."
}
}
# =============================================================================
# Development Packages
# =============================================================================
variable "npm_packages" {
description = "Global npm packages to install"
type = list(string)
default = [
"repomix", # Repository packaging tool
"create-next-app", # Next.js app generator
"nodemon", # Development server auto-reload
"concurrently", # Run multiple commands
"@types/node", # Node.js TypeScript types
"typescript", # TypeScript compiler
"eslint", # JavaScript linter
"prettier" # Code formatter
]
}
variable "python_packages" {
description = "Python packages to install via uv"
type = list(string)
default = [
"fastapi", # Modern web framework
"uvicorn", # ASGI server
"requests", # HTTP library
"pandas", # Data manipulation
"numpy", # Numerical computing
"psycopg2-binary", # PostgreSQL adapter
"redis", # Redis client
"qdrant-client", # Qdrant vector database client
"python-dotenv" # Environment variable loading
]
}
variable "system_packages" {
description = "Additional system packages to install"
type = list(string)
default = [
"make", # Build tool
"tree", # Directory tree viewer
"jq", # JSON processor
"curl", # HTTP client
"wget", # File downloader
"unzip", # Archive extractor
"build-essential" # Compilation tools
]
}
# =============================================================================
# AI Development Tools
# =============================================================================
variable "install_claude_code" {
description = "Install Claude Code CLI for AI assistance"
type = bool
default = true
}
variable "install_cursor_support" {
description = "Install Cursor IDE support and extensions"
type = bool
default = true
}
variable "install_windsurf_support" {
description = "Install Windsurf IDE support"
type = bool
default = false
}
# =============================================================================
# Performance Configuration
# =============================================================================
variable "workspace_memory_limit" {
description = "Memory limit for workspace container (MB)"
type = number
default = 8192
validation {
condition = var.workspace_memory_limit >= 2048 && var.workspace_memory_limit <= 32768
error_message = "Workspace memory limit must be between 2048MB (2GB) and 32768MB (32GB)."
}
}
variable "workspace_cpu_limit" {
description = "CPU limit for workspace container (cores)"
type = number
default = 4
validation {
condition = var.workspace_cpu_limit >= 1 && var.workspace_cpu_limit <= 16
error_message = "Workspace CPU limit must be between 1 and 16 cores."
}
}
# =============================================================================
# Feature Toggles
# =============================================================================
variable "enable_pgadmin" {
description = "Enable pgAdmin web interface (resource intensive)"
type = bool
default = true
}
variable "enable_monitoring" {
description = "Enable container monitoring and metrics collection"
type = bool
default = false
}
variable "enable_jupyter" {
description = "Enable Jupyter Lab for data science workflows"
type = bool
default = false
}
# =============================================================================
# Common Tags
# =============================================================================
variable "common_tags" {
description = "Common tags to apply to all resources"
type = map(string)
default = {
Environment = "development"
ManagedBy = "terraform"
Purpose = "remote-development"
}
}

157
tf/workspace.tf Normal file
View File

@@ -0,0 +1,157 @@
# =============================================================================
# Development Workspace Container
# Main development environment with all required tools
# =============================================================================
# =============================================================================
# Coder Agent - Workspace Management
# =============================================================================
resource "coder_agent" "main" {
arch = data.coder_provisioner.me.arch
os = "linux"
dir = "/workspaces"
# Environment variables for development
env = {
"GIT_AUTHOR_NAME" = local.git_author_name
"GIT_AUTHOR_EMAIL" = local.git_author_email
"GIT_COMMITTER_NAME" = local.git_author_name
"GIT_COMMITTER_EMAIL" = local.git_author_email
"NODE_VERSION" = var.node_version
"PYTHON_VERSION" = var.python_version
"PATH" = "$PATH:/home/coder/.cargo/bin:/home/coder/.local/bin:/usr/local/bin"
"HOME" = "/home/coder"
"USER" = "coder"
# Service URLs for development
"POSTGRES_URL" = data.coder_parameter.enable_services.value ? "postgresql://postgres:${var.postgres_password}@postgres-${local.workspace_id}:5432/postgres" : ""
"REDIS_URL" = data.coder_parameter.enable_services.value ? "redis://:${var.redis_password}@redis-${local.workspace_id}:6379" : ""
"QDRANT_URL" = data.coder_parameter.enable_services.value ? "http://qdrant-${local.workspace_id}:6333" : ""
# Additional environment variables for scripts
"ENABLE_SERVICES" = tostring(data.coder_parameter.enable_services.value)
}
# Load startup script from external file
startup_script = file("${path.module}/scripts/workspace-setup.sh")
# Performance and resource monitoring
metadata {
display_name = "CPU Usage"
key = "cpu_usage"
script = "coder stat cpu"
interval = 60
timeout = 10
}
metadata {
display_name = "RAM Usage"
key = "ram_usage"
script = "coder stat mem"
interval = 60
timeout = 10
}
metadata {
display_name = "Disk Usage"
key = "disk_usage"
script = "coder stat disk --path /workspaces"
interval = 300
timeout = 10
}
metadata {
display_name = "Git Branch"
key = "git_branch"
script = "cd /workspaces && git branch --show-current 2>/dev/null || echo 'no-repo'"
interval = 300
timeout = 5
}
}
# =============================================================================
# Main Development Container
# =============================================================================
resource "docker_container" "workspace" {
count = data.coder_workspace.me.start_count
image = docker_image.devcontainer.image_id
name = local.container_name
hostname = data.coder_workspace.me.name
# Container resource limits
memory = var.workspace_memory_limit * 1024 * 1024 # Convert MB to bytes
# Environment variables
env = [
"GIT_AUTHOR_NAME=${local.git_author_name}",
"GIT_AUTHOR_EMAIL=${local.git_author_email}",
"GIT_COMMITTER_NAME=${local.git_author_name}",
"GIT_COMMITTER_EMAIL=${local.git_author_email}",
"NODE_VERSION=${var.node_version}",
"PYTHON_VERSION=${var.python_version}",
"CODER_AGENT_TOKEN=${coder_agent.main.token}"
]
# Network configuration
networks_advanced {
name = docker_network.workspace.name
}
# Host networking for Docker-in-Docker and reverse proxy support
host {
host = "host.docker.internal"
ip = "host-gateway"
}
# No port mappings needed - reverse proxy will handle routing
# All services run within the isolated workspace network
# Coder's port forwarding and apps will provide access via reverse proxy
# Volume mounts
volumes {
container_path = "/workspaces"
volume_name = docker_volume.workspaces.name
read_only = false
}
# Mount the existing coder-home volume for user data persistence
volumes {
container_path = "/home/coder"
volume_name = "bwk8ckcok8o84cc0o4os4sso_coder-home"
read_only = false
}
# Docker socket for Docker-in-Docker
volumes {
host_path = "/var/run/docker.sock"
container_path = "/var/run/docker.sock"
}
# Working directory
working_dir = "/workspaces"
# Keep container running
command = ["/bin/bash", "-c", "${coder_agent.main.init_script} && sleep infinity"]
# Container labels for management
labels {
label = "coder.owner"
value = data.coder_workspace_owner.me.name
}
labels {
label = "coder.workspace_id"
value = local.workspace_id
}
labels {
label = "coder.project"
value = var.project_name
}
# Dependencies
depends_on = [
docker_network.workspace,
docker_volume.workspaces,
docker_image.devcontainer
]
}

BIN
ui.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB