├── CONTRIBUTING.md ├── README.md ├── docker-stack.yml ├── nginx-proxy ├── README.md ├── docker-compose.yml ├── portainer-swarm.yml └── vhost.d │ └── dev.portainer └── traefik ├── README.md ├── docker-compose.yml └── edge.png /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing Guidelines 2 | 3 | Some basic conventions for contributing to this project. 4 | 5 | ### General 6 | 7 | Please make sure that there aren't existing pull requests attempting to address the issue mentioned. Likewise, please check for issues related to update, as someone else may be working on the issue in a branch or fork. 8 | 9 | * Non-trivial changes should be discussed in an issue first 10 | * Develop in a topic branch, not master 11 | 12 | ### Linting 13 | 14 | Please check your code using `grunt lint` before submitting your pull requests. 15 | 16 | ### Commit Message Format 17 | 18 | Each commit message should include a **type**, a **scope** and a **subject**: 19 | 20 | ``` 21 | (): 22 | ``` 23 | 24 | Lines should not exceed 100 characters. This allows the message to be easier to read on github as well as in various git tools and produces a nice, neat commit log ie: 25 | 26 | ``` 27 | #271 feat(superservice): add the service superservice 28 | #270 fix(nginx): fix an issue with nginx configuration 29 | #269 fix(network): add a missing option for the local network 30 | ``` 31 | 32 | #### Type 33 | 34 | Must be one of the following: 35 | 36 | * **feat**: A new feature 37 | * **fix**: A bug fix 38 | * **docs**: Documentation only changes 39 | * **style**: Changes that do not affect the meaning of the code (white-space, formatting, missing 40 | semi-colons, etc) 41 | * **refactor**: A code change that neither fixes a bug or adds a feature 42 | * **test**: Adding missing tests 43 | * **chore**: Changes to the build process or auxiliary tools and libraries such as documentation 44 | generation 45 | 46 | #### Scope 47 | 48 | The scope could be anything specifying place of the commit change. For example `networks`, 49 | `services`, `nginx` etc... 50 | 51 | #### Subject 52 | 53 | The subject contains succinct description of the change: 54 | 55 | * use the imperative, present tense: "change" not "changed" nor "changes" 56 | * don't capitalize first letter 57 | * no dot (.) at the end 58 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Portainer compose setup 2 | 3 | A simple setup to deploy Portainer using `docker-compose` or `docker stack deploy` (Swarm). 4 | 5 | ## Requirements 6 | 7 | 1. Install [Docker](http://docker.io). 8 | 2. (optional) Install [Docker-compose](http://docs.docker.com/compose/install/). 9 | 3. Clone this repository 10 | 11 | ## Usage 12 | 13 | ### Compose 14 | 15 | See `nginx-proxy/` or `traefik/` for Compose deployments. 16 | 17 | ### Swarm 18 | 19 | Deploy this stack on a manager node inside your Swarm cluster: 20 | 21 | ``` 22 | docker stack deploy --compose-file=docker-stack.yml portainer 23 | ``` 24 | 25 | You can then access Portainer by using the IP address of any node in your Swarm cluster over port 9000 with a web browser. 26 | -------------------------------------------------------------------------------- /docker-stack.yml: -------------------------------------------------------------------------------- 1 | version: '3.2' 2 | 3 | services: 4 | agent: 5 | image: portainer/agent 6 | environment: 7 | # REQUIRED: Should be equal to the service name prefixed by "tasks." when 8 | # deployed inside an overlay network 9 | AGENT_CLUSTER_ADDR: tasks.agent 10 | # AGENT_PORT: 9001 11 | # LOG_LEVEL: debug 12 | volumes: 13 | - /var/run/docker.sock:/var/run/docker.sock 14 | - /var/lib/docker/volumes:/var/lib/docker/volumes 15 | networks: 16 | - agent_network 17 | deploy: 18 | mode: global 19 | placement: 20 | constraints: [node.platform.os == linux] 21 | 22 | portainer: 23 | image: portainer/portainer 24 | command: -H tcp://tasks.agent:9001 --tlsskipverify 25 | ports: 26 | - "9000:9000" 27 | - "8000:8000" 28 | volumes: 29 | - portainer_data:/data 30 | networks: 31 | - agent_network 32 | deploy: 33 | mode: replicated 34 | replicas: 1 35 | placement: 36 | constraints: [node.role == manager] 37 | 38 | networks: 39 | agent_network: 40 | driver: overlay 41 | 42 | volumes: 43 | portainer_data: 44 | -------------------------------------------------------------------------------- /nginx-proxy/README.md: -------------------------------------------------------------------------------- 1 | # Usage 2 | 3 | This setup comes up with the [jwilder/nginx-proxy](https://github.com/jwilder/nginx-proxy) reverse proxy to access the Portainer instance via a virtual host. 4 | 5 | The default configuration will make Portainer available via the `portainer.dev` domain. If you wish to change this, update the `VIRTUAL_HOST` environment variable for the Portainer service in the `docker-compose.yml` file. 6 | 7 | You'll also need to rename the `vhost.d/dev.portainer` file to match your changes. 8 | 9 | Deploy this stack on any Docker node: 10 | 11 | ``` 12 | docker-compose up -d 13 | ``` 14 | 15 | And then access Portainer by hitting [http://dev.portainer](http://dev.portainer) (or your own domain if you updated it) with a web browser. 16 | 17 | **NOTE**: Your machine must be able to resolve `dev.portainer` (or your own domain if you updated it). 18 | -------------------------------------------------------------------------------- /nginx-proxy/docker-compose.yml: -------------------------------------------------------------------------------- 1 | 2 | version: "2" 3 | 4 | services: 5 | nginx-proxy: 6 | image: jwilder/nginx-proxy 7 | restart: always 8 | networks: 9 | - proxy 10 | ports: 11 | - "80:80" 12 | volumes: 13 | - "/var/run/docker.sock:/tmp/docker.sock:ro" 14 | - "./vhost.d:/etc/nginx/vhost.d:ro" 15 | 16 | portainer: 17 | image: portainer/portainer-ce:2.0.0 18 | command: -H unix:///var/run/docker.sock 19 | restart: always 20 | networks: 21 | - proxy 22 | environment: 23 | - VIRTUAL_HOST=portainer.yourdomain.com 24 | - VIRTUAL_PORT=9000 25 | ports: 26 | - 8000:8000 27 | volumes: 28 | - /var/run/docker.sock:/var/run/docker.sock 29 | - portainer_data:/data 30 | 31 | networks: 32 | proxy: 33 | 34 | volumes: 35 | portainer_data: 36 | -------------------------------------------------------------------------------- /nginx-proxy/portainer-swarm.yml: -------------------------------------------------------------------------------- 1 | version: '3.2' 2 | 3 | services: 4 | nginx-proxy: 5 | image: jwilder/nginx-proxy 6 | networks: 7 | - proxy 8 | ports: 9 | - "80:80" 10 | volumes: 11 | - "/var/run/docker.sock:/tmp/docker.sock:ro" 12 | - "./vhost.d:/etc/nginx/vhost.d:ro" 13 | 14 | agent: 15 | image: portainer/agent 16 | environment: 17 | # REQUIRED: Should be equal to the service name prefixed by "tasks." when 18 | # deployed inside an overlay network 19 | AGENT_CLUSTER_ADDR: tasks.agent 20 | # AGENT_PORT: 9001 21 | # LOG_LEVEL: debug 22 | volumes: 23 | - /var/run/docker.sock:/var/run/docker.sock 24 | - /var/lib/docker/volumes:/var/lib/docker/volumes 25 | networks: 26 | - agent_network 27 | deploy: 28 | mode: global 29 | placement: 30 | constraints: [node.platform.os == linux] 31 | 32 | portainer: 33 | image: portainer/portainer-ce:2.0.0 34 | command: -H tcp://tasks.agent:9001 --tlsskipverify 35 | volumes: 36 | - data:/data 37 | environment: 38 | - VIRTUAL_HOST=portainer.yourdomain.com 39 | - VIRTUAL_PORT=9000 40 | ports: 41 | - 8000:8000 42 | networks: 43 | - proxy 44 | - agent_network 45 | deploy: 46 | mode: replicated 47 | replicas: 1 48 | placement: 49 | constraints: [node.role == manager] 50 | 51 | 52 | networks: 53 | proxy: 54 | external: true 55 | agent_network: 56 | external: true 57 | 58 | volumes: 59 | data: -------------------------------------------------------------------------------- /nginx-proxy/vhost.d/dev.portainer: -------------------------------------------------------------------------------- 1 | proxy_set_header Upgrade $http_upgrade; 2 | proxy_set_header Connection "upgrade"; 3 | proxy_http_version 1.1; 4 | -------------------------------------------------------------------------------- /traefik/README.md: -------------------------------------------------------------------------------- 1 | # Usage 2 | 3 | This setup comes up with the [Traefik](https://github.com/containous/traefik) v2.2.8 reverse proxy to access the Portainer instance via a virtual host, has support for SSL certificates using Let's Encrypt and automatic redirection from http to https. 4 | 5 | The default configuration will make Portainer frontend available via the `portainer.yourdomain.com` domain. If you wish to change this, update the `traefik.http.routers.frontend.rule=Host(`portainer.yourdomain.com`)` label for the Portainer service in the `docker-compose.yml` file. 6 | 7 | If you're going to use Edge agents. When you set up the endpoint from Portainer Configuration, you need to change the Portainer Server URL setting to match with the label specified for Edge. In this sample, the URL specified for the Edge service is `traefik.http.routers.frontend.rule=Host(`edge.yourdomain.com`)`. 8 | 9 | ![Edge](/traefik/edge.png) 10 | 11 | Deploy this stack on any Docker node: 12 | 13 | ``` 14 | docker-compose up -d 15 | ``` 16 | 17 | And then access Portainer by hitting [http://portainer.yourdomain.com](http://portainer.yourdomain.com) with a web browser. 18 | 19 | **NOTE**: Your machine must be able to resolve `portainer.yourdomain.com` (or your own domain if you updated it). 20 | -------------------------------------------------------------------------------- /traefik/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "3.3" 2 | 3 | services: 4 | traefik: 5 | container_name: traefik 6 | image: "traefik:v2.2.8" 7 | command: 8 | - --entrypoints.web.address=:80 9 | - --entrypoints.websecure.address=:443 10 | - --providers.docker 11 | - --log.level=DEBUG 12 | - --certificatesresolvers.leresolver.acme.httpchallenge=true 13 | - --certificatesresolvers.leresolver.acme.email=your-email #Set your email address here, is for the generation of SSL certificates with Let's Encrypt. 14 | - --certificatesresolvers.leresolver.acme.storage=./acme.json 15 | - --certificatesresolvers.leresolver.acme.httpchallenge.entrypoint=web 16 | ports: 17 | - "80:80" 18 | - "443:443" 19 | volumes: 20 | - "/var/run/docker.sock:/var/run/docker.sock:ro" 21 | - "./acme.json:/acme.json" 22 | labels: 23 | - "traefik.http.routers.http-catchall.rule=hostregexp(`{host:.+}`)" 24 | - "traefik.http.routers.http-catchall.entrypoints=web" 25 | - "traefik.http.routers.http-catchall.middlewares=redirect-to-https" 26 | - "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https" 27 | 28 | portainer: 29 | image: portainer/portainer-ce:2.0.0 30 | command: -H unix:///var/run/docker.sock 31 | restart: always 32 | volumes: 33 | - /var/run/docker.sock:/var/run/docker.sock 34 | - portainer_data:/data 35 | labels: 36 | # Frontend 37 | - "traefik.enable=true" 38 | - "traefik.http.routers.frontend.rule=Host(`portainer.yourdomain.com`)" 39 | - "traefik.http.routers.frontend.entrypoints=websecure" 40 | - "traefik.http.services.frontend.loadbalancer.server.port=9000" 41 | - "traefik.http.routers.frontend.service=frontend" 42 | - "traefik.http.routers.frontend.tls.certresolver=leresolver" 43 | 44 | # Edge 45 | - "traefik.http.routers.edge.rule=Host(`edge.yourdomain.com`)" 46 | - "traefik.http.routers.edge.entrypoints=websecure" 47 | - "traefik.http.services.edge.loadbalancer.server.port=8000" 48 | - "traefik.http.routers.edge.service=edge" 49 | - "traefik.http.routers.edge.tls.certresolver=leresolver" 50 | 51 | 52 | volumes: 53 | portainer_data: 54 | -------------------------------------------------------------------------------- /traefik/edge.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/portainer/portainer-compose/b6610410e6b280ea22d871114b891c9e39c9a8e1/traefik/edge.png --------------------------------------------------------------------------------