├── .gitignore ├── Dockerfile ├── LICENSE ├── README.md ├── docker-entrypoint └── nginx.conf.example /.gitignore: -------------------------------------------------------------------------------- 1 | build.sh 2 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine/git AS downloader 2 | 3 | ARG GIT_BRANCH=master 4 | ARG GIT_URL=https://github.com/Daniel15/simple-nuget-server 5 | 6 | # Download project 7 | RUN git clone --branch $GIT_BRANCH --depth 1 $GIT_URL /project && \ 8 | rm -rf /project/.git 9 | 10 | FROM nginx 11 | LABEL maintainer="Swire Chen " 12 | 13 | ENV APP_BASE /var/www/simple-nuget-server 14 | ENV DEFAULT_SIZE 20M 15 | ENV DEFAULT_WORKER_PROCESSES 1 16 | ENV DEFAULT_WORKER_CONNECTIONS 65535 17 | 18 | COPY --from=downloader /project $APP_BASE 19 | 20 | # Install PHP7 21 | RUN apt-get update && \ 22 | apt-get install -y --no-install-recommends --no-install-suggests \ 23 | php php-fpm php-sqlite3 php-xml php-zip && \ 24 | rm -rf /var/lib/apt/lists/* && \ 25 | chown www-data:www-data $APP_BASE/db $APP_BASE/packagefiles && \ 26 | chmod 0770 $APP_BASE/db $APP_BASE/packagefiles && \ 27 | rm /etc/nginx/conf.d/* 28 | 29 | # Activate the nginx configuration 30 | COPY nginx.conf.example /etc/nginx/conf.d/nuget.conf 31 | 32 | COPY docker-entrypoint /bin/docker-entrypoint 33 | 34 | # Set default upload file sizes limit 35 | RUN export PHP_VERSION=$(ls /etc/php/) && \ 36 | sed -i -e "s/post_max_size.*/post_max_size = $DEFAULT_SIZE/" /etc/php/$PHP_VERSION/fpm/php.ini && \ 37 | sed -i -e "s/upload_max_filesize.*/upload_max_filesize = $DEFAULT_SIZE/" /etc/php/$PHP_VERSION/fpm/php.ini && \ 38 | sed -i -e "s/;pm.max_requests.*$/pm.max_requests = 10240/" /etc/php/$PHP_VERSION/fpm/pool.d/www.conf && \ 39 | sed -i -e "/server_name.*$/a\ client_max_body_size $DEFAULT_SIZE;" /etc/nginx/conf.d/nuget.conf && \ 40 | sed -i -e "s/__PHP_VERSION__/$PHP_VERSION/g" /etc/nginx/conf.d/nuget.conf && \ 41 | sed -i -e "s/worker_processes.*$/worker_processes $DEFAULT_WORKER_PROCESSES;/" /etc/nginx/nginx.conf && \ 42 | sed -i -e "s/worker_connections.*$/ worker_connections $DEFAULT_WORKER_CONNECTIONS ;/" /etc/nginx/nginx.conf && \ 43 | sed -i -e "/worker_connections.*$/a\ use epoll;" /etc/nginx/nginx.conf && \ 44 | sed -i -e "s/keepalive_timeout.*$/ keepalive_timeout 5;/" /etc/nginx/nginx.conf && \ 45 | sed -i -e "s/__PHP_VERSION__/$PHP_VERSION/g" /bin/docker-entrypoint && \ 46 | cd /etc/ && tar -cf /tmp/nginx.tar nginx && \ 47 | usermod -G www-data nginx && \ 48 | chmod +x /bin/docker-entrypoint 49 | 50 | VOLUME ["$APP_BASE/db", "$APP_BASE/packagefiles"] 51 | 52 | EXPOSE 80-60000 53 | 54 | ENTRYPOINT ["docker-entrypoint"] 55 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 idoop 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # docker-nuget-server 2 | 3 | [![Docker Build Status](https://img.shields.io/docker/cloud/build/idoop/docker-nuget-server)](https://hub.docker.com/r/idoop/docker-nuget-server/) 4 | [![Docker Automated build](https://img.shields.io/docker/automated/idoop/docker-nuget-server)](https://hub.docker.com/r/idoop/docker-nuget-server/) 5 | [![Docker Pulls](https://img.shields.io/docker/pulls/idoop/docker-nuget-server.svg)](https://hub.docker.com/r/idoop/docker-nuget-server/) 6 | [![ImageLayers Size](https://img.shields.io/docker/image-size/idoop/docker-nuget-server/latest)](https://hub.docker.com/r/idoop/docker-nuget-server/) 7 | 8 | 9 | 10 | Auto build docker [image](https://hub.docker.com/r/idoop/docker-nuget-server/) for [simple-nuget-server](https://github.com/Daniel15/simple-nuget-server) 11 | 12 | ## Quick start 13 | 14 | ### docker command 15 | ``` shell 16 | docker run -d --name nuget-server -p 80:80 -e NUGET_API_KEY="112233" idoop/docker-nuget-server 17 | ``` 18 | 19 | ### docker-compose 20 | 21 | ``` yaml 22 | version: '2' 23 | services: 24 | nuget-server: 25 | container_name: nuget-server 26 | image: idoop/docker-nuget-server:latest 27 | network_mode: "host" 28 | restart: always 29 | environment: 30 | NUGET_API_KEY: "112233" 31 | UPLOAD_MAX_FILESIZE: "40M" 32 | 33 | ## When use host network mode, 34 | ## set SERVER_PORT value if you want change server expose port. 35 | # SERVER_PORT: "8080" 36 | 37 | ## Set nuget server domain[:port], also you can use machine(not container) ip[:port]. 38 | ## eg: "192.168.11.22:8080" or "nuet.eg.com:8080" 39 | SERVER_NAME: "nuget.example.com" 40 | WORKER_PROCESSES: "2" 41 | volumes: 42 | - nuget-db:/var/www/simple-nuget-server/db 43 | - nuget-packagefiles:/var/www/simple-nuget-server/packagefiles 44 | - nuget-nginx:/etc/nginx 45 | ulimits: 46 | nproc: 8096 47 | nofile: 48 | soft: 65535 49 | hard: 65535 50 | volumes: 51 | nuget-db: 52 | nuget-packagefiles: 53 | nuget-nginx: 54 | ``` 55 | 56 | **Note:** make sure your Host feed available on either port `80`. 57 | 58 | ## Environment configuration 59 | 60 | * `NUGET_API_KEY`: nuget api key. Default key: `112233` 61 | 62 | * `UPLOAD_MAX_FILESIZE`: the maximum size of an uploaded nuget package file. Default size: `20M` 63 | 64 | * `WORKER_PROCESSES`: nginx worker processes.Default: `1` 65 | 66 | * `WORKER_CONNECTIONS`: nginx worker connections. Default: `65535` 67 | 68 | * `SERVER_NAME`: name of server domain,set value with domain name or ip.Default: `localhost` (Require). 69 | 70 | * `SERVER_PORT`: server port. Default port: `80`. 71 | 72 | **Note:** If use `host` network mode,you can set `SERVER_PORT` value to change nuget server port. 73 | 74 | * `BASE_URL`: set a fixed base URL, instead of generating it from `SERVER_NAME` and `SERVER_PORT`. Use this when the container is not facing the outside world, e.g. when there is another reverse proxy. 75 | 76 | ## Volumes 77 | * `/var/www/simple-nuget-server/db` Path with SQLite database. 78 | * `/var/www/simple-nuget-server/packagefiles` Path with nuget packages save. 79 | * `/etc/nginx` Path with nginx config. If you want use https, please mount this path, generate cert/key and modify `/conf.d/nuget.conf` to support https,then restart container. 80 | 81 | 82 | ## Test 83 | 84 | Download [nuget commandline tool](https://www.nuget.org/downloads). 85 | 86 | #### Push nuget package: 87 | ``` shell 88 | nuget push xxx.nupkg -source SERVER_NAME -apikey NUGET_API_KEY 89 | ``` 90 | 91 | #### Download nuget package: 92 | ``` shell 93 | nuget install xxx -source SERVER_NAME -packagesavemode nupkg 94 | ``` 95 | 96 | ## Bug: 97 | 98 | If not set `SERVER_NAME` value ,client will resolve the default server name `localhost` at client machine. 99 | -------------------------------------------------------------------------------- /docker-entrypoint: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | NGINX_CONF_DEFAULT="/etc/nginx/nginx.conf" 4 | NGINX_CONF_NUGET="/etc/nginx/conf.d/nuget.conf" 5 | NGINX_FILES=`ls /etc/nginx/` 6 | if [ -z "${NGINX_FILES}" ];then 7 | chown nginx -R /etc/nginx 8 | cd /etc && tar -xf /tmp/nginx.tar 9 | fi 10 | 11 | if [ "${1:0:1}" == "-" ];then 12 | echo "Usage: docker run -d -p 80:80 --name nuget-server idoop/simple-nuget-server" 13 | elif [ "$#" == "0" ];then 14 | 15 | # Set API key. 16 | DEFAULT_API_KEY="112233" 17 | if [ -z ${NUGET_API_KEY} ];then 18 | echo "Using default Nuget push API key: ${DEFAULT_API_KEY}" 19 | NUGET_API_KEY=${DEFAULT_API_KEY} 20 | else 21 | echo "Using specified API key: ${NUGET_API_KEY}" 22 | fi 23 | sed -i -e "s/apiKey =.*/apiKey = '${NUGET_API_KEY}';/" $APP_BASE/inc/config.php 24 | 25 | # Set Upload max file size. 26 | if [ -z ${UPLOAD_MAX_FILESIZE} ];then 27 | echo "Using default max upload file size is ${DEFAULT_SIZE}." 28 | else 29 | echo "Using specified max upload file size is ${UPLOAD_MAX_FILESIZE}." 30 | sed -i -e "s/post_max_size.*$/post_max_size = ${UPLOAD_MAX_FILESIZE}/" /etc/php/__PHP_VERSION__/fpm/php.ini 31 | sed -i -e "s/upload_max_filesize.*$/upload_max_filesize = ${UPLOAD_MAX_FILESIZE}/" /etc/php/__PHP_VERSION__/fpm/php.ini 32 | sed -i -e "s/client_max_body_size.*$/client_max_body_size ${UPLOAD_MAX_FILESIZE};/g" /etc/nginx/conf.d/nuget.conf 33 | fi 34 | 35 | # Set server name. 36 | if [ -z ${SERVER_NAME} ];then 37 | echo "Using default server name: localhost" 38 | else 39 | echo "Using specified server name: ${SERVER_NAME}" 40 | sed -e "s/server_name.*/server_name ${SERVER_NAME};/" -i ${NGINX_CONF_NUGET} 41 | fi 42 | 43 | # Set server port. 44 | if [ -z ${SERVER_PORT} ];then 45 | echo "Using default port: 80" 46 | else 47 | echo "Using specified port: ${SERVER_PORT}" 48 | sed -e "s/listen.*/listen ${SERVER_PORT};/" -i ${NGINX_CONF_NUGET} 49 | fi 50 | 51 | # Set Worker_Processes 52 | if [ -z ${WORKER_PROCESSES} ];then 53 | echo "Using default nginx worker_processes: ${DEFAULT_WORKER_PROCESSES}" 54 | else 55 | echo "Using specified nginx worker_processes ${WORKER_PROCESSES}" 56 | sed -e "s/worker_processes.*$/worker_processes ${WORKER_PROCESSES};/" -i ${NGINX_CONF_DEFAULT} 57 | fi 58 | 59 | # Set Worker_Connections 60 | if [ -z ${WORKER_CONNECTIONS} ];then 61 | echo "Using default worker_connections: ${DEFAULT_WORKER_CONNECTIONS}" 62 | else 63 | echo "Using specified worker_connections: ${WORKER_CONNECTIONS}" 64 | sed -e "s/worker_connections.*$/ worker_connections ${WORKER_CONNECTIONS};/" -i ${NGINX_CONF_DEFAULT} 65 | fi 66 | 67 | if [ -n "${BASE_URL}" ];then 68 | echo "Use base URL: ${BASE_URL}" 69 | sed -e "/fastcgi_param BASE_URL.*$/d" \ 70 | -e "/fastcgi_temp_file_write_size.*$/a\ fastcgi_param BASE_URL ${BASE_URL};" -i ${NGINX_CONF_NUGET} 71 | fi 72 | 73 | # Set folder property. 74 | #chown www-data $APP_BASE/db $APP_BASE/packagefiles 75 | 76 | # Start 77 | echo 'Starting Services.' 78 | /etc/init.d/php__PHP_VERSION__-fpm start 79 | /etc/init.d/nginx start 80 | 81 | tail -f /dev/null 82 | 83 | else 84 | exec "$@" 85 | fi 86 | -------------------------------------------------------------------------------- /nginx.conf.example: -------------------------------------------------------------------------------- 1 | # Example of an Nginx configuration for Simple NuGet Server 2 | 3 | server { 4 | server_name localhost; 5 | listen 80 default backlog=1024; 6 | root /var/www/simple-nuget-server/public/; 7 | client_body_buffer_size 5M; 8 | client_header_buffer_size 4k; 9 | open_file_cache max=65535 inactive=60s; 10 | open_file_cache_valid 60s; 11 | open_file_cache_min_uses 1; 12 | open_file_cache_errors on; 13 | 14 | rewrite ^/$ /index.php; 15 | rewrite ^/\$metadata$ /metadata.xml; 16 | rewrite ^/Search\(\)/\$count$ /count.php; 17 | rewrite ^/Search\(\)$ /search.php; 18 | rewrite ^/Packages\(\)$ /search.php; 19 | rewrite ^/Packages\(Id='([^']+)',Version='([^']+)'\)$ /findByID.php?id=$1&version=$2; 20 | rewrite ^/GetUpdates\(\)$ /updates.php; 21 | rewrite ^/FindPackagesById\(\)$ /findByID.php; 22 | # NuGet.exe sometimes uses two slashes (//download/blah) 23 | rewrite ^//?download/([^/]+)/([^/]+)$ /download.php?id=$1&version=$2; 24 | rewrite ^/([^/]+)/([^/]+)$ /delete.php?id=$1&version=$2; 25 | 26 | # NuGet.exe adds /api/v2/ to URL when the server is at the root 27 | rewrite ^/api/v2/package/$ /index.php; 28 | rewrite ^/api/v2/package/([^/]+)/([^/]+)$ /delete.php?id=$1&version=$2; 29 | 30 | location ~ \.php$ { 31 | 32 | try_files $uri =404; 33 | fastcgi_split_path_info ^(.+\.php)(/.+)$; 34 | fastcgi_pass unix:/var/run/php/php__PHP_VERSION__-fpm.sock; 35 | fastcgi_index index.php; 36 | fastcgi_buffers 4 1024k; 37 | fastcgi_buffer_size 1024k; 38 | fastcgi_busy_buffers_size 1024k; 39 | fastcgi_temp_file_write_size 5M; 40 | fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; 41 | include fastcgi_params; 42 | 43 | } 44 | 45 | location = /index.php { 46 | dav_methods PUT DELETE; 47 | 48 | try_files $uri =404; 49 | fastcgi_split_path_info ^(.+\.php)(/.+)$; 50 | fastcgi_pass unix:/var/run/php/php__PHP_VERSION__-fpm.sock; 51 | fastcgi_index index.php; 52 | fastcgi_buffers 4 1024k; 53 | fastcgi_buffer_size 1024k; 54 | fastcgi_busy_buffers_size 1024k; 55 | fastcgi_temp_file_write_size 5M; 56 | fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; 57 | include fastcgi_params; 58 | 59 | # PHP doesn't parse request body for PUT requests, so fake a POST. 60 | fastcgi_param REQUEST_METHOD POST; 61 | fastcgi_param HTTP_X_METHOD_OVERRIDE $request_method; 62 | } 63 | 64 | # Used with X-Accel-Redirect 65 | location /packagefiles { 66 | internal; 67 | root /var/www/simple-nuget-server/; 68 | } 69 | } 70 | --------------------------------------------------------------------------------